association-1.0.0-alpha2/src/AssociationNegotiator.php

src/AssociationNegotiator.php
<?php

namespace Drupal\association;

use Drupal\association\Entity\AssociationInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Routing\RouteMatchInterface;

/**
 * Tagged service collector for entity association resolution handling.
 */
class AssociationNegotiator implements AssociationNegotiatorInterface {

  /**
   * The entity association discovered for the current route match.
   *
   * Most of the route based calls are going to be searching for the entity
   * association of the current route, and since this shouldn't change for the
   * route it's possible to keep this result instead of repetitive resolutions.
   *
   * @var \Drupal\association\Entity\AssociationInterface|false
   */
  private $defaultRouteAssoc = NULL;

  /**
   * Current discovered associations discovered by entities.
   *
   * Associations are keyed by the "{$entity_type_id}:{$entity_id}" they
   * were discovered by.
   *
   * @var \Drupal\association\Entity\AssociationInterface[]
   */
  private $byEntityCache = [];

  /**
   * The current route match.
   *
   * @var \Drupal\Core\Routing\RouteMatchInterface
   */
  protected $routeMatch;

  /**
   * List of association negotiators keyed by priority.
   *
   * @var array
   */
  protected $negotiators = [];

  /**
   * A flat sorted list of association negotiatorss.
   *
   * @var \Drupal\association\AssociationNegotiatorInterface[]
   */
  private $sorted;

  /**
   * Create a new instance of the AssociationNegotiator service collector.
   *
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   *   The current route match, to be used as a default when a route match
   *   is not provided during calls to the static::byRoute() method.
   */
  public function __construct(RouteMatchInterface $route_match) {
    $this->routeMatch = $route_match;
  }

  /**
   * Reset the internal discovery caches and allow changes to get recomputed.
   */
  public function resetCaches() {
    $this->defaultRouteAssoc = NULL;
    $this->byEntityCache = [];
  }

  /**
   * Sort and flatten the current list of negotiators if static::sorted is NULL.
   *
   * @return \Drupal\association\AssociationNegotiatorInterface[]
   *   The sorted and flattened list of AssociationNegotiatorInterface handlers.
   */
  protected function getSorted() {
    if (!isset($this->sorted)) {
      ksort($this->negotiators);

      // Merge all priority arrays into a single sorted array.
      $this->sorted = array_reduce($this->negotiators, 'array_merge', []);
    }

    return $this->sorted;
  }

  /**
   * Add more negotiator services by priority to the resolution stack.
   *
   * @param \Drupal\association\AssociationNegotiatorInterface $negotiator
   *   A association negotiator to add to the list of negotiators.
   * @param int $priority
   *   The priority of the negotiator being added. Lower numbers have a higher
   *   priority. Priorities of less than 0, will trigger before the default, and
   *   priorities higher than 1, will trigger after the default.
   *
   * @return \Drupal\association\AssociationNegotiatorInterface
   *   Return itself to allow for chaining.
   */
  public function addNegotiator(AssociationNegotiatorInterface $negotiator, $priority = 0) {
    $this->negotiators[$priority][] = $negotiator;
    $this->sorted = NULL;

    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function byRoute(RouteMatchInterface $route_match = NULL): ?AssociationInterface {
    // If using the current route match, then attempt to use the default.
    if (!$route_match || $route_match === $this->routeMatch) {
      if (!isset($this->defaultRouteAssoc)) {
        $this->defaultRouteAssoc = FALSE;

        foreach ($this->getSorted() as $negotiator) {
          if ($assoc = $negotiator->byRoute($this->routeMatch)) {
            $this->defaultRouteAssoc = $assoc;
            break;
          }
        }
      }

      return $this->defaultRouteAssoc ?: NULL;
    }
    else {
      foreach ($this->getSorted() as $negotiator) {
        if ($association = $negotiator->byRoute($route_match)) {
          return $association;
        }
      }
    }

    return NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function byEntity(EntityInterface $entity): ?AssociationInterface {
    $cacheKey = $entity->getEntityTypeId() . ':' . $entity->id();

    if (!isset($this->byEntityCache[$cacheKey])) {
      $this->byEntityCache[$cacheKey] = FALSE;

      foreach ($this->getSorted() as $negotiator) {
        if ($association = $negotiator->byEntity($entity)) {
          $this->byEntityCache[$cacheKey] = $association;
          break;
        }
      }
    }

    return $this->byEntityCache[$cacheKey] ?: NULL;
  }

}

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

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