graphql_compose-1.0.0-beta20/src/Plugin/GraphQL/DataProducer/FieldEntityReference.php

src/Plugin/GraphQL/DataProducer/FieldEntityReference.php
<?php

declare(strict_types=1);

namespace Drupal\graphql_compose\Plugin\GraphQL\DataProducer;

use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Field\EntityReferenceFieldItemListInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Plugin\Context\ContextDefinition;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\graphql\Attribute\DataProducer;
use Drupal\graphql\GraphQL\Execution\FieldContext;
use Drupal\graphql\Plugin\GraphQL\DataProducer\DataProducerPluginBase;
use Drupal\graphql\Plugin\GraphQL\DataProducer\Field\EntityReferenceTrait;
use Drupal\graphql_compose\EntityTranslateTrait;
use GraphQL\Deferred;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Produce the referenced entities from a field.
 *
 * Note: If you find a nice way to put this into a buffer, that can be used
 * to resolve multiple entity types and revisions at once, please contrib!
 *
 * Deferred with referencedEntities covers a lot of use cases.
 */
#[DataProducer(
  id: "field_entity_reference",
  name: new TranslatableMarkup("Field Entity Reference"),
  description: new TranslatableMarkup("Return entity references from a field."),
  produces: new ContextDefinition(
    data_type: "mixed",
    label: new TranslatableMarkup("Referenced entities"),
  ),
  consumes: [
    "entity" => new ContextDefinition(
      data_type: "entity",
      label: new TranslatableMarkup("Entity instance"),
    ),
    "field" => new ContextDefinition(
      data_type: "string",
      label: new TranslatableMarkup("Field name"),
    ),
    "types" => new ContextDefinition(
      data_type: "any",
      label: new TranslatableMarkup("Entity types allowed to load"),
      multiple: TRUE,
    ),
    "language" => new ContextDefinition(
      data_type: "string",
      label: new TranslatableMarkup("Language to use"),
      required: FALSE,
    ),
  ],
)]
class FieldEntityReference extends DataProducerPluginBase implements ContainerFactoryPluginInterface {

  use EntityReferenceTrait;
  use EntityTranslateTrait;

  /**
   * Constructs a new EntityLoadByUuidOrId instance.
   *
   * @param array $configuration
   *   The plugin configuration.
   * @param string $plugin_id
   *   The plugin ID.
   * @param mixed $plugin_definition
   *   The plugin definition.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   The entity type manager.
   */
  public function __construct(
    array $configuration,
    string $plugin_id,
    $plugin_definition,
    protected EntityTypeManagerInterface $entityTypeManager,
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('entity_type.manager'),
    );
  }

  /**
   * Finds the requested field on the entity.
   *
   * @param \Drupal\Core\Entity\EntityInterface|null $entity
   *   The entity to resolve a field fields off.
   * @param string $field
   *   The field to resolve entities off.
   * @param array $types
   *   The union entity types allowed to load.
   * @param string|null $language
   *   The language to use.
   * @param \Drupal\graphql\GraphQL\Execution\FieldContext $context
   *   The field context.
   *
   * @return \GraphQL\Deferred|array
   *   The resolves entities from the field.
   */
  public function resolve(?EntityInterface $entity, string $field, array $types, ?string $language, FieldContext $context): Deferred|array {

    if (!$entity instanceof FieldableEntityInterface || !$entity->hasField($field)) {
      return [];
    }

    $field = $entity->get($field);
    if (!$field instanceof EntityReferenceFieldItemListInterface || !$field->access('view')) {
      return [];
    }

    // Resolve the entities.
    return new Deferred(function () use ($field, $types, $language, $context) {
      $entities = $field->referencedEntities();

      if ($language) {
        $entities = array_map(
          fn (EntityInterface $entity) => $this->getTranslation($entity, $language),
          $entities
        );

        $entities = array_filter($entities);
      }

      foreach ($entities as $entity) {
        $context->addCacheableDependency($entity);
      }

      $entities = $this->filterAccessible($entities, NULL, 'view', $context);

      // Add a list cache tags for each empty type.
      foreach ($types as $type) {
        $has_entity = array_filter(
          $entities,
          fn ($entity) => $entity->getEntityTypeId() === $type
        );

        if (!$has_entity) {
          $type = $this->entityTypeManager->getDefinition($type);
          $tags = $type->getListCacheTags();
          $context->addCacheTags($tags);
        }
      }

      return $entities;
    });
  }

}

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

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