You are here

abstract class CoreViewsFacetSourceBase in Core Views Facets 8

Provide common functions for core Views based facet sources.

Hierarchy

Expanded class hierarchy of CoreViewsFacetSourceBase

2 files declare their use of CoreViewsFacetSourceBase
core_views_facets.module in ./core_views_facets.module
Contains core_views_facets.module.
ViewsFacetForm.php in src/Form/ViewsFacetForm.php

File

src/Plugin/facets/facet_source/CoreViewsFacetSourceBase.php, line 22

Namespace

Drupal\core_views_facets\Plugin\facets\facet_source
View source
abstract class CoreViewsFacetSourceBase extends FacetSourcePluginBase {

  /**
   * The current view.
   *
   * @var \Drupal\views\ViewExecutable
   */
  protected $view;

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

  /**
   * The url processor name.
   *
   * @var string
   */
  protected $urlProcessor = 'core_views_url_processor';

  /**
   * The master request.
   *
   * @var \Symfony\Component\HttpFoundation\Request
   */
  protected $request;

  /**
   * The route provider.
   *
   * @var \Drupal\Core\Routing\RouteProviderInterface
   */
  protected $routeProvider;

  /**
   * The route match.
   *
   * @var \Drupal\Core\Routing\RouteMatchInterface
   */
  protected $routeMatch;

  /**
   * The entity field manager.
   *
   * @var \Drupal\Core\Entity\EntityFieldManagerInterface
   */
  protected $entityFieldManager;

  /**
   * Constructs a CoreViewsContextualFilter object.
   *
   * @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\facets\QueryType\QueryTypePluginManager $query_type_plugin_manager
   *   The query type plugin manager.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity manager.
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The master Request.
   * @param \Drupal\Core\Routing\RouteProviderInterface $route_provider
   *   The route provider.
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   *   The route match.
   * @param \Drupal\views\ViewExecutableFactory $executable_factory
   *   The view executable factory.
   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
   *   The entity field manager.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, QueryTypePluginManager $query_type_plugin_manager, EntityTypeManagerInterface $entity_type_manager, Request $request, RouteProviderInterface $route_provider, RouteMatchInterface $route_match, ViewExecutableFactory $executable_factory, EntityFieldManagerInterface $entity_field_manager) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $query_type_plugin_manager);
    $this->entityTypeManager = $entity_type_manager;
    $this->request = $request;
    $this->routeProvider = $route_provider;
    $this->routeMatch = $route_match;

    // Load the view.

    /** @var \Drupal\views\ViewEntityInterface $view */
    $view = $this->entityTypeManager
      ->getStorage('view')
      ->load($plugin_definition['view_id']);
    $this->view = $executable_factory
      ->get($view);
    $this->view
      ->setDisplay($plugin_definition['view_display']);
    $this->entityFieldManager = $entity_field_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static($configuration, $plugin_id, $plugin_definition, $container
      ->get('plugin.manager.facets.query_type'), $container
      ->get('entity_type.manager'), $container
      ->get('request_stack')
      ->getMasterRequest(), $container
      ->get('router.route_provider'), $container
      ->get('current_route_match'), $container
      ->get('views.executable'), $container
      ->get('entity_field.manager'));
  }

  /**
   * Return the current view.
   *
   * @return \Drupal\views\ViewExecutable
   *   Current view.
   */
  public function getView() {
    return $this->view;
  }

  /**
   * {@inheritdoc}
   */
  public function getPath() {
    $path = $this->view
      ->getPath();
    if ($path[0] !== '/') {
      $path = '/' . $path;
    }
    return $path;
  }

  /**
   * {@inheritdoc}
   */
  public function isRenderedInCurrentRequest() {
    if ($this->request->attributes
      ->get('_controller') === 'Drupal\\views\\Routing\\ViewPageController::handle') {
      list(, $view) = explode(':', $this
        ->getPluginId());
      list($view_id, $view_display) = explode('__', $view);
      if ($this->request->attributes
        ->get('view_id') == $view_id && $this->request->attributes
        ->get('display_id') == $view_display) {
        return TRUE;
      }
    }
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $form['field_identifier'] = [
      '#type' => 'select',
      '#options' => [],
      '#title' => $this
        ->t('Facet field'),
      '#description' => $this
        ->t('Choose the filter to facet by.'),
      '#required' => TRUE,
      '#default_value' => $this->facet
        ->getFieldIdentifier(),
    ];
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
    $facet_source_id = $this->facet
      ->getFacetSourceId();
    $triggering_element = $form_state
      ->getTriggeringElement();
    if (!empty($triggering_element['#name']) && $triggering_element['#name'] === 'facet_source_configure') {
      return;
    }
    $views_filters = $this
      ->getFields();
    $field_identifier = $form_state
      ->getValue('facet_source_configs')[$facet_source_id]['field_identifier'];
    if (empty($field_identifier) || empty($views_filters[$field_identifier])) {
      $form_state
        ->setErrorByName('facet_source_id', t('Please select a valid field.'));
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getQueryTypesForFacet(FacetInterface $facet) {

    // We don't actually use this. Just put something that exists.
    return [
      'string' => 'search_api_string',
    ];
  }

  /**
   * Retrieves the current views arguments map and returns a detailed version.
   *
   * @return array
   *   Detail enriched argument data.
   */
  public function getViewsArgumentsMap() {
    if (empty($this->view
      ->getDisplay()
      ->getRoutedDisplay())) {
      return [];
    }
    $views_arguments = [];
    $arguments = $this->view
      ->getHandlers('argument', $this->view->current_display);
    foreach ($arguments as $argument_id => $argument) {
      $views_arguments[$argument_id] = $this->view->display_handler
        ->getHandler('argument', $argument_id);
    }
    reset($views_arguments);
    $route_name = $this->view
      ->getUrl()
      ->getRouteName();
    try {
      $route = $this->routeProvider
        ->getRouteByName($route_name);
    } catch (RouteNotFoundException $e) {
      return [];
    }
    $route_map = $route
      ->hasOption('_view_argument_map') ? $route
      ->getOption('_view_argument_map') : [];

    // Where do arguments come from?
    if ($this
      ->isRenderedInCurrentRequest()) {
      if ($ajax_arguments = drupal_static('core_views_contextual_filter_ajax_arguments')) {
        $argument_source = 'view_ajax';
        reset($ajax_arguments);
      }
      else {
        $argument_source = 'view_page';
      }
    }
    else {
      $argument_source = 'view_defaults';
    }

    // Each argument can only be active, if each previous argument was active
    // too. This variable is set to FALSE for all following arguments, when any
    // one argument is inactive.
    $active_value = TRUE;
    $map = [];

    // For all I can tell, the association view argument <-> route argument
    // happens entirely by counting up in both arrays...
    foreach ($route_map as $attribute => $parameter_name) {
      $current_map_entry = [];

      // Allow parameters be pulled from the request.
      // The map stores the actual name of the parameter in the request. Views
      // which override existing controller, use for example 'node' instead of
      // arg_nid as name.
      if (isset($map[$attribute])) {
        $attribute = $map[$attribute];
      }
      $current_map_entry['route_parameter'] = $attribute;
      $current_map_entry['views_argument_id'] = key($views_arguments);
      $current_map_entry['views_argument'] = current($views_arguments);
      next($views_arguments);
      $current_map_entry['neutral_value'] = empty($current_map_entry['views_argument']->options['exception']['value']) ? 'all' : $current_map_entry['views_argument']->options['exception']['value'];
      switch ($argument_source) {
        case 'view_page':

          // This is views page request, standard procedure.
          if ($current_request_argument = $this->routeMatch
            ->getRawParameter($attribute)) {
          }
          else {
            $current_request_argument = $this->routeMatch
              ->getParameter($attribute);
          }
          if (isset($current_request_argument)) {
            $current_map_entry['value'] = $current_request_argument;
            $current_map_entry['active'] = $active_value;
          }
          else {
            $current_map_entry['value'] = $current_map_entry['neutral_value'];
            $current_map_entry['active'] = FALSE;
            $active_value = FALSE;
          }
          break;
        case 'view_ajax':
          if (current($ajax_arguments)) {
            $current_map_entry['value'] = current($ajax_arguments);
            $current_map_entry['active'] = $active_value;
            if ($current_map_entry['value'] == $current_map_entry['neutral_value']) {
              $current_map_entry['active'] = FALSE;
            }
            next($ajax_arguments);
          }
          else {
            $current_map_entry['value'] = $current_map_entry['neutral_value'];
            $current_map_entry['active'] = FALSE;
            $active_value = FALSE;
          }
          break;
        default:

          // Just add the defaults.
          $current_map_entry['value'] = $current_map_entry['neutral_value'];
          $current_map_entry['active'] = FALSE;
          $active_value = FALSE;
      }
      $map[$current_map_entry['views_argument_id']] = $current_map_entry;
    }
    return $map;
  }

  /**
   * Optionally get JS settings when AJAX is enabled.
   *
   * @param \Drupal\facets\FacetInterface $facet
   *   The facet to get settings for.
   *
   * @return array
   *   The drupalSettings array.
   */
  public function getAjaxSettingsByFacet(FacetInterface $facet) {
    $this->view
      ->build($this->pluginDefinition['view_display']);
    $filter_handler = $this->view
      ->getHandler($this->view->current_display, 'filter', $facet
      ->getFieldIdentifier());
    return [
      'view_id' => $this->view
        ->id(),
      'current_display_id' => $this->view->current_display,
      'field_id' => $filter_handler['expose']['identifier'],
      'type' => $this
        ->getBaseId(),
      'view_base_path' => ltrim($this->view
        ->getPath(), '/'),
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function calculateDependencies() {
    $dependencies['config'] = [
      'views.view.' . $this->view
        ->id(),
    ];
    $dependencies['module'] = [
      'core_views_facets',
      'views',
    ];
    return $dependencies;
  }

  /**
   * {@inheritdoc}
   *
   * @throws \Drupal\facets\Exception\Exception
   */
  public function getDataDefinition($field_name) {
    throw new Exception("Field with name {$field_name} does not have a definition");
  }

  /**
   * Get original field name.
   *
   * @param array $definition
   *   Views handler defintion.
   *
   * @return string
   *   Original field name.
   *
   * @todo Find a better solution.
   */
  public function getOriginalFieldName(array $definition) {
    if (isset($definition['entity field'])) {
      return $definition['entity field'];
    }
    if (isset($definition['real_field'])) {
      return $definition['real_field'];
    }
    if (isset($definition['field_name'])) {
      return $definition['field_name'];
    }
    return $definition['field'] ?? '';
  }

}

Members

Namesort descending Modifiers Type Description Overrides
CoreViewsFacetSourceBase::$entityFieldManager protected property The entity field manager.
CoreViewsFacetSourceBase::$entityTypeManager protected property The entity manager.
CoreViewsFacetSourceBase::$request protected property The master request.
CoreViewsFacetSourceBase::$routeMatch protected property The route match.
CoreViewsFacetSourceBase::$routeProvider protected property The route provider.
CoreViewsFacetSourceBase::$urlProcessor protected property The url processor name.
CoreViewsFacetSourceBase::$view protected property The current view.
CoreViewsFacetSourceBase::buildConfigurationForm public function Form constructor. Overrides PluginFormInterface::buildConfigurationForm 2
CoreViewsFacetSourceBase::calculateDependencies public function Calculates dependencies for the configured plugin. Overrides DependentPluginInterface::calculateDependencies
CoreViewsFacetSourceBase::create public static function Creates an instance of the plugin. Overrides FacetSourcePluginBase::create 2
CoreViewsFacetSourceBase::getAjaxSettingsByFacet public function Optionally get JS settings when AJAX is enabled.
CoreViewsFacetSourceBase::getDataDefinition public function Overrides FacetSourcePluginInterface::getDataDefinition 2
CoreViewsFacetSourceBase::getOriginalFieldName public function Get original field name.
CoreViewsFacetSourceBase::getPath public function Returns the path of the facet source, used to build the facet url. Overrides FacetSourcePluginInterface::getPath
CoreViewsFacetSourceBase::getQueryTypesForFacet public function Returns the allowed query types for a given facet for the facet source. Overrides FacetSourcePluginBase::getQueryTypesForFacet
CoreViewsFacetSourceBase::getView public function Return the current view.
CoreViewsFacetSourceBase::getViewsArgumentsMap public function Retrieves the current views arguments map and returns a detailed version.
CoreViewsFacetSourceBase::isRenderedInCurrentRequest public function Returns true if the Facet source is being rendered in the current request. Overrides FacetSourcePluginBase::isRenderedInCurrentRequest 2
CoreViewsFacetSourceBase::validateConfigurationForm public function Form validation handler. Overrides FacetSourcePluginBase::validateConfigurationForm
CoreViewsFacetSourceBase::__construct public function Constructs a CoreViewsContextualFilter object. Overrides FacetSourcePluginBase::__construct 2
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
FacetSourcePluginBase::$facet protected property The facet we're editing for.
FacetSourcePluginBase::$keys protected property The search keys, or query text, submitted by the user.
FacetSourcePluginBase::$queryTypePluginManager protected property The plugin manager.
FacetSourcePluginBase::buildFacet public function Builds and returns an extra renderable array for this facet block plugin. Overrides FacetSourcePluginInterface::buildFacet 1
FacetSourcePluginBase::getCount public function Returns the number of results that were found for this search. Overrides FacetSourcePluginInterface::getCount 1
FacetSourcePluginBase::getFields public function Returns an array of fields that are defined on the facet source. Overrides FacetSourcePluginInterface::getFields 2
FacetSourcePluginBase::getSearchKeys public function Returns the search keys, or query text, submitted by the user. Overrides FacetSourcePluginInterface::getSearchKeys
FacetSourcePluginBase::setSearchKeys public function Sets the search keys, or query text, submitted by the user. Overrides FacetSourcePluginInterface::setSearchKeys
FacetSourcePluginBase::submitConfigurationForm public function Form submission handler. Overrides PluginFormInterface::submitConfigurationForm
FacetSourcePluginInterface::fillFacetsWithResults public function Fills the facet entities with results from the facet source. 1
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.