search_web_components-1.0.x-dev/modules/block/src/Plugin/Block/FacetBlockBase.php

modules/block/src/Plugin/Block/FacetBlockBase.php
<?php

declare(strict_types=1);

namespace Drupal\search_web_components_block\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Form\SubformStateInterface;
use Drupal\Core\Logger\LoggerChannelTrait;
use Drupal\Core\Messenger\MessengerTrait;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Template\Attribute;
use Drupal\Core\Url;
use Drupal\search_web_components_facets\Form\FacetElementHelperTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Defines a base facet block implementation that facet plugins can extend.
 *
 * This abstract class provides the generic block configuration form and default
 * facet settings included in the build method.
 *
 * @phpcs:disable Drupal.Semantics.FunctionT.NotLiteralString
 */
abstract class FacetBlockBase extends BlockBase implements ContainerFactoryPluginInterface {

  use LoggerChannelTrait;
  use MessengerTrait;
  use FacetElementHelperTrait;

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected EntityTypeManagerInterface $entityTypeManager;

  /**
   * The module handler.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected ModuleHandlerInterface $moduleHandler;

  /**
   * Construct Drupal\search_web_components_block\Plugin\Block\FacetBlockBase.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   The entity type manager.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler
   *   The module handler.
   */
  public function __construct($configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entityTypeManager, ModuleHandlerInterface $moduleHandler) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);

    $this->entityTypeManager = $entityTypeManager;
    $this->moduleHandler = $moduleHandler;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    // @phpstan-ignore new.static
    return new static($configuration, $plugin_id, $plugin_definition,
      $container->get('entity_type.manager'),
      $container->get('module_handler')
    );
  }

  /**
   * The facet widgets that this block supports.
   *
   * @return string[]
   *   An array of facet widget ids that are supported.
   */
  public function supportedWidgets(): array {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration(): array {
    return [
      'endpoint' => NULL,
      'facet' => NULL,
      'key' => '',
      'overrideLabel' => '',
    ] + $this->defaultValues();
  }

  /**
   * {@inheritdoc}
   */
  public function blockForm($form, FormStateInterface $form_state): array {
    $endpoints = $this->entityTypeManager->getStorage('search_api_endpoint')->loadMultiple();

    $endpointOptions = [];
    foreach ($endpoints as $endpoint) {
      $endpointOptions[$endpoint->id()] = $endpoint->label();
    }

    if (!$endpointOptions && $this->configuration['endpoint'] !== 'manual_entry') {
      $link = Url::fromRoute('entity.search_api_endpoint.collection')->toString();
      $this->messenger()->addWarning($this->t(
        'No Decoupled Search Endpoints configured, you can create one <a href=":url" target="_blank">here</a>.',
        [':url' => $link])
      );
      $form['message'] = [
        '#type' => 'status_messages',
        '#weight' => -10,
      ];
    }

    $endpointOptions['manual_entry'] = 'Remote/Other';

    $form['endpoint'] = [
      '#title' => 'Decoupled Search Endpoint',
      '#type' => 'select',
      '#required' => TRUE,
      '#options' => $endpointOptions,
      '#default_value' => $this->configuration['endpoint'] ?? array_key_first($endpointOptions),
      '#ajax' => [
        'callback' => [$this, 'buildAjaxSettingsForm'],
        'wrapper' => 'swc-settings-container',
        'method' => 'replace',
        'effect' => 'fade',
      ],
    ];

    $form['settings'] = [
      '#type' => 'container',
      '#id' => 'swc-settings-container',
    ];

    $complete_form_state = $form_state instanceof SubformStateInterface ? $form_state->getCompleteFormState() : $form_state;

    $endpointId = $complete_form_state->getValue(['settings', 'endpoint'], $this->configuration['endpoint'] ?? array_key_first($endpointOptions));
    if ($endpointId !== 'manual_entry') {
      $endpoint = $this->entityTypeManager->getStorage('search_api_endpoint')->load($endpointId);
      if ($endpoint) {
        $facets = $endpoint->getFacets();
        $facetOptions = [];
        $supported = $this->supportedWidgets();
        foreach ($facets as $option) {
          if (empty($supported) || in_array($option->getWidget()['type'], $supported)) {
            $facetOptions[$option->id()] = $option->getName();
          }
        }

        if (!$facetOptions) {
          if (!$this->moduleHandler->moduleExists('facets')) {
            $this->messenger()->addWarning($this->t(
              'The facets module is not enabled.',
            ));
          }
          else {
            $link = Url::fromRoute('entity.facets_facet.collection')->toString();
            $this->messenger()->addWarning($this->t(
              'No @type facets are configured, you can create some <a href=":url" target="_blank">here</a>.',
              ['@type' => implode(' ,', $this->supportedWidgets()), ':url' => $link])
            );
          }
          $form['message'] = [
            '#type' => 'status_messages',
            '#weight' => -10,
          ];
        }

        $facetValue = $complete_form_state->getValue(['settings', 'facet'], $this->configuration['facet'] ?? array_key_first($facetOptions));
        $facetValue = isset($facetOptions[$facetValue]) ? $facetValue : NULL;
        $form['settings']['facet'] = [
          '#title' => $this->t('Facet'),
          '#type' => 'select',
          '#required' => TRUE,
          '#default_value' => $facetValue,
          '#options' => $facetOptions,
        ];
      }
      else {
        $this->getLogger('search_web_components_block')->error(
          'Failed to load Decoupled Search Endpoint @id for block @block',
          ['@id' => $this->configuration['endpoint'], '@block' => $this->getPluginId()]
        );
      }
    }
    else {
      $form['settings']['key'] = [
        '#type' => 'textfield',
        '#title' => $this->t('Facet to display'),
        '#description' => $this->t('Machine name of the facet to display'),
        '#default_value' => $this->configuration['key'],
      ];
      $form['settings'] = array_merge($form['settings'], $this->formElements());
    }

    $form['settings']['overrideLabel'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Override the facet label'),
      '#default_value' => $this->configuration['overrideLabel'],
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function blockSubmit($form, FormStateInterface $form_state): void {
    $this->configuration['endpoint'] = $form_state->getValue('endpoint');
    $this->configuration['facet'] = $form_state->getValue(['settings', 'facet']);
    $this->configuration['key'] = $form_state->getValue(['settings', 'key']);
    $this->configuration['overrideLabel'] = $form_state->getValue(['settings', 'overrideLabel']);
    $this->submitElements($form_state, $form_state->getValue(['settings']));
  }

  /**
   * {@inheritdoc}
   */
  public function build(): array {
    $config = $this->configuration;
    $searchAttributes = new Attribute();

    $key = $config['facet'];
    if ($config['endpoint'] === 'manual_entry') {
      $key = $config['key'];
    }
    $searchAttributes->setAttribute('key', $key);

    if ($config['overrideLabel'] !== NULL) {
      $searchAttributes->setAttribute('overrideLabel', $this->t($config['overrideLabel'])->__toString());
    }

    return [
      '#search_attributes' => $this->renderProperties($searchAttributes),
      '#attached' => [
        'library' => [
          'search_web_components/components',
        ],
      ],
    ];
  }

  /**
   * Handles changes to the settings when the source changes.
   */
  public static function buildAjaxSettingsForm(array $form, FormStateInterface $form_state) {
    return $form['settings']['settings'];
  }

}

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

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