entity_value_inheritance-1.3.0/src/Services/Helper.php

src/Services/Helper.php
<?php

namespace Drupal\entity_value_inheritance\Services;

use Drupal\Component\EventDispatcher\Event;
use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldTypePluginManagerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\entity_value_inheritance\EntityValueInheritanceUpdaterPluginInterface;
use Drupal\entity_value_inheritance\EntityValueInheritanceUpdaterPluginManager;
use Psr\Log\LoggerInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;

/**
 * Service used for helping get more complex details.
 */
final class Helper {

  use StringTranslationTrait;

  /**
   * Constructs a new \Drupal\entity_value_inheritance\Services\Helper object.
   */
  public function __construct(protected FieldTypePluginManagerInterface $fieldTypePluginManager, protected EntityTypeManagerInterface $entityTypeManager, protected EntityTypeBundleInfoInterface $entityTypeBundleInfo, protected EntityFieldManagerInterface $entityFieldManager, protected ModuleHandlerInterface $moduleHandler, protected EntityValueInheritanceUpdaterPluginManager $pluginManager, protected LoggerInterface $logger, protected EventDispatcherInterface $eventDispatcher) {

  }

  /**
   * Return a list of all field types.
   *
   * @return array
   *   List of all field types.
   */
  protected function getFieldTypeList(): array {
    $list = $this->fieldTypePluginManager->getDefinitions();
    $this->moduleHandler->alter('entity_value_inheritance_field_type_list', $list);
    return $list;
  }

  /**
   * Return a list of all entities.
   *
   * @return \Drupal\Core\Entity\EntityTypeInterface[]
   *   List of entity types.
   */
  public function getEntityTypeList(): array {
    $list = $this->entityTypeManager->getDefinitions();
    array_filter($list, function ($item) {
      return !$item->entityClassImplements(FieldableEntityInterface::class);
    });

    $this->moduleHandler->alter('entity_value_inheritance_entity_type_list', $list);
    return $list;
  }

  /**
   * Return a list of all entity bundles.
   *
   * @param string $entityTypeId
   *   Entity Type ID.
   *
   * @return array
   *   List of all entity bundles.
   */
  public function getEntityBundleList(string $entityTypeId): array {
    $entity = $this->entityTypeManager->getDefinition($entityTypeId);
    if (!$entity->entityClassImplements(FieldableEntityInterface::class)) {
      return [];
    }

    $list = $this->entityTypeBundleInfo->getBundleInfo($entityTypeId);
    $hooks = [
      'entity_value_inheritance_entity_bundle_list',
      'entity_value_inheritance_entity_bundle_list__' . $entityTypeId,
    ];
    $this->moduleHandler->alter($hooks, $list, $entityTypeId);
    return $list;
  }

  /**
   * Return a list of all entity bundle fields.
   *
   * @param string $entityTypeId
   *   Entity Type ID.
   * @param string $entityBundleId
   *   Entity Bundle ID.
   *
   * @return array
   *   List of fields for the provided entity and bundle.
   */
  public function getEntityBundleFieldList(string $entityTypeId, string $entityBundleId): array {
    $entity = $this->entityTypeManager->getDefinition($entityTypeId);
    if (!$entity->entityClassImplements(FieldableEntityInterface::class)) {
      return [];
    }

    $list = $this->entityFieldManager->getFieldDefinitions($entityTypeId, $entityBundleId);

    // List of fields that should be excluded.
    $exclude = ['nid', 'vid'];
    $list = array_filter($list, function ($key) use ($exclude) {
      return !in_array($key, $exclude);
    }, ARRAY_FILTER_USE_KEY);

    $hooks = [
      'entity_value_inheritance_entity_bundle_field_list',
      'entity_value_inheritance_entity_bundle_field_list__' . $entityTypeId,
      'entity_value_inheritance_entity_bundle_field_list__' . $entityTypeId . '__' . $entityBundleId,
    ];
    $this->moduleHandler->alter($hooks, $list, $entityTypeId, $entityBundleId);
    return $list;
  }

  /**
   * Return a list of entity fields by type.
   *
   * @param string $entityTypeId
   *   Entity Type ID.
   * @param string $entityBundleId
   *   Entity Bundle ID.
   * @param string $fieldType
   *   Field type to search for.
   *
   * @return array
   *   Return a list of fields.
   */
  public function getEntityBundleFieldListByType(string $entityTypeId, string $entityBundleId, string $fieldType): array {
    $entity = $this->entityTypeManager->getDefinition($entityTypeId);
    if (!$entity->entityClassImplements(FieldableEntityInterface::class)) {
      return [];
    }

    $list = [];

    foreach ($this->getEntityBundleFieldList($entityTypeId, $entityBundleId) as $fieldId => $field) {
      if ($field->getType() !== $fieldType) {
        continue;
      }
      $list[$fieldId] = $field;
    }

    return $list;
  }

  /**
   * Return a list of field types.
   *
   * @return array<string, array<string>>
   *   List of field types.
   */
  public function getFieldTypes(): array {
    $fieldTypes = [];
    foreach ($this->getFieldTypeList() as $fieldTypeId => $fieldType) {
      $fieldTypes[$this->getText($fieldType['category'])][$fieldTypeId] = $this->getText($fieldType['label']);
      asort($fieldTypes[$this->getText($fieldType['category'])]);
    }
    ksort($fieldTypes);
    return $fieldTypes;
  }

  /**
   * Return a list of entities.
   *
   * @return string[]
   *   List of entities.
   */
  public function getEntities(): array {
    $entityTypes = [];
    foreach ($this->getEntityTypeList() as $entityTypeId => $entityType) {
      if (!$entityType->entityClassImplements(FieldableEntityInterface::class)) {
        continue;
      }
      $entityTypes[$entityTypeId] = $this->getText($entityType->getLabel());
    }
    asort($entityTypes);
    return $entityTypes;
  }

  /**
   * Return the entity type label.
   *
   * @param string $entityTypeId
   *   Entity type to look up.
   *
   * @return string
   *   Label for entity type.
   */
  public function getEntityTypeLabel(string $entityTypeId): string {
    $list = $this->getEntities();
    return $list[$entityTypeId] ?? $this->t('Unknown entity type');
  }

  /**
   * Return a list of entities and bundles.
   *
   * @return string[][]
   *   List of entity bundles.
   */
  public function getEntityBundles(): array {
    $bundles = [];
    foreach ($this->getEntityTypeList() as $entityTypeId => $entityType) {
      if (!$entityType->entityClassImplements(FieldableEntityInterface::class)) {
        continue;
      }
      $entityKey = $this->getText($entityType->getLabel());
      foreach ($this->getEntityBundleList($entityTypeId) as $entityBundleId => $entityBundle) {
        $bundles[$entityKey]["{$entityTypeId}.{$entityBundleId}"] = $this->getText($entityBundle['label']);
      }
      if (isset($bundles[$entityKey])) {
        asort($bundles[$entityKey]);
      }
    }
    ksort($bundles);
    return $bundles;
  }

  /**
   * Return the label for the provided bundle.
   *
   * @param string $entityTypeId
   *   Entity Type to search.
   * @param string $bundleId
   *   Bundle Key to look up.
   *
   * @return string
   *   String to return for the bundle.
   */
  public function getEntityBundleLabel(string $entityTypeId, string $bundleId): string {
    $bundles = $this->getEntityBundleList($entityTypeId);
    return array_key_exists($bundleId, $bundles) && array_key_exists('label', $bundles[$bundleId]) ?
      $this->getText($bundles[$bundleId]['label']) :
      $this->t('Unknown bundle');
  }

  /**
   * Return a list of bundles for the provided entity type.
   *
   * @param string $entityTypeId
   *   Entity types to search for.
   *
   * @return string[]
   *   List of bundles for entity.
   */
  public function getBundlesOptions(string $entityTypeId): array {
    if (empty($entityTypeId)) {
      return [];
    }

    $list = [];
    foreach ($this->getEntityBundleList($entityTypeId) as $bundle_id => $bundle) {
      $list[$bundle_id] = $this->getText($bundle['label']);
    }
    asort($list);
    return $list;
  }

  /**
   * Return a field definition.
   *
   * @param string $entityTypeId
   *   Entity Type ID to search.
   * @param string $entityBundleId
   *   Entity Bundle ID to search.
   * @param string $entityFieldId
   *   Entity Field ID to search.
   *
   * @return \Drupal\Core\Field\FieldDefinitionInterface|null
   *   List of all fields for entity.
   */
  public function getEntityBundleField(string $entityTypeId, string $entityBundleId, string $entityFieldId): ?FieldDefinitionInterface {
    $list = $this->getEntityBundleFieldList($entityTypeId, $entityBundleId);
    return $list[$entityFieldId] ?? NULL;
  }

  /**
   * Return a list of all fields for a bundle.
   */
  public function getEntityBundleFieldsOptions(string $entityTypeId, string $entityBundleId, ?string $sourceFieldId = NULL): array {
    if (empty($entityTypeId) || empty($entityBundleId)) {
      return [];
    }

    $list = [];

    $sourceFieldType = NULL;
    if ($sourceFieldId !== NULL) {
      [$sourceEntityId, $sourceEntityBundleId, $sourceEntityFieldId] = explode('.', $sourceFieldId);
      $fieldList = $this->getEntityBundleFieldList($sourceEntityId, $sourceEntityBundleId);
      $sourceFieldType = $fieldList[$sourceEntityFieldId]?->getType();
    }

    foreach ($this->getEntityBundleFieldList($entityTypeId, $entityBundleId) as $entityBundleFieldId => $entityBundleField) {
      if (!is_null($sourceFieldType) && $entityBundleField->getType() !== $sourceFieldType) {
        continue;
      }
      $list[$entityBundleFieldId] = sprintf(
        '%s (%s) - %s',
        $this->getText($entityBundleField->getLabel()),
        $entityBundleFieldId,
        $entityBundleField->getType()
      );
    }

    return $list;
  }

  /**
   * Return the label for the provided field.
   *
   * @param string $entityTypeId
   *   Entity Type ID.
   * @param string $bundleId
   *   Bundle ID to look up.
   * @param string $fieldId
   *   Field ID to look up.
   *
   * @return string
   *   Label for the field.
   */
  public function getEntityBundleFieldLabel(string $entityTypeId, string $bundleId, string $fieldId): ?string {
    $list = $this->getEntityBundleFieldList($entityTypeId, $bundleId);
    return array_key_exists($fieldId, $list) ? $this->getText($list[$fieldId]->getLabel()) : $this->t('Unknown field');
  }

  /**
   * Return a list of entity reference fields.
   *
   * @param string $entityTypeId
   *   Entity Type ID to search for.
   * @param string $entityBundleId
   *   Entity Bundle ID to search for.
   * @param string $targetEntity
   *   Entity Type to search reference fields for.
   */
  public function getEntityReferenceFieldsOptions(string $entityTypeId, string $entityBundleId, string $targetEntity): array {
    if (empty($entityTypeId) || empty($entityBundleId)) {
      return [];
    }

    $list = [];
    foreach ($this->getEntityBundleFieldListByType($entityTypeId, $entityBundleId, 'entity_reference') as $field_id => $field) {
      if ($field->getItemDefinition()->getSetting('target_type') !== $targetEntity) {
        continue;
      }
      $list[$field_id] = sprintf(
        '%s - %s (%s)',
        $this->getText($field->getLabel()),
        $field->getType(),
        $field_id
      );
    }
    asort($list);

    return $list;
  }

  /**
   * Return a list of fields for an entity bundle.
   *
   * @return string[][]
   *   Return a list of entity bundle fields.
   */
  public function getEntityBundleFields(): array {
    $fields = [];
    foreach ($this->getEntityTypeList() as $entityTypeId => $entityType) {
      if (!$entityType->entityClassImplements(FieldableEntityInterface::class)) {
        continue;
      }
      foreach ($this->getEntityBundleList($entityTypeId) as $entityBundleId => $entityBundle) {
        $entityBundleKey = "{$this->getText($entityType->getLabel())} - {$this->getText($entityBundle['label'])}";
        foreach ($this->getEntityBundleFieldList($entityTypeId, $entityBundleId) as $entityBundleFieldId => $entityBundleField) {
          $fields[$entityBundleKey]["{$entityTypeId}.{$entityBundleId}.{$entityBundleFieldId}"] = $this->getText($entityBundleField->getLabel());
        }

        if (isset($fields[$entityBundleKey])) {
          asort($fields[$entityBundleKey]);
        }
      }
    }
    ksort($fields);

    return $fields;
  }

  /**
   * Get the text value for the provided item.
   *
   * @return string
   *   Return the value for the string.
   */
  public function getText(TranslatableMarkup|string $text): string {
    return ($text instanceof TranslatableMarkup) ? $text->__toString() : $text;
  }

  /**
   * Get a list of all the plugins.
   *
   * @return \Drupal\entity_value_inheritance\EntityValueInheritanceUpdaterPluginInterface[]
   *   List of plugins.
   */
  public function getPlugins(): array {
    $list = $this->pluginManager->getDefinitions();
    uasort($list, function ($a, $b) {
      if ($a['title'] === $b['title']) {
        return 0;
      }
      return $a['title'] > $b['title'] ? 1 : -1;
    });
    return $list;
  }

  /**
   * Search storage for inheritances for the provided criteria.
   *
   * @param array $search
   *   Search parameters.
   *
   * @return \Drupal\entity_value_inheritance\Entity\InheritanceInterface[]
   *   Return a list of enabled inheritance items.
   */
  protected function searchStorage(array $search): array {
    $items = [];
    try {
      /** @var \Drupal\entity_value_inheritance\Entity\InheritanceInterface[] $items */
      $items = $this
        ->entityTypeManager
        ->getStorage('inheritance')
        ->loadByProperties($search);
    }
    catch (InvalidPluginDefinitionException | PluginNotFoundException $exception) {
      $this->logger->error(
        'Searching Storage Error. <pre>@message</pre>',
        ['@message' => $exception->getMessage()]
      );
    }
    return $items;
  }

  /**
   * Query for entities based on their reference.
   *
   * @param string $entity_type
   *   Entity type to search against.
   * @param \Drupal\entity_value_inheritance\Entity\InheritanceInterface[] $inheritances
   *   Inheritances to group together to find the destinations.
   * @param \Drupal\Core\Entity\EntityInterface $refEntity
   *   Source Entity to search for a reference to.
   *
   * @return \Drupal\Core\Entity\EntityInterface[]
   *   Entities returned from the query.
   */
  public function queryEntities(string $entity_type, array $inheritances, EntityInterface $refEntity): array {
    try {
      $query = $this
        ->entityTypeManager
        ->getStorage($entity_type)
        // @todo Question Does this pose a security risk?
        ->getQuery()
        ->accessCheck(FALSE);
      $group = $query->orConditionGroup();

      $searchGroup = [];
      foreach ($inheritances as $inheritance) {
        $key = sprintf('%s.%s', $inheritance->getDestinationBundle(), $inheritance->getDestinationReferenceField());
        if (!isset($searchGroup[$key])) {
          $tmpCondition = $query->andConditionGroup();
          $tmpCondition->condition("type", $inheritance->getDestinationBundle());
          $tmpCondition->condition("{$inheritance->getDestinationReferenceField()}.target_id", $refEntity->id());
          $group->condition($tmpCondition);
          $searchGroup[$key] = TRUE;
        }
      }
      $query->condition($group);

      $ids = $query->execute();
      $list = $this
        ->entityTypeManager
        ->getStorage($entity_type)
        ->loadMultiple($ids);
    }
    catch (PluginNotFoundException | InvalidPluginDefinitionException $exception) {
      $this->logger->error(
        'Error trying load entities - <pre>@message</pre>',
        ['@message' => $exception->getMessage()]
      );
      return [];
    }
    return $list;
  }

  /**
   * Return an array of inheritances by specific field.
   *
   * @param \Drupal\entity_value_inheritance\Entity\InheritanceInterface[] $inheritances
   *   Array of inheritances.
   * @param string $property
   *   Property within Inheritance entity to group by.
   *
   * @return \Drupal\entity_value_inheritance\Entity\InheritanceInterface[][]
   *   List of inheritances grouped by property.
   */
  public function groupByProperty(array $inheritances, string $property): array {
    $list = [];
    foreach ($inheritances as $inheritance) {
      $key = $inheritance->get($property);
      if (!array_key_exists($key, $list)) {
        $list[$key] = [];
      }
      $list[$key][] = $inheritance;
    }
    return $list;
  }

  /**
   * Execute Event for event dispatcher.
   *
   * @param \Drupal\Component\EventDispatcher\Event $event
   *   Event to get processed and returned.
   * @param string $eventName
   *   Event Name being announced.
   *
   * @return \Drupal\Component\EventDispatcher\Event
   *   Event returned from dispatcher.
   */
  public function dispatchEvent(Event $event, string $eventName): Event {
    return $this->eventDispatcher->dispatch($event, $eventName);
  }

  /**
   * Return a list of all items that are matching the source item.
   *
   * @param string $entityTypeId
   *   Source Entity to search for destinations.
   * @param string|null $bundleId
   *   Source Bundle to search for.
   *
   * @return \Drupal\entity_value_inheritance\Entity\InheritanceInterface[]
   *   Return a list of enabled inheritance items.
   */
  public function getSourceItems(string $entityTypeId, ?string $bundleId = NULL): array {
    $search = [
      'source_entity_type' => $entityTypeId,
      'status' => 1,
    ];
    if ($bundleId) {
      $search['source_entity_bundle'] = $bundleId;
    }
    return $this->searchStorage($search);
  }

  /**
   * Return a list of all items where destination entity is provided.
   *
   * @param string $entityTypeId
   *   Entity Type ID to search.
   * @param string|null $bundleId
   *   Bundle ID to search.
   *
   * @return \Drupal\entity_value_inheritance\Entity\InheritanceInterface[]
   *   Return a list of enabled inheritance items.
   */
  public function getDestinationItems(string $entityTypeId, ?string $bundleId = NULL): array {
    $search = [
      'destination_entity_type' => $entityTypeId,
      'status' => 1,
    ];

    if ($bundleId) {
      $search['destination_entity_bundle'] = $bundleId;
    }
    return $this->searchStorage($search);
  }

  /**
   * Return all inheritances by the destination entity type.
   *
   * @param string $entityType
   *   Entity Type to search.
   *
   * @return \Drupal\entity_value_inheritance\Entity\InheritanceInterface[]
   */
  public function getDestinationByEntityType(string $entityType): array {
    return $this->searchStorage([
      'destination_entity_type' => $entityType,
      'status' => 1,
    ]);
  }

  /**
   * Return a list of inheritances by destination configuration.
   */
  public function getDestinationsByField(string $entityType, string $bundleType, string $field, string $fieldName = 'destination_entity_field'): array {
    return $this->searchStorage([
      'destination_entity_type' => $entityType,
      'destination_entity_bundle' => $bundleType,
      $fieldName => $field,
      'status' => 1,
    ]);
  }

  /**
   * Get all the inherited items for the provided source entity.
   *
   * @param \Drupal\Core\Entity\EntityInterface $sourceEntity
   *   Source Entity to search for.
   *
   * @return \Drupal\entity_value_inheritance\Entity\InheritanceInterface[]
   *   Items put into a multidimensional array.
   */
  public function getInheritanceItemsBySource(EntityInterface $sourceEntity): array {
    return $this->getSourceItems($sourceEntity->getEntityTypeId(), $sourceEntity->bundle());
  }

  /**
   * Get all the inherited items for the provided destination entity.
   *
   * @param \Drupal\Core\Entity\EntityInterface $destinationEntity
   *   Destination entity to search for.
   *
   * @return \Drupal\entity_value_inheritance\Entity\InheritanceInterface[]
   *   Inheritances put into array.
   */
  public function getInheritanceItemsByDestination(EntityInterface $destinationEntity): array {
    return $this->getDestinationItems($destinationEntity->getEntityTypeId(), $destinationEntity->bundle());
  }

  /**
   * Check to see if there are active records for the entity type.
   *
   * @param string $entityType
   *   Entity type id to search.
   * @param bool $source
   *   Check the source type.
   *
   * @return bool
   *   TRUE if records are found
   */
  public function hasActiveRecords(string $entityType, bool $source = FALSE): bool {
    return count($this->searchStorage([
      ($source ? 'source' : 'destination') . '_entity_type' => $entityType,
      'status' => 1,
    ])) > 0;
  }

  /**
   * Return the logger service.
   *
   * @return \Psr\Log\LoggerInterface
   *   Logging service.
   */
  public function logger(): LoggerInterface {
    return $this->logger;
  }

  /**
   * Return the strategy label.
   *
   * @param \Drupal\entity_value_inheritance\EntityValueInheritanceUpdaterPluginInterface $plugin
   *   Strategy Plugin.
   *
   * @return string
   *   Label to return.
   */
  public function getStrategyLabel(EntityValueInheritanceUpdaterPluginInterface $plugin): string {
    return $plugin->getTitle();
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc