gamify-1.1.x-dev/src/Plugin/Action/LogsFilter.php

src/Plugin/Action/LogsFilter.php
<?php

namespace Drupal\gamify\Plugin\Action;

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

/**
 * Provide all tamper plugins as ECA actions.
 *
 * @Action(
 *   id = "gamify_filter_logs",
 *   label = @Translation("Gamify: Logs Filter (by RegEx or search string).")
 * )
 */
class LogsFilter extends ConfigurableActionBase {

  /**
   * {@inheritdoc}
   *
   * @throws \Drupal\Component\Plugin\Exception\PluginException | \Drupal\Core\TypedData\Exception\MissingDataException
   */
  public function execute(): void {
    $dataKey = $this->configuration['eca_data'] ?? NULL;
    $data = $dataKey ? $this->tokenServices->getTokenData($dataKey)->toArray() : NULL;

    $interim_result = [];
    if (is_array($data ?? NULL)) {
      // Set parameter bag distilled from previous query.
      $parameterKey = $this->configuration['filter_params'] ?? NULL;
      $parameter = $parameterKey ? $this->tokenServices->getTokenData($parameterKey)->toArray() : NULL;

      $pattern = $this->configuration['filter_pattern'];
      // Check if we have to work with params from ResultRegExDistiller.
      if (is_array($parameter)) {
        // Using params => +1 loop more because have to handle each param set.
        foreach ($parameter as $params_key => $params) {
          $matches = $params['matches'] ?? NULL;
          if ($matches && $prepared_pattern = $this->preparePattern($pattern, $matches)) {
            if ($search_result = $this->searchEntries($data, $prepared_pattern)) {
              $interim_result[$params_key] = $search_result;
            }
          }
        }
      }
      elseif ($prepared_pattern = $this->preparePattern($pattern, [])) {
        if ($search_result = $this->searchEntries($data, $prepared_pattern)) {
          $interim_result[] = $search_result;
        }
      }
    }
    $this->tokenServices->addTokenData($this->configuration['eca_token_name'], $interim_result);
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration(): array {
    return [
      'eca_data' => '',
      'filter_pattern' => '',
      'filter_params' => '',
      'eca_token_name' => '',
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
    $form['eca_data'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Log entries to be filtered'),
      '#description' => $this->t('This field supports tokens.'),
      '#default_value' => $this->configuration['eca_data'],
      '#required' => TRUE,
      '#weight' => 10,
    ];
    $form['filter_pattern'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Filter pattern'),
      '#description' => $this->t('Filter logs by RegEx or search string. If you are using filter parameters (see field below), use $0, $1, ... as placeholder where to insert.'),
      '#default_value' => $this->configuration['filter_pattern'],
      '#required' => TRUE,
      '#weight' => 20,
    ];
    $form['filter_params'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Filter parameters'),
      '#description' => $this->t('Token for replacement params from action "Logs params distiller".'),
      '#default_value' => $this->configuration['filter_params'],
      '#weight' => 30,
    ];
    $form['eca_token_name'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Result token name'),
      '#description' => $this->t('Provide a token name under which the tampered result will be made available for subsequent actions.'),
      '#default_value' => $this->configuration['eca_token_name'],
      '#required' => TRUE,
      '#weight' => 40,
    ];
    return parent::buildConfigurationForm($form, $form_state);
  }

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

  /**
   * Prepare search pattern.
   *
   * @param string $pattern
   *   The search pattern, optional with placeholders ($1, $2, ...) for params.
   * @param array $params
   *   The params are the match result from a ResultRegExDistiller.
   *
   * @return mixed
   *   Prepared search pattern.
   */
  protected function preparePattern(string $pattern, array $params): mixed {
    $is_regex = (str_starts_with($pattern, '/') && str_ends_with($pattern, '/'));
    if (count($params)) {
      $replacer = [];
      foreach ($params as $key => $param) {
        $replacer["$$key"] = ($is_regex) ? preg_quote($param) : $param;
      }
      $pattern = str_replace(array_keys($replacer), $replacer, $pattern);
    }
    if ($is_regex && @preg_match($pattern, NULL) === FALSE) {
      return FALSE;
    }
    return ($is_regex)
      ? $pattern
      : explode('|', $pattern);
  }

  /**
   * Searches for entries, where log_hash matching the pattern.
   *
   * @param array[] $entries
   *   Entries from log with at least a log_hash property.
   * @param mixed $pattern
   *   Search pattern. RegEx OR array of search strings where each string must
   *   match the log hash of an entry.
   *
   * @return array|null
   *   Result array of entries filtered by the pattern.
   */
  protected function searchEntries(array $entries, mixed $pattern): ?array {
    $result = [];
    foreach ($entries as $result_key => $prev_result) {
      $matched = FALSE;
      // If preparePattern returns array => String search.
      if (is_array($pattern)) {
        foreach ($pattern as $str) {
          $matched = str_contains($prev_result['log_hash'], $str);
          if (!$matched) {
            break;
          }
        }
      }
      // If preparePattern returns string => RegEx.
      elseif (is_string($pattern)) {
        $matched = preg_match($pattern, $prev_result['log_hash']);
      }
      if ($matched) {
        $result[$result_key] = $prev_result;
      }
    }
    return count($result) ? $result : NULL;
  }

}

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

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