You are here

class SaveSearch in Search API Saved Searches 8

Displays the "Save search" form in a block.

Plugin annotation


@Block(
  id = "search_api_saved_searches",
  admin_label = @Translation("Save search"),
  category = @Translation("Forms"),
)

Hierarchy

Expanded class hierarchy of SaveSearch

File

src/Plugin/Block/SaveSearch.php, line 26

Namespace

Drupal\search_api_saved_searches\Plugin\Block
View source
class SaveSearch extends BlockBase implements ContainerFactoryPluginInterface {

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

  /**
   * The form builder.
   *
   * @var \Drupal\Core\Form\FormBuilderInterface|null
   */
  protected $formBuilder;

  /**
   * The query helper.
   *
   * @var \Drupal\search_api\Utility\QueryHelperInterface|null
   */
  protected $queryHelper;

  /**
   * The request stack.
   *
   * @var \Symfony\Component\HttpFoundation\RequestStack|null
   */
  protected $requestStack;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    $block = new static($configuration, $plugin_id, $plugin_definition);
    $block
      ->setStringTranslation($container
      ->get('string_translation'));
    $block
      ->setEntityTypeManager($container
      ->get('entity_type.manager'));
    $block
      ->setFormBuilder($container
      ->get('form_builder'));
    $block
      ->setQueryHelper($container
      ->get('search_api.query_helper'));
    $block
      ->setRequestStack($container
      ->get('request_stack'));
    return $block;
  }

  /**
   * Retrieves the entity type manager.
   *
   * @return \Drupal\Core\Entity\EntityTypeManagerInterface
   *   The entity type manager.
   */
  public function getEntityTypeManager() {
    return $this->entityTypeManager ?: \Drupal::entityTypeManager();
  }

  /**
   * Sets the entity type manager.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The new entity type manager.
   *
   * @return $this
   */
  public function setEntityTypeManager(EntityTypeManagerInterface $entity_type_manager) {
    $this->entityTypeManager = $entity_type_manager;
    return $this;
  }

  /**
   * Retrieves the form builder.
   *
   * @return \Drupal\Core\Form\FormBuilderInterface
   *   The form builder.
   */
  public function getFormBuilder() {
    return $this->formBuilder ?: \Drupal::formBuilder();
  }

  /**
   * Sets the form builder.
   *
   * @param \Drupal\Core\Form\FormBuilderInterface $form_builder
   *   The new form builder.
   *
   * @return $this
   */
  public function setFormBuilder(FormBuilderInterface $form_builder) {
    $this->formBuilder = $form_builder;
    return $this;
  }

  /**
   * Retrieves the query helper.
   *
   * @return \Drupal\search_api\Utility\QueryHelperInterface
   *   The query helper.
   */
  public function getQueryHelper() {
    return $this->queryHelper ?: \Drupal::service('search_api.query_helper');
  }

  /**
   * Sets the query helper.
   *
   * @param \Drupal\search_api\Utility\QueryHelperInterface $query_helper
   *   The new query helper.
   *
   * @return $this
   */
  public function setQueryHelper(QueryHelperInterface $query_helper) {
    $this->queryHelper = $query_helper;
    return $this;
  }

  /**
   * Retrieves the request stack.
   *
   * @return \Symfony\Component\HttpFoundation\RequestStack
   *   The request stack.
   */
  public function getRequestStack() {
    return $this->requestStack ?: \Drupal::service('request_stack');
  }

  /**
   * Sets the request stack.
   *
   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
   *   The new request stack.
   *
   * @return $this
   */
  public function setRequestStack(RequestStack $request_stack) {
    $this->requestStack = $request_stack;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    return [
      'type' => NULL,
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function blockForm($form, FormStateInterface $form_state) {
    $types = $this
      ->getEntityTypeManager()
      ->getStorage('search_api_saved_search_type')
      ->loadMultiple();
    $type_options = [];
    foreach ($types as $type_id => $type) {
      $type_options[$type_id] = $type
        ->label();
    }
    $form['type'] = [
      '#type' => 'select',
      '#title' => $this
        ->t('Saved search type'),
      '#description' => $this
        ->t('The type/bundle of saved searches that should be created by this block.'),
      '#options' => $type_options,
      '#default_value' => $this->configuration['type'] ?: key($type_options),
      '#required' => TRUE,
    ];
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function blockSubmit($form, FormStateInterface $form_state) {
    $this->configuration['type'] = $form_state
      ->getValue('type');
  }

  /**
   * {@inheritdoc}
   */
  public function access(AccountInterface $account, $return_as_object = FALSE) {
    $access = parent::access($account, TRUE);
    $create_access = $this
      ->getEntityTypeManager()
      ->getAccessControlHandler('search_api_saved_search')
      ->createAccess($this->configuration['type'], $account, [], TRUE);
    $access = $access
      ->andIf($create_access);
    return $return_as_object ? $access : $access
      ->isAllowed();
  }

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

    // @todo Move those checks to access()? Would mean access results can't be
    //   cached, though.
    $type = $this
      ->getSavedSearchType();
    if (!$type) {
      $tags = $this
        ->getEntityTypeManager()
        ->getDefinition('search_api_saved_search_type')
        ->getListCacheTags();
      $cacheability
        ->addCacheTags($tags);
      $cacheability
        ->applyTo($build);
      return $build;
    }
    $cacheability
      ->addCacheableDependency($type);
    if (!$type
      ->status()) {
      $cacheability
        ->applyTo($build);
      return $build;
    }

    // Since there is no cache context for "search query on this page", we can't
    // cache this block (unless building it didn't get this far).
    $cacheability
      ->setCacheMaxAge(0);
    $cacheability
      ->applyTo($build);
    $query = $type
      ->getActiveQuery($this
      ->getQueryHelper());
    if (!$query) {
      return $build;
    }
    $description = $type
      ->getOption('description');
    if ($description) {
      $build['description']['#markup'] = Xss::filterAdmin($description);
    }
    $values = [
      'type' => $type
        ->id(),
      'index_id' => $query
        ->getIndex()
        ->id(),
      'query' => $query,
      // Remember the page on which the search was created.
      'path' => $this
        ->getCurrentPath(),
    ];
    $saved_search = $this
      ->getEntityTypeManager()
      ->getStorage('search_api_saved_search')
      ->create($values);
    $form_object = $this
      ->getEntityTypeManager()
      ->getFormObject('search_api_saved_search', 'create');
    $form_object
      ->setEntity($saved_search);
    $build['form'] = $this
      ->getFormBuilder()
      ->getForm($form_object);
    return $build;
  }

  /**
   * {@inheritdoc}
   */
  public function calculateDependencies() {
    $dependencies = parent::calculateDependencies();
    $type = $this
      ->getSavedSearchType();
    if ($type) {
      $dependencies['config'][] = $type
        ->getConfigDependencyName();
    }
    return $dependencies;
  }

  /**
   * Loads the saved search type used for this block.
   *
   * @return \Drupal\search_api_saved_searches\SavedSearchTypeInterface|null
   *   The saved search type, or NULL if it couldn't be loaded.
   */
  protected function getSavedSearchType() {
    if (!$this->configuration['type']) {
      return NULL;
    }

    /** @var \Drupal\search_api_saved_searches\SavedSearchTypeInterface $type */
    $type = $this
      ->getEntityTypeManager()
      ->getStorage('search_api_saved_search_type')
      ->load($this->configuration['type']);
    return $type;
  }

  /**
   * Retrieves a sanitized version of the current path.
   *
   * @return string
   *   The current path, relative to the Drupal installation.
   */
  protected function getCurrentPath() {

    // Get the current path.
    $path = $this
      ->getRequestStack()
      ->getCurrentRequest()
      ->getRequestUri();

    // Remove the Drupal base path, if any.
    $base_path = rtrim(base_path(), '/');
    $base_path_length = strlen($base_path);
    if ($base_path && substr($path, 0, $base_path_length) === $base_path) {
      $path = substr($path, $base_path_length);
    }

    // Remove AJAX parameters.
    $path = preg_replace('/([?&])(ajax_form|_wrapper_format)=[^&#]+/', '$1', $path);

    // Sanitize empty GET parameter arrays.
    $path = preg_replace('/\\?(#|$)/', '$1', $path);
    return $path;
  }

}

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::baseConfigurationDefaults protected function Returns generic default configuration for block plugins.
BlockPluginTrait::blockAccess protected function Indicates whether the block should be shown. 16
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::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
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::getCacheMaxAge public function The maximum age for which this object may be cached. Overrides CacheableDependencyInterface::getCacheMaxAge 7
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
SaveSearch::$entityTypeManager protected property The entity type manager.
SaveSearch::$formBuilder protected property The form builder.
SaveSearch::$queryHelper protected property The query helper.
SaveSearch::$requestStack protected property The request stack.
SaveSearch::access public function Overrides BlockPluginTrait::access
SaveSearch::blockForm public function Overrides BlockPluginTrait::blockForm
SaveSearch::blockSubmit public function Overrides BlockPluginTrait::blockSubmit
SaveSearch::build public function Builds and returns the renderable array for this block plugin. Overrides BlockPluginInterface::build
SaveSearch::calculateDependencies public function Overrides BlockPluginTrait::calculateDependencies
SaveSearch::create public static function Creates an instance of the plugin. Overrides ContainerFactoryPluginInterface::create
SaveSearch::defaultConfiguration public function Overrides BlockPluginTrait::defaultConfiguration
SaveSearch::getCurrentPath protected function Retrieves a sanitized version of the current path.
SaveSearch::getEntityTypeManager public function Retrieves the entity type manager.
SaveSearch::getFormBuilder public function Retrieves the form builder.
SaveSearch::getQueryHelper public function Retrieves the query helper.
SaveSearch::getRequestStack public function Retrieves the request stack.
SaveSearch::getSavedSearchType protected function Loads the saved search type used for this block.
SaveSearch::setEntityTypeManager public function Sets the entity type manager.
SaveSearch::setFormBuilder public function Sets the form builder.
SaveSearch::setQueryHelper public function Sets the query helper.
SaveSearch::setRequestStack public function Sets the request stack.
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