tamper-8.x-1.x-dev/src/Plugin/Tamper/Encode.php

src/Plugin/Tamper/Encode.php
<?php

namespace Drupal\tamper\Plugin\Tamper;

use Drupal\Component\Serialization\Json;
use Drupal\Core\Form\FormStateInterface;
use Drupal\tamper\Exception\TamperException;
use Drupal\tamper\TamperBase;
use Drupal\tamper\TamperableItemInterface;
use Symfony\Component\Yaml\Yaml;

/**
 * Plugin implementation for encoding / decoding.
 *
 * @Tamper(
 *   id = "encode",
 *   label = @Translation("Encode/Decode"),
 *   description = @Translation("Encode (or Decode) the field contents."),
 *   category = @Translation("Text"),
 *   handle_multiples = TRUE,
 *   itemUsage = "ignored"
 * )
 */
class Encode extends TamperBase {

  const SETTING_MODE = 'mode';

  /**
   * Flag indicating whether there are multiple values.
   *
   * @var bool
   */
  protected $multiple = FALSE;

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    $config = parent::defaultConfiguration();
    $config[self::SETTING_MODE] = 'serialize';
    return $config;
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $modes = $this->getModes();

    $form[self::SETTING_MODE] = [
      '#type' => 'radios',
      '#title' => $this->t('Conversion mode:'),
      '#options' => array_combine(array_keys($modes), array_column($modes, 'label')),
      '#default_value' => $this->getSetting(self::SETTING_MODE),
    ];

    foreach ($modes as $key => $mode) {
      if (isset($mode['description'])) {
        $form[self::SETTING_MODE][$key]['#description'] = $mode['description'];
      }
    }

    return $form;
  }

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

  /**
   * Returns a list of encode/decode modes.
   *
   * @return array
   *   A list of encode modes. The keys of the array are the machine names of
   *   the modes, and the values are an associative array with the following
   *   keys:
   *   - label: (string) the label of the mode.
   *   - description: (string) a short description about the encode mode.
   *   - callback: (callable) the function or method to call for doing the
   *     encode/decode operation.
   *   - handle_multiples: (bool) whether or not the encode mode can handle
   *     array values. If TRUE, the data is passed to the encode/decode function
   *     as is. If FALSE and if the data is an array, their array values are
   *     iterated over.
   */
  protected function getModes(): array {
    return [
      'serialize' => [
        'label' => $this->t('PHP Serialize'),
        'description' => $this->t('Generates a storable representation of a value.'),
        'callback' => 'serialize',
        'handle_multiples' => TRUE,
      ],
      'unserialize' => [
        'label' => $this->t('PHP Unserialize'),
        'description' => $this->t('Creates a PHP value from a stored representation.'),
        'callback' => 'unserialize',
        'handle_multiples' => FALSE,
      ],
      'json_encode' => [
        'label' => $this->t('Json Encode'),
        'description' => $this->t('Creates the JSON representation of a value.'),
        'callback' => [Json::class, 'encode'],
        'handle_multiples' => TRUE,
      ],
      'json_decode' => [
        'label' => $this->t('Json Decode'),
        'description' => $this->t('Takes a JSON encoded string and converts it into a PHP value.'),
        'callback' => [Json::class, 'decode'],
        'handle_multiples' => FALSE,
      ],
      'base64_encode' => [
        'label' => $this->t('Base64 Encode'),
        'description' => $this->t('Encodes data with MIME base64.'),
        'callback' => 'base64_encode',
        'handle_multiples' => FALSE,
      ],
      'base64_decode' => [
        'label' => $this->t('Base64 Decode'),
        'description' => $this->t('Decodes data encoded with MIME base64.'),
        'callback' => 'base64_decode',
        'handle_multiples' => FALSE,
      ],
      'yaml_encode' => [
        'label' => $this->t('YAML Encode'),
        'description' => $this->t('Creates the YAML representation of a value.'),
        'callback' => [Yaml::class, 'dump'],
        'handle_multiples' => TRUE,
      ],
      'yaml_decode' => [
        'label' => $this->t('YAML Decode'),
        'description' => $this->t('Takes a YAML encoded string and converts it into a PHP value.'),
        'callback' => [Yaml::class, 'parse'],
        'handle_multiples' => FALSE,
      ],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function tamper($data, ?TamperableItemInterface $item = NULL) {
    $modes = $this->getModes();
    $selected_mode = $this->getSetting(self::SETTING_MODE);

    if (!isset($modes[$selected_mode])) {
      throw new TamperException(sprintf('The selected encode mode "%s" is invalid.', $selected_mode));
    }

    // Check if the selected mode supports arrays.
    $handles_multiples = $modes[$selected_mode]['handle_multiples'] ?? FALSE;
    if (!$handles_multiples && is_array($data)) {
      // Iterate over all values.
      foreach ($data as $key => $subvalues) {
        $data[$key] = $this->applyEncode($subvalues, $modes[$selected_mode], $selected_mode);
      }
    }
    else {
      $data = $this->applyEncode($data, $modes[$selected_mode], $selected_mode);
    }

    // Set flag for if the data returned is an array (and therefore multiple
    // values).
    $this->multiple = is_array($data);

    return $data;
  }

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

  /**
   * Applies the encoding.
   *
   * @param mixed $data
   *   The data to encode or decode.
   * @param array $mode
   *   The selected mode to apply.
   * @param string $selected_mode
   *   The selected mode.
   *
   * @return mixed
   *   The encoded or decoded data.
   *
   * @throws \LogicException
   *   In case no callback for the selected mode is defined.
   */
  protected function applyEncode($data, array $mode, string $selected_mode) {
    // All modes in ::getModes() should have a callback defined.
    if (!isset($mode['callback']) || !is_callable($mode['callback'])) {
      throw new \LogicException(sprintf('The encoding could not be applied because the selected mode "%s" has no valid callback.', $selected_mode));
    }

    return call_user_func($mode['callback'], $data);
  }

}

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

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