toolshed-8.x-1.x-dev/modules/toolshed_search/src/Plugin/views/filter/IncludeDatasourceFilter.php

modules/toolshed_search/src/Plugin/views/filter/IncludeDatasourceFilter.php
<?php

namespace Drupal\toolshed_search\Plugin\views\filter;

use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Form\FormStateInterface;
use Drupal\search_api\Plugin\views\filter\SearchApiFilterTrait;
use Drupal\search_api\SearchApiException;
use Drupal\views\Plugin\views\filter\FilterPluginBase;

/**
 * A Search API datasource filter to toggle a datasource.
 *
 * This filter is mostly only useful when used as exposed input, when you want
 * to allow users to remove a datasource. An example would be a checkbox
 * for controlling including "media" into search results.
 *
 * @ViewsFilter("toolshed_datasource_filter")
 */
class IncludeDatasourceFilter extends FilterPluginBase {

  use SearchApiFilterTrait;

  /**
   * {@inheritdoc}
   */
  public function adminSummary(): \Stringable|string {
    try {
      $datasource = $this
        ->getIndex()
        ->getDatasource($this->options['search_api_datasource']);

      $srcName = $datasource->getPluginDefinition()['label'] ?? $this->options['search_api_datasource'];
      return new FormattableMarkup('@source=@status', [
        '@source' => $srcName,
        '@status' => $this->value ? $this->t('on') : $this->t('off'),
      ]);
    }
    catch (SearchApiException $e) {
      return $this->t('datasource');
    }
  }

  /**
   * {@inheritdoc}
   */
  public function acceptExposedInput($input): bool {
    if (empty($this->options['exposed'])) {
      return TRUE;
    }

    $filterKey = $this->options['expose']['identifier'];
    $this->value = !empty($input[$filterKey]);
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function buildExposedForm(&$form, FormStateInterface $form_state): void {
    if (empty($this->options['exposed'])) {
      return;
    }

    $input = $form_state->getUserInput();
    $exposeInfo = $this->exposedInfo();
    $filterKey = $this->options['expose']['identifier'];

    // Check if form has been submitted. If not submitted we need to apply
    // the default plugin value. Note that this only needs to be updated
    // when the value is "TRUE" since "FALSE" is empty input.
    if (empty($input)) {
      if ($this->value) {
        $input[$filterKey] = $this->value;
        $form_state->setUserInput($input);
      }
    }

    $form[$filterKey] = [
      '#type' => 'checkbox',
      '#title' => $exposeInfo['label'] ?? $this->t('Include datasource'),
      '#default_value' => $this->value,
    ];

    // A hack which allows us to know if the form was submitted as opposed to
    // on initial load, and the current value should be used.
    // This happens because unchecked boxes, don't appear in the URL query for
    // GET request, therefore we're faking some input that will appear. If this
    // was an input already using this key, purpose is still served.
    // This issue happens when this checkbox is without other exposed filters.
    //
    // @todo find way to resolve get filter to set query param even when 'off'
    // or only use this when there are no other exposed filters.
    if (!isset($form['ds']) && $this->options['value']) {
      $form['ds'] = [
        '#type' => 'hidden',
        '#default_value' => 0,
      ];
    }
  }

  /**
   * {@inheritdoc}
   */
  protected function defineOptions(): array {
    $options = parent::defineOptions();

    $options['exposed']['default'] = TRUE;
    $options['search_api_datasource'] = ['default' => NULL];

    return $options;
  }

  /**
   * {@inheritdoc}
   */
  protected function setOptionDefaults(array &$storage, array $options): void {
    parent::setOptionDefaults($storage, $options);

    // For this filter, it is only effective if it is exposed, and cannot
    // be required.
    if (isset($storage['exposed'])) {
      $storage['exposed'] = TRUE;
      $storage['expose']['required'] = FALSE;
      $storage['expose']['multiple'] = FALSE;
    }
  }

  /**
   * {@inheritdoc}
   */
  public function buildOptionsForm(&$form, FormStateInterface $form_state): void {
    parent::buildOptionsForm($form, $form_state);

    $form['expose_button']['#access'] = FALSE;
    $form['expose']['required']['#access'] = FALSE;
    $form['expose']['multiple']['#access'] = FALSE;

    $srcOptions = [];
    foreach ($this->getIndex()->getDatasources() as $did => $datasource) {
      $sourceDef = $datasource->getPluginDefinition();
      $srcOptions[$did] = $sourceDef['label'] ?? $did;
    }

    // Generally use the value form to set this value, however, due to some
    // views options form layout issues, create in the options form and
    // reassign the value to the proper options value after submit.
    $form['enabled_by_default'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Enable datasource by default'),
      '#default_value' => $this->options['value'],
    ];

    $form['search_api_datasource'] = [
      '#type' => 'select',
      '#title' => $this->t('Datasource to toggle'),
      '#required' => TRUE,
      '#options' => $srcOptions,
      '#default_value' => $this->options['search_api_datasource'],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function submitOptionsForm(&$form, FormStateInterface $form_state): void {
    parent::submitOptionsForm($form, $form_state);

    $this->options['value'] = $form_state->getValue([
      'options',
      'enabled_by_default',
    ]);
  }

  /**
   * {@inheritdoc}
   */
  public function query(): void {
    $datasource = $this->options['search_api_datasource'] ?? NULL;

    if ($this->value || !$datasource) {
      return;
    }

    $group = $this->options['group'];
    $field = "{$this->tableAlias}.{$this->realField}";

    $this->ensureMyTable();
    $this->getQuery()->addWhere($group, $field, $datasource, '<>');
  }

}

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

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