You are here

class SearchApiSortsBlock in Search API sorts 8

Exposes a search api sorts rendered as a block.

Plugin annotation


@Block(
  id = "search_api_sorts_block",
  deriver = "Drupal\search_api_sorts\Plugin\Block\SearchApiSortsBlockDeriver"
)

Hierarchy

Expanded class hierarchy of SearchApiSortsBlock

File

src/Plugin/Block/SearchApiSortsBlock.php, line 19

Namespace

Drupal\search_api_sorts\Plugin\Block
View source
class SearchApiSortsBlock extends BlockBase {
  use ConfigIdEscapeTrait;

  /**
   * {@inheritdoc}
   */
  public function build() {
    $build = [];

    /** @var \Drupal\search_api\Display\DisplayInterface $search_api_display */
    $search_api_display = $this->pluginDefinition['search_api_display'];
    if (!$search_api_display
      ->isRenderedInCurrentRequest()) {

      // Display is not rendered in current request, hide block.
      return [];
    }

    /** @var \Drupal\search_api_sorts\SearchApiSortsManagerInterface $search_api_sorts_manager */
    $search_api_sorts_manager = \Drupal::service('search_api_sorts.manager');
    $enabled_sorts = $search_api_sorts_manager
      ->getEnabledSorts($search_api_display);
    if (!$enabled_sorts) {

      // No fields are enabled for sorting, hide block.
      return [];
    }
    $active_sort = $search_api_sorts_manager
      ->getActiveSort($search_api_display);
    $current_sort_field = $active_sort
      ->getFieldName();
    $current_sort_order = $active_sort
      ->getOrder();
    if ($active_sort
      ->getFieldName() == NULL) {
      $default_sort = $search_api_sorts_manager
        ->getDefaultSort($search_api_display);
      $current_sort_field = $default_sort
        ->getFieldName();
      $current_sort_order = $default_sort
        ->getOrder();
    }

    // Helper array to sort enabled sorts by weight.
    $sorts = [];
    foreach ($enabled_sorts as $enabled_sort) {
      $sorts[$enabled_sort
        ->get('field_identifier')] = [
        'label' => $enabled_sort
          ->get('label'),
        'weight' => $enabled_sort
          ->get('weight'),
        'default_order' => $enabled_sort
          ->get('default_order'),
      ];
    }
    uasort($sorts, [
      'Drupal\\Component\\Utility\\SortArray',
      'sortByWeightElement',
    ]);

    // TODO: fetch path by configuration (data source?) instead of current path.
    $url = \Drupal::request()
      ->getRequestUri();
    $base_path = \Drupal::request()
      ->getBasePath();
    $url = str_replace($base_path, '', $url);
    $url_array = UrlHelper::parse($url);
    $items = [];
    foreach ($sorts as $sort_field => $sort) {
      $order = $sort['default_order'];
      if ($sort_field == $current_sort_field) {
        $order = $current_sort_order == 'desc' ? 'asc' : 'desc';
      }
      $url_array['query']['sort'] = $sort_field;
      $url_array['query']['order'] = $order;
      $active = $sort_field == $current_sort_field;
      $order_indicator = '';
      if ($active) {
        $order_indicator = [
          '#theme' => 'tablesort_indicator',
          '#style' => $order,
        ];
      }
      $items[] = [
        '#theme' => 'search_api_sorts_sort',
        '#label' => $sort['label'],
        '#url' => Url::fromUserInput($url_array['path'], [
          'query' => $url_array['query'],
          'fragment' => $url_array['fragment'],
        ])
          ->toString(),
        '#active' => $active,
        '#order' => $order,
        '#order_indicator' => $order_indicator,
        '#sort_field' => $sort_field,
      ];
    }
    $build['links'] = [
      '#theme' => 'item_list__search_api_sorts',
      '#items' => $items,
      '#attributes' => [
        'class' => [
          'search-api-sorts',
          'search-api-sorts--' . Html::getClass($search_api_display
            ->getPluginId()),
        ],
      ],
    ];
    $build['#contextual_links']['search_api_sorts'] = [
      'route_parameters' => [
        'search_api_index' => $search_api_display
          ->getIndex()
          ->id(),
        'search_api_display' => $this
          ->getEscapedConfigId($search_api_display
          ->getPluginId()),
      ],
    ];
    return $build;
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheMaxAge() {

    // A search api sorts block cannot be cached, because it must always match
    // the current search results, and Search API gets those search results from
    // a data source that can be external to Drupal. Therefore it is impossible
    // to guarantee that the search results are in sync with the data managed by
    // Drupal. Consequently, it is not possible to cache the search results at
    // all. If the search results cannot be cached, then neither can the search
    // api sorts, because they must always match.
    // Fortunately, search api sorts blocks are rendered using a lazy builder
    // (like all blocks in Drupal), which means their rendering can be deferred
    // (unlike the search results, which are the main content of the page, and
    // deferring their rendering would mean sending an empty page to the user).
    // This means that search api sorts blocks can be rendered and sent *after*
    // the initial page was loaded, by installing the BigPipe (big_pipe) module.
    //
    // When BigPipe is enabled, the search results will appear first, and then
    // each search api sorts block will appear one-by-one, in DOM order.
    // See https://www.drupal.org/project/big_pipe.
    //
    // In a future version of search api sorts API, this could be refined, but
    // due to the reliance on external data sources, it will be very difficult
    // if not impossible to improve this significantly.
    return 0;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
BlockPluginInterface::BLOCK_LABEL_VISIBLE constant Indicates the block label (title) should be displayed to end users.
BlockPluginTrait::$transliteration protected property The transliteration service.
BlockPluginTrait::access public function
BlockPluginTrait::baseConfigurationDefaults protected function Returns generic default configuration for block plugins.
BlockPluginTrait::blockAccess protected function Indicates whether the block should be shown. 16
BlockPluginTrait::blockForm public function 16
BlockPluginTrait::blockSubmit public function 13
BlockPluginTrait::blockValidate public function 3
BlockPluginTrait::buildConfigurationForm public function Creates a generic configuration form for all block types. Individual block plugins can add elements to this form by overriding BlockBase::blockForm(). Most block plugins should not override this method unless they need to alter the generic form elements. 2
BlockPluginTrait::calculateDependencies public function
BlockPluginTrait::defaultConfiguration public function 19
BlockPluginTrait::getConfiguration public function 1
BlockPluginTrait::getMachineNameSuggestion public function 1
BlockPluginTrait::getPreviewFallbackString public function 3
BlockPluginTrait::label public function
BlockPluginTrait::setConfiguration public function
BlockPluginTrait::setConfigurationValue public function
BlockPluginTrait::setTransliteration public function Sets the transliteration service.
BlockPluginTrait::submitConfigurationForm public function Most block plugins should not override this method. To add submission handling for a specific block type, override BlockBase::blockSubmit().
BlockPluginTrait::transliteration protected function Wraps the transliteration service.
BlockPluginTrait::validateConfigurationForm public function Most block plugins should not override this method. To add validation for a specific block type, override BlockBase::blockValidate(). 1
BlockPluginTrait::__construct public function 22
ConfigIdEscapeTrait::getEscapedConfigId protected function Escape a config id which can be used to save as a config entity.
ConfigIdEscapeTrait::getOriginalConfigId protected function Get original config id after loading a config entity using an escaped id.
ContextAwarePluginAssignmentTrait::addContextAssignmentElement protected function Builds a form element for assigning a context to a given slot.
ContextAwarePluginAssignmentTrait::contextHandler protected function Wraps the context handler.
ContextAwarePluginBase::$context protected property The data objects representing the context of this plugin.
ContextAwarePluginBase::$contexts Deprecated private property Data objects representing the contexts passed in the plugin configuration.
ContextAwarePluginBase::createContextFromConfiguration protected function Overrides ContextAwarePluginBase::createContextFromConfiguration
ContextAwarePluginBase::getCacheContexts public function The cache contexts associated with this object. Overrides CacheableDependencyInterface::getCacheContexts 9
ContextAwarePluginBase::getCacheTags public function The cache tags associated with this object. Overrides CacheableDependencyInterface::getCacheTags 4
ContextAwarePluginBase::getContext public function This code is identical to the Component in order to pick up a different Context class. Overrides ContextAwarePluginBase::getContext
ContextAwarePluginBase::getContextDefinition public function Overrides ContextAwarePluginBase::getContextDefinition
ContextAwarePluginBase::getContextDefinitions public function Overrides ContextAwarePluginBase::getContextDefinitions
ContextAwarePluginBase::getContextMapping public function Gets a mapping of the expected assignment names to their context names. Overrides ContextAwarePluginInterface::getContextMapping
ContextAwarePluginBase::getContexts public function Gets the defined contexts. Overrides ContextAwarePluginInterface::getContexts
ContextAwarePluginBase::getContextValue public function Gets the value for a defined context. Overrides ContextAwarePluginInterface::getContextValue
ContextAwarePluginBase::getContextValues public function Gets the values for all defined contexts. Overrides ContextAwarePluginInterface::getContextValues
ContextAwarePluginBase::setContext public function Set a context on this plugin. Overrides ContextAwarePluginBase::setContext
ContextAwarePluginBase::setContextMapping public function Sets a mapping of the expected assignment names to their context names. Overrides ContextAwarePluginInterface::setContextMapping
ContextAwarePluginBase::setContextValue public function Sets the value for a defined context. Overrides ContextAwarePluginBase::setContextValue
ContextAwarePluginBase::validateContexts public function Validates the set values for the defined contexts. Overrides ContextAwarePluginInterface::validateContexts
ContextAwarePluginBase::__get public function Implements magic __get() method.
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
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.
PluginWithFormsTrait::getFormClass public function
PluginWithFormsTrait::hasFormClass public function
SearchApiSortsBlock::build public function Builds and returns the renderable array for this block plugin. Overrides BlockPluginInterface::build
SearchApiSortsBlock::getCacheMaxAge public function The maximum age for which this object may be cached. Overrides ContextAwarePluginBase::getCacheMaxAge
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.
TypedDataTrait::$typedDataManager protected property The typed data manager used for creating the data types.
TypedDataTrait::getTypedDataManager public function Gets the typed data manager. 2
TypedDataTrait::setTypedDataManager public function Sets the typed data manager. 2