pluginreference-2.0.0/src/Plugin/PluginReferenceSelection/FilteredSelection.php

src/Plugin/PluginReferenceSelection/FilteredSelection.php
<?php

namespace Drupal\pluginreference\Plugin\PluginReferenceSelection;

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\pluginreference\Attribute\PluginReferenceSelection;

/**
 * Provides the default selection for block plugins.
 */
#[PluginReferenceSelection(
  id: 'filtered',
  label: new TranslatableMarkup('Filtered selection'),
  group: 'filtered',
  weight: 0,
  deriver: 'Drupal\pluginreference\Plugin\Derivative\DefaultSelectionDeriver',
)]
class FilteredSelection extends DefaultSelection {

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    return [
      'filter' => [
        'key' => 'id',
        'negate' => FALSE,
        'target_values' => [],
      ],
    ] + parent::defaultConfiguration();
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildConfigurationForm($form, $form_state);

    $configuration = $this->getConfiguration();
    $form['filter'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Filter options'),
      '#weight' => -1,
    ];

    $form['filter']['key'] = [
      '#type' => 'select',
      '#title' => $this->t('Filter by'),
      '#options' => $this->getFilterableKeys(),
      '#default_value' => $configuration['filter']['key'],
      '#ajax' => TRUE,
    ];

    $form['filter']['negate'] = [
      '#type' => 'radios',
      '#title' => $this->t('Filter by'),
      '#options' => [
        FALSE => $this->t('Include the selected below'),
        TRUE => $this->t('Exclude the selected below'),
      ],
      '#default_value' => (int) $configuration['filter']['negate'],
    ];

    $form['filter']['target_values'] = $this->buildTargetValuesElement($form, $form_state);

    return $form;
  }

  /**
   * Build the target values form element.
   *
   * @param array $form
   *   An associative array containing the initial structure of the plugin form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   *
   * @return array
   *   The target values form element.
   */
  protected function buildTargetValuesElement(array $form, FormStateInterface $form_state): array {
    $configuration = $this->getConfiguration();

    $filter_key = $form_state->getValue([
      'settings',
      'handler_settings',
      'filter',
      'key',
    ]) ?? $configuration['filter']['key'];

    if (empty($filter_key)) {
      return [];
    }

    if ($filter_key === 'id') {
      $element = [
        '#type' => 'tableselect',
        '#header' => [
          $this->t('Label/ID'),
          $this->t('Provider'),
        ],
        '#js_select' => TRUE,
        '#empty_option' => $this->t('No options available.'),
      ];
    }
    else {
      $element = [
        '#type' => 'checkboxes',
      ];
    }

    $element += [
      '#title' => $this->t('Filter values'),
      '#options' => $this->getTargetValuesOptions($filter_key),
      '#required' => TRUE,
      '#default_value' => $configuration['filter']['target_values'],
      '#element_validate' => [[static::class, 'elementValidateFilter']],
    ];

    return $element;
  }

  /**
   * Helper method that builds an array of target values.
   *
   * @param string $filter_key
   *   The key on which the plugins will be filtered.
   *
   * @return array
   *   An array of target values.
   */
  protected function getTargetValuesOptions(string $filter_key) {
    $options = [];
    $target_type = $this->getConfiguration()['target_type'];
    $plugin_definitions = $this->pluginTypeHelper->getPluginDefinitions($target_type);
    foreach ($plugin_definitions as $plugin_id => $plugin_definition) {
      switch ($filter_key) {
        case 'id':
          $options[$plugin_id] = [
            ['label' => $this->pluginTypeHelper->getPluginLabel($plugin_definition) . ' (' . $plugin_id . ')'],
            ['provider' => $plugin_definition['provider']],
          ];
          break;

        case 'provider':
          $options[$plugin_definition[$filter_key]] = $this->pluginTypeHelper->getProviderName($plugin_definition[$filter_key]);
          break;

        default:
          if ($plugin_definition[$filter_key] instanceof TranslatableMarkup) {
            $options[$plugin_definition[$filter_key]->getUntranslatedString()] = $plugin_definition[$filter_key];
          }
          else {
            $options[$plugin_definition[$filter_key]] = $plugin_definition[$filter_key];
          }
      }
    }

    ksort($options);

    return $options;
  }

  /**
   * Get all keys that are supported to filter on.
   *
   * @return array
   *   An array of keys that are allowed to filter on.
   */
  protected function getFilterableKeys(): array {
    return [
      'id' => $this->t('Plugin'),
      'provider' => $this->t('Provider'),
    ];
  }

  /**
   * {@inheritdoc}
   */
  protected function filterReferenceablePluginDefinitions(array &$plugin_definitions): void {
    $filter_key = $this->getConfiguration()['filter']['key'];
    $filter_negate = $this->getConfiguration()['filter']['negate'];
    $filter_target_values = $this->getConfiguration()['filter']['target_values'];

    foreach ($plugin_definitions as $plugin_id => $plugin_definition) {
      if ($filter_negate === FALSE && !in_array($plugin_definition[$filter_key], $filter_target_values, TRUE)) {
        unset($plugin_definitions[$plugin_id]);
      }
      elseif ($filter_negate === TRUE && in_array($plugin_definition[$filter_key], $filter_target_values, TRUE)) {
        unset($plugin_definitions[$plugin_id]);
      }
    }
  }

  /**
   * Form element validation handler; Filters the #value property of an element.
   */
  public static function elementValidateFilter(array &$element, FormStateInterface $form_state): void {
    $element['#value'] = array_filter($element['#value']);
    $form_state->setValueForElement($element, $element['#value']);
  }

}

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

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