You are here

class KeywordFilter in Tamper 8

Plugin implementation for filtering based on a list of words/phrases.

Plugin annotation


@Tamper(
  id = "keyword_filter",
  label = @Translation("Keyword filter"),
  description = @Translation("Filter based on a list of words/phrases."),
  category = "Filter",
  handle_multiples = TRUE
)

Hierarchy

Expanded class hierarchy of KeywordFilter

1 file declares its use of KeywordFilter
KeywordFilterTest.php in tests/src/Unit/Plugin/Tamper/KeywordFilterTest.php

File

src/Plugin/Tamper/KeywordFilter.php, line 21

Namespace

Drupal\tamper\Plugin\Tamper
View source
class KeywordFilter extends TamperBase {

  /**
   * A list of words/phrases appearing in the text. Enter one value per line.
   */
  const WORDS = 'words';

  /**
   * If checked, then "book" will match "book" but not "bookcase"..
   */
  const WORD_BOUNDARIES = 'word_boundaries';

  /**
   * A list of words/phrases appearing in the text. Enter one value per line.
   */
  const EXACT = 'exact';

  /**
   * If checked -> "book" === "book". Override the "Respect word boundaries".
   */
  const CASE_SENSITIVE = 'case_sensitive';

  /**
   * If checked, then "book" will match "book" but not "Book" or "BOOK".
   */
  const INVERT = 'invert';

  /**
   * Index for the word list configuration option.
   *
   * The word list option holds the calculated value of the word list after all
   * settings are applied.
   */
  const WORD_LIST = 'word_list';

  /**
   * Flags whether or not we'll be using regex to match.
   *
   * This value is calculated by other options.
   */
  const REGEX = 'regex';

  /**
   * Holds which string position function will be used.
   *
   * This value is calculated by other options.
   */
  const FUNCTION = 'function';

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    $config = parent::defaultConfiguration();
    $config[self::WORDS] = '';
    $config[self::WORD_BOUNDARIES] = FALSE;
    $config[self::EXACT] = FALSE;
    $config[self::CASE_SENSITIVE] = FALSE;
    $config[self::INVERT] = FALSE;
    $config[self::WORD_LIST] = [];
    $config[self::REGEX] = FALSE;
    $config[self::FUNCTION] = 'matchRegex';
    return $config;
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $form[self::WORDS] = [
      '#type' => 'textarea',
      '#title' => $this
        ->t('Words or phrases to filter on'),
      '#default_value' => $this
        ->getSetting(self::WORDS),
      '#description' => $this
        ->t('A list of words/phrases that need to appear in the text. Enter one value per line.'),
    ];
    $form[self::WORD_BOUNDARIES] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Respect word boundaries'),
      '#default_value' => $this
        ->getSetting(self::WORD_BOUNDARIES),
      '#description' => $this
        ->t('If checked, then "book" will match "book" but not "bookcase".'),
    ];
    $form[self::EXACT] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Exact'),
      '#default_value' => $this
        ->getSetting(self::EXACT),
      '#description' => $this
        ->t('If checked, then "book" will only match "book". This will override the "Respect word boundaries" setting above.'),
    ];
    $form[self::CASE_SENSITIVE] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Case sensitive'),
      '#default_value' => $this
        ->getSetting(self::CASE_SENSITIVE),
      '#description' => $this
        ->t('If checked, then "book" will match "book" but not "Book" or "BOOK".'),
    ];
    $form[self::INVERT] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Invert filter'),
      '#default_value' => $this
        ->getSetting(self::INVERT),
      '#description' => $this
        ->t('Inverting the filter will remove items with the specified text.'),
    ];
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
    parent::submitConfigurationForm($form, $form_state);
    $this
      ->setConfiguration([
      self::WORDS => $form_state
        ->getValue(self::WORDS),
      self::WORD_BOUNDARIES => $form_state
        ->getValue(self::WORD_BOUNDARIES),
      self::EXACT => $form_state
        ->getValue(self::EXACT),
      self::CASE_SENSITIVE => $form_state
        ->getValue(self::CASE_SENSITIVE),
      self::INVERT => $form_state
        ->getValue(self::INVERT),
      self::WORD_LIST => $form_state
        ->getValue(self::WORD_LIST),
      self::REGEX => $form_state
        ->getValue(self::REGEX),
      self::FUNCTION => $form_state
        ->getValue(self::FUNCTION),
    ]);
  }

  /**
   * {@inheritdoc}
   */
  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
    $is_multibyte = Unicode::getStatus() == Unicode::STATUS_MULTIBYTE ? TRUE : FALSE;
    $word_list = str_replace("\r", '', $form_state
      ->getValue(self::WORDS));
    $word_list = explode("\n", $word_list);
    $word_list = array_map('trim', $word_list);
    $setting_regex = FALSE;
    $setting_function = 'matchRegex';
    $exact = $form_state
      ->getValue(self::EXACT);
    $word_boundaries = $form_state
      ->getValue(self::WORD_BOUNDARIES);
    $case_sensitive = $form_state
      ->getValue(self::CASE_SENSITIVE);
    if (!empty($exact) || $word_boundaries) {
      foreach ($word_list as &$word) {
        if (!empty($exact)) {
          $word = '/^' . preg_quote($word, '/') . '$/u';
        }
        elseif ($word_boundaries) {

          // Word boundaries can only match a word with letters at the end.
          if (!preg_match('/^\\w(.*\\w)?$/u', $word)) {
            $form_state
              ->setErrorByName(self::WORDS, $this
              ->t('Search text must begin and end with a letter, number, or underscore to use the %option option.', [
              '%option' => t('Respect word boundaries'),
            ]));
          }
          $word = '/\\b' . preg_quote($word, '/') . '\\b/u';
        }
        if (!$case_sensitive) {
          $word .= 'i';
        }
      }
      $setting_regex = TRUE;
    }
    elseif (!$word_boundaries && $case_sensitive) {
      $setting_function = $is_multibyte ? 'mb_strpos' : 'strpos';
    }
    elseif (!$word_boundaries && !$case_sensitive) {
      $setting_function = $is_multibyte ? 'mb_stripos' : 'stripos';
    }
    $form_state
      ->setValue(self::WORD_LIST, $word_list);
    $form_state
      ->setValue(self::REGEX, $setting_regex);
    $form_state
      ->setValue(self::FUNCTION, $setting_function);
  }

  /**
   * {@inheritdoc}
   */
  public function tamper($data, TamperableItemInterface $item = NULL) {
    $match_func = $this
      ->getSetting(self::FUNCTION);
    $match = FALSE;
    $word_list = $this
      ->getSetting(self::WORD_LIST);
    if (is_array($data)) {
      foreach ($data as $value) {
        if ($this
          ->match($match_func, $value, $word_list)) {
          $match = TRUE;
          break;
        }
      }
      reset($data);
    }
    else {
      $match = $this
        ->match($match_func, $data, $word_list);
    }
    if (!$match && empty($this
      ->getSetting(self::INVERT))) {
      return '';
    }
    if ($match && !empty($this
      ->getSetting(self::INVERT))) {
      return '';
    }
    return $data;
  }

  /**
   * Determines whether we get a keyword filter match.
   */
  protected function match($match_func, $field, array $word_list) {
    foreach ($word_list as $word) {
      if ($match_func == "matchRegex") {
        if ($this
          ->{$match_func}($field, $word) !== FALSE) {
          return TRUE;
        }
      }
      elseif ($match_func($field, $word) !== FALSE) {
        return TRUE;
      }
    }
    return FALSE;
  }

  /**
   * Determines whether we get a keyword filter match using regex.
   */
  protected function matchRegex($field, $word) {
    return preg_match($word, $field) > 0;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
KeywordFilter::buildConfigurationForm public function Form constructor. Overrides TamperBase::buildConfigurationForm
KeywordFilter::CASE_SENSITIVE constant If checked -> "book" === "book". Override the "Respect word boundaries".
KeywordFilter::defaultConfiguration public function Gets default configuration for this plugin. Overrides TamperBase::defaultConfiguration
KeywordFilter::EXACT constant A list of words/phrases appearing in the text. Enter one value per line.
KeywordFilter::FUNCTION constant Holds which string position function will be used.
KeywordFilter::INVERT constant If checked, then "book" will match "book" but not "Book" or "BOOK".
KeywordFilter::match protected function Determines whether we get a keyword filter match.
KeywordFilter::matchRegex protected function Determines whether we get a keyword filter match using regex.
KeywordFilter::REGEX constant Flags whether or not we'll be using regex to match.
KeywordFilter::submitConfigurationForm public function Form submission handler. Overrides TamperBase::submitConfigurationForm
KeywordFilter::tamper public function Tamper data. Overrides TamperInterface::tamper
KeywordFilter::validateConfigurationForm public function Form validation handler. Overrides TamperBase::validateConfigurationForm
KeywordFilter::WORDS constant A list of words/phrases appearing in the text. Enter one value per line.
KeywordFilter::WORD_BOUNDARIES constant If checked, then "book" will match "book" but not "bookcase"..
KeywordFilter::WORD_LIST constant Index for the word list configuration option.
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
PluginBase::$configuration protected property Configuration information passed into the plugin. 1
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
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 3
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::isConfigurable public function Determines if the plugin is configurable.
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
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.
TamperBase::$sourceDefinition protected property The source definition.
TamperBase::getConfiguration public function Gets this plugin's configuration. Overrides ConfigurableInterface::getConfiguration
TamperBase::getSetting public function Get a particular configuration value. Overrides TamperInterface::getSetting
TamperBase::multiple public function Indicates whether the returned value requires multiple handling. Overrides TamperInterface::multiple 5
TamperBase::setConfiguration public function Sets the configuration for this plugin instance. Overrides ConfigurableInterface::setConfiguration
TamperBase::__construct public function Constructs a TamperBase object. Overrides PluginBase::__construct 1