abstract class AbstractSearchApiSolrMultilingualBackend in Search API Solr 8.2
A abstract base class for all multilingual Solr Search API backends.
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
- class \Drupal\search_api\Plugin\HideablePluginBase implements HideablePluginInterface
- class \Drupal\search_api\Plugin\ConfigurablePluginBase implements ConfigurablePluginInterface uses PluginDependencyTrait
- class \Drupal\search_api\Backend\BackendPluginBase implements BackendInterface uses LoggerTrait
- class \Drupal\search_api_solr\Plugin\search_api\backend\SearchApiSolrBackend implements PluginFormInterface, SolrAutocompleteInterface, SolrBackendInterface uses PluginFormTrait, SolrCommitTrait
- class \Drupal\search_api_solr\Plugin\search_api\backend\AbstractSearchApiSolrMultilingualBackend implements SolrMultilingualBackendInterface
- class \Drupal\search_api_solr\Plugin\search_api\backend\SearchApiSolrBackend implements PluginFormInterface, SolrAutocompleteInterface, SolrBackendInterface uses PluginFormTrait, SolrCommitTrait
- class \Drupal\search_api\Backend\BackendPluginBase implements BackendInterface uses LoggerTrait
- class \Drupal\search_api\Plugin\ConfigurablePluginBase implements ConfigurablePluginInterface uses PluginDependencyTrait
- class \Drupal\search_api\Plugin\HideablePluginBase implements HideablePluginInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
Expanded class hierarchy of AbstractSearchApiSolrMultilingualBackend
File
- src/
Plugin/ search_api/ backend/ AbstractSearchApiSolrMultilingualBackend.php, line 31
Namespace
Drupal\search_api_solr\Plugin\search_api\backendView source
abstract class AbstractSearchApiSolrMultilingualBackend extends SearchApiSolrBackend implements SolrMultilingualBackendInterface {
/**
* The unprocessed search keys.
*
* @var mixed
*/
protected $origKeys = FALSE;
/**
* Creates and deploys a missing dynamic Solr field if the server supports it.
*
* @param string $solr_field_name
* The name of the new dynamic Solr field.
*
* @param string $solr_field_type_name
* The name of the Solr Field Type to be used for the new dynamic Solr
* field.
*/
protected abstract function createSolrDynamicField($solr_field_name, $solr_field_type_name);
/**
* Creates and deploys a missing Solr Field Type if the server supports it.
*
* @param string $solr_field_type_name
* The name of the Solr Field Type.
*/
protected abstract function createSolrMultilingualFieldType($solr_field_type_name);
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form = parent::buildConfigurationForm($form, $form_state);
$form['multilingual'] = [
'#type' => 'fieldset',
'#title' => $this
->t('Multilingual'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
];
$form['multilingual']['sasm_limit_search_page_to_content_language'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Limit to current content language.'),
'#description' => $this
->t('Limit all search results for custom queries or search pages not managed by Views to current content language if no language is specified in the query.'),
'#default_value' => isset($this->configuration['sasm_limit_search_page_to_content_language']) ? $this->configuration['sasm_limit_search_page_to_content_language'] : FALSE,
];
$form['multilingual']['sasm_search_page_include_language_independent'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Include language independent content in search results.'),
'#description' => $this
->t('This option will include content without a language assigned in the results of custom queries or search pages not managed by Views. For example, if you search for English content, but have an article with languague of "undefined", you will see those results as well. If you disable this option, you will only see content that matches the language.'),
'#default_value' => isset($this->configuration['sasm_search_page_include_language_independent']) ? $this->configuration['sasm_search_page_include_language_independent'] : FALSE,
];
$form['multilingual']['sasm_language_unspecific_fallback_on_schema_issues'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Use language fallbacks.'),
'#description' => $this
->t('This option is suitable for two use-cases. First, if you have languages like "de" and "de-at", both could be handled by a shared configuration for "de". Second, new languages will be handled by language-unspecific fallback configuration until the schema gets updated on your Solr server.'),
'#default_value' => isset($this->configuration['sasm_language_unspecific_fallback_on_schema_issues']) ? $this->configuration['sasm_language_unspecific_fallback_on_schema_issues'] : TRUE,
];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
parent::validateConfigurationForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
$values = $form_state
->getValues();
// Since the form is nested into another, we can't simply use #parents for
// doing this array restructuring magic. (At least not without creating an
// unnecessary dependency on internal implementation.)
foreach ($values['multilingual'] as $key => $value) {
$form_state
->setValue($key, $value);
}
// Clean-up the form to avoid redundant entries in the stored configuration.
$form_state
->unsetValue('multilingual');
parent::submitConfigurationForm($form, $form_state);
}
/**
* Adjusts the language filter before converting the query into a Solr query.
*
* @param \Drupal\search_api\Query\QueryInterface $query
* The \Drupal\search_api\Query\Query object.
*/
protected function alterSearchApiQuery(QueryInterface $query) {
// Do not modify 'Server index status' queries.
// @see https://www.drupal.org/node/2668852
if ($query
->hasTag('server_index_status') || $query
->hasTag('mlt')) {
return;
}
parent::alterSearchApiQuery($query);
$languages = $query
->getLanguages();
// If there are no languages set, we need to set them.
// As an example, a language might be set by a filter in a search view.
if (empty($languages)) {
if (!$query
->hasTag('views') && $this->configuration['sasm_limit_search_page_to_content_language']) {
// Limit the language to the current language being used.
$languages[] = \Drupal::languageManager()
->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)
->getId();
}
else {
// If the query is generated by views and/or the query isn't limited by
// any languages we have to search for all languages using their
// specific fields.
$languages = array_keys(\Drupal::languageManager()
->getLanguages());
}
}
if ($this->configuration['sasm_search_page_include_language_independent']) {
$languages[] = LanguageInterface::LANGCODE_NOT_SPECIFIED;
$languages[] = LanguageInterface::LANGCODE_NOT_APPLICABLE;
}
$query
->setLanguages($languages);
}
/**
* Modify the query before it is sent to solr.
*
* Replaces all language unspecific fulltext query fields by language specific
* ones.
*
* @param \Solarium\Core\Query\QueryInterface $solarium_query
* The Solarium select query object.
* @param \Drupal\search_api\Query\QueryInterface $query
* The \Drupal\search_api\Query\Query object representing the executed
* search query.
*/
protected function preQuery(SolariumQueryInterface $solarium_query, QueryInterface $query) {
// Do not modify 'Server index status' queries.
// @see https://www.drupal.org/node/2668852
if ($query
->hasTag('server_index_status')) {
return;
}
parent::preQuery($solarium_query, $query);
$language_ids = $query
->getLanguages();
if (!empty($language_ids)) {
$index = $query
->getIndex();
$fulltext_fields = $this
->getQueryFulltextFields($query);
$field_names = $this
->getSolrFieldNames($index);
$language_specific_fields = [];
foreach ($language_ids as $language_id) {
foreach ($fulltext_fields as $fulltext_field) {
$field_name = $field_names[$fulltext_field];
$language_specific_fields[$language_id][$field_name] = Utility::encodeSolrName(Utility::getLanguageSpecificSolrDynamicFieldNameForSolrDynamicFieldName($field_name, $language_id));
}
}
$components = $solarium_query
->getComponents();
if (isset($components[ComponentAwareQueryInterface::COMPONENT_HIGHLIGHTING])) {
$hl = $solarium_query
->getHighlighting();
$highlighted_fields = $hl
->getFields();
foreach ($field_names as $field_name) {
if (isset($highlighted_fields[$field_name])) {
$exchanged = FALSE;
foreach ($language_ids as $language_id) {
if (isset($language_specific_fields[$language_id][$field_name])) {
$language_specific_field = $language_specific_fields[$language_id][$field_name];
// Copy the already set highlighting options over to the language
// specific fields. getField() creates a new one first.
$highlighted_field = $hl
->getField($language_specific_field);
$highlighted_field
->setOptions($highlighted_fields[$field_name]
->getOptions());
$highlighted_field
->setName($language_specific_field);
$exchanged = TRUE;
}
}
if ($exchanged) {
$hl
->removeField($field_name);
}
}
}
}
if (!empty($this->configuration['retrieve_data'])) {
if ($fields_to_be_retrieved = $query
->getOption('search_api_retrieved_field_values', [])) {
$language_specific_fields_to_retrieve = [];
$fields_to_retrieve = $solarium_query
->getFields();
foreach ($fields_to_retrieve as $key => $field_name) {
$language_specific_name = FALSE;
foreach ($language_ids as $language_id) {
if (isset($language_specific_fields[$language_id][$field_name])) {
$language_specific_fields_to_retrieve[] = $language_specific_fields[$language_id][$field_name];
$language_specific_name = TRUE;
}
}
if ($language_specific_name) {
unset($fields_to_retrieve[$key]);
}
}
if ($language_specific_fields_to_retrieve) {
$solarium_query
->setFields(array_merge($language_specific_fields_to_retrieve, $fields_to_retrieve));
}
}
}
if ($query
->hasTag('mlt')) {
$mlt_fields = [];
foreach ($language_ids as $language_id) {
/** @var \Solarium\QueryType\MoreLikeThis\Query $solarium_query */
foreach ($solarium_query
->getMltFields() as $mlt_field) {
if (isset($language_specific_fields[$language_id][$mlt_field])) {
$mlt_fields[] = $language_specific_fields[$language_id][$mlt_field];
}
else {
// Make sure untranslated fields are still kept.
$mlt_fields[$mlt_field] = $mlt_field;
}
}
}
$solarium_query
->setMltFields($mlt_fields);
}
elseif ($keys = $query
->getKeys()) {
/** @var \Solarium\QueryType\Select\Query\Query $solarium_query */
$edismax = $solarium_query
->getEDisMax();
if ($solr_fields = $edismax
->getQueryFields()) {
$parse_mode_id = $query
->getParseMode()
->getPluginId();
if ('terms' == $parse_mode_id) {
// Using the 'phrase' parse mode, Search API provides one big phrase
// as keys. Using the 'terms' parse mode, Search API provides chunks
// of single terms as keys. But these chunks might contain not just
// real terms but again a phrase if you enter something like this in
// the search box: term1 "term2 as phrase" term3. This will be
// converted in this keys array: ['term1', 'term2 as phrase',
// 'term3']. To have Solr behave like the database backend, these
// three "terms" should be handled like three phrases.
$parse_mode_id = 'phrase';
}
$new_keys = [];
foreach ($language_ids as $language_id) {
$new_solr_fields = $solr_fields;
foreach ($fulltext_fields as $fulltext_field) {
$field_name = $field_names[$fulltext_field];
$new_solr_fields = str_replace($field_name, $language_specific_fields[$language_id][$field_name], $new_solr_fields);
}
if ($new_solr_fields == $solr_fields) {
// If there's no change for the first language, there won't be
// any change for the other languages, too.
return;
}
$flat_keys = $this
->flattenKeys($keys, explode(' ', $new_solr_fields), $parse_mode_id);
if (strpos($flat_keys, '(') !== 0 && strpos($flat_keys, '+(') !== 0 && strpos($flat_keys, '-(') !== 0) {
$flat_keys = '(' . $flat_keys . ')';
}
$new_keys[] = $flat_keys;
}
if (count($new_keys) > 1) {
$new_keys['#conjunction'] = 'OR';
}
$new_keys['#escaped'] = TRUE;
// Preserve the original keys to be set again in postQuery().
$this->origKeys = $query
->getOriginalKeys();
// The orginal keys array is now already flatten once per language.
// that means that we already build Solr query strings containing
// fields and keys. Now we set these query strings again as keys
// using an OR conjunction but remove all query fields. That will
// cause the parent class to just concatenate the language specific
// query strings using OR as they are.
$query
->keys($new_keys);
$edismax
->setQueryFields([]);
}
}
}
}
/**
* {@inheritdoc}
*/
protected function getFilterQueries(QueryInterface $query, array $solr_fields, array $index_fields, array &$options) {
$condition_group = $query
->getConditionGroup();
$conditions = $condition_group
->getConditions();
if (empty($conditions) || empty($query
->getLanguages())) {
return parent::getFilterQueries($query, $solr_fields, $index_fields, $options);
}
$fq = [];
foreach ($conditions as $condition) {
$language_fqs = [];
foreach ($query
->getLanguages() as $langcode) {
$language_specific_condition_group = $query
->createConditionGroup();
$language_specific_condition_group
->addCondition(SEARCH_API_LANGUAGE_FIELD_NAME, $langcode);
$language_specific_conditions =& $language_specific_condition_group
->getConditions();
$language_specific_conditions[] = $condition;
$language_fqs = array_merge($language_fqs, $this
->reduceFilterQueries($this
->createFilterQueries($language_specific_condition_group, $this
->getLanguageSpecificSolrFieldNames($langcode, $solr_fields, reset($index_fields)
->getIndex()), $index_fields, $options, $query), $condition_group));
}
$language_aware_condition_group = $query
->createConditionGroup('OR');
$fq = array_merge($fq, $this
->reduceFilterQueries($language_fqs, $language_aware_condition_group, TRUE));
}
return $fq;
}
/**
* Gets a language-specific mapping from Drupal to Solr field names.
*
* @param string $langcode
* The lanaguage to get the mapping for.
* @param array $solr_fields
* The mapping from Drupal to Solr field names.
* @param \Drupal\search_api\IndexInterface $index_fields
* The fields handled by the curent index.
*
* @return array
* The language-specific mapping from Drupal to Solr field names.
*/
protected function getLanguageSpecificSolrFieldNames($lancgcode, array $solr_fields, IndexInterface $index) {
// @todo Caching.
foreach ($index
->getFulltextFields() as $fulltext_field) {
$solr_fields[$fulltext_field] = Utility::encodeSolrName(Utility::getLanguageSpecificSolrDynamicFieldNameForSolrDynamicFieldName($solr_fields[$fulltext_field], $lancgcode));
}
return $solr_fields;
}
/**
* @inheritdoc
*/
protected function alterSolrResponseBody(&$body, QueryInterface $query) {
$data = json_decode($body);
$index = $query
->getIndex();
$field_names = $this
->getSolrFieldNames($index, TRUE);
$doc_languages = [];
if (isset($data->response)) {
foreach ($data->response->docs as $doc) {
$language_id = $doc_languages[$this
->createId($this
->getIndexId($index), $doc->{$field_names['search_api_id']})] = $doc->{$field_names[SEARCH_API_LANGUAGE_FIELD_NAME]};
foreach (array_keys(get_object_vars($doc)) as $language_specific_field_name) {
$field_name = Utility::getSolrDynamicFieldNameForLanguageSpecificSolrDynamicFieldName($language_specific_field_name);
if ($field_name != $language_specific_field_name) {
if (Utility::getLanguageIdFromLanguageSpecificSolrDynamicFieldName($language_specific_field_name) == $language_id) {
$doc->{$field_name} = $doc->{$language_specific_field_name};
unset($doc->{$language_specific_field_name});
}
}
}
}
}
if (isset($data->highlighting)) {
foreach ($data->highlighting as $solr_id => &$item) {
foreach (array_keys(get_object_vars($item)) as $language_specific_field_name) {
$field_name = Utility::getSolrDynamicFieldNameForLanguageSpecificSolrDynamicFieldName($language_specific_field_name);
if ($field_name != $language_specific_field_name) {
if (Utility::getLanguageIdFromLanguageSpecificSolrDynamicFieldName($language_specific_field_name) == $doc_languages[$solr_id]) {
$item->{$field_name} = $item->{$language_specific_field_name};
unset($item->{$language_specific_field_name});
}
}
}
}
}
if (isset($data->facet_counts)) {
$facet_set_helper = new FacetSet();
foreach (get_object_vars($data->facet_counts->facet_fields) as $language_specific_field_name => $facet_terms) {
$field_name = Utility::getSolrDynamicFieldNameForLanguageSpecificSolrDynamicFieldName($language_specific_field_name);
if ($field_name != $language_specific_field_name) {
if (isset($data->facet_counts->facet_fields->{$field_name})) {
// @todo this simple merge of all language specific fields to one
// language unspecific fields should be configurable.
$key_value = $facet_set_helper
->convertToKeyValueArray($data->facet_counts->facet_fields->{$field_name}) + $facet_set_helper
->convertToKeyValueArray($facet_terms);
$facet_terms = [];
foreach ($key_value as $key => $value) {
// @todo check for NULL key of "missing facets".
$facet_terms[] = $key;
$facet_terms[] = $value;
}
}
$data->facet_counts->facet_fields->{$field_name} = $facet_terms;
}
}
}
$body = json_encode($data);
}
/**
* {@inheritdoc}
*/
protected function postQuery(ResultSetInterface $results, QueryInterface $query, $response) {
if ($this->origKeys) {
$query
->keys($this->origKeys);
}
parent::postQuery($results, $query, $response);
}
/**
* Replaces language unspecific fulltext fields by language specific ones.
*
* @param \Solarium\QueryType\Update\Query\Document\Document[] $documents
* An array of \Solarium\QueryType\Update\Query\Document\Document objects
* ready to be indexed, generated from $items array.
* @param \Drupal\search_api\IndexInterface $index
* The search index for which items are being indexed.
* @param array $items
* An array of items being indexed.
*
* @see hook_search_api_solr_documents_alter()
*/
protected function alterSolrDocuments(array &$documents, IndexInterface $index, array $items) {
parent::alterSolrDocuments($documents, $index, $items);
$fulltext_fields = $index
->getFulltextFields();
$multiple_field_names = $this
->getSolrFieldNames($index);
$field_names = $this
->getSolrFieldNames($index, TRUE);
$fulltext_field_names = array_filter(array_flip($multiple_field_names) + array_flip($field_names), function ($value) use ($fulltext_fields) {
return in_array($value, $fulltext_fields);
});
$field_name_map_per_language = [];
foreach ($documents as $document) {
$fields = $document
->getFields();
$language_id = $fields[$field_names[SEARCH_API_LANGUAGE_FIELD_NAME]];
foreach ($fields as $monolingual_solr_field_name => $field_value) {
if (array_key_exists($monolingual_solr_field_name, $fulltext_field_names)) {
$multilingual_solr_field_name = Utility::getLanguageSpecificSolrDynamicFieldNameForSolrDynamicFieldName($monolingual_solr_field_name, $language_id);
$field_name_map_per_language[$language_id][$monolingual_solr_field_name] = Utility::encodeSolrName($multilingual_solr_field_name);
}
}
}
foreach ($field_name_map_per_language as $language_id => $map) {
$solr_field_type_name = Utility::encodeSolrName('text' . '_' . $language_id);
if (!$this
->isPartOfSchema('fieldTypes', $solr_field_type_name) && !$this
->createSolrMultilingualFieldType($solr_field_type_name) && !$this
->hasLanguageUndefinedFallback()) {
throw new SearchApiSolrException('Missing field type ' . $solr_field_type_name . ' in schema.');
}
// Handle dynamic fields for multilingual tm and ts.
foreach ([
'ts',
'tm',
] as $prefix) {
$multilingual_solr_field_name = Utility::encodeSolrName(Utility::getLanguageSpecificSolrDynamicFieldPrefix($prefix, $language_id)) . '*';
if (!$this
->isPartOfSchema('dynamicFields', $multilingual_solr_field_name) && !$this
->createSolrDynamicField($multilingual_solr_field_name, $solr_field_type_name) && !$this
->hasLanguageUndefinedFallback()) {
throw new SearchApiSolrException('Missing dynamic field ' . $multilingual_solr_field_name . ' in schema.');
}
}
}
foreach ($documents as $document) {
$fields = $document
->getFields();
foreach ($field_name_map_per_language as $language_id => $map) {
if ($fields[$field_names[SEARCH_API_LANGUAGE_FIELD_NAME]] == $language_id) {
foreach ($fields as $monolingual_solr_field_name => $value) {
if (isset($map[$monolingual_solr_field_name])) {
if ('twm_suggest' != $monolingual_solr_field_name) {
$document
->addField($map[$monolingual_solr_field_name], $value, $document
->getFieldBoost($monolingual_solr_field_name));
$document
->removeField($monolingual_solr_field_name);
}
}
}
}
}
}
}
/**
* Indicates if an 'element' is part of the Solr server's schema.
*
* @param string $kind
* The kind of the element, for example 'dynamicFields' or 'fieldTypes'.
*
* @param string $name
* The name of the element.
*
* @return bool
* True if an element of the given kind and name exists, false otherwise.
*
* @throws \Drupal\search_api_solr\SearchApiSolrException
*/
protected function isPartOfSchema($kind, $name) {
static $previous_calls;
$state_key = 'sasm.' . $this
->getServer()
->id() . '.schema_parts';
$state = \Drupal::state();
$schema_parts = $state
->get($state_key);
// @todo reset that drupal state from time to time
if (!is_array($schema_parts) || empty($schema_parts[$kind]) || !in_array($name, $schema_parts[$kind]) && !isset($previous_calls[$kind])) {
$response = $this
->getSolrConnector()
->coreRestGet('schema/' . strtolower($kind));
if (empty($response[$kind])) {
throw new SearchApiSolrException('Missing information about ' . $kind . ' in response to REST request.');
}
// Delete the old state.
$schema_parts[$kind] = [];
foreach ($response[$kind] as $row) {
$schema_parts[$kind][] = $row['name'];
}
$state
->set($state_key, $schema_parts);
$previous_calls[$kind] = TRUE;
}
return in_array($name, $schema_parts[$kind]);
}
/**
* {@inheritdoc}
*/
public function getSchemaLanguageStatistics() {
$available = $this
->getSolrConnector()
->pingCore();
$stats = [];
foreach (\Drupal::languageManager()
->getLanguages() as $language) {
$solr_field_type_name = Utility::encodeSolrName('text' . '_' . $language
->getId());
$stats[$language
->getId()] = $available ? $this
->isPartOfSchema('fieldTypes', $solr_field_type_name) : FALSE;
}
return $stats;
}
/**
* {@inheritdoc}
*/
public function hasLanguageUndefinedFallback() {
return isset($this->configuration['sasm_language_unspecific_fallback_on_schema_issues']) ? $this->configuration['sasm_language_unspecific_fallback_on_schema_issues'] : FALSE;
}
/**
* {@inheritdoc}
*/
protected function setFacets(QueryInterface $query, Query $solarium_query, array $field_names) {
parent::setFacets($query, $solarium_query, $field_names);
if ($languages = $query
->getLanguages()) {
foreach ($languages as $language) {
$language_specific_field_names = $this
->getLanguageSpecificSolrFieldNames($language, $field_names, $query
->getIndex());
parent::setFacets($query, $solarium_query, array_diff_assoc($language_specific_field_names, $field_names));
}
}
}
/**
* {@inheritdoc}
*/
protected function getAutocompleteFields(QueryInterface $query) {
$fl = [];
$solr_field_names = $this
->getSolrFieldNames($query
->getIndex());
foreach ($query
->getLanguages() as $langcode) {
// We explicit allow to get terms from twm_suggest. Therefore we call
// BackendPluginBase::getQueryFulltextFields() to not filter twm_suggest.
$fulltext_fields = BackendPluginBase::getQueryFulltextFields($query);
$language_specific_fulltext_fields = $this
->getLanguageSpecificSolrFieldNames($langcode, $solr_field_names, $query
->getIndex());
foreach ($fulltext_fields as $fulltext_field) {
$fl[] = $language_specific_fulltext_fields[$fulltext_field];
}
}
return array_unique($fl);
}
/**
* {@inheritdoc}
*/
protected function setAutocompleteSuggesterQuery(QueryInterface $query, AutocompleteQuery $solarium_query, $user_input, $options = []) {
if (isset($options['context_filter_tags']) && in_array('drupal/langcode:multilingual', $options['context_filter_tags'])) {
$langcodes = $query
->getLanguages();
if (count($langcodes) == 1) {
$langcode = reset($langcodes);
$options['context_filter_tags'] = str_replace('drupal/langcode:multilingual', 'drupal/langcode:' . $langcode, $options['context_filter_tags']);
$options['dictionary'] = $langcode;
}
else {
foreach ($options['context_filter_tags'] as $key => $tag) {
if ('drupal/langcode:multilingual' == $tag) {
unset($options['context_filter_tags'][$key]);
break;
}
}
}
}
parent::setAutocompleteSuggesterQuery($query, $solarium_query, $user_input, $options);
}
}
Members
Name![]() |
Modifiers | Type | Description | Overrides |
---|---|---|---|---|
AbstractSearchApiSolrMultilingualBackend:: |
protected | property | The unprocessed search keys. | |
AbstractSearchApiSolrMultilingualBackend:: |
protected | function |
Adjusts the language filter before converting the query into a Solr query. Overrides SearchApiSolrBackend:: |
|
AbstractSearchApiSolrMultilingualBackend:: |
protected | function |
Replaces language unspecific fulltext fields by language specific ones. Overrides SearchApiSolrBackend:: |
|
AbstractSearchApiSolrMultilingualBackend:: |
protected | function |
@inheritdoc Overrides SearchApiSolrBackend:: |
|
AbstractSearchApiSolrMultilingualBackend:: |
public | function |
Form constructor. Overrides SearchApiSolrBackend:: |
|
AbstractSearchApiSolrMultilingualBackend:: |
abstract protected | function | Creates and deploys a missing dynamic Solr field if the server supports it. | 2 |
AbstractSearchApiSolrMultilingualBackend:: |
abstract protected | function | Creates and deploys a missing Solr Field Type if the server supports it. | 2 |
AbstractSearchApiSolrMultilingualBackend:: |
protected | function |
Get the fields to search for autocomplete terms. Overrides SearchApiSolrBackend:: |
|
AbstractSearchApiSolrMultilingualBackend:: |
protected | function |
Serializes a query's conditions as Solr filter queries. Overrides SearchApiSolrBackend:: |
|
AbstractSearchApiSolrMultilingualBackend:: |
protected | function | Gets a language-specific mapping from Drupal to Solr field names. | |
AbstractSearchApiSolrMultilingualBackend:: |
public | function |
Gets schema language statistics for the multilingual Solr server. Overrides SolrMultilingualBackendInterface:: |
|
AbstractSearchApiSolrMultilingualBackend:: |
public | function |
Indicates if the fallback for not supported languages is active. Overrides SolrMultilingualBackendInterface:: |
|
AbstractSearchApiSolrMultilingualBackend:: |
protected | function | Indicates if an 'element' is part of the Solr server's schema. | |
AbstractSearchApiSolrMultilingualBackend:: |
protected | function |
Allow custom changes before search results are returned for subclasses. Overrides SearchApiSolrBackend:: |
|
AbstractSearchApiSolrMultilingualBackend:: |
protected | function |
Modify the query before it is sent to solr. Overrides SearchApiSolrBackend:: |
|
AbstractSearchApiSolrMultilingualBackend:: |
protected | function |
Set the suggester parameters for the solarium autocomplete query. Overrides SearchApiSolrBackend:: |
|
AbstractSearchApiSolrMultilingualBackend:: |
protected | function |
Helper method for creating the facet field parameters. Overrides SearchApiSolrBackend:: |
|
AbstractSearchApiSolrMultilingualBackend:: |
public | function |
Form submission handler. Overrides SearchApiSolrBackend:: |
|
AbstractSearchApiSolrMultilingualBackend:: |
public | function |
Form validation handler. Overrides SearchApiSolrBackend:: |
|
BackendPluginBase:: |
protected | property |
The messenger. Overrides MessengerTrait:: |
|
BackendPluginBase:: |
protected | property | The server this backend is configured for. | |
BackendPluginBase:: |
protected | property | The backend's server's ID. | |
BackendPluginBase:: |
public | function |
Adds a new index to this server. Overrides BackendSpecificInterface:: |
2 |
BackendPluginBase:: |
public | function | Retrieves the fields helper. | |
BackendPluginBase:: |
public | function | Retrieves the messenger. | |
BackendPluginBase:: |
public | function |
Retrieves the server entity for this backend. Overrides BackendInterface:: |
|
BackendPluginBase:: |
protected | function | Creates dummy field objects for the "magic" fields present for every index. | 1 |
BackendPluginBase:: |
public | function |
Reacts to the server's creation. Overrides BackendInterface:: |
1 |
BackendPluginBase:: |
public | function |
Notifies the backend that its configuration was updated. Overrides BackendInterface:: |
2 |
BackendPluginBase:: |
public | function |
Notifies the backend that the server is about to be deleted. Overrides BackendInterface:: |
1 |
BackendPluginBase:: |
public | function |
Notifies the backend that its configuration is about to be updated. Overrides BackendInterface:: |
1 |
BackendPluginBase:: |
public | function | Sets the fields helper. | |
BackendPluginBase:: |
public | function |
Sets the messenger. Overrides MessengerTrait:: |
|
BackendPluginBase:: |
public | function |
Sets the server entity for this backend. Overrides BackendInterface:: |
|
BackendPluginBase:: |
protected | function | Verifies that the given condition operator is valid for this backend. | |
BackendPluginBase:: |
public | function |
Implements the magic __sleep() method. Overrides DependencySerializationTrait:: |
1 |
BackendPluginBase:: |
public | function |
Implements the magic __wakeup() method. Overrides DependencySerializationTrait:: |
1 |
ConfigurablePluginBase:: |
protected | function | Calculates and adds dependencies of a specific plugin instance. | |
ConfigurablePluginBase:: |
public | function |
Gets this plugin's configuration. Overrides ConfigurableInterface:: |
|
ConfigurablePluginBase:: |
public | function |
Returns the plugin's description. Overrides ConfigurablePluginInterface:: |
|
ConfigurablePluginBase:: |
protected | function | Calculates and returns dependencies of a specific plugin instance. | |
ConfigurablePluginBase:: |
public | function |
Returns the label for use on the administration pages. Overrides ConfigurablePluginInterface:: |
|
ConfigurablePluginBase:: |
protected | function | Wraps the module handler. | |
ConfigurablePluginBase:: |
public | function |
Informs the plugin that some of its dependencies are being removed. Overrides ConfigurablePluginInterface:: |
5 |
ConfigurablePluginBase:: |
protected | function | Wraps the theme handler. | |
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencyTrait:: |
protected | property | The object's dependencies. | |
DependencyTrait:: |
protected | function | Adds multiple dependencies. | |
DependencyTrait:: |
protected | function | Adds a dependency. | |
HideablePluginBase:: |
public | function |
Determines whether this plugin should be hidden in the UI. Overrides HideablePluginInterface:: |
1 |
LoggerTrait:: |
protected | property | The logging channel to use. | |
LoggerTrait:: |
public | function | Retrieves the logger. | |
LoggerTrait:: |
protected | function | Logs an exception. | |
LoggerTrait:: |
public | function | Sets the logger. | |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
PluginBase:: |
protected | property | Configuration information passed into the plugin. | 1 |
PluginBase:: |
protected | property | The plugin implementation definition. | 1 |
PluginBase:: |
protected | property | The plugin_id. | |
PluginBase:: |
constant | A string which is used to separate base plugin IDs from the derivative ID. | ||
PluginBase:: |
public | function |
Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: |
3 |
PluginBase:: |
public | function |
Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface:: |
|
PluginBase:: |
public | function | Determines if the plugin is configurable. | |
PluginDependencyTrait:: |
protected | function | Calculates and adds dependencies of a specific plugin instance. Aliased as: traitCalculatePluginDependencies | 1 |
PluginDependencyTrait:: |
protected | function | Calculates and returns dependencies of a specific plugin instance. Aliased as: traitGetPluginDependencies | |
PluginDependencyTrait:: |
protected | function | Wraps the module handler. Aliased as: traitModuleHandler | 1 |
PluginDependencyTrait:: |
protected | function | Wraps the theme handler. Aliased as: traitThemeHandler | 1 |
PluginFormTrait:: |
public | function | Form submission handler. Aliased as: traitSubmitConfigurationForm | 7 |
SearchApiSolrBackend:: |
protected | property | The data type helper. | |
SearchApiSolrBackend:: |
protected | property | Metadata describing fields on the Solr/Lucene index. | |
SearchApiSolrBackend:: |
protected | property |
Overrides BackendPluginBase:: |
|
SearchApiSolrBackend:: |
protected | property | The language manager. | |
SearchApiSolrBackend:: |
protected | property | The module handler. | |
SearchApiSolrBackend:: |
protected | property | The Solarium query helper. | |
SearchApiSolrBackend:: |
protected | property | A config object for 'search_api_solr.settings'. | |
SearchApiSolrBackend:: |
protected | property | ||
SearchApiSolrBackend:: |
protected | property | The backend plugin manager. | |
SearchApiSolrBackend:: |
protected | function | Helper method for indexing. | |
SearchApiSolrBackend:: |
protected | function | Adds item language conditions to the condition group, if applicable. | |
SearchApiSolrBackend:: |
public | function |
Allow custom changes to the Solarium Spellcheck autocomplete query. Overrides SolrAutocompleteInterface:: |
|
SearchApiSolrBackend:: |
public | function |
Allow custom changes to the Solarium Suggester autocomplete query. Overrides SolrAutocompleteInterface:: |
|
SearchApiSolrBackend:: |
public | function |
Allow custom changes to the Solarium Terms autocomplete query. Overrides SolrAutocompleteInterface:: |
|
SearchApiSolrBackend:: |
protected | function | Apply workarounds for special Solr versions before searching. | 1 |
SearchApiSolrBackend:: |
public static | function | Handles switching the selected Solr connector plugin. | |
SearchApiSolrBackend:: |
public | function | Builds the backend-specific configuration form. | |
SearchApiSolrBackend:: |
public | function |
Calculates dependencies for the configured plugin. Overrides ConfigurablePluginBase:: |
|
SearchApiSolrBackend:: |
public static | function |
Creates an instance of the plugin. Overrides BackendPluginBase:: |
|
SearchApiSolrBackend:: |
protected | function | Recursively transforms conditions into a flat array of Solr filter queries. | |
SearchApiSolrBackend:: |
protected | function | Create a single search query string. | |
SearchApiSolrBackend:: |
protected | function | Creates an ID used as the unique identifier at the Solr server. | |
SearchApiSolrBackend:: |
protected | function | Create a single search query string. | |
SearchApiSolrBackend:: |
public | function |
Gets default configuration for this plugin. Overrides ConfigurablePluginBase:: |
1 |
SearchApiSolrBackend:: |
public | function |
Deletes all the items from the index. Overrides BackendSpecificInterface:: |
|
SearchApiSolrBackend:: |
public | function |
Deletes the specified items from the index. Overrides BackendSpecificInterface:: |
|
SearchApiSolrBackend:: |
public | function |
Executes a graph streaming expression. Overrides SolrBackendInterface:: |
|
SearchApiSolrBackend:: |
public | function |
Executes a streaming expression. Overrides SolrBackendInterface:: |
|
SearchApiSolrBackend:: |
public | function |
Extract a file's content using tika within a solr server. Overrides SolrBackendInterface:: |
|
SearchApiSolrBackend:: |
protected | function | Extracts facets from a Solarium result set. | |
SearchApiSolrBackend:: |
protected | function | Extract results from a Solr response. | |
SearchApiSolrBackend:: |
protected | function | ||
SearchApiSolrBackend:: |
public | function |
Overrides SolrBackendInterface:: |
|
SearchApiSolrBackend:: |
protected | function | Flattens keys and fields into a single search string. | |
SearchApiSolrBackend:: |
public | function | Tries to format given date with solarium query helper. | |
SearchApiSolrBackend:: |
protected | function | Format a value for filtering on a field of a specific type. | |
SearchApiSolrBackend:: |
protected | function | ||
SearchApiSolrBackend:: |
protected | function | Get the spellcheck suggestions from the autocomplete query result. | |
SearchApiSolrBackend:: |
protected | function | Get the term suggestions from the autocomplete query result. | |
SearchApiSolrBackend:: |
public | function | Implements autocomplete compatible to AutocompleteBackendInterface. | |
SearchApiSolrBackend:: |
protected | function | Get the term suggestions from the autocomplete query result. | |
SearchApiSolrBackend:: |
public | function |
Provides information on additional fields made available by the backend. Overrides BackendPluginBase:: |
|
SearchApiSolrBackend:: |
public | function |
Limits the processors displayed in the UI for indexes on this server. Overrides BackendPluginBase:: |
|
SearchApiSolrBackend:: |
public | function |
Retrieves a Solr document from an search api index item. Overrides SolrBackendInterface:: |
|
SearchApiSolrBackend:: |
public | function |
Retrieves Solr documents from search api index items. Overrides SolrBackendInterface:: |
|
SearchApiSolrBackend:: |
public | function |
Returns the targeted content domain of the server. Overrides SolrBackendInterface:: |
|
SearchApiSolrBackend:: |
protected | function | Extract and format highlighting information for a specific item. | |
SearchApiSolrBackend:: |
public | function |
Returns a ready to use query string to filter results by index and site. Overrides SolrBackendInterface:: |
|
SearchApiSolrBackend:: |
protected | function | Prefixes an index ID as configured. | |
SearchApiSolrBackend:: |
protected | function | Changes the query to a "More Like This" query. | |
SearchApiSolrBackend:: |
protected | function | Computes the cardinality of a complete property path. | |
SearchApiSolrBackend:: |
protected | function |
Don't return the big twm_suggest field. Overrides BackendPluginBase:: |
|
SearchApiSolrBackend:: |
public | function |
Overrides SolrBackendInterface:: |
|
SearchApiSolrBackend:: |
protected | function | Returns all available backend plugins, as an options list. | |
SearchApiSolrBackend:: |
public | function |
Creates a list of all indexed field names mapped to their Solr field names. Overrides SolrBackendInterface:: |
1 |
SearchApiSolrBackend:: |
public | function |
Autocompletion suggestions for some user input using Spellcheck component. Overrides SolrAutocompleteInterface:: |
|
SearchApiSolrBackend:: |
public | function |
Autocompletion suggestions for some user input using Suggester component. Overrides SolrAutocompleteInterface:: |
|
SearchApiSolrBackend:: |
public | function |
Returns all features that this backend supports. Overrides BackendPluginBase:: |
|
SearchApiSolrBackend:: |
public | function |
Autocompletion suggestions for some user input using Terms component. Overrides SolrAutocompleteInterface:: |
|
SearchApiSolrBackend:: |
protected | function | Checks if hierarchical properties are nested on an entity-typed property. | |
SearchApiSolrBackend:: |
protected | function | Checks if the recently updated index had any fields changed. | |
SearchApiSolrBackend:: |
public | function |
Indexes the specified items. Overrides BackendSpecificInterface:: |
|
SearchApiSolrBackend:: |
public | function |
Overrides BackendPluginBase:: |
|
SearchApiSolrBackend:: |
protected | function | Checks if a field is (potentially) hierarchical. | |
SearchApiSolrBackend:: |
public | function |
Indicates if the Solr server uses a managed schema. Overrides SolrBackendInterface:: |
1 |
SearchApiSolrBackend:: |
protected | function | Reduces an array of filter queries to an array containing one filter query. | |
SearchApiSolrBackend:: |
public | function |
Removes an index from this server. Overrides BackendPluginBase:: |
|
SearchApiSolrBackend:: |
public | function |
Options on $query prefixed by 'solr_param_' will be passed natively to Solr
as query parameter without the prefix. For example you can set the "Minimum
Should Match" parameter 'mm' to '75%' like this: Overrides BackendSpecificInterface:: |
|
SearchApiSolrBackend:: |
protected | function | Set the spellcheck parameters for the solarium autocomplete query. | |
SearchApiSolrBackend:: |
protected | function | Set the term parameters for the solarium autocomplete query. | |
SearchApiSolrBackend:: |
public | function |
Sets the configuration for this plugin instance. Overrides BackendPluginBase:: |
|
SearchApiSolrBackend:: |
protected | function | Set the list of fields Solr should return as result. | |
SearchApiSolrBackend:: |
protected | function | Sets grouping for the query. | |
SearchApiSolrBackend:: |
protected | function | Sets the highlighting parameters. | |
SearchApiSolrBackend:: |
protected | function | Adds rpt spatial features to the search query. | |
SearchApiSolrBackend:: |
protected | function | Sets sorting for the query. | |
SearchApiSolrBackend:: |
protected | function | Adds spatial features to the search query. | |
SearchApiSolrBackend:: |
public | function |
Determines whether the backend supports a given add-on data type. Overrides BackendPluginBase:: |
|
SearchApiSolrBackend:: |
public | function |
Notifies the server that an index attached to it has been changed. Overrides BackendPluginBase:: |
|
SearchApiSolrBackend:: |
public | function |
Overrides BackendPluginBase:: |
|
SearchApiSolrBackend:: |
public | function |
Constructs a \Drupal\Component\Plugin\PluginBase object. Overrides BackendPluginBase:: |
|
SolrCommitTrait:: |
protected | function | Explicitly sent a commit command to a Solr server. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. |