You are here

class RuleExpression in Rules 8.3

Provides a rule, executing actions when conditions are met.

Actions added to a rule can also be rules themselves, so it is possible to nest several rules into one rule. This is the functionality of so called "rule sets" in Drupal 7.

Plugin annotation


@RulesExpression(
  id = "rules_rule",
  label = @Translation("Rule"),
  form_class = "\Drupal\rules\Form\Expression\RuleExpressionForm"
)

Hierarchy

Expanded class hierarchy of RuleExpression

2 files declare their use of RuleExpression
ConfigEntityTest.php in tests/src/Kernel/ConfigEntityTest.php
RuleExpressionTest.php in tests/src/Unit/RuleExpressionTest.php

File

src/Plugin/RulesExpression/RuleExpression.php, line 34

Namespace

Drupal\rules\Plugin\RulesExpression
View source
class RuleExpression extends ExpressionBase implements RuleExpressionInterface, ContainerFactoryPluginInterface {

  /**
   * The rules expression plugin manager.
   *
   * @var \Drupal\rules\Engine\ExpressionManagerInterface
   */
  protected $expressionManager;

  /**
   * List of conditions that must be met before actions are executed.
   *
   * @var \Drupal\rules\Engine\ConditionExpressionContainerInterface
   */
  protected $conditions;

  /**
   * List of actions that get executed if the conditions are met.
   *
   * @var \Drupal\rules\Engine\ActionExpressionContainerInterface
   */
  protected $actions;

  /**
   * The rules debug logger channel.
   *
   * @var \Drupal\Core\Logger\LoggerChannelInterface
   */
  protected $rulesDebugLogger;

  /**
   * Constructs a new class instance.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param array $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\rules\Engine\ExpressionManagerInterface $expression_manager
   *   The rules expression plugin manager.
   * @param \Drupal\Core\Logger\LoggerChannelInterface $logger
   *   The Rules debug logger channel.
   */
  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ExpressionManagerInterface $expression_manager, LoggerChannelInterface $logger) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $configuration += [
      'conditions' => [],
      'actions' => [],
    ];

    // Per default the outer condition container of a rule is initialized as
    // conjunction (AND), meaning that all conditions in it must evaluate to
    // TRUE to fire the actions.
    $this->conditions = $expression_manager
      ->createInstance('rules_and', $configuration['conditions']);
    $this->conditions
      ->setRoot($this
      ->getRoot());
    $this->actions = $expression_manager
      ->createInstance('rules_action_set', $configuration['actions']);
    $this->actions
      ->setRoot($this
      ->getRoot());
    $this->expressionManager = $expression_manager;
    $this->rulesDebugLogger = $logger;
  }

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

  /**
   * {@inheritdoc}
   */
  public function executeWithState(ExecutionStateInterface $state) {

    // Evaluate the rule's conditions.
    $this->rulesDebugLogger
      ->info('Evaluating conditions of rule %label.', [
      '%label' => $this
        ->getLabel(),
      'element' => $this,
    ]);
    if (!$this->conditions
      ->isEmpty() && !$this->conditions
      ->executeWithState($state)) {

      // Do not run the actions if the conditions are not met.
      return;
    }
    $this->rulesDebugLogger
      ->info('Rule %label fires.', [
      '%label' => $this
        ->getLabel(),
      'element' => $this,
      'scope' => TRUE,
    ]);
    $this->actions
      ->executeWithState($state);
    $this->rulesDebugLogger
      ->info('Rule %label has fired.', [
      '%label' => $this
        ->getLabel(),
      'element' => $this,
      'scope' => FALSE,
    ]);
  }

  /**
   * {@inheritdoc}
   */
  public function addCondition($condition_id, ContextConfig $config = NULL) {
    return $this->conditions
      ->addCondition($condition_id, $config);
  }

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

  /**
   * {@inheritdoc}
   */
  public function setConditions(ConditionExpressionContainerInterface $conditions) {
    $this->conditions = $conditions;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function addAction($action_id, ContextConfig $config = NULL) {
    return $this->actions
      ->addAction($action_id, $config);
  }

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

  /**
   * {@inheritdoc}
   */
  public function setActions(ActionExpressionContainerInterface $actions) {
    $this->actions = $actions;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function addExpressionObject(ExpressionInterface $expression) {
    if ($expression instanceof ConditionExpressionInterface) {
      $this->conditions
        ->addExpressionObject($expression);
    }
    elseif ($expression instanceof ActionExpressionInterface) {
      $this->actions
        ->addExpressionObject($expression);
    }
    else {
      throw new InvalidExpressionException();
    }
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function addExpression($plugin_id, ContextConfig $config = NULL) {
    return $this
      ->addExpressionObject($this->expressionManager
      ->createInstance($plugin_id, $config ? $config
      ->toArray() : []));
  }

  /**
   * {@inheritdoc}
   */
  public function getConfiguration() {
    $configuration = parent::getConfiguration();

    // We need to update the configuration in case actions/conditions have been
    // added or changed.
    $configuration['conditions'] = $this->conditions
      ->getConfiguration();
    $configuration['actions'] = $this->actions
      ->getConfiguration();
    return $configuration;
  }

  /**
   * {@inheritdoc}
   */
  public function getIterator() {

    // Just pass up the actions for iterating over.
    return $this->actions
      ->getIterator();
  }

  /**
   * {@inheritdoc}
   */
  public function getExpression($uuid) {
    $condition = $this->conditions
      ->getExpression($uuid);
    if ($condition) {
      return $condition;
    }
    return $this->actions
      ->getExpression($uuid);
  }

  /**
   * {@inheritdoc}
   */
  public function deleteExpression($uuid) {
    $deleted = $this->conditions
      ->deleteExpression($uuid);
    if (!$deleted) {
      $deleted = $this->actions
        ->deleteExpression($uuid);
    }
    return $deleted;
  }

  /**
   * {@inheritdoc}
   */
  public function checkIntegrity(ExecutionMetadataStateInterface $metadata_state, $apply_assertions = TRUE) {
    $violation_list = $this->conditions
      ->checkIntegrity($metadata_state, $apply_assertions);
    $violation_list
      ->addAll($this->actions
      ->checkIntegrity($metadata_state, $apply_assertions));
    return $violation_list;
  }

  /**
   * {@inheritdoc}
   */
  public function prepareExecutionMetadataState(ExecutionMetadataStateInterface $metadata_state, ExpressionInterface $until = NULL, $apply_assertions = TRUE) {

    // @todo If the rule is nested, we may not pass assertions to following
    // expressions as we do not know whether the rule fires at all. Should we
    // clone the metadata state to ensure modifications stay local?
    $found = $this->conditions
      ->prepareExecutionMetadataState($metadata_state, $until, $apply_assertions);
    if ($found) {
      return TRUE;
    }
    return $this->actions
      ->prepareExecutionMetadataState($metadata_state, $until, $apply_assertions);
  }

  /**
   * PHP magic __clone function.
   */
  public function __clone() {
    $this->actions = clone $this->actions;
    $this->actions
      ->setRoot($this
      ->getRoot());
    $this->conditions = clone $this->conditions;
    $this->conditions
      ->setRoot($this
      ->getRoot());
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
ExpressionBase::$configEntityId protected property The config entity this expression is associated with, if any.
ExpressionBase::$configuration protected property The plugin configuration. Overrides PluginBase::$configuration
ExpressionBase::$root protected property The root expression if this object is nested.
ExpressionBase::$uuid protected property The UUID of this expression.
ExpressionBase::$weight protected property The weight (list order) of this expression.
ExpressionBase::calculateDependencies public function Calculates dependencies for the configured plugin. Overrides DependentPluginInterface::calculateDependencies
ExpressionBase::defaultConfiguration public function Gets default configuration for this plugin. Overrides ConfigurableInterface::defaultConfiguration 2
ExpressionBase::execute public function Executes a rules expression. Overrides ExecutableInterface::execute
ExpressionBase::getFormHandler public function Returns the form handling class for this expression. Overrides ExpressionInterface::getFormHandler 2
ExpressionBase::getLabel public function The label of this expression element that can be shown in the UI. Overrides ExpressionInterface::getLabel 2
ExpressionBase::getRoot public function Returns the root expression if this expression is nested. Overrides ExpressionInterface::getRoot
ExpressionBase::getUuid public function Returns the UUID of this expression if it is nested in another expression. Overrides ExpressionInterface::getUuid
ExpressionBase::getWeight public function Returns the list order of this expression. Overrides ExpressionInterface::getWeight
ExpressionBase::setConfiguration public function Sets the configuration for this plugin instance. Overrides ConfigurableInterface::setConfiguration 2
ExpressionBase::setRoot public function Set the root expression for this expression if it is nested. Overrides ExpressionInterface::setRoot
ExpressionBase::setUuid public function Sets the UUID of this expression in an expression tree. Overrides ExpressionInterface::setUuid
ExpressionBase::setWeight public function Sets the list order of this expression in an expression tree. Overrides ExpressionInterface::setWeight
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::getBaseId public function Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface::getBaseId
PluginBase::getDerivativeId public function Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface::getDerivativeId
PluginBase::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition 3
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::isConfigurable public function Determines if the plugin is configurable.
RuleExpression::$actions protected property List of actions that get executed if the conditions are met.
RuleExpression::$conditions protected property List of conditions that must be met before actions are executed.
RuleExpression::$expressionManager protected property The rules expression plugin manager.
RuleExpression::$rulesDebugLogger protected property The rules debug logger channel.
RuleExpression::addAction public function Creates an action expression and adds it to the container. Overrides RuleExpressionInterface::addAction
RuleExpression::addCondition public function Creates a condition expression and adds it to the container. Overrides RuleExpressionInterface::addCondition
RuleExpression::addExpression public function Creates and adds an expression. Overrides ExpressionContainerInterface::addExpression
RuleExpression::addExpressionObject public function Adds an expression object. Overrides ExpressionContainerInterface::addExpressionObject
RuleExpression::checkIntegrity public function Verifies that this expression is configured correctly. Overrides ExpressionInterface::checkIntegrity
RuleExpression::create public static function Creates an instance of the plugin. Overrides ContainerFactoryPluginInterface::create
RuleExpression::deleteExpression public function Deletes an expression identified by the specified UUID in the container. Overrides ExpressionContainerInterface::deleteExpression
RuleExpression::executeWithState public function Execute the expression with a given Rules state. Overrides ExpressionInterface::executeWithState
RuleExpression::getActions public function Returns the actions of this rule. Overrides RuleExpressionInterface::getActions
RuleExpression::getConditions public function Returns the conditions container of this rule. Overrides RuleExpressionInterface::getConditions
RuleExpression::getConfiguration public function Gets this plugin's configuration. Overrides ExpressionBase::getConfiguration
RuleExpression::getExpression public function Looks up the expression by UUID in this container. Overrides ExpressionContainerInterface::getExpression
RuleExpression::getIterator public function
RuleExpression::prepareExecutionMetadataState public function Prepares the execution metadata state by adding metadata to it. Overrides ExpressionInterface::prepareExecutionMetadataState
RuleExpression::setActions public function Sets the action container. Overrides RuleExpressionInterface::setActions
RuleExpression::setConditions public function Sets the condition container. Overrides RuleExpressionInterface::setConditions
RuleExpression::__clone public function PHP magic __clone function.
RuleExpression::__construct public function Constructs a new class instance. Overrides ExpressionBase::__construct
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.