computed_field-8.x-2.x-dev/src/Plugin/ComputedField/ReverseEntityReference.php

src/Plugin/ComputedField/ReverseEntityReference.php
<?php

namespace Drupal\computed_field\Plugin\ComputedField;

use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Component\Plugin\ConfigurableInterface;
use Drupal\computed_field\Attribute\ComputedField;
use Drupal\computed_field\Field\ComputedFieldDefinitionWithValuePluginInterface;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\PluginFormInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;

/**
 * Provides a reverse entity reference computed field.
 */
#[ComputedField(
  id: 'reverse_entity_reference',
  label: new TranslatableMarkup('Reverse entity reference'),
  field_type: 'entity_reference',
)]
class ReverseEntityReference extends ComputedFieldBase implements PluginFormInterface, ConfigurableInterface {

  use StringTranslationTrait;

  /**
   * {@inheritdoc}
   */
  public function computeValue(EntityInterface $host_entity, ComputedFieldDefinitionWithValuePluginInterface $computed_field_definition): array {
    [$referencing_entity_type_id, $field_name] = explode('-', $this->configuration['reference_field']);

    $query = \Drupal::service('entity_type.manager')->getStorage($referencing_entity_type_id)->getQuery();
    $query
      ->accessCheck(TRUE)
      ->condition($field_name, $host_entity->id());
    $result = $query->execute();

    return array_values($result);
  }

  /**
   * {@inheritdoc}
   */
  public function useLazyBuilder(EntityInterface $host_entity, ComputedFieldDefinitionWithValuePluginInterface $computed_field_definition): bool {
    // Our field has a cache dependency not only on the entities it shows, but
    // on the referring entity type as a whole (that is, the ENTITY_TYPE_list
    // cache tag) because a new entity might need to be included.
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheability(EntityInterface $host_entity, ComputedFieldDefinitionWithValuePluginInterface $computed_field_definition): ?CacheableMetadata {
    $cacheability = new CacheableMetadata();

    [$referencing_entity_type_id, ] = explode('-', $this->configuration['reference_field']);
    $referencing_entity_type = \Drupal::service('entity_type.manager')->getDefinition($referencing_entity_type_id);

    $cacheability->addCacheTags($referencing_entity_type->getListCacheTags());

    foreach ($host_entity->get($computed_field_definition->getName())->referencedEntities() as $entity) {
      $cacheability->addCacheableDependency($entity);
    }

    return $cacheability;
  }

  /**
   * {@inheritdoc}
   */
  public function getStorageDefinitionSettings(): array {
    [$referencing_entity_type_id, ] = explode('-', $this->configuration['reference_field']);

    return [
      'target_type' => $referencing_entity_type_id,
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    // Find all fields that point to the computed entity's host entity bundle.
    // We have to inspect the computed_field entity, and first get it from the
    // form object. This makes the assumption that this plugin is being used
    // within a ComputedEntityForm.
    $form_object = $form_state->getFormObject();
    $computed_field_entity = $form_object->getEntity();
    $referencing_entity_type_id = $computed_field_entity->getTargetEntityTypeId();
    $entity_type_manager = \Drupal::service('entity_type.manager');

    $field_map = \Drupal::service('entity_field.manager')->getFieldMapByFieldType('entity_reference');
    $options = [];
    foreach ($field_map as $entity_type_id => $entity_type_map_data) {
      $field_storage_definitions = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions($entity_type_id);
      foreach ($entity_type_map_data as $field_name => $field_map_data) {
        if (!isset($field_storage_definitions[$field_name])) {
          continue;
        }

        $field_storage_definition = $field_storage_definitions[$field_name];

        if ($field_storage_definition->getSettings()['target_type'] != $referencing_entity_type_id) {
          continue;
        }

        $options[$entity_type_id . '-' . $field_name] = $this->t("%field on %entity-type entities", [
          // @todo Get the label from one of the field configs if the storage is
          // a config entity.
          '%field' => $field_storage_definition->getLabel(),
          '%entity-type' => $entity_type_manager->getDefinition($entity_type_id)->getLabel(),
        ]);
      }
    }

    natcasesort($options);

    $form['reference_field'] = [
      '#type' => 'select',
      '#title' => $this->t("Entity reference field"),
      '#description' => $this->t("The reference field that will be queried for entities that point to the current entity."),
      '#options' => $options,
      '#empty_value' => '',
      '#required' => TRUE,
    ];
    if (empty($options)) {
      $form['reference_field']['#empty_option'] = $this->t("There are no reference fields that point to this entity bundle.");
    }

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {

  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {

  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    return [
      // The referencing field, in the format HOST_ENTITY_TYPE-FIELD_NAME. For
      // example, 'node-uid'.
      'reference_field' => '',
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getConfiguration() {
    return $this->configuration;
  }

  /**
   * {@inheritdoc}
   */
  public function setConfiguration(array $configuration) {
    $this->configuration = $configuration + $this->defaultConfiguration();
  }

}

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

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