You are here

class TokenArgument in Views Token Argument 2.0.x

Same name and namespace in other branches
  1. 8 src/Plugin/views/argument_default/TokenArgument.php \Drupal\views_argument_token\Plugin\views\argument_default\TokenArgument

The Token argument default handler.

@ViewsArgumentDefault( id = "token", title = @Translation("Token") ) @package Drupal\views_argument_token\Plugin\views\argument_default

Hierarchy

Expanded class hierarchy of TokenArgument

File

src/Plugin/views/argument_default/TokenArgument.php, line 25

Namespace

Drupal\views_argument_token\Plugin\views\argument_default
View source
class TokenArgument extends ArgumentDefaultPluginBase implements CacheableDependencyInterface {

  /**
   * The current user.
   *
   * @var \Drupal\Core\Session\AccountProxy
   */
  protected $currentUser;

  /**
   * The EntityTypeManagerInterface definition.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
    $instance->currentUser = $container
      ->get('current_user');
    $instance->entityTypeManager = $container
      ->get('entity_type.manager');
    return $instance;
  }

  /**
   * {@inheritdoc}
   */
  protected function defineOptions() {
    $options = parent::defineOptions();
    $options['argument'] = [
      'default' => '',
    ];
    $options['process'] = [
      'default' => 0,
    ];
    $options['and_or'] = [
      'default' => '+',
    ];
    $options['all_option'] = [
      'default' => TRUE,
    ];
    $options['debug'] = [
      'default' => 0,
    ];
    return $options;
  }

  /**
   * {@inheritdoc}
   */
  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
    $form['argument'] = [
      '#type' => 'textfield',
      '#title' => $this
        ->t('Token'),
      '#default_value' => $this->options['argument'],
    ];
    if (\Drupal::moduleHandler()
      ->moduleExists('token')) {
      $form['token'] = \Drupal::service('views_argument_token.token')
        ->tokenBrowser();
    }
    $form['process'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Get fields raw values'),
      '#description' => $this
        ->t('Get raw values of fields (only fields are supported).<br/>For example, get ID instead of title for entity reference fields.'),
      '#default_value' => $this->options['process'],
    ];

    // @todo : allow to choose and / or for any multiple value.
    $form['and_or'] = [
      '#type' => 'radios',
      '#title' => $this
        ->t('Multiple values handling condition'),
      '#options' => [
        '+' => $this
          ->t('Or'),
        ',' => $this
          ->t('And'),
      ],
      '#default_value' => $this->options['and_or'],
      '#states' => [
        'invisible' => [
          ':input[name="options[argument_default][token][process]"]' => [
            'checked' => FALSE,
          ],
        ],
      ],
      '#description' => $this
        ->t('You should authorize multiple values at the bottom of this form.'),
    ];
    $form['all_option'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Send "all" if no value'),
      '#default_value' => $this->options['all_option'],
      '#description' => $this
        ->t('You should enable the "all" argument below.'),
    ];
    $form['debug'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Show debug'),
      '#default_value' => $this->options['debug'],
      '#description' => $this
        ->t('Show as a message the argument value for debugging purposes.'),
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getArgument() {
    $token_service = \Drupal::token();
    $argument = $this->options['argument'];
    $process = $this->options['process'];
    $debug = $this->options['debug'];
    $all_option = $this->options['all_option'];
    $tokens = $this
      ->tokenScan($argument);

    // Presence of a token concerning current user.
    if (isset($tokens['current-user'])) {

      // Case of processing with raw values.
      if ($process) {

        // Get current user value.
        $current_user = $this->currentUser;
        $account = $this->entityTypeManager
          ->getStorage('user')
          ->load($current_user
          ->id());

        // Process raw value (even multiple values).
        $argument = $this
          ->processToken($account, 'current-user', $argument);
      }

      // If there is still a current user token.
      if (strpos($argument, 'current-user')) {
        if (!isset($current_user)) {

          // @todo : dependency injection.
          $current_user = \Drupal::currentUser();
        }

        // If the token cannot be translated, it will be removed from
        // the final text.
        $argument = $token_service
          ->replace($argument, [
          'current-user' => $current_user,
        ], [
          'clear' => TRUE,
        ]);
      }
    }

    // Get type current entity.
    $current_path = \Drupal::service('path.current')
      ->getPath();
    $params = Url::fromUri("internal:" . $current_path)
      ->getRouteParameters();
    $entity_type = key($params);

    // If existing token, try to get current entity and replace tokens with
    // the right data.
    // @todo : dependency injection.
    if (isset($tokens[$entity_type]) && ($entity = \Drupal::request()->attributes
      ->get($entity_type))) {

      // Process with raw values for fields.
      if ($process) {
        $argument = $this
          ->processToken($entity, $entity_type, $argument);
      }

      // If still a token, try to replace with token.
      if (strpos($argument, $entity_type)) {

        // If the token cannot be translated, it will be removed from
        // the final text.
        $argument = $token_service
          ->replace($argument, [
          $entity_type => $entity,
        ], [
          'clear' => TRUE,
        ]);
      }
    }

    // Allow for global arguments (e.g. current-date)
    if (!isset($tokens['current-user']) && !isset($tokens[$entity_type])) {
      $argument = $token_service
        ->replace($argument);
    }

    // Decode final argument HTML entities, as token returns encoded values.
    $argument = PlainTextOutput::renderFromHtml($argument);

    // Show debug for checking the value in the current context.
    if ($debug) {
      $this
        ->messenger()
        ->addStatus($argument);
    }
    if (!$argument) {
      if (!$all_option) {
        return '';
      }
      $argument = 'all';
    }

    // Clean value (if + or , at the begining or at the end).
    // @todo : remove.
    if (!empty($argument)) {
      $argument = $this
        ->cleanArgumentValue($argument);
    }
    return $argument;
  }

  /**
   * Process tokens as raw values.
   *
   * @param \Drupal\Core\Entity\FieldableEntityInterface $entity
   *   Entity to process.
   * @param string $entity_type
   *   Entity type.
   * @param string $argument
   *   Argument to process.
   *
   * @return string
   *   Processed token.
   */
  public function processToken(FieldableEntityInterface $entity, $entity_type, $argument) {

    // @todo: $entity_type could potentially be retrieved by checking on $entity.
    $and_or = $this->options['and_or'];
    $field_names = $this
      ->tokenScan($argument);
    foreach ($field_names[$entity_type] as $field_name => $token) {
      $replace_values = [];
      if ($entity
        ->hasField($field_name)) {
        $field_values = $entity
          ->get($field_name)
          ->getValue();
        foreach ($field_values as $field_value) {
          $replace_values[] = array_values($field_value)[0];
        }

        // Replace and implode with , or + for multiple value management.
        $replace = implode($and_or, $replace_values);
        $argument = str_replace($token, $replace, $argument);
      }
    }
    return $argument;
  }

  /**
   * Scans a string to detect potential tokens.
   *
   * @param string $text
   *   The string to scan.
   *
   * @return string[]
   *   An array containing potential tokens ready for processing.
   */
  public function tokenScan($text) {

    // Matches tokens with the following pattern: [$type:$name]
    // $type and $name may not contain  [ ] characters.
    // $type may not contain : or whitespace characters, but $name may.
    preg_match_all('/
    \\[             # [ - pattern start
    ([^\\s\\[\\]:]*)  # match $type not containing whitespace : [ or ]
    :              # : - separator
    ([^\\[\\]]*)     # match $name not containing [ or ]
    \\]             # ] - pattern end
    /x', $text, $matches);
    $types = $matches[1];
    $tokens = $matches[2];

    // Iterate through the matches, building an associative array containing
    // $tokens grouped by $types, pointing to the version of the token found in
    // the source text. For example, $results['node']['title'] = '[node:title]'.
    $results = [];
    for ($i = 0; $i < count($tokens); $i++) {
      $results[$types[$i]][$tokens[$i]] = $matches[0][$i];
    }
    return $results;
  }

  /**
   * Removes '+' or ',' at the beginning and at the end of an argument string.
   *
   * @param string $argument
   *   Argument string to clean.
   *
   * @todo: evaluate if still needed.
   *
   * @return string
   *   Cleaned argument.
   */
  public function cleanArgumentValue($argument) {

    // Remove '+' or ',' at the beginning.
    if ($argument[0] == '+' || $argument[0] == ',') {
      $argument = substr($argument, 1);
    }

    // Remove '+' or ',' at the the end.
    if ($argument[strlen($argument) - 1] == '+' || $argument[strlen($argument) - 1] == ',') {
      $argument = substr($argument, 0, -1);
    }
    return $argument;
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheMaxAge() {
    return Cache::PERMANENT;
  }

  /**
   * {@inheritdoc}
   *
   * @todo : define cachecontexts.
   */
  public function getCacheContexts() {
    return [];
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ArgumentDefaultPluginBase::$argument protected property The argument handler instance associated with this plugin.
ArgumentDefaultPluginBase::access public function Determine if the administrator has the privileges to use this plugin.
ArgumentDefaultPluginBase::checkAccess protected function If we don't have access to the form but are showing it anyway, ensure that the form is safe and cannot be changed from user input.
ArgumentDefaultPluginBase::getCacheTags public function
ArgumentDefaultPluginBase::setArgument public function Sets the parent argument this plugin is associated with.
ArgumentDefaultPluginBase::submitOptionsForm public function Provide the default form form for submitting options. Overrides PluginBase::submitOptionsForm 1
ArgumentDefaultPluginBase::validateOptionsForm public function Provide the default form form for validating options. Overrides PluginBase::validateOptionsForm
DependencySerializationTrait::$_entityStorages protected property
DependencySerializationTrait::$_serviceIds protected property
DependencySerializationTrait::__sleep public function 2
DependencySerializationTrait::__wakeup public function 2
MessengerTrait::$messenger protected property The messenger. 27
MessengerTrait::messenger public function Gets the messenger. 27
MessengerTrait::setMessenger public function Sets the messenger.
PluginBase::$configuration protected property Configuration information passed into the plugin. 1
PluginBase::$definition public property Plugins's definition.
PluginBase::$displayHandler public property The display object this plugin is for.
PluginBase::$options public property Options for this plugin will be held here.
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::$renderer protected property Stores the render API renderer. 3
PluginBase::$usesOptions protected property Denotes whether the plugin has an additional options form. 8
PluginBase::$view public property The top object of a view. 1
PluginBase::calculateDependencies public function Calculates dependencies for the configured plugin. Overrides DependentPluginInterface::calculateDependencies 14
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::destroy public function Clears a plugin. Overrides ViewsPluginInterface::destroy 2
PluginBase::doFilterByDefinedOptions protected function Do the work to filter out stored options depending on the defined options.
PluginBase::filterByDefinedOptions public function Filter out stored options depending on the defined options. Overrides ViewsPluginInterface::filterByDefinedOptions
PluginBase::getAvailableGlobalTokens public function Returns an array of available token replacements. Overrides ViewsPluginInterface::getAvailableGlobalTokens
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 2
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::getProvider public function Returns the plugin provider. Overrides ViewsPluginInterface::getProvider
PluginBase::getRenderer protected function Returns the render API renderer. 1
PluginBase::globalTokenForm public function Adds elements for available core tokens to a form. Overrides ViewsPluginInterface::globalTokenForm
PluginBase::globalTokenReplace public function Returns a string with any core tokens replaced. Overrides ViewsPluginInterface::globalTokenReplace
PluginBase::INCLUDE_ENTITY constant Include entity row languages when listing languages.
PluginBase::INCLUDE_NEGOTIATED constant Include negotiated languages when listing languages.
PluginBase::init public function Initialize the plugin. Overrides ViewsPluginInterface::init 6
PluginBase::isConfigurable public function Determines if the plugin is configurable.
PluginBase::listLanguages protected function Makes an array of languages, optionally including special languages.
PluginBase::pluginTitle public function Return the human readable name of the display. Overrides ViewsPluginInterface::pluginTitle
PluginBase::preRenderAddFieldsetMarkup public static function Moves form elements into fieldsets for presentation purposes. Overrides ViewsPluginInterface::preRenderAddFieldsetMarkup
PluginBase::preRenderFlattenData public static function Flattens the structure of form elements. Overrides ViewsPluginInterface::preRenderFlattenData
PluginBase::query public function Add anything to the query that we might need to. Overrides ViewsPluginInterface::query 8
PluginBase::queryLanguageSubstitutions public static function Returns substitutions for Views queries for languages.
PluginBase::setOptionDefaults protected function Fills up the options of the plugin with defaults.
PluginBase::summaryTitle public function Returns the summary of the settings in the display. Overrides ViewsPluginInterface::summaryTitle 6
PluginBase::themeFunctions public function Provide a full list of possible theme templates used by this style. Overrides ViewsPluginInterface::themeFunctions 1
PluginBase::trustedCallbacks public static function Lists the trusted callbacks provided by the implementing class. Overrides TrustedCallbackInterface::trustedCallbacks 6
PluginBase::unpackOptions public function Unpack options over our existing defaults, drilling down into arrays so that defaults don't get totally blown away. Overrides ViewsPluginInterface::unpackOptions
PluginBase::usesOptions public function Returns the usesOptions property. Overrides ViewsPluginInterface::usesOptions 8
PluginBase::validate public function Validate that the plugin is correct and can be saved. Overrides ViewsPluginInterface::validate 6
PluginBase::viewsTokenReplace protected function Replaces Views' tokens in a given string. The resulting string will be sanitized with Xss::filterAdmin. 1
PluginBase::VIEWS_QUERY_LANGUAGE_SITE_DEFAULT constant Query string to indicate the site default language.
PluginBase::__construct public function Constructs a PluginBase object. Overrides PluginBase::__construct
StringTranslationTrait::$stringTranslation protected property The string translation service. 4
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.
TokenArgument::$currentUser protected property The current user.
TokenArgument::$entityTypeManager protected property The EntityTypeManagerInterface definition.
TokenArgument::buildOptionsForm public function Provide the default form for setting options. Overrides ArgumentDefaultPluginBase::buildOptionsForm
TokenArgument::cleanArgumentValue public function Removes '+' or ',' at the beginning and at the end of an argument string.
TokenArgument::create public static function Creates an instance of the plugin. Overrides PluginBase::create
TokenArgument::defineOptions protected function Retrieve the options when this is a new access control plugin. Overrides ArgumentDefaultPluginBase::defineOptions
TokenArgument::getArgument public function Return the default argument. Overrides ArgumentDefaultPluginBase::getArgument
TokenArgument::getCacheContexts public function @todo : define cachecontexts. Overrides CacheableDependencyInterface::getCacheContexts
TokenArgument::getCacheMaxAge public function The maximum age for which this object may be cached. Overrides CacheableDependencyInterface::getCacheMaxAge
TokenArgument::processToken public function Process tokens as raw values.
TokenArgument::tokenScan public function Scans a string to detect potential tokens.
TrustedCallbackInterface::THROW_EXCEPTION constant Untrusted callbacks throw exceptions.
TrustedCallbackInterface::TRIGGER_SILENCED_DEPRECATION constant Untrusted callbacks trigger silenced E_USER_DEPRECATION errors.
TrustedCallbackInterface::TRIGGER_WARNING constant Untrusted callbacks trigger E_USER_WARNING errors.