flow-1.0.0-beta8/src/Plugin/flow/Derivative/Subject/ReferenceDeriver.php

src/Plugin/flow/Derivative/Subject/ReferenceDeriver.php
<?php

namespace Drupal\flow\Plugin\flow\Derivative\Subject;

use Drupal\flow\Helpers\EntityFieldManagerTrait;
use Drupal\flow\Plugin\flow\Derivative\ContentDeriverBase;
use Drupal\flow\Plugin\FlowSubjectManager;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Subject plugin deriver for content referenced from other content.
 *
 * This deriver wraps other plugin definitions and thus makes use of the
 * subject plugin manager by itself. To prevent infinite recursion during
 * plugin definition discovery, an internal flag will be used. This deriver
 * might also add a lot more plugin definitions, making the list of available
 * subjects quite large. This could be improved in the future.
 *
 * @see \Drupal\flow\Plugin\flow\Subject\Reference
 */
class ReferenceDeriver extends ContentDeriverBase {

  use EntityFieldManagerTrait;

  /**
   * The Flow subject manager for retreiving other plugin definitions.
   *
   * @var \Drupal\flow\Plugin\FlowSubjectManager
   */
  protected FlowSubjectManager $subjectManager;

  /**
   * A flag indicating whether we are calling the definitions from root level.
   *
   * This flag is used to prevent infinite recursion, as we want to use other
   * existing plugin definitions, and wrap them using existing reference fields.
   *
   * @var bool
   */
  protected bool $rootDefinitionCall = TRUE;

  /**
   * A statically cached list of reference derivatives.
   *
   * @var array|null
   */
  protected static ?array $referenceDerivatives;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, $base_plugin_id) {
    /** @var \Drupal\flow\Plugin\flow\Derivative\Subject\ReferenceDeriver $instance */
    $instance = parent::create($container, $base_plugin_id);
    $instance->setSubjectManager($container->get('plugin.manager.flow.subject'));
    $instance->setEntityFieldManager($container->get(self::$entityFieldManagerServiceName));
    return $instance;
  }

  /**
   * {@inheritdoc}
   */
  public function getDerivativeDefinitions($base_plugin_definition) {
    if (!$this->rootDefinitionCall) {
      // Coming from the root call, only return an empty array at this point.
      return [];
    }
    if (isset(self::$referenceDerivatives)) {
      $this->rootDefinitionCall = TRUE;
      return self::$referenceDerivatives;
    }

    // From here on, flag this one not to be the root level call.
    $this->rootDefinitionCall = FALSE;
    $other_definitions = $this->subjectManager->getDefinitions();

    $reference_derivatives = [];
    $content_derivatives = parent::getDerivativeDefinitions($base_plugin_definition);
    foreach ($other_definitions as $other_plugin_id => $other_definition) {
      $field_definitions = $this->entityFieldManager->getFieldDefinitions($other_definition['entity_type'], $other_definition['bundle']);
      $reference_targets = [];
      foreach ($field_definitions as $field_definition) {
        $field_storage_definition = $field_definition->getFieldStorageDefinition();
        if (!(strpos($field_storage_definition->getType(), 'entity_reference') === 0)) {
          continue;
        };
        $target_type = $field_storage_definition->getSetting('target_type');
        $handler_settings = $field_definition->getConfig($other_definition['bundle'])->getSetting('handler_settings');
        if (!isset($reference_targets[$target_type])) {
          $reference_targets[$target_type] = [];
        }
        if (!empty($handler_settings['target_bundles'])) {
          $reference_targets[$target_type] += $handler_settings['target_bundles'];
        }
        else {
          $reference_targets[$target_type] = [];
        }
      }
      foreach ($reference_targets as $target_type => $target_bundles) {
        foreach ($content_derivatives as $content_derivative) {
          $entity_type_id = $content_derivative['entity_type'];
          $bundle = $content_derivative['bundle'];
          if (($target_type !== $entity_type_id) || (!empty($target_bundles) && !in_array($bundle, $target_bundles))) {
            continue;
          }
          $derivative_id = $entity_type_id . '.' . $bundle . '::' . $other_plugin_id;
          $reference_derivatives[$derivative_id] = [
            'task_modes' => $other_definition['task_modes'],
            'targets' => $other_definition['targets'],
            'label' => $this->t('@reference referenced from @content', [
              '@reference' => $content_derivative['label'],
              '@content' => $other_definition['label'],
            ]),
          ] + $content_derivative;
        }
      }
    }

    // Reset the flag, in order to have the same behavior also on a cache reset.
    $this->rootDefinitionCall = TRUE;
    self::$referenceDerivatives = $reference_derivatives;
    return $reference_derivatives;
  }

  /**
   * Set the Flow subject plugin manager.
   *
   * @param \Drupal\flow\Plugin\FlowSubjectManager $subject_manager
   *   The subject plugin manager.
   */
  public function setSubjectManager(FlowSubjectManager $subject_manager): void {
    $this->subjectManager = $subject_manager;
  }

}

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

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