You are here

function rules_element_invoke_component in Rules 7.2

Action and condition callback: Invokes a rules component.

We do not use the execute() method, but handle executing ourself. That way we can utilize the existing state for saving passed variables.

Related topics

2 string references to 'rules_element_invoke_component'
rules_rules_core_action_info in modules/rules_core.rules.inc
Implements hook_rules_action_info() on behalf of the pseudo rules_core module.
rules_rules_core_condition_info in modules/rules_core.rules.inc
Implements hook_rules_condition_info() on behalf of the pseudo rules_core module.

File

modules/rules_core.eval.inc, line 18
Contains rules core integration needed during evaluation.

Code

function rules_element_invoke_component($arguments, RulesPlugin $element) {
  $info = $element
    ->info();
  $state = $arguments['state'];
  $wrapped_args = $state->currentArguments;
  if ($component = rules_get_cache('comp_' . $info['#config_name'])) {
    $replacements = array(
      '%label' => $component
        ->label(),
      '@plugin' => $component
        ->plugin(),
    );

    // Handle recursion prevention.
    if ($state
      ->isBlocked($component)) {
      return rules_log('Not evaluating @plugin %label to prevent recursion.', $replacements, RulesLog::INFO, $component);
    }
    $state
      ->block($component);
    rules_log('Evaluating @plugin %label.', $replacements, RulesLog::INFO, $component, TRUE);
    module_invoke_all('rules_config_execute', $component);

    // Manually create a new evaluation state and evaluate the component.
    $args = array_intersect_key($wrapped_args, $component
      ->parameterInfo());
    $new_state = $component
      ->setUpState($wrapped_args);
    $return = $component
      ->evaluate($new_state);

    // Care for the right return value in case we have to provide vars.
    if ($component instanceof RulesActionInterface && !empty($info['provides'])) {
      $return = array();
      foreach ($info['provides'] as $var => $var_info) {
        $return[$var] = $new_state
          ->get($var);
      }
    }

    // Now merge the info about to be saved variables in the parent state.
    $state
      ->mergeSaveVariables($new_state, $component, $element->settings);
    $state
      ->unblock($component);

    // Cleanup the state, what saves not mergeable variables now.
    $new_state
      ->cleanup();
    rules_log('Finished evaluation of @plugin %label.', $replacements, RulesLog::INFO, $component, FALSE);
    return $return;
  }
  else {
    throw new RulesEvaluationException('Unable to get the component %name', array(
      '%name' => $info['#config_name'],
    ), $element, RulesLog::ERROR);
  }
}