toolshed-8.x-1.x-dev/src/Condition/ConditionEvaluatorTrait.php

src/Condition/ConditionEvaluatorTrait.php
<?php

namespace Drupal\toolshed\Condition;

use Drupal\Component\Plugin\Exception\ContextException;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\Core\Condition\ConditionManager;
use Drupal\Core\Plugin\Context\ContextHandlerInterface;
use Drupal\Core\Plugin\ContextAwarePluginInterface;

/**
 * Trait for common evaluation and handling of a list of condition plugins.
 */
trait ConditionEvaluatorTrait {

  /**
   * Plugin manager for creation and discovery of condition plugins.
   *
   * @var \Drupal\Core\Condition\ConditionManager|null
   */
  protected ?ConditionManager $conditionManager;

  /**
   * Static method to fetch the condition plugin manager service.
   *
   * @return \Drupal\Core\Condition\ConditionManager
   *   The manager of condition plugins.
   */
  protected function getConditionManager(): ConditionManager {
    if (!isset($this->conditionManager)) {
      $this->conditionManager = \Drupal::service('plugin.manager.condition');
    }

    return $this->conditionManager;
  }

  /**
   * Get the context handler object.
   *
   * @return \Drupal\Core\Plugin\Context\ContextHandlerInterface
   *   Get the Drupal context handler.
   */
  protected function getContextHandler(): ContextHandlerInterface {
    return \Drupal::service('context.handler');
  }

  /**
   * Build and test a configured set of condition plugins.
   *
   * @param \Drupal\Core\Plugin\ContextInterface[] $contexts
   *   The contexts to use when testing conditions. Most condition plugins
   *   evaluate and often require contexts.
   * @param array $conditions
   *   An array of condition plugin configurations to use to evaluate if
   *   the conditions will pass.
   * @param string $conjunction
   *   Whether to combine the conditions using 'AND' or 'OR' boolean operaters.
   *
   * @return bool
   *   TRUE if the set of conditions passes, FALSE otherwise.
   */
  protected function evalConditions(array $contexts = [], array $conditions = [], $conjunction = 'AND'): bool {
    if (empty($conditions)) {
      return TRUE;
    }

    $condManager = $this->getConditionManager();
    $contextHandler = $this->getContextHandler();
    $isAllReq = strtoupper($conjunction) === 'AND';

    foreach ($conditions as $def) {
      try {
        $condition = $condManager->createInstance($def['plugin_id'], $def['configuration']);

        if ($condition instanceof ContextAwarePluginInterface) {
          $contextHandler->applyContextMapping($condition, $contexts);
        }

        // Decide if we can shortcircuit the logic.
        // For "AND" the first failure results in FALSE.
        // For "OR" the first success results in TRUE.
        if (($condition->evaluate() xor $condition->isNegated()) xor $isAllReq) {
          return !$isAllReq;
        }
      }
      catch (ContextException | PluginNotFoundException $e) {
        // A missing condition counts as that condition failing.
        if ($isAllReq) {
          return FALSE;
        }
      }
    }

    // If "AND" then reaching here means none of the conditions have failed,
    // and therefore return TRUE. If "OR" then none of the conditions have
    // passed at this point (AKA: no SHORTCIRCUIT of logic) return FALSE.
    // This just happens to be the same value as $isAllReq.
    return $isAllReq;
  }

}

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

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