Commit 46166175 authored by mxh's avatar mxh Committed by Jürgen Haas
Browse files

Issue #3300517 by mxh, jurgenhaas: Provide a mechanic for popping off items from a list

parent 9691b936
Loading
Loading
Loading
Loading
+59 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\eca_base\Plugin\Action;

use Drupal\Core\Form\FormStateInterface;
use Drupal\eca\Plugin\Action\ListAddBase;

/**
 * Action to add an item to a list.
 *
 * @Action(
 *   id = "eca_list_add",
 *   label = @Translation("List: add item"),
 *   description = @Translation("Add an item to a list using a specified token.")
 * )
 */
class ListAdd extends ListAddBase {

  /**
   * {@inheritdoc}
   */
  public function execute() {
    $value = $this->tokenServices->getOrReplace($this->configuration['value']);
    $this->addItem($value);
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration(): array {
    return [
      'value' => '',
    ] + parent::defaultConfiguration();
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
    $form = parent::buildConfigurationForm($form, $form_state);
    $form['value'] = [
      '#type' => 'textarea',
      '#title' => $this->t('Value to add'),
      '#description' => $this->t('This field supports tokens.'),
      '#default_value' => $this->configuration['value'],
      '#weight' => 20,
    ];
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void {
    parent::submitConfigurationForm($form, $form_state);
    $this->configuration['value'] = $form_state->getValue('value');
  }

}
+5 −13
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
namespace Drupal\eca_base\Plugin\Action;

use Drupal\Core\Form\FormStateInterface;
use Drupal\eca\Plugin\Action\ConfigurableActionBase;
use Drupal\eca\Plugin\Action\ListOperationBase;
use Drupal\eca_base\Plugin\ListCountTrait;

/**
@@ -11,10 +11,10 @@ use Drupal\eca_base\Plugin\ListCountTrait;
 *
 * @Action(
 *   id = "eca_count",
 *   label = @Translation("Count list items")
 *   label = @Translation("List: count items")
 * )
 */
class ListCount extends ConfigurableActionBase {
class ListCount extends ListOperationBase {

  use ListCountTrait;

@@ -31,7 +31,6 @@ class ListCount extends ConfigurableActionBase {
   */
  public function defaultConfiguration(): array {
    return [
      'list_token' => '',
      'token_name' => '',
    ] + parent::defaultConfiguration();
  }
@@ -41,17 +40,11 @@ class ListCount extends ConfigurableActionBase {
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
    $form = parent::buildConfigurationForm($form, $form_state);
    $form['list_token'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Token containing the list'),
      '#description' => $this->t('Provide the name of the token that contains a list from which the number of items should be counted.'),
      '#default_value' => $this->configuration['list_token'],
      '#weight' => -20,
    ];
    $form['list_token']['#description'] = $this->t('Provide the name of the token that contains a list from which the number of items should be counted.');
    $form['token_name'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Name of token'),
      '#description' => $this->t('Provide the name of a new token where the result should be stored.'),
      '#description' => $this->t('Provide the name of a new token where the counting result should be stored.'),
      '#default_value' => $this->configuration['token_name'],
      '#weight' => -10,
    ];
@@ -62,7 +55,6 @@ class ListCount extends ConfigurableActionBase {
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void {
    $this->configuration['list_token'] = $form_state->getValue('list_token');
    $this->configuration['token_name'] = $form_state->getValue('token_name');
    parent::submitConfigurationForm($form, $form_state);
  }
+78 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\eca_base\Plugin\Action;

use Drupal\Core\Form\FormStateInterface;
use Drupal\eca\Plugin\Action\ListRemoveBase;

/**
 * Action to remove an item from a list.
 *
 * @Action(
 *   id = "eca_list_remove",
 *   label = @Translation("List: remove item"),
 *   description = @Translation("Remove an item from a list and optionally store the item as a token.")
 * )
 */
class ListRemove extends ListRemoveBase {

  /**
   * {@inheritdoc}
   */
  public function execute() {
    $token_name = trim((string) $this->configuration['token_name']);
    $item = $this->removeItem();
    if ($token_name !== '') {
      $this->tokenServices->addTokenData($token_name, $item);
    }
  }

  /**
   * {@inheritdoc}
   */
  protected function getValueToRemove() {
    return $this->tokenServices->getOrReplace($this->configuration['value']);
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration(): array {
    return [
      'value' => '',
      'token_name' => '',
    ] + parent::defaultConfiguration();
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
    $form = parent::buildConfigurationForm($form, $form_state);
    $form['value'] = [
      '#type' => 'textarea',
      '#title' => $this->t('Value to remove'),
      '#description' => $this->t('When <em>Drop by specified value</em> is selected above, then a value must be specified here. This field supports tokens.'),
      '#default_value' => $this->configuration['value'],
      '#weight' => 20,
    ];
    $form['token_name'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Name of token'),
      '#description' => $this->t('Provide the name of a token that holds the removed item.'),
      '#default_value' => $this->configuration['token_name'],
      '#weight' => 30,
    ];
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void {
    parent::submitConfigurationForm($form, $form_state);
    $this->configuration['value'] = $form_state->getValue('value');
    $this->configuration['token_name'] = $form_state->getValue('token_name');
  }

}
+91 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\eca_base\Plugin\ECA\Condition;

use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\TypedData\ComplexDataInterface;
use Drupal\Core\TypedData\ListInterface;
use Drupal\eca\Plugin\DataType\DataTransferObject;
use Drupal\eca\Plugin\ECA\Condition\ConditionBase;

/**
 * ECA condition plugin for evaluating whether a token exists.
 *
 * @EcaCondition(
 *   id = "eca_token_exists",
 *   label = @Translation("Token: exists")
 * )
 */
class TokenExists extends ConditionBase {

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration(): array {
    return ['token_name' => ''] + parent::defaultConfiguration();
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
    $form['token_name'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Name of token'),
      '#description' => $this->t('Provide the name of the token to check for.'),
      '#default_value' => $this->configuration['token_name'],
      '#weight' => -10,
      '#required' => TRUE,
    ];
    return parent::buildConfigurationForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void {
    $this->configuration['token_name'] = $form_state->getValue('token_name');
    parent::submitConfigurationForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function evaluate(): bool {
    $token_name = trim((string) $this->configuration['token_name']);
    if ($token_name === '') {
      return FALSE;
    }
    $token_exists = NULL;

    // First, try a cautious but quick lookup into available data.
    $token_data = $this->tokenServices->getTokenData($token_name);
    if (($token_data instanceof EntityInterface) && $this->tokenServices->getTokenType($token_data)) {
      // When no brackets are given, the intention of the check is directly
      // targeted towards the entity itself, and in this case there is one.
      $token_exists = TRUE;
    }
    if (($token_data instanceof ComplexDataInterface || $token_data instanceof ListInterface) && $token_data->isEmpty()) {
      // Data is empty and thus it will not produce any output.
      $token_exists = FALSE;
    }
    elseif ($token_data instanceof DataTransferObject) {
      // We know how the DTO behaves on token resolution, and when not empty,
      // it will produce some output.
      $token_exists = TRUE;
    }

    if (NULL === $token_exists) {
      // Existence could not be resolved with the first try above, perform a
      // full resolution now.
      if (mb_substr($token_name, 0, 1) !== '[') {
        $token_name = '[' . $token_name . ']';
      }
      $token_exists = trim((string) $this->tokenServices->replaceClear($token_name)) !== '';
    }

    return $this->negationCheck($token_exists);
  }

}
+0 −60
Original line number Diff line number Diff line
<?php

namespace Drupal\Tests\eca_base\Kernel;

use Drupal\KernelTests\KernelTestBase;

/**
 * Kernel tests for the "eca_count" action plugin.
 *
 * @group eca
 * @group eca_base
 */
class ListCountTest extends KernelTestBase {

  /**
   * The modules.
   *
   * @var string[]
   *   The modules.
   */
  protected static $modules = [
    'system',
    'user',
    'eca',
    'eca_base',
  ];

  /**
   * {@inheritdoc}
   */
  public function setUp(): void {
    parent::setUp();
    $this->installEntitySchema('user');
    $this->installConfig(static::$modules);
  }

  /**
   * Tests TokenSetValue.
   */
  public function testTokenSetValue(): void {
    /** @var \Drupal\Core\Action\ActionManager $action_manager */
    $action_manager = \Drupal::service('plugin.manager.action');
    /** @var \Drupal\eca\Token\TokenInterface $token_services */
    $token_services = \Drupal::service('eca.token_services');

    $count = 3;
    $list = (array) $this->randomObject($count);
    $token_services->addTokenData('list', $list);
    /** @var \Drupal\eca_base\Plugin\Action\ListCount $action */
    $action = $action_manager->createInstance('eca_count', [
      'token_name' => 'my_custom_token:value1',
      'list_token' => 'list',
    ]);
    $this->assertTrue($action->access(NULL));
    $action->execute(NULL);
    $this->assertEquals($count, $token_services->replaceClear('[my_custom_token:value1]'));
    $this->assertEquals('', $token_services->replaceClear('[my_custom_token:value2]'));
  }

}
Loading