ActionForm.php

Namespace

Drupal\rules\Form\Expression

File

src/Form/Expression/ActionForm.php

View source
<?php

namespace Drupal\rules\Form\Expression;

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\rules\Context\Form\ContextFormTrait;
use Drupal\rules\Core\RulesActionManagerInterface;
use Drupal\rules\Engine\ActionExpressionInterface;
use Drupal\rules\Ui\RulesUiHandlerTrait;

/**
 * UI form for adding/editing a Rules action.
 */
class ActionForm implements ExpressionFormInterface {
  use ContextFormTrait;
  use StringTranslationTrait;
  use RulesUiHandlerTrait;
  
  /**
   * The action plugin manager.
   *
   * @var \Drupal\rules\Core\RulesActionManagerInterface
   */
  protected $actionManager;
  
  /**
   * The action expression that is edited in the form.
   *
   * @var \Drupal\rules\Engine\ActionExpressionInterface
   */
  protected $actionExpression;
  
  /**
   * Creates a new object of this class.
   */
  public function __construct(ActionExpressionInterface $action_expression, RulesActionManagerInterface $action_manager) {
    $this->actionManager = $action_manager;
    $this->actionExpression = $action_expression;
  }
  
  /**
   * {@inheritdoc}
   */
  public function form(array $form, FormStateInterface $form_state) {
    $action_id = $form_state->get('action_id');
    $configuration = $this->actionExpression
      ->getConfiguration();
    if (empty($action_id) && !empty($configuration['action_id'])) {
      $action_id = $configuration['action_id'];
      $form_state->set('action_id', $action_id);
    }
    // Step 1 of the multistep form.
    if (!$action_id) {
      $action_definitions = $this->actionManager
        ->getGroupedDefinitions();
      $options = [];
      foreach ($action_definitions as $group => $definitions) {
        foreach ($definitions as $id => $definition) {
          $options[$group][$id] = $definition['label'];
        }
      }
      $form['action_id'] = [
        '#type' => 'select',
        '#title' => $this->t('Action'),
        '#options' => $options,
        '#required' => TRUE,
      ];
      $form['continue'] = [
        '#type' => 'submit',
        '#value' => $this->t('Continue'),
        '#name' => 'continue',
        // Only validate the selected action in the first step.
'#limit_validation_errors' => [
          [
            'action_id',
          ],
        ],
        '#submit' => [
          static::class . '::submitFirstStep',
        ],
      ];
      return $form;
    }
    // Step 2 of the form.
    $action = $this->actionManager
      ->createInstance($action_id);
    $form['summary'] = [
      '#type' => 'details',
      '#title' => $this->t('Summary'),
    ];
    $form['summary']['description'] = [
      '#type' => 'container',
      '#plain_text' => $this->t('Action: @summary', [
        '@summary' => $action->summary(),
      ]),
      '#attributes' => [
        'class' => [
          'form-item',
        ],
      ],
    ];
    $context_definitions = $action->getContextDefinitions();
    if (!empty($context_definitions)) {
      $form['context_definitions'] = [
        '#type' => 'details',
        '#title' => $this->t('Context variables'),
        '#open' => TRUE,
        '#tree' => TRUE,
      ];
      foreach ($context_definitions as $context_name => $context_definition) {
        $form = $this->buildContextForm($form, $form_state, $context_name, $context_definition, $configuration);
      }
    }
    $provides_definitions = $action->getProvidedContextDefinitions();
    if (!empty($provides_definitions)) {
      $form['provides'] = [
        '#type' => 'details',
        '#title' => $this->t('Provided variables'),
        '#description' => $this->t('You may change the name of any provided variables, but note that renaming already-utilized variables invalidates the existing uses.'),
        '#tree' => TRUE,
      ];
      foreach ($provides_definitions as $provides_name => $provides_definition) {
        $form = $this->buildProvidedContextForm($form, $form_state, $provides_name, $provides_definition, $configuration);
      }
    }
    $form['save'] = [
      '#type' => 'submit',
      '#value' => $this->t('Save'),
      '#name' => 'save',
    ];
    return $form;
  }
  
  /**
   * {@inheritdoc}
   */
  public function validateForm(array $form, FormStateInterface $form_state) {
    // Only if there is an action selected already we can validate something.
    if ($form_state->get('action_id')) {
      // Invoke the submission handler which will setup the expression being
      // edited in the form. That way the expression is ready for other
      // validation handlers.
      $this->submitForm($form, $form_state);
    }
  }
  
  /**
   * Submit callback: save the selected action in the first step.
   */
  public static function submitFirstStep(array &$form, FormStateInterface $form_state) {
    $form_state->set('action_id', $form_state->getValue('action_id'));
    $form_state->setRebuild();
  }
  
  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $action_id = $form_state->get('action_id');
    // Nothing to do as long as the first step is not completed.
    if (!$action_id) {
      return;
    }
    $action_definition = $this->actionManager
      ->getDefinition($action_id);
    $context_config = $this->getContextConfigFromFormValues($form_state, $action_definition['context_definitions']);
    // Rename provided variables, if any.
    if ($provided_variables = $form_state->getValue('provides')) {
      foreach ($provided_variables as $provides_name => $provides_context) {
        // Do this only on rename.
        if ($provides_name !== $provides_context['name']) {
          \Drupal::messenger()->addWarning("providing '" . $provides_name . "' as '" . $provides_context['name'] . "'");
          $context_config->provideAs($provides_name, $provides_context['name']);
        }
      }
    }
    $configuration = $context_config->toArray();
    $configuration['action_id'] = $action_id;
    $this->actionExpression
      ->setConfiguration($configuration);
  }

}

Classes

Title Deprecated Summary
ActionForm UI form for adding/editing a Rules action.