You are here

abstract class BackendPluginBase in Search API 8

Defines a base class for backend plugins.

Plugins extending this class need to define a plugin definition array through annotation. These definition arrays may be altered through hook_search_api_backend_info_alter(). The definition includes the following keys:

  • id: The unique, system-wide identifier of the backend class.
  • label: The human-readable name of the backend class, translated.
  • description: A human-readable description for the backend class, translated.

A complete plugin definition should be written as in this example:


@SearchApiBackend(
  id = "my_backend",
  label = @Translation("My backend"),
  description = @Translation("Searches with SuperSearch™.")
)

Hierarchy

Expanded class hierarchy of BackendPluginBase

See also

\Drupal\search_api\Annotation\SearchApiBackend

\Drupal\search_api\Backend\BackendPluginManager

\Drupal\search_api\Backend\BackendInterface

Plugin API

3 files declare their use of BackendPluginBase
Database.php in modules/search_api_db/src/Plugin/search_api/backend/Database.php
NoUi.php in tests/search_api_test_no_ui/src/Plugin/search_api/backend/NoUi.php
TestBackend.php in tests/search_api_test/src/Plugin/search_api/backend/TestBackend.php

File

src/Backend/BackendPluginBase.php, line 44

Namespace

Drupal\search_api\Backend
View source
abstract class BackendPluginBase extends ConfigurablePluginBase implements BackendInterface {
  use LoggerTrait;

  /**
   * The server this backend is configured for.
   *
   * @var \Drupal\search_api\ServerInterface
   */
  protected $server;

  /**
   * The backend's server's ID.
   *
   * Used for serialization.
   *
   * @var string
   */
  protected $serverId;

  /**
   * The fields helper.
   *
   * @var \Drupal\search_api\Utility\FieldsHelper|null
   */
  protected $fieldsHelper;

  /**
   * The messenger.
   *
   * @var \Drupal\Core\Messenger\MessengerInterface|null
   */
  protected $messenger;

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, array $plugin_definition) {
    if (($configuration['#server'] ?? NULL) instanceof ServerInterface) {
      $this
        ->setServer($configuration['#server']);
      unset($configuration['#server']);
    }
    parent::__construct($configuration, $plugin_id, $plugin_definition);
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {

    /** @var static $plugin */
    $plugin = parent::create($container, $configuration, $plugin_id, $plugin_definition);
    $plugin
      ->setFieldsHelper($container
      ->get('search_api.fields_helper'));
    $plugin
      ->setMessenger($container
      ->get('messenger'));
    return $plugin;
  }

  /**
   * Retrieves the fields helper.
   *
   * @return \Drupal\search_api\Utility\FieldsHelper
   *   The fields helper.
   */
  public function getFieldsHelper() {
    return $this->fieldsHelper ?: \Drupal::service('search_api.fields_helper');
  }

  /**
   * Sets the fields helper.
   *
   * @param \Drupal\search_api\Utility\FieldsHelper $fields_helper
   *   The new fields helper.
   *
   * @return $this
   */
  public function setFieldsHelper(FieldsHelper $fields_helper) {
    $this->fieldsHelper = $fields_helper;
    return $this;
  }

  /**
   * Retrieves the messenger.
   *
   * @return \Drupal\Core\Messenger\MessengerInterface
   *   The messenger.
   */
  public function getMessenger() {
    return $this->messenger ?: \Drupal::service('messenger');
  }

  /**
   * Sets the messenger.
   *
   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
   *   The new messenger.
   *
   * @return $this
   */
  public function setMessenger(MessengerInterface $messenger) {
    $this->messenger = $messenger;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function setConfiguration(array $configuration) {
    parent::setConfiguration($configuration);
    if ($this->server && $this->server
      ->getBackendConfig() !== $configuration) {
      $this->server
        ->setBackendConfig($configuration);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getServer() {
    return $this->server;
  }

  /**
   * {@inheritdoc}
   */
  public function setServer(ServerInterface $server) {
    $this->server = $server;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function viewSettings() {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function isAvailable() {
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function getSupportedFeatures() {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function supportsDataType($type) {
    return FALSE;
  }

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

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

  /**
   * {@inheritdoc}
   */
  public function postUpdate() {
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function preDelete() {
    try {
      $this
        ->getServer()
        ->deleteAllItems();
    } catch (SearchApiException $e) {
      $vars = [
        '%server' => $this
          ->getServer()
          ->label(),
      ];
      $this
        ->logException($e, '%type while deleting items from server %server: @message in %function (line %line of %file).', $vars);
      $this
        ->getMessenger()
        ->addError($this
        ->t('Deleting some of the items on the server failed. Check the logs for details. The server was still removed.'));
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getBackendDefinedFields(IndexInterface $index) {
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function addIndex(IndexInterface $index) {
  }

  /**
   * {@inheritdoc}
   */
  public function updateIndex(IndexInterface $index) {
  }

  /**
   * {@inheritdoc}
   */
  public function removeIndex($index) {

    // Only delete the index's data if the index isn't read-only. (If only the
    // ID is given, we assume the index was read-only, to be on the safe side.)
    if ($index instanceof IndexInterface && !$index
      ->isReadOnly()) {
      $this
        ->deleteAllIndexItems($index);
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getDiscouragedProcessors() {
    return [];
  }

  /**
   * Creates dummy field objects for the "magic" fields present for every index.
   *
   * @param \Drupal\search_api\IndexInterface $index
   *   The index for which to create the fields. (Needed since field objects
   *   always need an index set.)
   * @param \Drupal\search_api\Item\ItemInterface|null $item
   *   (optional) If given, an item whose data should be used for the fields'
   *   values.
   *
   * @return \Drupal\search_api\Item\FieldInterface[]
   *   An array of field objects for all "magic" fields, keyed by field IDs.
   */
  protected function getSpecialFields(IndexInterface $index, ItemInterface $item = NULL) {
    $field_info = [
      'type' => 'string',
      'original type' => 'string',
    ];
    $fields['search_api_id'] = $this
      ->getFieldsHelper()
      ->createField($index, 'search_api_id', $field_info);
    $fields['search_api_datasource'] = $this
      ->getFieldsHelper()
      ->createField($index, 'search_api_datasource', $field_info);
    $fields['search_api_language'] = $this
      ->getFieldsHelper()
      ->createField($index, 'search_api_language', $field_info);
    if ($item) {
      $fields['search_api_id']
        ->setValues([
        $item
          ->getId(),
      ]);
      $fields['search_api_datasource']
        ->setValues([
        $item
          ->getDatasourceId(),
      ]);
      $fields['search_api_language']
        ->setValues([
        $item
          ->getLanguage(),
      ]);
    }
    return $fields;
  }

  /**
   * Verifies that the given condition operator is valid for this backend.
   *
   * @param string $operator
   *   The operator in question.
   *
   * @throws \Drupal\search_api\SearchApiException
   *   Thrown if the operator is not known.
   *
   * @see \Drupal\search_api\Query\ConditionSetInterface::addCondition()
   */
  protected function validateOperator($operator) {
    switch ($operator) {
      case '=':
      case '<>':
      case '<':
      case '<=':
      case '>=':
      case '>':
      case 'IN':
      case 'NOT IN':
      case 'BETWEEN':
      case 'NOT BETWEEN':
        return;
    }
    throw new SearchApiException("Unknown operator '{$operator}' used in search query condition");
  }

  /**
   * Implements the magic __sleep() method.
   *
   * Prevents the server entity from being serialized.
   */
  public function __sleep() {
    if ($this->server) {
      $this->serverId = $this->server
        ->id();
    }
    $properties = array_flip(parent::__sleep());
    unset($properties['server']);
    unset($properties['logger']);
    return array_keys($properties);
  }

  /**
   * Implements the magic __wakeup() method.
   *
   * Reloads the server entity.
   */
  public function __wakeup() {
    parent::__wakeup();
    if ($this->serverId) {
      $this->server = Server::load($this->serverId);
      $this->serverId = NULL;
    }
  }

  /**
   * Retrieves the effective fulltext fields from the query.
   *
   * Automatically translates a NULL value in the query object to all fulltext
   * fields in the search index.
   *
   * If a specific backend supports any "virtual" fulltext fields not listed in
   * the index, it should override this method to add them, if appropriate.
   *
   * @param \Drupal\search_api\Query\QueryInterface $query
   *   The search query.
   *
   * @return string[]
   *   The fulltext fields in which to search for the search keys.
   *
   * @see \Drupal\search_api\Query\QueryInterface::getFulltextFields()
   */
  protected function getQueryFulltextFields(QueryInterface $query) {
    $fulltext_fields = $query
      ->getFulltextFields();
    $index_fields = $query
      ->getIndex()
      ->getFulltextFields();
    return $fulltext_fields === NULL ? $index_fields : array_intersect($fulltext_fields, $index_fields);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
BackendPluginBase::$fieldsHelper protected property The fields helper.
BackendPluginBase::$messenger protected property The messenger. Overrides MessengerTrait::$messenger
BackendPluginBase::$server protected property The server this backend is configured for.
BackendPluginBase::$serverId protected property The backend's server's ID.
BackendPluginBase::addIndex public function Adds a new index to this server. Overrides BackendSpecificInterface::addIndex 2
BackendPluginBase::create public static function Creates an instance of the plugin. Overrides ConfigurablePluginBase::create 1
BackendPluginBase::getBackendDefinedFields public function Provides information on additional fields made available by the backend. Overrides BackendSpecificInterface::getBackendDefinedFields
BackendPluginBase::getDiscouragedProcessors public function Limits the processors displayed in the UI for indexes on this server. Overrides BackendSpecificInterface::getDiscouragedProcessors 1
BackendPluginBase::getFieldsHelper public function Retrieves the fields helper.
BackendPluginBase::getMessenger public function Retrieves the messenger.
BackendPluginBase::getQueryFulltextFields protected function Retrieves the effective fulltext fields from the query.
BackendPluginBase::getServer public function Retrieves the server entity for this backend. Overrides BackendInterface::getServer
BackendPluginBase::getSpecialFields protected function Creates dummy field objects for the "magic" fields present for every index. 1
BackendPluginBase::getSupportedFeatures public function Returns all features that this backend supports. Overrides BackendSpecificInterface::getSupportedFeatures 2
BackendPluginBase::isAvailable public function Returns a boolean with the availability of the backend. Overrides BackendSpecificInterface::isAvailable 1
BackendPluginBase::postInsert public function Reacts to the server's creation. Overrides BackendInterface::postInsert 1
BackendPluginBase::postUpdate public function Notifies the backend that its configuration was updated. Overrides BackendInterface::postUpdate 2
BackendPluginBase::preDelete public function Notifies the backend that the server is about to be deleted. Overrides BackendInterface::preDelete 1
BackendPluginBase::preUpdate public function Notifies the backend that its configuration is about to be updated. Overrides BackendInterface::preUpdate 1
BackendPluginBase::removeIndex public function Removes an index from this server. Overrides BackendSpecificInterface::removeIndex 2
BackendPluginBase::setConfiguration public function Sets the configuration for this plugin instance. Overrides ConfigurablePluginBase::setConfiguration
BackendPluginBase::setFieldsHelper public function Sets the fields helper.
BackendPluginBase::setMessenger public function Sets the messenger. Overrides MessengerTrait::setMessenger
BackendPluginBase::setServer public function Sets the server entity for this backend. Overrides BackendInterface::setServer
BackendPluginBase::supportsDataType public function Determines whether the backend supports a given add-on data type. Overrides BackendSpecificInterface::supportsDataType 1
BackendPluginBase::updateIndex public function Notifies the server that an index attached to it has been changed. Overrides BackendSpecificInterface::updateIndex 2
BackendPluginBase::validateOperator protected function Verifies that the given condition operator is valid for this backend.
BackendPluginBase::viewSettings public function Returns additional, backend-specific information about this server. Overrides BackendSpecificInterface::viewSettings 2
BackendPluginBase::__construct public function Constructs a \Drupal\Component\Plugin\PluginBase object. Overrides ConfigurablePluginBase::__construct 1
BackendPluginBase::__sleep public function Implements the magic __sleep() method. Overrides DependencySerializationTrait::__sleep 1
BackendPluginBase::__wakeup public function Implements the magic __wakeup() method. Overrides DependencySerializationTrait::__wakeup 1
BackendSpecificInterface::deleteAllIndexItems public function Deletes all the items from the index. 4
BackendSpecificInterface::deleteItems public function Deletes the specified items from the index. 4
BackendSpecificInterface::indexItems public function Indexes the specified items. 4
BackendSpecificInterface::search public function Executes a search on this server. 4
ConfigurablePluginBase::calculateDependencies public function Calculates dependencies for the configured plugin. Overrides DependentPluginInterface::calculateDependencies 6
ConfigurablePluginBase::calculatePluginDependencies Deprecated protected function Calculates and adds dependencies of a specific plugin instance.
ConfigurablePluginBase::defaultConfiguration public function Gets default configuration for this plugin. Overrides ConfigurableInterface::defaultConfiguration 11
ConfigurablePluginBase::getConfiguration public function Gets this plugin's configuration. Overrides ConfigurableInterface::getConfiguration
ConfigurablePluginBase::getDescription public function Returns the plugin's description. Overrides ConfigurablePluginInterface::getDescription
ConfigurablePluginBase::getPluginDependencies Deprecated protected function Calculates and returns dependencies of a specific plugin instance.
ConfigurablePluginBase::label public function Returns the label for use on the administration pages. Overrides ConfigurablePluginInterface::label
ConfigurablePluginBase::moduleHandler Deprecated protected function Wraps the module handler.
ConfigurablePluginBase::onDependencyRemoval public function Informs the plugin that some of its dependencies are being removed. Overrides ConfigurablePluginInterface::onDependencyRemoval 5
ConfigurablePluginBase::themeHandler Deprecated protected function Wraps the theme handler.
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.
DependencyTrait::$dependencies protected property The object's dependencies.
DependencyTrait::addDependencies protected function Adds multiple dependencies.
DependencyTrait::addDependency protected function Adds a dependency.
HideablePluginBase::isHidden public function Determines whether this plugin should be hidden in the UI. Overrides HideablePluginInterface::isHidden 1
LoggerTrait::$logger protected property The logging channel to use.
LoggerTrait::getLogger public function Retrieves the logger.
LoggerTrait::logException protected function Logs an exception.
LoggerTrait::setLogger public function Sets the logger.
MessengerTrait::messenger public function Gets the messenger. 29
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.
PluginDependencyTrait::calculatePluginDependencies protected function Calculates and adds dependencies of a specific plugin instance. Aliased as: traitCalculatePluginDependencies 1
PluginDependencyTrait::getPluginDependencies protected function Calculates and returns dependencies of a specific plugin instance. Aliased as: traitGetPluginDependencies
PluginDependencyTrait::moduleHandler protected function Wraps the module handler. Aliased as: traitModuleHandler 1
PluginDependencyTrait::themeHandler protected function Wraps the theme handler. Aliased as: traitThemeHandler 1
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.