updated contrib modules : pathauto, token, entity_api, search_api, redirect, features
This commit is contained in:
@@ -1,3 +1,62 @@
|
||||
Search API 1.9 (2018-07-19):
|
||||
----------------------------
|
||||
- #2956012 by drunken monkey, DuaelFr: Added uncustomized view modes as options
|
||||
when rendering items.
|
||||
- #2980903 by drunken monkey, kristofferwiklund, borisson_: Fixed undefined
|
||||
index notice in Views date filter.
|
||||
- #2982693 by jhedstrom, borisson_, drunken monkey: Adapted tests to latest
|
||||
Core changes.
|
||||
- #2971033 by mErilainen, drunken monkey, borisson_: Added an option for prefix
|
||||
matching to the database backend.
|
||||
- #2973034 by idebr, drunken monkey: Removed outdated @todo comment.
|
||||
- #2972510 by msankhala, drunken monkey: Replaced Unicode::* methods with mb_*
|
||||
functions.
|
||||
- #2973047 by idebr, drunken monkey: Fixed misnamed test config files.
|
||||
- #2860167 by drunken monkey, borisson_, fenstrat: Added "orderby" to our
|
||||
config schema definitions.
|
||||
- #2948820 by capysara, drunken monkey, borisson_: Added a link to the "need to
|
||||
reindex" message on the Filters tab.
|
||||
- #2965803 by capysara, drunken monkey: Fixed left-over use of @url placeholder.
|
||||
- #2957650 by drunken monkey, borisson_: Fixed two minor problems.
|
||||
- #2939010 by nedjo, drunken monkey: Fixed deleted fields when index is created
|
||||
during module install.
|
||||
- #2931730 by drunken monkey, borisson_, chanderbhushan: Adapted to changes in
|
||||
drupal_set_message().
|
||||
- #2955607 by drunken monkey, borisson_: Removed our custom Query::__wakeup()
|
||||
work-around.
|
||||
- #2940138 by drunken monkey, borisson_: Switched to new Core tempstore service.
|
||||
- #2936630 by drunken monkey, borisson_: Adapted override detection code to use
|
||||
Config::hasOverrides().
|
||||
- #2961537 by drunken monkey: Increased Core dependency to Drupal 8.5.
|
||||
- #2959809 by drunken monkey, Rob230, mkalkbrenner, borisson_: Fixed small
|
||||
coding mistake in the "URL field" processor.
|
||||
- #2960931 by drunken monkey, borisson_: Fixed viewing of multiple content
|
||||
entity items.
|
||||
|
||||
Search API 1.8 (2018-04-16):
|
||||
----------------------------
|
||||
- #2960854 by nedjo, drunken monkey: Fixed "Database search defaults" index.
|
||||
- #2930839 by drunken monkey: Update tests according to latest PHPUnit
|
||||
compatibility changes
|
||||
- #2921022 by drunken monkey, marcvangend: Fixed automatic task execution with
|
||||
Drush.
|
||||
- #2955887 by drunken monkey, borisson_: Added a way to re-execute a query.
|
||||
- #2925464 by drunken monkey, borisson_, .jch: Fixed problem with missing "NOT
|
||||
NULL" attribute in database backend.
|
||||
- #2953266 by drunken monkey, borisson_: Added a helper method for
|
||||
"selected"/"default" checks.
|
||||
- #2953267 by drunken monkey, borisson_: Fixed REST dependency of Views test
|
||||
module.
|
||||
- #2945870 by Dropa, drunken monkey: Fixed timezone of indexed date strings.
|
||||
- #2948659 by drunken monkey, borisson_, bskibinski: Added support for HTML5
|
||||
placeholder in Views exposed filters.
|
||||
- #2951055 by bradjones1, borisson_, drunken monkey: Fixed documentation for
|
||||
IndexInterface::addField().
|
||||
- #2945560 by mkalkbrenner, drunken monkey, borisson_: Fixed handling of
|
||||
existing highlighting data in Highlight processor.
|
||||
- #2946386 by drunken monkey, borisson_: Fixed typo in Query::getAbortMessage().
|
||||
- #2945675 by drunken monkey, borisson_: Unified use of self and static.
|
||||
|
||||
Search API 1.7 (2018-02-23):
|
||||
----------------------------
|
||||
- #2922525 by drunken monkey, borisson_: Changed "Index items immediately" to
|
||||
|
||||
+2
@@ -12,6 +12,7 @@
|
||||
selected:
|
||||
type: sequence
|
||||
label: 'The selected bundles'
|
||||
orderby: value
|
||||
sequence:
|
||||
type: string
|
||||
label: 'A bundle machine name'
|
||||
@@ -25,6 +26,7 @@
|
||||
selected:
|
||||
type: sequence
|
||||
label: 'The selected languages'
|
||||
orderby: value
|
||||
sequence:
|
||||
type: string
|
||||
label: 'A language code'
|
||||
|
||||
@@ -20,6 +20,7 @@ search_api.index.*:
|
||||
field_settings:
|
||||
type: sequence
|
||||
label: 'Indexed fields'
|
||||
orderby: key
|
||||
sequence:
|
||||
type: mapping
|
||||
label: field
|
||||
@@ -56,18 +57,21 @@ search_api.index.*:
|
||||
datasource_settings:
|
||||
type: sequence
|
||||
label: 'Datasource settings'
|
||||
orderby: key
|
||||
sequence:
|
||||
type: plugin.plugin_configuration.search_api_datasource.[%key]
|
||||
label: 'The configuration for a single datasource'
|
||||
processor_settings:
|
||||
type: sequence
|
||||
label: 'Processor settings'
|
||||
orderby: key
|
||||
sequence:
|
||||
type: plugin.plugin_configuration.search_api_processor.[%key]
|
||||
label: 'The configuration for a single processor'
|
||||
tracker_settings:
|
||||
type: sequence
|
||||
label: 'Tracker settings'
|
||||
orderby: key
|
||||
sequence:
|
||||
type: plugin.plugin_configuration.search_api_tracker.[%key]
|
||||
label: 'The configuration for the tracker'
|
||||
|
||||
+17
-2
@@ -7,6 +7,7 @@ search_api.default_processor_configuration:
|
||||
weights:
|
||||
type: sequence
|
||||
label: 'The processor''s weights for the different processing stages'
|
||||
orderby: key
|
||||
sequence:
|
||||
type: integer
|
||||
label: 'The processor''s weight for this stage'
|
||||
@@ -21,6 +22,7 @@ search_api.fields_processor_configuration:
|
||||
fields:
|
||||
type: sequence
|
||||
label: 'The selected fields'
|
||||
orderby: value
|
||||
sequence:
|
||||
type: string
|
||||
label: 'Selected field'
|
||||
@@ -37,7 +39,8 @@ plugin.plugin_configuration.search_api_processor.hierarchy:
|
||||
mapping:
|
||||
fields:
|
||||
type: sequence
|
||||
label: 'Fields for which to add the hierarchy'
|
||||
label: 'Fields for which to add the hierarchy, mapped to their hierarchical nested property'
|
||||
orderby: key
|
||||
sequence:
|
||||
type: string
|
||||
label: 'Field ID'
|
||||
@@ -61,6 +64,7 @@ plugin.plugin_configuration.search_api_processor.highlight:
|
||||
exclude_fields:
|
||||
type: sequence
|
||||
label: 'Fields excluded from excerpt'
|
||||
orderby: value
|
||||
sequence:
|
||||
type: string
|
||||
label: 'An excluded field''s ID'
|
||||
@@ -84,6 +88,7 @@ plugin.plugin_configuration.search_api_processor.html_filter:
|
||||
tags:
|
||||
type: sequence
|
||||
label: 'Tag boosts'
|
||||
orderby: key
|
||||
sequence:
|
||||
type: integer
|
||||
label: Boost
|
||||
@@ -106,6 +111,7 @@ plugin.plugin_configuration.search_api_processor.ignore_character:
|
||||
character_sets:
|
||||
type: sequence
|
||||
label: 'Configuration of the character sets'
|
||||
orderby: key
|
||||
sequence:
|
||||
type: ignore
|
||||
label: 'Character set'
|
||||
@@ -117,6 +123,7 @@ plugin.plugin_configuration.search_api_processor.stemmer:
|
||||
exceptions:
|
||||
type: sequence
|
||||
label: 'Stemming exceptions'
|
||||
orderby: key
|
||||
sequence:
|
||||
type: string
|
||||
label: Exception
|
||||
@@ -131,6 +138,7 @@ plugin.plugin_configuration.search_api_processor.role_filter:
|
||||
roles:
|
||||
type: sequence
|
||||
label: 'The selected roles'
|
||||
orderby: value
|
||||
sequence:
|
||||
type: string
|
||||
label: 'The role name'
|
||||
@@ -141,7 +149,8 @@ plugin.plugin_configuration.search_api_processor.stopwords:
|
||||
mapping:
|
||||
stopwords:
|
||||
type: sequence
|
||||
label: 'entered stopwords'
|
||||
label: 'Entered stopwords'
|
||||
orderby: value
|
||||
sequence:
|
||||
type: string
|
||||
label: Stopword
|
||||
@@ -174,6 +183,7 @@ plugin.plugin_configuration.search_api_processor.type_boost:
|
||||
boosts:
|
||||
type: sequence
|
||||
label: 'Boost settings'
|
||||
orderby: key
|
||||
sequence:
|
||||
type: mapping
|
||||
label: 'Datasource boost settings'
|
||||
@@ -184,6 +194,7 @@ plugin.plugin_configuration.search_api_processor.type_boost:
|
||||
bundle_boosts:
|
||||
type: sequence
|
||||
label: 'Bundle-specific boosts'
|
||||
orderby: key
|
||||
sequence:
|
||||
type: float
|
||||
label: 'The boost value for this bundle'
|
||||
@@ -205,6 +216,7 @@ search_api.property_configuration.aggregated_field:
|
||||
fields:
|
||||
type: sequence
|
||||
label: 'The properties to be aggregated'
|
||||
orderby: value
|
||||
sequence:
|
||||
type: string
|
||||
label: 'A property that should be part of the aggregation'
|
||||
@@ -216,15 +228,18 @@ search_api.property_configuration.rendered_item:
|
||||
roles:
|
||||
type: sequence
|
||||
label: 'The selected roles'
|
||||
orderby: key
|
||||
sequence:
|
||||
type: string
|
||||
label: 'The user roles which will be active when the entity is rendered'
|
||||
view_mode:
|
||||
type: sequence
|
||||
label: 'The selected view modes for each datasource, by bundle'
|
||||
orderby: key
|
||||
sequence:
|
||||
type: sequence
|
||||
label: 'The selected view modes for the datasource, by bundle'
|
||||
orderby: key
|
||||
sequence:
|
||||
type: string
|
||||
label: 'The view mode used to render the entity for the specified bundle'
|
||||
|
||||
@@ -16,9 +16,11 @@ views.row.search_api:
|
||||
view_modes:
|
||||
type: sequence
|
||||
label: View modes for each datasource
|
||||
orderby: key
|
||||
sequence:
|
||||
type: sequence
|
||||
label: A list of all the bundles and their configured view mode
|
||||
orderby: key
|
||||
sequence:
|
||||
type: string
|
||||
label: View mode for the specific bundle
|
||||
@@ -70,6 +72,7 @@ views.argument.search_api_fulltext:
|
||||
fields:
|
||||
type: sequence
|
||||
label: 'Fields'
|
||||
orderby: value
|
||||
sequence:
|
||||
type: string
|
||||
label: 'Field'
|
||||
@@ -81,6 +84,7 @@ views.argument.search_api_more_like_this:
|
||||
fields:
|
||||
type: sequence
|
||||
label: 'Fields'
|
||||
orderby: value
|
||||
sequence:
|
||||
type: string
|
||||
label: 'Field'
|
||||
@@ -147,6 +151,7 @@ views.field.search_api_entity:
|
||||
display_methods:
|
||||
type: sequence
|
||||
label: 'Display settings'
|
||||
orderby: key
|
||||
sequence:
|
||||
type: mapping
|
||||
label: 'Display settings for bundle'
|
||||
@@ -216,9 +221,17 @@ views.filter.search_api_fulltext:
|
||||
fields:
|
||||
type: sequence
|
||||
label: Fields to search on
|
||||
orderby: value
|
||||
sequence:
|
||||
type: string
|
||||
label: Field name
|
||||
expose:
|
||||
type: mapping
|
||||
label: 'Exposed'
|
||||
mapping:
|
||||
placeholder:
|
||||
type: label
|
||||
label: 'Placeholder'
|
||||
|
||||
views.filter.search_api_language:
|
||||
type: views.filter.language
|
||||
@@ -269,6 +282,7 @@ views.filter_value.search_api_numeric:
|
||||
|
||||
views.filter_value.search_api_options:
|
||||
type: sequence
|
||||
orderby: value
|
||||
sequence:
|
||||
type: string
|
||||
label: 'Value'
|
||||
|
||||
+3
-3
@@ -8,9 +8,9 @@ plugin.plugin_configuration.search_api_backend.search_api_db:
|
||||
min_chars:
|
||||
type: 'integer'
|
||||
label: 'Minimum length of indexed words'
|
||||
partial_matches:
|
||||
type: 'boolean'
|
||||
label: 'Whether to also search on parts of a word'
|
||||
matching:
|
||||
type: 'string'
|
||||
label: 'The matching mode – "words", "prefix" or "partial"'
|
||||
autocomplete:
|
||||
type: mapping
|
||||
label: Autcomplete configuration
|
||||
|
||||
+3
-3
@@ -6,8 +6,8 @@ package: Search
|
||||
dependencies:
|
||||
- search_api:search_api
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-02-23
|
||||
version: '8.x-1.7'
|
||||
# Information added by Drupal.org packaging script on 2018-07-19
|
||||
version: '8.x-1.9'
|
||||
core: '8.x'
|
||||
project: 'search_api'
|
||||
datestamp: 1519387691
|
||||
datestamp: 1531985591
|
||||
|
||||
+31
@@ -76,3 +76,34 @@ function search_api_db_update_8102() {
|
||||
|
||||
return t('Primary keys added to all denormalized index tables.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the old "partial_matches" option to the new "matching" option.
|
||||
*/
|
||||
function search_api_db_update_8103() {
|
||||
// @see https://www.drupal.org/project/search_api/issues/2971033
|
||||
|
||||
$config_factory = \Drupal::configFactory();
|
||||
$count = 0;
|
||||
foreach ($config_factory->listAll('search_api.server.') as $server_id) {
|
||||
$server = $config_factory->getEditable($server_id);
|
||||
if ($server->get('backend') !== 'search_api_db') {
|
||||
continue;
|
||||
}
|
||||
|
||||
++$count;
|
||||
$config = $server->get('backend_config') ?: [];
|
||||
$config['matching'] = empty($config['partial_matches']) ? 'words' : 'partial';
|
||||
unset($config['partial_matches']);
|
||||
$server->set('backend_config', $config);
|
||||
// Mark the resulting configuration as trusted data. This avoids issues
|
||||
// with future schema changes.
|
||||
$server->save(TRUE);
|
||||
}
|
||||
|
||||
if ($count) {
|
||||
return \Drupal::translation()
|
||||
->formatPlural($count, 'Updated 1 server.', 'Updated @count servers.');
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+43
-43
@@ -3,12 +3,33 @@ name: 'Default content index'
|
||||
description: 'Default content index created by the Database Search Defaults module'
|
||||
read_only: false
|
||||
field_settings:
|
||||
title:
|
||||
label: Title
|
||||
type: text
|
||||
author:
|
||||
label: 'Author name'
|
||||
type: string
|
||||
datasource_id: 'entity:node'
|
||||
property_path: title
|
||||
boost: 8
|
||||
property_path: 'uid:entity:name'
|
||||
changed:
|
||||
label: Changed
|
||||
type: date
|
||||
datasource_id: 'entity:node'
|
||||
property_path: changed
|
||||
created:
|
||||
label: 'Authored on'
|
||||
type: date
|
||||
datasource_id: 'entity:node'
|
||||
property_path: created
|
||||
field_tags:
|
||||
label: Tags
|
||||
type: integer
|
||||
datasource_id: 'entity:node'
|
||||
property_path: 'field_tags'
|
||||
node_grants:
|
||||
label: 'Node access information'
|
||||
type: string
|
||||
property_path: search_api_node_grants
|
||||
indexed_locked: true
|
||||
type_locked: true
|
||||
hidden: true
|
||||
rendered_item:
|
||||
label: 'Rendered item'
|
||||
type: text
|
||||
@@ -20,57 +41,36 @@ field_settings:
|
||||
'entity:node':
|
||||
article: search_index
|
||||
page: search_index
|
||||
created:
|
||||
label: 'Authored on'
|
||||
type: date
|
||||
datasource_id: 'entity:node'
|
||||
property_path: created
|
||||
changed:
|
||||
label: Changed
|
||||
type: date
|
||||
datasource_id: 'entity:node'
|
||||
property_path: changed
|
||||
status:
|
||||
label: 'Publishing status'
|
||||
type: boolean
|
||||
datasource_id: 'entity:node'
|
||||
property_path: status
|
||||
index_locked: true
|
||||
indexed_locked: true
|
||||
type_locked: true
|
||||
sticky:
|
||||
label: 'Sticky at top of lists'
|
||||
type: boolean
|
||||
datasource_id: 'entity:node'
|
||||
property_path: sticky
|
||||
field_tags:
|
||||
label: Tags
|
||||
type: integer
|
||||
title:
|
||||
label: Title
|
||||
type: text
|
||||
datasource_id: 'entity:node'
|
||||
property_path: 'field_tags'
|
||||
author:
|
||||
label: 'Author name'
|
||||
type: string
|
||||
datasource_id: 'entity:node'
|
||||
property_path: 'uid:entity:name'
|
||||
uid:
|
||||
label: 'Author ID'
|
||||
type: integer
|
||||
datasource_id: 'entity:node'
|
||||
property_path: uid
|
||||
index_locked: true
|
||||
type_locked: true
|
||||
node_grants:
|
||||
label: 'Node access information'
|
||||
type: string
|
||||
property_path: search_api_node_grants
|
||||
index_locked: true
|
||||
type_locked: true
|
||||
hidden: true
|
||||
property_path: title
|
||||
boost: 8
|
||||
type:
|
||||
label: 'Content type'
|
||||
type: string
|
||||
datasource_id: 'entity:node'
|
||||
property_path: type
|
||||
uid:
|
||||
label: 'Author ID'
|
||||
type: integer
|
||||
datasource_id: 'entity:node'
|
||||
property_path: uid
|
||||
indexed_locked: true
|
||||
type_locked: true
|
||||
processor_settings:
|
||||
add_url:
|
||||
weights:
|
||||
@@ -82,6 +82,9 @@ processor_settings:
|
||||
weights:
|
||||
preprocess_index: -6
|
||||
preprocess_query: -4
|
||||
entity_status:
|
||||
weights:
|
||||
preprocess_index: -10
|
||||
html_filter:
|
||||
weights:
|
||||
preprocess_index: -3
|
||||
@@ -103,9 +106,6 @@ processor_settings:
|
||||
fields:
|
||||
- rendered_item
|
||||
- title
|
||||
entity_status:
|
||||
weights:
|
||||
preprocess_index: -10
|
||||
rendered_item:
|
||||
weights:
|
||||
add_properties: 0
|
||||
@@ -171,8 +171,8 @@ processor_settings:
|
||||
- rendered_item
|
||||
- title
|
||||
options:
|
||||
index_directly: true
|
||||
cron_limit: 50
|
||||
index_directly: true
|
||||
datasource_settings:
|
||||
'entity:node': { }
|
||||
tracker_settings:
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ backend: search_api_db
|
||||
backend_config:
|
||||
database: 'default:default'
|
||||
min_chars: 3
|
||||
partial_matches: false
|
||||
matching: 'words'
|
||||
autocomplete:
|
||||
suggest_suffix: true
|
||||
suggest_words: true
|
||||
|
||||
+3
-3
@@ -13,8 +13,8 @@ dependencies:
|
||||
- drupal:views
|
||||
- search_api:search_api_db
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-02-23
|
||||
version: '8.x-1.7'
|
||||
# Information added by Drupal.org packaging script on 2018-07-19
|
||||
version: '8.x-1.9'
|
||||
core: '8.x'
|
||||
project: 'search_api'
|
||||
datestamp: 1519387691
|
||||
datestamp: 1531985591
|
||||
|
||||
+1
-2
@@ -3,7 +3,6 @@
|
||||
namespace Drupal\search_api_db\DatabaseCompatibility;
|
||||
|
||||
use Drupal\Component\Transliteration\TransliterationInterface;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Database\Connection;
|
||||
|
||||
/**
|
||||
@@ -66,7 +65,7 @@ class GenericDatabase implements DatabaseCompatibilityHandlerInterface {
|
||||
if ($type == 'text') {
|
||||
return $value;
|
||||
}
|
||||
return Unicode::strtolower($this->transliterator->transliterate($value));
|
||||
return mb_strtolower($this->transliterator->transliterate($value));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+59
-44
@@ -399,7 +399,7 @@ class Database extends BackendPluginBase implements PluginFormInterface {
|
||||
return [
|
||||
'database' => NULL,
|
||||
'min_chars' => 1,
|
||||
'partial_matches' => FALSE,
|
||||
'matching' => 'words',
|
||||
'autocomplete' => [
|
||||
'suggest_suffix' => TRUE,
|
||||
'suggest_words' => TRUE,
|
||||
@@ -465,11 +465,15 @@ class Database extends BackendPluginBase implements PluginFormInterface {
|
||||
'#default_value' => $this->configuration['min_chars'],
|
||||
];
|
||||
|
||||
$form['partial_matches'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Search on parts of a word'),
|
||||
'#description' => $this->t('Find keywords in parts of a word, too. (For example, find results with "database" when searching for "base"). <strong>Caution:</strong> This can make searches much slower on large sites!'),
|
||||
'#default_value' => $this->configuration['partial_matches'],
|
||||
$form['matching'] = [
|
||||
'#type' => 'radios',
|
||||
'#title' => $this->t('Partial matching'),
|
||||
'#default_value' => $this->configuration['matching'],
|
||||
'#options' => [
|
||||
'words' => $this->t('Match whole words only'),
|
||||
'partial' => $this->t('Match on parts of a word'),
|
||||
'prefix' => $this->t('Match words starting with given keywords'),
|
||||
],
|
||||
];
|
||||
|
||||
if ($this->getModuleHandler()->moduleExists('search_api_autocomplete')) {
|
||||
@@ -511,10 +515,17 @@ class Database extends BackendPluginBase implements PluginFormInterface {
|
||||
'info' => $this->configuration['min_chars'],
|
||||
];
|
||||
}
|
||||
$info[] = [
|
||||
'label' => $this->t('Search on parts of a word'),
|
||||
'info' => !empty($this->configuration['partial_matches']) ? $this->t('enabled') : $this->t('disabled'),
|
||||
|
||||
$labels = [
|
||||
'words' => $this->t('Match whole words only'),
|
||||
'partial' => $this->t('Match on parts of a word'),
|
||||
'prefix' => $this->t('Match words starting with given keywords'),
|
||||
];
|
||||
$info[] = [
|
||||
'label' => $this->t('Partial matching'),
|
||||
'info' => $labels[$this->configuration['matching']],
|
||||
];
|
||||
|
||||
if (!empty($this->configuration['autocomplete'])) {
|
||||
$this->configuration['autocomplete'] += [
|
||||
'suggest_suffix' => TRUE,
|
||||
@@ -669,12 +680,12 @@ class Database extends BackendPluginBase implements PluginFormInterface {
|
||||
// A DB prefix might further reduce the maximum length of the table name.
|
||||
$max_bytes = 62;
|
||||
if ($db_prefix = $this->database->tablePrefix()) {
|
||||
// Use strlen() instead of Unicode::strlen() since we want to measure
|
||||
// bytes, not characters.
|
||||
// Use strlen() instead of mb_strlen() since we want to measure bytes, not
|
||||
// characters.
|
||||
$max_bytes -= strlen($db_prefix);
|
||||
}
|
||||
|
||||
$base = $table = Unicode::truncateBytes($prefix . Unicode::strtolower(preg_replace('/[^a-z0-9]/i', '_', $name)), $max_bytes);
|
||||
$base = $table = Unicode::truncateBytes($prefix . mb_strtolower(preg_replace('/[^a-z0-9]/i', '_', $name)), $max_bytes);
|
||||
$i = 0;
|
||||
while ($this->database->schema()->tableExists($table)) {
|
||||
$suffix = '_' . ++$i;
|
||||
@@ -703,7 +714,7 @@ class Database extends BackendPluginBase implements PluginFormInterface {
|
||||
protected function findFreeColumn($table, $column) {
|
||||
$maxbytes = 62;
|
||||
|
||||
$base = $name = Unicode::truncateBytes(Unicode::strtolower(preg_replace('/[^a-z0-9]/i', '_', $column)), $maxbytes);
|
||||
$base = $name = Unicode::truncateBytes(mb_strtolower(preg_replace('/[^a-z0-9]/i', '_', $column)), $maxbytes);
|
||||
// If the table does not exist yet, the initial name is not taken.
|
||||
if ($this->database->schema()->tableExists($table)) {
|
||||
$i = 0;
|
||||
@@ -769,7 +780,7 @@ class Database extends BackendPluginBase implements PluginFormInterface {
|
||||
$db_field += [
|
||||
'description' => "The field's value for this item",
|
||||
];
|
||||
if ($new_table) {
|
||||
if ($new_table || $type === 'field') {
|
||||
$db_field['not null'] = TRUE;
|
||||
}
|
||||
$this->database->schema()->addField($db['table'], $column, $db_field);
|
||||
@@ -924,8 +935,13 @@ class Database extends BackendPluginBase implements PluginFormInterface {
|
||||
elseif ($this->sqlType($old_type) != $this->sqlType($new_type)) {
|
||||
// There is a change in SQL type. We don't have to clear the index,
|
||||
// since types can be converted.
|
||||
$this->database->schema()->changeField($field['table'], 'value', 'value', $this->sqlType($new_type) + ['description' => "The field's value for this item"]);
|
||||
$this->database->schema()->changeField($denormalized_table, $field['column'], $field['column'], $this->sqlType($new_type) + ['description' => "The field's value for this item"]);
|
||||
$sql_spec = $this->sqlType($new_type);
|
||||
$sql_spec += [
|
||||
'description' => "The field's value for this item",
|
||||
];
|
||||
$this->database->schema()->changeField($denormalized_table, $field['column'], $field['column'], $sql_spec);
|
||||
$sql_spec['not null'] = TRUE;
|
||||
$this->database->schema()->changeField($field['table'], 'value', 'value', $sql_spec);
|
||||
$reindex = TRUE;
|
||||
}
|
||||
elseif ($old_type == 'date' || $new_type == 'date') {
|
||||
@@ -955,7 +971,7 @@ class Database extends BackendPluginBase implements PluginFormInterface {
|
||||
}
|
||||
$this->database->update($text_table)
|
||||
->expression('score', $expression, $args)
|
||||
->condition('field_name', self::getTextFieldName($field_id))
|
||||
->condition('field_name', static::getTextFieldName($field_id))
|
||||
->execute();
|
||||
}
|
||||
else {
|
||||
@@ -1081,7 +1097,7 @@ class Database extends BackendPluginBase implements PluginFormInterface {
|
||||
if ($this->getDataTypeHelper()->isTextType($field['type'])) {
|
||||
// Remove data from the text table.
|
||||
$this->database->delete($field['table'])
|
||||
->condition('field_name', self::getTextFieldName($name))
|
||||
->condition('field_name', static::getTextFieldName($name))
|
||||
->execute();
|
||||
}
|
||||
elseif ($this->database->schema()->tableExists($field['table'])) {
|
||||
@@ -1263,7 +1279,7 @@ class Database extends BackendPluginBase implements PluginFormInterface {
|
||||
|
||||
// Store the first 30 characters of the string as the denormalized
|
||||
// value.
|
||||
if (Unicode::strlen($denormalized_value) < 30) {
|
||||
if (mb_strlen($denormalized_value) < 30) {
|
||||
$denormalized_value .= $word . ' ';
|
||||
}
|
||||
|
||||
@@ -1271,7 +1287,7 @@ class Database extends BackendPluginBase implements PluginFormInterface {
|
||||
if (is_numeric($word)) {
|
||||
$word = ltrim($word, '-0');
|
||||
}
|
||||
elseif (Unicode::strlen($word) < $this->configuration['min_chars']) {
|
||||
elseif (mb_strlen($word) < $this->configuration['min_chars']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1295,12 +1311,13 @@ class Database extends BackendPluginBase implements PluginFormInterface {
|
||||
$unique_tokens[$word_base_form]['score'] += $score;
|
||||
}
|
||||
}
|
||||
$denormalized_values[$column] = Unicode::substr(trim($denormalized_value), 0, 30);
|
||||
$denormalized_values[$column] = mb_substr(trim($denormalized_value), 0, 30);
|
||||
if ($unique_tokens) {
|
||||
$field_name = self::getTextFieldName($field_id);
|
||||
$field_name = static::getTextFieldName($field_id);
|
||||
$boost = $field_info['boost'];
|
||||
foreach ($unique_tokens as $token) {
|
||||
$score = round($token['score'] * $boost * self::SCORE_MULTIPLIER);
|
||||
$score = $token['score'] * $boost * self::SCORE_MULTIPLIER;
|
||||
$score = round($score);
|
||||
// Take care that the score doesn't exceed the maximum value for
|
||||
// the database column (2^32-1).
|
||||
$score = min((int) $score, 4294967295);
|
||||
@@ -1420,9 +1437,9 @@ class Database extends BackendPluginBase implements PluginFormInterface {
|
||||
}
|
||||
foreach (static::splitIntoWords($text) as $word) {
|
||||
if ($word) {
|
||||
if (Unicode::strlen($word) > 50) {
|
||||
if (mb_strlen($word) > 50) {
|
||||
$this->getLogger()->warning('An overlong word (more than 50 characters) was encountered while indexing: %word.<br />Since database search servers currently cannot index words of more than 50 characters, the word was truncated for indexing. If this should not be a single word, please make sure the "Tokenizer" processor is enabled and configured correctly for index %index.', ['%word' => $word, '%index' => $index->label()]);
|
||||
$word = Unicode::substr($word, 0, 50);
|
||||
$word = mb_substr($word, 0, 50);
|
||||
}
|
||||
$tokens[] = new TextToken($word);
|
||||
}
|
||||
@@ -1434,12 +1451,12 @@ class Database extends BackendPluginBase implements PluginFormInterface {
|
||||
// Check for over-long tokens.
|
||||
$score = $token->getBoost();
|
||||
$word = $token->getText();
|
||||
if (Unicode::strlen($word) > 50) {
|
||||
if (mb_strlen($word) > 50) {
|
||||
$new_tokens = [];
|
||||
foreach (static::splitIntoWords($word) as $word) {
|
||||
if (Unicode::strlen($word) > 50) {
|
||||
if (mb_strlen($word) > 50) {
|
||||
$this->getLogger()->warning('An overlong word (more than 50 characters) was encountered while indexing: %word.<br />Since database search servers currently cannot index words of more than 50 characters, the word was truncated for indexing. If this should not be a single word, please make sure the "Tokenizer" processor is enabled and configured correctly for index %index.', ['%word' => $word, '%index' => $index->label()]);
|
||||
$word = Unicode::substr($word, 0, 50);
|
||||
$word = mb_substr($word, 0, 50);
|
||||
}
|
||||
$new_tokens[] = new TextToken($word, $score);
|
||||
}
|
||||
@@ -1459,13 +1476,14 @@ class Database extends BackendPluginBase implements PluginFormInterface {
|
||||
if ($original_type == 'date') {
|
||||
return date('c', $value);
|
||||
}
|
||||
if (Unicode::strlen($value) > 255) {
|
||||
$value = Unicode::substr($value, 0, 255);
|
||||
if (mb_strlen($value) > 255) {
|
||||
$value = mb_substr($value, 0, 255);
|
||||
$this->getLogger()->warning('An overlong value (more than 255 characters) was encountered while indexing: %value.<br />Database search servers currently cannot index such values correctly – the value was therefore trimmed to the allowed length.', ['%value' => $value]);
|
||||
}
|
||||
return $value;
|
||||
|
||||
case 'integer':
|
||||
case 'date':
|
||||
case 'duration':
|
||||
case 'decimal':
|
||||
return 0 + $value;
|
||||
@@ -1473,12 +1491,6 @@ class Database extends BackendPluginBase implements PluginFormInterface {
|
||||
case 'boolean':
|
||||
return $value ? 1 : 0;
|
||||
|
||||
case 'date':
|
||||
if (is_numeric($value) || !$value) {
|
||||
return 0 + $value;
|
||||
}
|
||||
return strtotime($value);
|
||||
|
||||
default:
|
||||
throw new SearchApiException("Unknown field type '$type'.");
|
||||
}
|
||||
@@ -1791,7 +1803,7 @@ class Database extends BackendPluginBase implements PluginFormInterface {
|
||||
if (is_numeric($processed_keys)) {
|
||||
return ltrim($processed_keys, '-0');
|
||||
}
|
||||
elseif (Unicode::strlen($processed_keys) < $this->configuration['min_chars']) {
|
||||
elseif (mb_strlen($processed_keys) < $this->configuration['min_chars']) {
|
||||
$this->ignored[$keys] = 1;
|
||||
return NULL;
|
||||
}
|
||||
@@ -1886,8 +1898,9 @@ class Database extends BackendPluginBase implements PluginFormInterface {
|
||||
$db_query = NULL;
|
||||
$mul_words = FALSE;
|
||||
$neg_nested = $neg && $conj == 'AND';
|
||||
$match_parts = !empty($this->configuration['partial_matches']);
|
||||
$match_parts = $this->configuration['matching'] !== 'words';
|
||||
$keyword_hits = [];
|
||||
$prefix_search = $this->configuration['matching'] === 'prefix';
|
||||
|
||||
foreach ($keys as $i => $key) {
|
||||
if (!Element::child($i)) {
|
||||
@@ -1944,7 +1957,9 @@ class Database extends BackendPluginBase implements PluginFormInterface {
|
||||
}
|
||||
|
||||
foreach ($words as $i => $word) {
|
||||
$db_or->condition('t.word', '%' . $this->database->escapeLike($word) . '%', 'LIKE');
|
||||
$like = $this->database->escapeLike($word);
|
||||
$like = $prefix_search ? "$like%" : "%$like%";
|
||||
$db_or->condition('t.word', $like, 'LIKE');
|
||||
|
||||
// Add an expression for each keyword that shows whether the indexed
|
||||
// word matches that particular keyword. That way we don't return a
|
||||
@@ -2547,8 +2562,8 @@ class Database extends BackendPluginBase implements PluginFormInterface {
|
||||
|
||||
// Make the input lowercase as the indexed data is (usually) also all
|
||||
// lowercase.
|
||||
$incomplete_key = Unicode::strtolower($incomplete_key);
|
||||
$user_input = Unicode::strtolower($user_input);
|
||||
$incomplete_key = mb_strtolower($incomplete_key);
|
||||
$user_input = mb_strtolower($user_input);
|
||||
|
||||
// Decide which methods we want to use.
|
||||
if ($incomplete_key && $settings['suggest_suffix']) {
|
||||
@@ -2578,12 +2593,12 @@ class Database extends BackendPluginBase implements PluginFormInterface {
|
||||
$query->keys($user_input);
|
||||
}
|
||||
// To avoid suggesting incomplete words, we have to temporarily disable
|
||||
// the "partial_matches" option. There should be no way we'll save the
|
||||
// server during the createDbQuery() call, so this should be safe.
|
||||
// partial matching. There should be no way we'll save the server during
|
||||
// the createDbQuery() call, so this should be safe.
|
||||
$configuration = $this->configuration;
|
||||
$db_query = NULL;
|
||||
try {
|
||||
$this->configuration['partial_matches'] = FALSE;
|
||||
$this->configuration['matching'] = 'words';
|
||||
$db_query = $this->createDbQuery($query, $fields);
|
||||
$this->configuration = $configuration;
|
||||
|
||||
|
||||
+3
-3
@@ -8,8 +8,8 @@ dependencies:
|
||||
# core: 8.x
|
||||
hidden: true
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-02-23
|
||||
version: '8.x-1.7'
|
||||
# Information added by Drupal.org packaging script on 2018-07-19
|
||||
version: '8.x-1.9'
|
||||
core: '8.x'
|
||||
project: 'search_api'
|
||||
datestamp: 1519387691
|
||||
datestamp: 1531985591
|
||||
|
||||
+143
-7
@@ -4,6 +4,7 @@ namespace Drupal\Tests\search_api_db\Kernel;
|
||||
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\Core\Database\Database as CoreDatabase;
|
||||
use Drupal\search_api\Entity\Index;
|
||||
use Drupal\search_api\Entity\Server;
|
||||
use Drupal\search_api\IndexInterface;
|
||||
use Drupal\search_api\Item\ItemInterface;
|
||||
@@ -73,6 +74,8 @@ class BackendTest extends BackendTestBase {
|
||||
$this->checkMultiValuedInfo();
|
||||
$this->editServerPartial();
|
||||
$this->searchSuccessPartial();
|
||||
$this->editServerStartsWith();
|
||||
$this->searchSuccessStartsWith();
|
||||
$this->editServerMinChars();
|
||||
$this->searchSuccessMinChars();
|
||||
$this->checkUnknownOperator();
|
||||
@@ -89,6 +92,7 @@ class BackendTest extends BackendTestBase {
|
||||
$this->regressionTest2846932();
|
||||
$this->regressionTest2926733();
|
||||
$this->regressionTest2938646();
|
||||
$this->regressionTest2925464();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -205,14 +209,11 @@ class BackendTest extends BackendTestBase {
|
||||
|
||||
/**
|
||||
* Edits the server to enable partial matches.
|
||||
*
|
||||
* @param bool $enable
|
||||
* (optional) Whether partial matching should be enabled or disabled.
|
||||
*/
|
||||
protected function editServerPartial($enable = TRUE) {
|
||||
protected function editServerPartial() {
|
||||
$server = $this->getServer();
|
||||
$backend_config = $server->getBackendConfig();
|
||||
$backend_config['partial_matches'] = $enable;
|
||||
$backend_config['matching'] = 'partial';
|
||||
$server->setBackendConfig($backend_config);
|
||||
$this->assertTrue((bool) $server->save(), 'The server was successfully edited.');
|
||||
$this->resetEntityCache();
|
||||
@@ -241,7 +242,7 @@ class BackendTest extends BackendTestBase {
|
||||
$this->assertResults([], $results, 'Partial search for »foo nonexistent«');
|
||||
|
||||
$results = $this->buildSearch('bar nonexistent')->execute();
|
||||
$this->assertResults([], $results, 'Partial search for »foo nonexistent«');
|
||||
$this->assertResults([], $results, 'Partial search for »bar nonexistent«');
|
||||
|
||||
$keys = [
|
||||
'#conjunction' => 'AND',
|
||||
@@ -269,6 +270,69 @@ class BackendTest extends BackendTestBase {
|
||||
$this->assertResults([1, 2, 3, 4], $results, 'Partial search with multi-field fulltext filter');
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits the server to enable prefix matching.
|
||||
*/
|
||||
protected function editServerStartsWith() {
|
||||
$server = $this->getServer();
|
||||
$backend_config = $server->getBackendConfig();
|
||||
$backend_config['matching'] = 'prefix';
|
||||
$server->setBackendConfig($backend_config);
|
||||
$this->assertTrue((bool) $server->save(), 'The server was successfully edited.');
|
||||
$this->resetEntityCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether prefix matching works.
|
||||
*/
|
||||
protected function searchSuccessStartsWith() {
|
||||
$results = $this->buildSearch('foobaz')->range(0, 1)->execute();
|
||||
$this->assertResults([1], $results, 'Prefix search for »foobaz«');
|
||||
|
||||
$results = $this->buildSearch('foo', [], [], FALSE)
|
||||
->sort('search_api_relevance', QueryInterface::SORT_DESC)
|
||||
->sort('id')
|
||||
->execute();
|
||||
$this->assertResults([1, 2, 4, 3, 5], $results, 'Prefix search for »foo«');
|
||||
|
||||
$results = $this->buildSearch('foo tes')->execute();
|
||||
$this->assertResults([1, 2, 3, 4], $results, 'Prefix search for »foo tes«');
|
||||
|
||||
$results = $this->buildSearch('oob est')->execute();
|
||||
$this->assertResults([], $results, 'Prefix search for »oob est«');
|
||||
|
||||
$results = $this->buildSearch('foo nonexistent')->execute();
|
||||
$this->assertResults([], $results, 'Prefix search for »foo nonexistent«');
|
||||
|
||||
$results = $this->buildSearch('bar nonexistent')->execute();
|
||||
$this->assertResults([], $results, 'Prefix search for »bar nonexistent«');
|
||||
|
||||
$keys = [
|
||||
'#conjunction' => 'AND',
|
||||
'foob',
|
||||
[
|
||||
'#conjunction' => 'OR',
|
||||
'tes',
|
||||
'nonexistent',
|
||||
],
|
||||
];
|
||||
$results = $this->buildSearch($keys)->execute();
|
||||
$this->assertResults([1, 2, 3], $results, 'Prefix search for complex keys');
|
||||
|
||||
$results = $this->buildSearch('foo', ['category,item_category'], [], FALSE)
|
||||
->sort('id', QueryInterface::SORT_DESC)
|
||||
->execute();
|
||||
$this->assertResults([2, 1], $results, 'Prefix search for »foo« with additional filter');
|
||||
|
||||
$query = $this->buildSearch();
|
||||
$conditions = $query->createConditionGroup('OR');
|
||||
$conditions->addCondition('name', 'test');
|
||||
$conditions->addCondition('body', 'test');
|
||||
$query->addConditionGroup($conditions);
|
||||
$results = $query->execute();
|
||||
$this->assertResults([1, 2, 3, 4], $results, 'Prefix search with multi-field fulltext filter');
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits the server to change the "Minimum word length" setting.
|
||||
*/
|
||||
@@ -276,7 +340,7 @@ class BackendTest extends BackendTestBase {
|
||||
$server = $this->getServer();
|
||||
$backend_config = $server->getBackendConfig();
|
||||
$backend_config['min_chars'] = 4;
|
||||
$backend_config['partial_matches'] = FALSE;
|
||||
$backend_config['matching'] = 'words';
|
||||
$server->setBackendConfig($backend_config);
|
||||
$success = (bool) $server->save();
|
||||
$this->assertTrue($success, 'The server was successfully edited.');
|
||||
@@ -556,6 +620,23 @@ class BackendTest extends BackendTestBase {
|
||||
$this->assertEquals(2 * $old_score, $new_score);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests changing of field types.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2925464
|
||||
*/
|
||||
protected function regressionTest2925464() {
|
||||
$index = $this->getIndex();
|
||||
|
||||
$index->getField('category')->setType('integer');
|
||||
$index->save();
|
||||
|
||||
$index->getField('category')->setType('string');
|
||||
$index->save();
|
||||
|
||||
$this->indexItems($index->id());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -750,4 +831,59 @@ class BackendTest extends BackendTestBase {
|
||||
$this->assertEquals($class, get_class($dbms_comp2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether indexing of dates works correctly.
|
||||
*/
|
||||
public function testDateIndexing() {
|
||||
// Load all existing entities.
|
||||
$storage = \Drupal::entityTypeManager()
|
||||
->getStorage('entity_test_mulrev_changed');
|
||||
$storage->delete($storage->loadMultiple());
|
||||
|
||||
$index = Index::load('database_search_index');
|
||||
$index->getField('name')->setType('date');
|
||||
$index->save();
|
||||
|
||||
// Simulate date field creation in one timezone and indexing in another.
|
||||
date_default_timezone_set('America/Chicago');
|
||||
|
||||
// Test different input values, similar to @dataProvider (but with less
|
||||
// overhead).
|
||||
$t = 1400000000;
|
||||
$f = 'Y-m-d H:i:s';
|
||||
$test_values = [
|
||||
'null' => [NULL, NULL],
|
||||
'timestamp' => [$t, $t],
|
||||
'string timestamp' => ["$t", $t],
|
||||
'float timestamp' => [$t + 0.12, $t],
|
||||
'date string' => [gmdate($f, $t), $t],
|
||||
'date string with timezone' => [date($f . 'P', $t), $t],
|
||||
];
|
||||
|
||||
// Get storage information for quickly checking the indexed value.
|
||||
$db_info = $this->getIndexDbInfo();
|
||||
$table = $db_info['index_table'];
|
||||
$column = $db_info['field_tables']['name']['column'];
|
||||
$sql = "SELECT $column FROM {{$table}} WHERE item_id = :id";
|
||||
|
||||
$id = 0;
|
||||
date_default_timezone_set('Asia/Seoul');
|
||||
foreach ($test_values as $label => list($field_value, $expected)) {
|
||||
$entity = $this->addTestEntity(++$id, [
|
||||
'name' => $field_value,
|
||||
'type' => 'item',
|
||||
]);
|
||||
$item_id = $this->getItemIds([$id])[0];
|
||||
$index->indexSpecificItems([$item_id => $entity->getTypedData()]);
|
||||
$args[':id'] = $item_id;
|
||||
$indexed_value = \Drupal::database()->query($sql, $args)->fetchField();
|
||||
if ($expected === NULL) {
|
||||
$this->assertSame($expected, $indexed_value, "Indexing of date field with $label value.");
|
||||
}
|
||||
else {
|
||||
$this->assertEquals($expected, $indexed_value, "Indexing of date field with $label value.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -11,8 +11,8 @@ dependencies:
|
||||
- drupal:taxonomy
|
||||
- drupal:views
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-02-23
|
||||
version: '8.x-1.7'
|
||||
# Information added by Drupal.org packaging script on 2018-07-19
|
||||
version: '8.x-1.9'
|
||||
core: '8.x'
|
||||
project: 'search_api'
|
||||
datestamp: 1519387691
|
||||
datestamp: 1531985591
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
<!-- Only include specific sniffs that pass. This ensures that, if new sniffs are added, HEAD does not fail.-->
|
||||
<!-- Drupal sniffs -->
|
||||
<rule ref="Generic.Arrays.DisallowLongArraySyntax"/>
|
||||
<rule ref="Drupal.Array.DisallowLongArraySyntax"/>
|
||||
<rule ref="Drupal.Classes.ClassCreateInstance"/>
|
||||
<rule ref="Drupal.Classes.ClassDeclaration"/>
|
||||
<rule ref="Drupal.Classes.FullyQualifiedNamespace"/>
|
||||
|
||||
@@ -241,7 +241,8 @@ function hook_search_api_index_items_alter(\Drupal\search_api\IndexInterface $in
|
||||
'%index' => $index->label(),
|
||||
'@ids' => implode(', ', array_keys($items)),
|
||||
];
|
||||
drupal_set_message(t('Indexing items on index %index with the following IDs: @ids', $arguments));
|
||||
$message = t('Indexing items on index %index with the following IDs: @ids', $arguments);
|
||||
\Drupal::messenger()->addStatus($message);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -257,7 +258,8 @@ function hook_search_api_items_indexed(\Drupal\search_api\IndexInterface $index,
|
||||
// Note that this is just an example, and would only work if there are only
|
||||
// nodes indexed in that index (and even then the printed IDs would probably
|
||||
// not be as expected).
|
||||
drupal_set_message(t('Nodes indexed: @ids.', implode(', ', $item_ids)));
|
||||
$message = t('Nodes indexed: @ids.', implode(', ', $item_ids));
|
||||
\Drupal::messenger()->addStatus($message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@ package: Search
|
||||
# core: 8.x
|
||||
configure: search_api.overview
|
||||
dependencies:
|
||||
- system (>=8.4)
|
||||
- system (>=8.5)
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-02-23
|
||||
version: '8.x-1.7'
|
||||
# Information added by Drupal.org packaging script on 2018-07-19
|
||||
version: '8.x-1.9'
|
||||
core: '8.x'
|
||||
project: 'search_api'
|
||||
datestamp: 1519387691
|
||||
datestamp: 1531985591
|
||||
|
||||
@@ -572,7 +572,8 @@ function search_api_view_insert(ViewEntityInterface $view) {
|
||||
}
|
||||
|
||||
if ($change) {
|
||||
drupal_set_message(\Drupal::translation()->translate('The selected caching mechanism does not work with views on Search API indexes. Please either use one of the Search API-specific caching options or "None". Caching was turned off for this view.'), 'warning');
|
||||
$warning = t('The selected caching mechanism does not work with views on Search API indexes. Please either use one of the Search API-specific caching options or "None". Caching was turned off for this view.');
|
||||
\Drupal::messenger()->addWarning($warning);
|
||||
$view->set('display', $displays);
|
||||
$view->save();
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ services:
|
||||
|
||||
paramconverter.search_api:
|
||||
class: Drupal\search_api\ParamConverter\SearchApiConverter
|
||||
arguments: ['@entity.manager', '@user.shared_tempstore', '@current_user']
|
||||
arguments: ['@entity.manager', '@tempstore.shared', '@current_user']
|
||||
tags:
|
||||
- { name: paramconverter, priority: 10 }
|
||||
lazy: true
|
||||
@@ -72,7 +72,7 @@ services:
|
||||
class: Drupal\search_api\Utility\PostRequestIndexing
|
||||
arguments: ['@entity_type.manager']
|
||||
tags:
|
||||
- { name: event_subscriber }
|
||||
- { name: needs_destruction }
|
||||
|
||||
search_api.query_helper:
|
||||
class: Drupal\search_api\Utility\QueryHelper
|
||||
@@ -86,7 +86,7 @@ services:
|
||||
|
||||
search_api.task_manager:
|
||||
class: Drupal\search_api\Task\TaskManager
|
||||
arguments: ['@entity_type.manager', '@event_dispatcher', '@string_translation']
|
||||
arguments: ['@entity_type.manager', '@event_dispatcher', '@string_translation', '@messenger']
|
||||
|
||||
search_api.vbo_view_data_provider:
|
||||
class: Drupal\search_api\Contrib\ViewsBulkOperationsEventSubscriber
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Drupal\search_api\Backend;
|
||||
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\search_api\Entity\Server;
|
||||
use Drupal\search_api\Item\ItemInterface;
|
||||
use Drupal\search_api\LoggerTrait;
|
||||
@@ -11,6 +12,7 @@ use Drupal\search_api\IndexInterface;
|
||||
use Drupal\search_api\Plugin\ConfigurablePluginBase;
|
||||
use Drupal\search_api\ServerInterface;
|
||||
use Drupal\search_api\Utility\FieldsHelper;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Defines a base class for backend plugins.
|
||||
@@ -66,6 +68,13 @@ abstract class BackendPluginBase extends ConfigurablePluginBase implements Backe
|
||||
*/
|
||||
protected $fieldsHelper;
|
||||
|
||||
/**
|
||||
* The messenger.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface|null
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -77,6 +86,19 @@ abstract class BackendPluginBase extends ConfigurablePluginBase implements Backe
|
||||
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.
|
||||
*
|
||||
@@ -100,6 +122,29 @@ abstract class BackendPluginBase extends ConfigurablePluginBase implements Backe
|
||||
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}
|
||||
*/
|
||||
@@ -172,7 +217,7 @@ abstract class BackendPluginBase extends ConfigurablePluginBase implements Backe
|
||||
'%server' => $this->getServer()->label(),
|
||||
];
|
||||
$this->logException($e, '%type while deleting items from server %server: @message in %function (line %line of %file).', $vars);
|
||||
drupal_set_message($this->t('Deleting some of the items on the server failed. Check the logs for details. The server was still removed.'), 'error');
|
||||
$this->getMessenger()->addError($this->t('Deleting some of the items on the server failed. Check the logs for details. The server was still removed.'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -127,7 +127,7 @@ interface BackendSpecificInterface {
|
||||
* Notifies the server that an index attached to it has been changed.
|
||||
*
|
||||
* If any user action is necessary as a result of this, the method should
|
||||
* use drupal_set_message() to notify the user.
|
||||
* set a message to notify the user.
|
||||
*
|
||||
* @param \Drupal\search_api\IndexInterface $index
|
||||
* The updated index.
|
||||
|
||||
@@ -35,7 +35,7 @@ class RowsOfMultiValueFields extends RowsOfFields implements RenderCellInterface
|
||||
protected static function arrayToString(array $array) {
|
||||
$elements = [];
|
||||
foreach ($array as $element) {
|
||||
$elements[] = is_array($element) ? '"' . self::arrayToString($element) . '"' : $element;
|
||||
$elements[] = is_array($element) ? '"' . static::arrayToString($element) . '"' : $element;
|
||||
}
|
||||
return implode(',', $elements);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ use Drupal\Core\Ajax\AjaxResponse;
|
||||
use Drupal\Core\Ajax\RemoveCommand;
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\Core\EventSubscriber\AjaxResponseSubscriber;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\search_api\IndexInterface;
|
||||
use Drupal\search_api\SearchApiException;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
@@ -25,6 +26,13 @@ class IndexController extends ControllerBase {
|
||||
*/
|
||||
protected $requestStack;
|
||||
|
||||
/**
|
||||
* The messenger.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface|null
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -33,6 +41,7 @@ class IndexController extends ControllerBase {
|
||||
$controller = parent::create($container);
|
||||
|
||||
$controller->setRequestStack($container->get('request_stack'));
|
||||
$controller->setMessenger($container->get('messenger'));
|
||||
|
||||
return $controller;
|
||||
}
|
||||
@@ -70,6 +79,29 @@ class IndexController extends ControllerBase {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays information about a search index.
|
||||
*
|
||||
@@ -125,11 +157,11 @@ class IndexController extends ControllerBase {
|
||||
// enabled if its server is not set or disabled.
|
||||
if ($search_api_index->status()) {
|
||||
// Notify the user about the status change.
|
||||
drupal_set_message($this->t('The search index %name has been enabled.', ['%name' => $search_api_index->label()]));
|
||||
$this->getMessenger()->addStatus($this->t('The search index %name has been enabled.', ['%name' => $search_api_index->label()]));
|
||||
}
|
||||
else {
|
||||
// Notify the user that the status change did not succeed.
|
||||
drupal_set_message($this->t('The search index %name could not be enabled. Check if its server is set and enabled.', ['%name' => $search_api_index->label()]));
|
||||
$this->getMessenger()->addStatus($this->t('The search index %name could not be enabled. Check if its server is set and enabled.', ['%name' => $search_api_index->label()]));
|
||||
}
|
||||
|
||||
// Redirect to the index's "View" page.
|
||||
@@ -162,7 +194,7 @@ class IndexController extends ControllerBase {
|
||||
}
|
||||
catch (SearchApiException $e) {
|
||||
$args['%field'] = $fields[$field_id]->getLabel();
|
||||
drupal_set_message($this->t('The field %field is locked and cannot be removed.', $args), 'error');
|
||||
$this->getMessenger()->addError($this->t('The field %field is locked and cannot be removed.', $args));
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -4,13 +4,57 @@ namespace Drupal\search_api\Controller;
|
||||
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\search_api\ServerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides block routines for search server-specific routes.
|
||||
*/
|
||||
class ServerController extends ControllerBase {
|
||||
|
||||
/**
|
||||
* The messenger.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface|null
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
/** @var static $controller */
|
||||
$controller = parent::create($container);
|
||||
|
||||
$controller->setMessenger($container->get('messenger'));
|
||||
|
||||
return $controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays information about a search server.
|
||||
*
|
||||
@@ -65,7 +109,7 @@ class ServerController extends ControllerBase {
|
||||
$search_api_server->setStatus(TRUE)->save();
|
||||
|
||||
// Notify the user about the status change.
|
||||
drupal_set_message($this->t('The search server %name has been enabled.', ['%name' => $search_api_server->label()]));
|
||||
$this->getMessenger()->addStatus($this->t('The search server %name has been enabled.', ['%name' => $search_api_server->label()]));
|
||||
|
||||
// Redirect to the server's "View" page.
|
||||
$url = $search_api_server->toUrl('canonical');
|
||||
|
||||
@@ -18,7 +18,7 @@ use Drupal\search_api\SearchApiException;
|
||||
use Drupal\search_api\ServerInterface;
|
||||
use Drupal\search_api\Tracker\TrackerInterface;
|
||||
use Drupal\search_api\Utility\Utility;
|
||||
use Drupal\user\TempStoreException;
|
||||
use Drupal\Core\TempStore\TempStoreException;
|
||||
use Drupal\views\Views;
|
||||
|
||||
/**
|
||||
@@ -89,6 +89,7 @@ use Drupal\views\Views;
|
||||
*/
|
||||
class Index extends ConfigEntityBase implements IndexInterface {
|
||||
|
||||
use InstallingTrait;
|
||||
use LoggerTrait;
|
||||
|
||||
/**
|
||||
@@ -914,15 +915,19 @@ class Index extends ConfigEntityBase implements IndexInterface {
|
||||
if ($this->hasValidTracker() && !$this->isReadOnly()) {
|
||||
$tracker = $this->getTrackerInstance();
|
||||
$next_set = $tracker->getRemainingItems($limit, $datasource_id);
|
||||
if (!$next_set) {
|
||||
return 0;
|
||||
}
|
||||
$items = $this->loadItemsMultiple($next_set);
|
||||
if ($items) {
|
||||
try {
|
||||
return count($this->indexSpecificItems($items));
|
||||
}
|
||||
catch (SearchApiException $e) {
|
||||
$variables['%index'] = $this->label();
|
||||
$this->logException($e, '%type while trying to index items on index %index: @message in %function (line %line of %file)', $variables);
|
||||
}
|
||||
if (!$items) {
|
||||
return 0;
|
||||
}
|
||||
try {
|
||||
return count($this->indexSpecificItems($items));
|
||||
}
|
||||
catch (SearchApiException $e) {
|
||||
$variables['%index'] = $this->label();
|
||||
$this->logException($e, '%type while trying to index items on index %index: @message in %function (line %line of %file)', $variables);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -1197,9 +1202,10 @@ class Index extends ConfigEntityBase implements IndexInterface {
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function preSave(EntityStorageInterface $storage) {
|
||||
// If we are in the process of syncing, we shouldn't change any entity
|
||||
// If we are in the process of syncing, or in the process of installing
|
||||
// configuration from an extension, we shouldn't change any entity
|
||||
// properties (or other configuration).
|
||||
if ($this->isSyncing()) {
|
||||
if ($this->isSyncing() || $this->isInstallingFromExtension()) {
|
||||
parent::preSave($storage);
|
||||
return;
|
||||
}
|
||||
@@ -1559,8 +1565,8 @@ class Index extends ConfigEntityBase implements IndexInterface {
|
||||
\Drupal::cache('discovery')->delete('views:wizard');
|
||||
}
|
||||
|
||||
/** @var \Drupal\user\SharedTempStore $temp_store */
|
||||
$temp_store = \Drupal::service('user.shared_tempstore')->get('search_api_index');
|
||||
/** @var \Drupal\Core\TempStore\SharedTempStore $temp_store */
|
||||
$temp_store = \Drupal::service('tempstore.shared')->get('search_api_index');
|
||||
foreach ($entities as $entity) {
|
||||
try {
|
||||
$temp_store->delete($entity->id());
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\search_api\Entity;
|
||||
|
||||
/**
|
||||
* Provides a helper method for checking a saved config entity's source.
|
||||
*/
|
||||
trait InstallingTrait {
|
||||
|
||||
/**
|
||||
* Determines if this config entity is being installed from an extension.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the item is being installed from an extension; FALSE otherwise.
|
||||
*/
|
||||
protected function isInstallingFromExtension() {
|
||||
// A configuration item is being installed from an extension if both of the
|
||||
// following are true:
|
||||
// - It is marked as new.
|
||||
// - It has the _core property set.
|
||||
// @see \Drupal\core\Config\ConfigInstaller::installConfiguration().
|
||||
return ($this->isNew() && !empty($this->_core));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the entity is new.
|
||||
*
|
||||
* Usually an entity is new if no ID exists for it yet. However, entities may
|
||||
* be enforced to be new with existing IDs too.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the entity is new, or FALSE if the entity has already been saved.
|
||||
*
|
||||
* @see \Drupal\Core\Entity\EntityInterface::isNew()
|
||||
*/
|
||||
abstract public function isNew();
|
||||
|
||||
}
|
||||
@@ -62,6 +62,7 @@ use Drupal\search_api\Utility\Utility;
|
||||
*/
|
||||
class Server extends ConfigEntityBase implements ServerInterface {
|
||||
|
||||
use InstallingTrait;
|
||||
use LoggerTrait;
|
||||
|
||||
/**
|
||||
@@ -500,6 +501,7 @@ class Server extends ConfigEntityBase implements ServerInterface {
|
||||
|
||||
// If the server is being disabled, also disable all its indexes.
|
||||
if (!$this->isSyncing()
|
||||
&& !$this->isInstallingFromExtension()
|
||||
&& !isset($overrides['status'])
|
||||
&& !$this->status()
|
||||
&& $this->original->status()) {
|
||||
|
||||
@@ -10,6 +10,7 @@ use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\Core\Render\RendererInterface;
|
||||
use Drupal\search_api\Processor\ConfigurablePropertyInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
@@ -44,11 +45,11 @@ class FieldConfigurationForm extends EntityForm {
|
||||
protected $formIdAttribute;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* The messenger.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'search_api_field_config';
|
||||
}
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* Constructs a FieldConfigurationForm object.
|
||||
@@ -61,12 +62,15 @@ class FieldConfigurationForm extends EntityForm {
|
||||
* The date formatter.
|
||||
* @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
|
||||
* The request stack.
|
||||
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
|
||||
* The messenger.
|
||||
*/
|
||||
public function __construct(EntityTypeManagerInterface $entity_type_manager, RendererInterface $renderer, DateFormatterInterface $date_formatter, RequestStack $request_stack) {
|
||||
public function __construct(EntityTypeManagerInterface $entity_type_manager, RendererInterface $renderer, DateFormatterInterface $date_formatter, RequestStack $request_stack, MessengerInterface $messenger) {
|
||||
$this->entityTypeManager = $entity_type_manager;
|
||||
$this->renderer = $renderer;
|
||||
$this->dateFormatter = $date_formatter;
|
||||
$this->requestStack = $request_stack;
|
||||
$this->messenger = $messenger;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,8 +81,23 @@ class FieldConfigurationForm extends EntityForm {
|
||||
$renderer = $container->get('renderer');
|
||||
$date_formatter = $container->get('date.formatter');
|
||||
$request_stack = $container->get('request_stack');
|
||||
$messenger = $container->get('messenger');
|
||||
|
||||
return new static($entity_type_manager, $renderer, $date_formatter, $request_stack);
|
||||
return new static($entity_type_manager, $renderer, $date_formatter, $request_stack, $messenger);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getBaseFormId() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'search_api_field_config';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -179,7 +198,7 @@ class FieldConfigurationForm extends EntityForm {
|
||||
$property = $field->getDataDefinition();
|
||||
$property->submitConfigurationForm($field, $form, $form_state);
|
||||
|
||||
drupal_set_message($this->t('The field configuration was successfully saved.'));
|
||||
$this->messenger->addStatus($this->t('The field configuration was successfully saved.'));
|
||||
if ($this->getRequest()->query->get('modal_redirect')) {
|
||||
$url = $this->entity->toUrl('add-fields-ajax')
|
||||
->setOption('query', [
|
||||
|
||||
@@ -10,6 +10,7 @@ use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\Entity\TypedData\EntityDataDefinitionInterface;
|
||||
use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\Core\Render\RendererInterface;
|
||||
use Drupal\Core\TypedData\ComplexDataDefinitionInterface;
|
||||
use Drupal\Core\TypedData\DataReferenceDefinitionInterface;
|
||||
@@ -75,18 +76,11 @@ class IndexAddFieldsForm extends EntityForm {
|
||||
protected $formIdAttribute;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* The messenger.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'search_api_index_add_fields';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getBaseFormId() {
|
||||
return NULL;
|
||||
}
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* Constructs an IndexAddFieldsForm object.
|
||||
@@ -101,15 +95,18 @@ class IndexAddFieldsForm extends EntityForm {
|
||||
* The renderer to use.
|
||||
* @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
|
||||
* The date formatter.
|
||||
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
|
||||
* The messenger.
|
||||
* @param array $parameters
|
||||
* The parameters for this page request.
|
||||
*/
|
||||
public function __construct(EntityTypeManagerInterface $entity_type_manager, FieldsHelperInterface $fields_helper, DataTypeHelperInterface $data_type_helper, RendererInterface $renderer, DateFormatterInterface $date_formatter, array $parameters) {
|
||||
public function __construct(EntityTypeManagerInterface $entity_type_manager, FieldsHelperInterface $fields_helper, DataTypeHelperInterface $data_type_helper, RendererInterface $renderer, DateFormatterInterface $date_formatter, MessengerInterface $messenger, array $parameters) {
|
||||
$this->entityTypeManager = $entity_type_manager;
|
||||
$this->fieldsHelper = $fields_helper;
|
||||
$this->dataTypeHelper = $data_type_helper;
|
||||
$this->renderer = $renderer;
|
||||
$this->dateFormatter = $date_formatter;
|
||||
$this->messenger = $messenger;
|
||||
$this->parameters = $parameters;
|
||||
}
|
||||
|
||||
@@ -123,9 +120,24 @@ class IndexAddFieldsForm extends EntityForm {
|
||||
$renderer = $container->get('renderer');
|
||||
$date_formatter = $container->get('date.formatter');
|
||||
$request_stack = $container->get('request_stack');
|
||||
$messenger = $container->get('messenger');
|
||||
$parameters = $request_stack->getCurrentRequest()->query->all();
|
||||
|
||||
return new static($entity_type_manager, $fields_helper, $data_type_helper, $renderer, $date_formatter, $parameters);
|
||||
return new static($entity_type_manager, $fields_helper, $data_type_helper, $renderer, $date_formatter, $messenger, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getBaseFormId() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'search_api_index_add_fields';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -480,7 +492,7 @@ class IndexAddFieldsForm extends EntityForm {
|
||||
}
|
||||
|
||||
$args['%label'] = $field->getLabel();
|
||||
drupal_set_message($this->t('Field %label was added to the index.', $args));
|
||||
$this->messenger->addStatus($this->t('Field %label was added to the index.', $args));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,8 +5,9 @@ namespace Drupal\search_api\Form;
|
||||
use Drupal\Core\Entity\EntityConfirmFormBase;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\Core\Render\RendererInterface;
|
||||
use Drupal\user\SharedTempStoreFactory;
|
||||
use Drupal\Core\TempStore\SharedTempStoreFactory;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
@@ -14,10 +15,17 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
*/
|
||||
class IndexBreakLockForm extends EntityConfirmFormBase {
|
||||
|
||||
/**
|
||||
* The messenger.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* The shared temporary storage for unsaved search indexes.
|
||||
*
|
||||
* @var \Drupal\user\SharedTempStore
|
||||
* @var \Drupal\Core\TempStore\SharedTempStore
|
||||
*/
|
||||
protected $tempStore;
|
||||
|
||||
@@ -38,28 +46,32 @@ class IndexBreakLockForm extends EntityConfirmFormBase {
|
||||
/**
|
||||
* Constructs an IndexBreakLockForm object.
|
||||
*
|
||||
* @param \Drupal\user\SharedTempStoreFactory $temp_store_factory
|
||||
* @param \Drupal\Core\TempStore\SharedTempStoreFactory $temp_store_factory
|
||||
* The factory for shared temporary storages.
|
||||
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
|
||||
* The Entity manager.
|
||||
* @param \Drupal\Core\Render\RendererInterface $renderer
|
||||
* The renderer to use.
|
||||
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
|
||||
* The messenger.
|
||||
*/
|
||||
public function __construct(SharedTempStoreFactory $temp_store_factory, EntityTypeManagerInterface $entity_type_manager, RendererInterface $renderer) {
|
||||
public function __construct(SharedTempStoreFactory $temp_store_factory, EntityTypeManagerInterface $entity_type_manager, RendererInterface $renderer, MessengerInterface $messenger) {
|
||||
$this->tempStore = $temp_store_factory->get('search_api_index');
|
||||
$this->entityTypeManager = $entity_type_manager;
|
||||
$this->renderer = $renderer;
|
||||
$this->messenger = $messenger;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
$temp_store_factory = $container->get('user.shared_tempstore');
|
||||
$temp_store_factory = $container->get('tempstore.shared');
|
||||
$entity_type_manager = $container->get('entity_type.manager');
|
||||
$renderer = $container->get('renderer');
|
||||
$messenger = $container->get('messenger');
|
||||
|
||||
return new static($temp_store_factory, $entity_type_manager, $renderer);
|
||||
return new static($temp_store_factory, $entity_type_manager, $renderer, $messenger);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,7 +132,7 @@ class IndexBreakLockForm extends EntityConfirmFormBase {
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
$this->tempStore->delete($this->entity->id());
|
||||
$form_state->setRedirectUrl($this->entity->toUrl('fields'));
|
||||
drupal_set_message($this->t('The lock has been broken. You may now edit this search index.'));
|
||||
$this->messenger->addStatus($this->t('The lock has been broken. You may now edit this search index.'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,12 +7,24 @@ use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Core\Utility\Error;
|
||||
use Drupal\search_api\SearchApiException;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Defines a confirm form for clearing an index.
|
||||
*/
|
||||
class IndexClearConfirmForm extends EntityConfirmFormBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
$form = parent::create($container);
|
||||
|
||||
$form->setMessenger($container->get('messenger'));
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -43,10 +55,11 @@ class IndexClearConfirmForm extends EntityConfirmFormBase {
|
||||
|
||||
try {
|
||||
$index->clear();
|
||||
drupal_set_message($this->t('All items were successfully deleted from search index %name.', ['%name' => $index->label()]));
|
||||
$this->messenger()
|
||||
->addStatus($this->t('All items were successfully deleted from search index %name.', ['%name' => $index->label()]));
|
||||
}
|
||||
catch (SearchApiException $e) {
|
||||
drupal_set_message($this->t('Failed to clear the search index %name.', ['%name' => $index->label()]), 'error');
|
||||
$this->messenger->addError($this->t('Failed to clear the search index %name.', ['%name' => $index->label()]));
|
||||
$message = '%type while trying to clear the index %name: @message in %function (line %line of %file)';
|
||||
$variables = [
|
||||
'%name' => $index->label(),
|
||||
|
||||
@@ -4,13 +4,41 @@ namespace Drupal\search_api\Form;
|
||||
|
||||
use Drupal\Core\Entity\EntityDeleteForm;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Defines a confirm form for deleting an index.
|
||||
*/
|
||||
class IndexDeleteConfirmForm extends EntityDeleteForm {
|
||||
|
||||
/**
|
||||
* The messenger.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* Constructs an IndexDeleteConfirmForm object.
|
||||
*
|
||||
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
|
||||
* The messenger.
|
||||
*/
|
||||
public function __construct(MessengerInterface $messenger) {
|
||||
$this->messenger = $messenger;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
$messenger = $container->get('messenger');
|
||||
|
||||
return new static($messenger);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -37,7 +65,7 @@ class IndexDeleteConfirmForm extends EntityDeleteForm {
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
$this->entity->delete();
|
||||
drupal_set_message($this->t('The search index %name has been removed.', ['%name' => $this->entity->label()]));
|
||||
$this->messenger->addStatus($this->t('The search index %name has been removed.', ['%name' => $this->entity->label()]));
|
||||
$form_state->setRedirect('search_api.overview');
|
||||
}
|
||||
|
||||
|
||||
@@ -4,13 +4,41 @@ namespace Drupal\search_api\Form;
|
||||
|
||||
use Drupal\Core\Entity\EntityConfirmFormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Defines a confirm form for disabling an index.
|
||||
*/
|
||||
class IndexDisableConfirmForm extends EntityConfirmFormBase {
|
||||
|
||||
/**
|
||||
* The messenger.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* Constructs an IndexDisableConfirmForm object.
|
||||
*
|
||||
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
|
||||
* The messenger.
|
||||
*/
|
||||
public function __construct(MessengerInterface $messenger) {
|
||||
$this->messenger = $messenger;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
$messenger = $container->get('messenger');
|
||||
|
||||
return new static($messenger);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -47,7 +75,7 @@ class IndexDisableConfirmForm extends EntityConfirmFormBase {
|
||||
$entity = $this->entity;
|
||||
|
||||
$entity->setStatus(FALSE)->save();
|
||||
drupal_set_message($this->t('The search index %name has been disabled.', ['%name' => $this->entity->label()]));
|
||||
$this->messenger->addStatus($this->t('The search index %name has been disabled.', ['%name' => $this->entity->label()]));
|
||||
$form_state->setRedirect('search_api.overview');
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ use Drupal\Core\Datetime\DateFormatterInterface;
|
||||
use Drupal\Core\Entity\EntityForm;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\Core\Render\RendererInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\search_api\DataType\DataTypePluginManager;
|
||||
@@ -16,7 +17,7 @@ use Drupal\search_api\SearchApiException;
|
||||
use Drupal\search_api\UnsavedConfigurationInterface;
|
||||
use Drupal\search_api\Utility\DataTypeHelperInterface;
|
||||
use Drupal\search_api\Utility\FieldsHelperInterface;
|
||||
use Drupal\user\SharedTempStoreFactory;
|
||||
use Drupal\Core\TempStore\SharedTempStoreFactory;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
@@ -36,7 +37,7 @@ class IndexFieldsForm extends EntityForm {
|
||||
/**
|
||||
* The shared temporary storage for unsaved search indexes.
|
||||
*
|
||||
* @var \Drupal\user\SharedTempStore
|
||||
* @var \Drupal\Core\TempStore\SharedTempStore
|
||||
*/
|
||||
protected $tempStore;
|
||||
|
||||
@@ -62,23 +63,16 @@ class IndexFieldsForm extends EntityForm {
|
||||
protected $fieldsHelper;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* The messenger.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'search_api_index_fields';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getBaseFormId() {
|
||||
return NULL;
|
||||
}
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* Constructs an IndexFieldsForm object.
|
||||
*
|
||||
* @param \Drupal\user\SharedTempStoreFactory $temp_store_factory
|
||||
* @param \Drupal\Core\TempStore\SharedTempStoreFactory $temp_store_factory
|
||||
* The factory for shared temporary storages.
|
||||
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
|
||||
* The entity type manager.
|
||||
@@ -92,8 +86,10 @@ class IndexFieldsForm extends EntityForm {
|
||||
* The data type helper.
|
||||
* @param \Drupal\search_api\Utility\FieldsHelperInterface $fields_helper
|
||||
* The fields helper.
|
||||
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
|
||||
* The messenger.
|
||||
*/
|
||||
public function __construct(SharedTempStoreFactory $temp_store_factory, EntityTypeManagerInterface $entity_type_manager, DataTypePluginManager $data_type_plugin_manager, RendererInterface $renderer, DateFormatterInterface $date_formatter, DataTypeHelperInterface $data_type_helper, FieldsHelperInterface $fields_helper) {
|
||||
public function __construct(SharedTempStoreFactory $temp_store_factory, EntityTypeManagerInterface $entity_type_manager, DataTypePluginManager $data_type_plugin_manager, RendererInterface $renderer, DateFormatterInterface $date_formatter, DataTypeHelperInterface $data_type_helper, FieldsHelperInterface $fields_helper, MessengerInterface $messenger) {
|
||||
$this->tempStore = $temp_store_factory->get('search_api_index');
|
||||
$this->entityTypeManager = $entity_type_manager;
|
||||
$this->dataTypePluginManager = $data_type_plugin_manager;
|
||||
@@ -101,21 +97,37 @@ class IndexFieldsForm extends EntityForm {
|
||||
$this->dateFormatter = $date_formatter;
|
||||
$this->dataTypeHelper = $data_type_helper;
|
||||
$this->fieldsHelper = $fields_helper;
|
||||
$this->messenger = $messenger;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
$temp_store_factory = $container->get('user.shared_tempstore');
|
||||
$temp_store_factory = $container->get('tempstore.shared');
|
||||
$entity_type_manager = $container->get('entity_type.manager');
|
||||
$data_type_plugin_manager = $container->get('plugin.manager.search_api.data_type');
|
||||
$renderer = $container->get('renderer');
|
||||
$date_formatter = $container->get('date.formatter');
|
||||
$data_type_helper = $container->get('search_api.data_type_helper');
|
||||
$fields_helper = $container->get('search_api.fields_helper');
|
||||
$messenger = $container->get('messenger');
|
||||
|
||||
return new static($temp_store_factory, $entity_type_manager, $data_type_plugin_manager, $renderer, $date_formatter, $data_type_helper, $fields_helper);
|
||||
return new static($temp_store_factory, $entity_type_manager, $data_type_plugin_manager, $renderer, $date_formatter, $data_type_helper, $fields_helper, $messenger);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getBaseFormId() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormId() {
|
||||
return 'search_api_index_fields';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -155,7 +167,7 @@ class IndexFieldsForm extends EntityForm {
|
||||
],
|
||||
];
|
||||
|
||||
$form['description']['#markup'] = $this->t('<p>The data type of a field determines how it can be used for searching and filtering. The boost is used to give additional weight to certain fields, for example titles or tags.</p> <p>For information about the data types available for indexing, see the <a href="@url">data types table</a> at the bottom of the page.</p>', ['@url' => '#search-api-data-types-table']);
|
||||
$form['description']['#markup'] = $this->t('<p>The data type of a field determines how it can be used for searching and filtering. The boost is used to give additional weight to certain fields, for example titles or tags.</p> <p>For information about the data types available for indexing, see the <a href=":url">data types table</a> at the bottom of the page.</p>', [':url' => '#search-api-data-types-table']);
|
||||
|
||||
if ($fields = $index->getFieldsByDatasource(NULL)) {
|
||||
$form['_general'] = $this->buildFieldsTable($fields);
|
||||
@@ -216,7 +228,9 @@ class IndexFieldsForm extends EntityForm {
|
||||
if ($fallback_types) {
|
||||
foreach ($fields as $field) {
|
||||
if (isset($fallback_types[$field->getType()])) {
|
||||
drupal_set_message($this->t("Some of the used data types aren't supported by the server's backend. See the <a href=\":url\">data types table</a> to find out which types are supported.", [':url' => '#search-api-data-types-table']), 'warning');
|
||||
$args = [':url' => '#search-api-data-types-table'];
|
||||
$warning = $this->t("Some of the used data types aren't supported by the server's backend. See the <a href=\":url\">data types table</a> to find out which types are supported.", $args);
|
||||
$this->messenger->addWarning($warning);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -274,6 +288,7 @@ class IndexFieldsForm extends EntityForm {
|
||||
],
|
||||
];
|
||||
|
||||
uasort($fields, [$this->fieldsHelper, 'compareFieldLabels']);
|
||||
foreach ($fields as $key => $field) {
|
||||
$build['fields'][$key]['#access'] = !$field->isHidden();
|
||||
|
||||
@@ -444,7 +459,7 @@ class IndexFieldsForm extends EntityForm {
|
||||
foreach ($field_values as $field_id => $new_settings) {
|
||||
if (!isset($fields[$field_id])) {
|
||||
$args['%field_id'] = $field_id;
|
||||
drupal_set_message($this->t('The field with ID %field_id does not exist anymore.', $args), 'warning');
|
||||
$this->messenger->addWarning($this->t('The field with ID %field_id does not exist anymore.', $args));
|
||||
continue;
|
||||
}
|
||||
$field = $fields[$field_id];
|
||||
@@ -471,9 +486,9 @@ class IndexFieldsForm extends EntityForm {
|
||||
$index->save();
|
||||
}
|
||||
|
||||
drupal_set_message($this->t('The changes were successfully saved.'));
|
||||
$this->messenger->addStatus($this->t('The changes were successfully saved.'));
|
||||
if ($this->entity->isReindexing()) {
|
||||
drupal_set_message($this->t('All content was scheduled for reindexing so the new settings can take effect.'));
|
||||
$this->messenger->addStatus($this->t('All content was scheduled for reindexing so the new settings can take effect.'));
|
||||
}
|
||||
|
||||
return SAVED_UPDATED;
|
||||
|
||||
@@ -4,13 +4,14 @@ namespace Drupal\search_api\Form;
|
||||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Core\Entity\EntityForm;
|
||||
use Drupal\Core\Entity\EntityStorageException;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\Core\Plugin\PluginFormInterface;
|
||||
use Drupal\Core\Form\SubformState;
|
||||
use Drupal\Core\Utility\Error;
|
||||
use Drupal\search_api\IndexInterface;
|
||||
use Drupal\search_api\SearchApiException;
|
||||
use Drupal\search_api\Utility\PluginHelperInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
@@ -26,6 +27,13 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
*/
|
||||
class IndexForm extends EntityForm {
|
||||
|
||||
/**
|
||||
* The messenger.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* The entity type manager.
|
||||
*
|
||||
@@ -54,10 +62,13 @@ class IndexForm extends EntityForm {
|
||||
* The entity type manager.
|
||||
* @param \Drupal\search_api\Utility\PluginHelperInterface $plugin_helper
|
||||
* The plugin helper.
|
||||
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
|
||||
* The messenger.
|
||||
*/
|
||||
public function __construct(EntityTypeManagerInterface $entity_type_manager, PluginHelperInterface $plugin_helper) {
|
||||
public function __construct(EntityTypeManagerInterface $entity_type_manager, PluginHelperInterface $plugin_helper, MessengerInterface $messenger) {
|
||||
$this->entityTypeManager = $entity_type_manager;
|
||||
$this->pluginHelper = $plugin_helper;
|
||||
$this->messenger = $messenger;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,7 +77,9 @@ class IndexForm extends EntityForm {
|
||||
public static function create(ContainerInterface $container) {
|
||||
$entity_type_manager = $container->get('entity_type.manager');
|
||||
$plugin_helper = $container->get('search_api.plugin_helper');
|
||||
return new static($entity_type_manager, $plugin_helper);
|
||||
$messenger = $container->get('messenger');
|
||||
|
||||
return new static($entity_type_manager, $plugin_helper, $messenger);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -358,7 +371,7 @@ class IndexForm extends EntityForm {
|
||||
// If the user changed the datasources and there is at least one datasource
|
||||
// config form, show a message telling the user to configure it.
|
||||
if ($selected_datasources && $show_message) {
|
||||
drupal_set_message($this->t('Please configure the used datasources.'), 'warning');
|
||||
$this->messenger->addWarning($this->t('Please configure the used datasources.'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,7 +395,7 @@ class IndexForm extends EntityForm {
|
||||
// Only notify the user of a missing tracker plugin if we're editing an
|
||||
// existing index.
|
||||
elseif (!$index->isNew()) {
|
||||
drupal_set_message($this->t('The tracker plugin is missing or invalid.'), 'error');
|
||||
$this->messenger->addError($this->t('The tracker plugin is missing or invalid.'));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -412,7 +425,7 @@ class IndexForm extends EntityForm {
|
||||
// If the user changed the tracker and the new one has a config form, show
|
||||
// a message telling the user to configure it.
|
||||
if ($selected_tracker && $selected_tracker != $tracker->getPluginId()) {
|
||||
drupal_set_message($this->t('Please configure the used tracker.'), 'warning');
|
||||
$this->messenger->addWarning($this->t('Please configure the used tracker.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -598,7 +611,7 @@ class IndexForm extends EntityForm {
|
||||
/** @var \Drupal\search_api\IndexInterface $index */
|
||||
$index = $this->getEntity();
|
||||
$index->save();
|
||||
drupal_set_message($this->t('The index was successfully saved.'));
|
||||
$this->messenger->addStatus($this->t('The index was successfully saved.'));
|
||||
$button = $form_state->getTriggeringElement();
|
||||
if (!empty($button['#redirect_to_url'])) {
|
||||
$form_state->setRedirectUrl($index->toUrl($button['#redirect_to_url']));
|
||||
@@ -607,14 +620,14 @@ class IndexForm extends EntityForm {
|
||||
$form_state->setRedirect('entity.search_api_index.canonical', ['search_api_index' => $index->id()]);
|
||||
}
|
||||
}
|
||||
catch (SearchApiException $e) {
|
||||
catch (EntityStorageException $e) {
|
||||
$form_state->setRebuild();
|
||||
|
||||
$message = '%type: @message in %function (line %line of %file).';
|
||||
$variables = Error::decodeException($e);
|
||||
$this->getLogger('search_api')->error($message, $variables);
|
||||
|
||||
drupal_set_message($this->t('The index could not be saved.'), 'error');
|
||||
$this->messenger->addError($this->t('The index could not be saved.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ use Drupal\Component\Utility\Html;
|
||||
use Drupal\Core\Entity\EntityForm;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\Core\Plugin\PluginFormInterface;
|
||||
use Drupal\Core\Form\SubformState;
|
||||
use Drupal\search_api\Processor\ProcessorInterface;
|
||||
@@ -18,6 +19,13 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
*/
|
||||
class IndexProcessorsForm extends EntityForm {
|
||||
|
||||
/**
|
||||
* The messenger.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* The index being configured.
|
||||
*
|
||||
@@ -55,11 +63,14 @@ class IndexProcessorsForm extends EntityForm {
|
||||
* The processor plugin manager.
|
||||
* @param \Psr\Log\LoggerInterface $logger
|
||||
* The logger.
|
||||
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
|
||||
* The messenger.
|
||||
*/
|
||||
public function __construct(EntityTypeManagerInterface $entity_type_manager, ProcessorPluginManager $processor_plugin_manager, LoggerInterface $logger) {
|
||||
public function __construct(EntityTypeManagerInterface $entity_type_manager, ProcessorPluginManager $processor_plugin_manager, LoggerInterface $logger, MessengerInterface $messenger) {
|
||||
$this->entityTypeManager = $entity_type_manager;
|
||||
$this->processorPluginManager = $processor_plugin_manager;
|
||||
$this->logger = $logger;
|
||||
$this->messenger = $messenger;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,8 +80,9 @@ class IndexProcessorsForm extends EntityForm {
|
||||
$entity_type_manager = $container->get('entity_type.manager');
|
||||
$processor_plugin_manager = $container->get('plugin.manager.search_api.processor');
|
||||
$logger = $container->get('logger.channel.search_api');
|
||||
$messenger = $container->get('messenger');
|
||||
|
||||
return new static($entity_type_manager, $processor_plugin_manager, $logger);
|
||||
return new static($entity_type_manager, $processor_plugin_manager, $logger, $messenger);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -322,13 +334,14 @@ class IndexProcessorsForm extends EntityForm {
|
||||
public function save(array $form, FormStateInterface $form_state) {
|
||||
if ($form_state->get('processors_changed')) {
|
||||
$save_status = parent::save($form, $form_state);
|
||||
drupal_set_message($this->t('The indexing workflow was successfully edited.'));
|
||||
$this->messenger->addStatus($this->t('The indexing workflow was successfully edited.'));
|
||||
if ($this->entity->isReindexing()) {
|
||||
drupal_set_message($this->t('All content was scheduled for reindexing so the new settings can take effect.'));
|
||||
$url = $this->entity->toUrl();
|
||||
$this->messenger->addStatus($this->t('All content was scheduled for <a href=":url">reindexing</a> so the new settings can take effect.', [':url' => $url->toString()]));
|
||||
}
|
||||
}
|
||||
else {
|
||||
drupal_set_message($this->t('No values were changed.'));
|
||||
$this->messenger->addStatus($this->t('No values were changed.'));
|
||||
$save_status = SAVED_UPDATED;
|
||||
}
|
||||
|
||||
|
||||
+14
-1
@@ -5,12 +5,24 @@ namespace Drupal\search_api\Form;
|
||||
use Drupal\Core\Entity\EntityConfirmFormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Defines a confirm form for clearing an index.
|
||||
*/
|
||||
class IndexRebuildTrackerConfirmForm extends EntityConfirmFormBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
$form = parent::create($container);
|
||||
|
||||
$form->setMessenger($container->get('messenger'));
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -39,7 +51,8 @@ class IndexRebuildTrackerConfirmForm extends EntityConfirmFormBase {
|
||||
/** @var \Drupal\search_api\IndexInterface $index */
|
||||
$index = $this->getEntity();
|
||||
$index->rebuildTracker();
|
||||
drupal_set_message($this->t('The tracking information for search index %name will be rebuilt.', ['%name' => $index->label()]));
|
||||
$this->messenger()
|
||||
->addStatus($this->t('The tracking information for search index %name will be rebuilt.', ['%name' => $index->label()]));
|
||||
$form_state->setRedirect('entity.search_api_index.canonical', ['search_api_index' => $index->id()]);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,15 +4,43 @@ namespace Drupal\search_api\Form;
|
||||
|
||||
use Drupal\Core\Entity\EntityConfirmFormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Core\Utility\Error;
|
||||
use Drupal\search_api\SearchApiException;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Defines a confirm form for reindexing an index.
|
||||
*/
|
||||
class IndexReindexConfirmForm extends EntityConfirmFormBase {
|
||||
|
||||
/**
|
||||
* The messenger.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* Constructs an IndexReindexConfirmForm object.
|
||||
*
|
||||
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
|
||||
* The messenger.
|
||||
*/
|
||||
public function __construct(MessengerInterface $messenger) {
|
||||
$this->messenger = $messenger;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
$messenger = $container->get('messenger');
|
||||
|
||||
return new static($messenger);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -43,10 +71,10 @@ class IndexReindexConfirmForm extends EntityConfirmFormBase {
|
||||
|
||||
try {
|
||||
$index->reindex();
|
||||
drupal_set_message($this->t('The search index %name was successfully reindexed.', ['%name' => $index->label()]));
|
||||
$this->messenger->addStatus($this->t('The search index %name was successfully reindexed.', ['%name' => $index->label()]));
|
||||
}
|
||||
catch (SearchApiException $e) {
|
||||
drupal_set_message($this->t('Failed to reindex items for the search index %name.', ['%name' => $index->label()]), 'error');
|
||||
$this->messenger->addError($this->t('Failed to reindex items for the search index %name.', ['%name' => $index->label()]));
|
||||
$message = '%type while trying to reindex items on index %name: @message in %function (line %line of %file)';
|
||||
$variables = [
|
||||
'%name' => $index->label(),
|
||||
|
||||
@@ -2,19 +2,46 @@
|
||||
|
||||
namespace Drupal\search_api\Form;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\search_api\IndexBatchHelper;
|
||||
use Drupal\search_api\SearchApiException;
|
||||
use Drupal\search_api\IndexInterface;
|
||||
use Drupal\search_api\Task\IndexTaskManagerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides a form for indexing, clearing, etc., an index.
|
||||
*/
|
||||
class IndexStatusForm extends FormBase {
|
||||
|
||||
/**
|
||||
* The messenger.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* Constructs an IndexStatusForm object.
|
||||
*
|
||||
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
|
||||
* The messenger.
|
||||
*/
|
||||
public function __construct(MessengerInterface $messenger) {
|
||||
$this->messenger = $messenger;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
$messenger = $container->get('messenger');
|
||||
|
||||
return new static($messenger);
|
||||
}
|
||||
|
||||
/**
|
||||
* The index task manager.
|
||||
*
|
||||
@@ -184,12 +211,12 @@ class IndexStatusForm extends FormBase {
|
||||
if ($form_state->getTriggeringElement()['#name'] === 'index_now') {
|
||||
$values = $form_state->getValues();
|
||||
// Get the translated "all" value and lowercase it for comparison.
|
||||
$all_value = Unicode::strtolower($values['all']);
|
||||
$all_value = mb_strtolower($values['all']);
|
||||
|
||||
foreach (['limit', 'batch_size'] as $field) {
|
||||
// Trim and lowercase the value so we correctly identify "all" values,
|
||||
// even if not matching exactly.
|
||||
$value = Unicode::strtolower(trim($values[$field]));
|
||||
$value = mb_strtolower(trim($values[$field]));
|
||||
|
||||
if ($value === $all_value) {
|
||||
$value = -1;
|
||||
@@ -221,7 +248,7 @@ class IndexStatusForm extends FormBase {
|
||||
IndexBatchHelper::create($index, $values['batch_size'], $values['limit']);
|
||||
}
|
||||
catch (SearchApiException $e) {
|
||||
drupal_set_message($this->t('Failed to create a batch, please check the batch size and limit.'), 'warning');
|
||||
$this->messenger->addWarning($this->t('Failed to create a batch, please check the batch size and limit.'));
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -4,15 +4,43 @@ namespace Drupal\search_api\Form;
|
||||
|
||||
use Drupal\Core\Entity\EntityConfirmFormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Core\Utility\Error;
|
||||
use Drupal\search_api\SearchApiException;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Defines a confirm form for clearing a server.
|
||||
*/
|
||||
class ServerClearConfirmForm extends EntityConfirmFormBase {
|
||||
|
||||
/**
|
||||
* The messenger.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* Constructs a ServerClearConfirmForm object.
|
||||
*
|
||||
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
|
||||
* The messenger.
|
||||
*/
|
||||
public function __construct(MessengerInterface $messenger) {
|
||||
$this->messenger = $messenger;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
$messenger = $container->get('messenger');
|
||||
|
||||
return new static($messenger);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -43,10 +71,10 @@ class ServerClearConfirmForm extends EntityConfirmFormBase {
|
||||
|
||||
try {
|
||||
$server->deleteAllItems();
|
||||
drupal_set_message($this->t('All indexed data was successfully deleted from the server.'));
|
||||
$this->messenger->addStatus($this->t('All indexed data was successfully deleted from the server.'));
|
||||
}
|
||||
catch (SearchApiException $e) {
|
||||
drupal_set_message($this->t('Indexed data could not be cleared for some indexes. Check the logs for details.'), 'error');
|
||||
$this->messenger->addError($this->t('Indexed data could not be cleared for some indexes. Check the logs for details.'));
|
||||
}
|
||||
|
||||
$failed_reindexing = [];
|
||||
@@ -74,7 +102,7 @@ class ServerClearConfirmForm extends EntityConfirmFormBase {
|
||||
$args = [
|
||||
'@indexes' => implode(', ', $failed_reindexing),
|
||||
];
|
||||
drupal_set_message($this->t('Failed to mark the following indexes for reindexing: @indexes. Check the logs for details.', $args), 'warning');
|
||||
$this->messenger->addWarning($this->t('Failed to mark the following indexes for reindexing: @indexes. Check the logs for details.', $args));
|
||||
}
|
||||
|
||||
$form_state->setRedirect('entity.search_api_server.canonical', ['search_api_server' => $server->id()]);
|
||||
|
||||
@@ -4,13 +4,41 @@ namespace Drupal\search_api\Form;
|
||||
|
||||
use Drupal\Core\Entity\EntityDeleteForm;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Defines a confirm form for deleting a server.
|
||||
*/
|
||||
class ServerDeleteConfirmForm extends EntityDeleteForm {
|
||||
|
||||
/**
|
||||
* The messenger.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* Constructs a ServerDeleteConfirmForm object.
|
||||
*
|
||||
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
|
||||
* The messenger.
|
||||
*/
|
||||
public function __construct(MessengerInterface $messenger) {
|
||||
$this->messenger = $messenger;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
$messenger = $container->get('messenger');
|
||||
|
||||
return new static($messenger);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -44,7 +72,7 @@ class ServerDeleteConfirmForm extends EntityDeleteForm {
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
$this->entity->delete();
|
||||
drupal_set_message($this->t('The search server %name has been deleted.', ['%name' => $this->entity->label()]));
|
||||
$this->messenger->addStatus($this->t('The search server %name has been deleted.', ['%name' => $this->entity->label()]));
|
||||
$form_state->setRedirect('search_api.overview');
|
||||
}
|
||||
|
||||
|
||||
@@ -4,13 +4,41 @@ namespace Drupal\search_api\Form;
|
||||
|
||||
use Drupal\Core\Entity\EntityConfirmFormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Defines a confirm form for disabling a server.
|
||||
*/
|
||||
class ServerDisableConfirmForm extends EntityConfirmFormBase {
|
||||
|
||||
/**
|
||||
* The messenger.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* Constructs a ServerDisableConfirmForm object.
|
||||
*
|
||||
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
|
||||
* The messenger.
|
||||
*/
|
||||
public function __construct(MessengerInterface $messenger) {
|
||||
$this->messenger = $messenger;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
$messenger = $container->get('messenger');
|
||||
|
||||
return new static($messenger);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -47,7 +75,7 @@ class ServerDisableConfirmForm extends EntityConfirmFormBase {
|
||||
$server = $this->entity;
|
||||
$server->setStatus(FALSE)->save();
|
||||
|
||||
drupal_set_message($this->t('The search server %name has been disabled.', ['%name' => $this->entity->label()]));
|
||||
$this->messenger->addStatus($this->t('The search server %name has been disabled.', ['%name' => $this->entity->label()]));
|
||||
$form_state->setRedirect('search_api.overview');
|
||||
}
|
||||
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
namespace Drupal\search_api\Form;
|
||||
|
||||
use Drupal\Core\Entity\EntityForm;
|
||||
use Drupal\Core\Entity\EntityStorageException;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\Core\Plugin\PluginFormInterface;
|
||||
use Drupal\Core\Form\SubformState;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Core\Utility\Error;
|
||||
use Drupal\search_api\Backend\BackendPluginManager;
|
||||
use Drupal\search_api\SearchApiException;
|
||||
use Drupal\search_api\ServerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
@@ -25,21 +26,34 @@ class ServerForm extends EntityForm {
|
||||
*/
|
||||
protected $backendPluginManager;
|
||||
|
||||
/**
|
||||
* The messenger.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* Constructs a ServerForm object.
|
||||
*
|
||||
* @param \Drupal\search_api\Backend\BackendPluginManager $backend_plugin_manager
|
||||
* The backend plugin manager.
|
||||
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
|
||||
* The messenger.
|
||||
*/
|
||||
public function __construct(BackendPluginManager $backend_plugin_manager) {
|
||||
public function __construct(BackendPluginManager $backend_plugin_manager, MessengerInterface $messenger) {
|
||||
$this->backendPluginManager = $backend_plugin_manager;
|
||||
$this->messenger = $messenger;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static($container->get('plugin.manager.search_api.backend'));
|
||||
$backend_plugin_manager = $container->get('plugin.manager.search_api.backend');
|
||||
$messenger = $container->get('messenger');
|
||||
|
||||
return new static($backend_plugin_manager, $messenger);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -154,7 +168,10 @@ class ServerForm extends EntityForm {
|
||||
$form['backend'] += $descriptions;
|
||||
}
|
||||
else {
|
||||
drupal_set_message($this->t('There are no backend plugins available for the Search API. Please install a <a href=":url">module that provides a backend plugin</a> to proceed.', [':url' => Url::fromUri('https://www.drupal.org/node/1254698')->toString()]), 'error');
|
||||
$url = 'https://www.drupal.org/node/1254698';
|
||||
$args[':url'] = Url::fromUri($url)->toString();
|
||||
$error = $this->t('There are no backend plugins available for the Search API. Please install a <a href=":url">module that provides a backend plugin</a> to proceed.', $args);
|
||||
$this->messenger->addError($error);
|
||||
$form = [];
|
||||
}
|
||||
}
|
||||
@@ -176,7 +193,7 @@ class ServerForm extends EntityForm {
|
||||
$form_state->set('backend', $backend->getPluginId());
|
||||
if ($backend instanceof PluginFormInterface) {
|
||||
if ($form_state->isRebuilding()) {
|
||||
drupal_set_message($this->t('Please configure the selected backend.'), 'warning');
|
||||
$this->messenger->addWarning($this->t('Please configure the selected backend.'));
|
||||
}
|
||||
// Attach the backend plugin configuration form.
|
||||
$backend_form_state = SubformState::createForSubform($form['backend_config'], $form, $form_state);
|
||||
@@ -191,7 +208,7 @@ class ServerForm extends EntityForm {
|
||||
// Only notify the user of a missing backend plugin if we're editing an
|
||||
// existing server.
|
||||
elseif (!$server->isNew()) {
|
||||
drupal_set_message($this->t('The backend plugin is missing or invalid.'), 'error');
|
||||
$this->messenger->addError($this->t('The backend plugin is missing or invalid.'));
|
||||
return;
|
||||
}
|
||||
$form['backend_config'] += [
|
||||
@@ -282,17 +299,17 @@ class ServerForm extends EntityForm {
|
||||
try {
|
||||
$server = $this->getEntity();
|
||||
$server->save();
|
||||
drupal_set_message($this->t('The server was successfully saved.'));
|
||||
$this->messenger->addStatus($this->t('The server was successfully saved.'));
|
||||
$form_state->setRedirect('entity.search_api_server.canonical', ['search_api_server' => $server->id()]);
|
||||
}
|
||||
catch (SearchApiException $e) {
|
||||
catch (EntityStorageException $e) {
|
||||
$form_state->setRebuild();
|
||||
|
||||
$message = '%type: @message in %function (line %line of %file).';
|
||||
$variables = Error::decodeException($e);
|
||||
$this->getLogger('search_api')->error($message, $variables);
|
||||
|
||||
drupal_set_message($this->t('The server could not be saved.'), 'error');
|
||||
$this->messenger->addError($this->t('The server could not be saved.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,23 +187,23 @@ class IndexBatchHelper {
|
||||
// Build the indexed message.
|
||||
$indexed_message = static::formatPlural($results['indexed'], 'Successfully indexed 1 item.', 'Successfully indexed @count items.');
|
||||
// Notify user about indexed items.
|
||||
drupal_set_message($indexed_message);
|
||||
\Drupal::messenger()->addStatus($indexed_message);
|
||||
// Display the number of items not indexed.
|
||||
if (!empty($results['not indexed'])) {
|
||||
// Build the not indexed message.
|
||||
$not_indexed_message = static::formatPlural($results['not indexed'], '1 item could not be indexed. Check the logs for details.', '@count items could not be indexed. Check the logs for details.');
|
||||
// Notify user about not indexed items.
|
||||
drupal_set_message($not_indexed_message, 'warning');
|
||||
\Drupal::messenger()->addWarning($not_indexed_message);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Notify user about failure to index items.
|
||||
drupal_set_message(static::t("Couldn't index items. Check the logs for details."), 'error');
|
||||
\Drupal::messenger()->addError(static::t("Couldn't index items. Check the logs for details."));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Notify user about batch job failure.
|
||||
drupal_set_message(static::t('An error occurred while trying to index items. Check the logs for details.'), 'error');
|
||||
\Drupal::messenger()->addError(static::t('An error occurred while trying to index items. Check the logs for details.'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -399,18 +399,15 @@ interface IndexInterface extends ConfigEntityInterface {
|
||||
/**
|
||||
* Adds a field to this index.
|
||||
*
|
||||
* If the field is already present (with the same datasource and property
|
||||
* path) its settings will be updated.
|
||||
*
|
||||
* @param \Drupal\search_api\Item\FieldInterface $field
|
||||
* The field to add, or update.
|
||||
* The field to add.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws \Drupal\search_api\SearchApiException
|
||||
* Thrown if the field could not be added, either because a different field
|
||||
* with the same field ID would be overwritten, or because the field
|
||||
* identifier is one of the pseudo-fields that can be used in search
|
||||
* Thrown if the field could not be added, either because a field with the
|
||||
* same field ID already exists, or because the field identifier is one of
|
||||
* the reserved field IDs of pseudo-fields that can be used in search
|
||||
* queries.
|
||||
*/
|
||||
public function addField(FieldInterface $field);
|
||||
|
||||
+3
-3
@@ -8,7 +8,7 @@ use Drupal\Core\ParamConverter\EntityConverter;
|
||||
use Drupal\Core\ParamConverter\ParamConverterInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\search_api\UnsavedIndexConfiguration;
|
||||
use Drupal\user\SharedTempStoreFactory;
|
||||
use Drupal\Core\TempStore\SharedTempStoreFactory;
|
||||
use Symfony\Component\Routing\Route;
|
||||
|
||||
/**
|
||||
@@ -24,7 +24,7 @@ class SearchApiConverter extends EntityConverter implements ParamConverterInterf
|
||||
/**
|
||||
* The shared temporary storage factory.
|
||||
*
|
||||
* @var \Drupal\user\SharedTempStoreFactory
|
||||
* @var \Drupal\Core\TempStore\SharedTempStoreFactory
|
||||
*/
|
||||
protected $tempStoreFactory;
|
||||
|
||||
@@ -40,7 +40,7 @@ class SearchApiConverter extends EntityConverter implements ParamConverterInterf
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
* @param \Drupal\user\SharedTempStoreFactory $temp_store_factory
|
||||
* @param \Drupal\Core\TempStore\SharedTempStoreFactory $temp_store_factory
|
||||
* The factory for the temp store object.
|
||||
* @param \Drupal\Core\Session\AccountInterface $user
|
||||
* The current user.
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Drupal\search_api\Plugin\DataType;
|
||||
*
|
||||
* @DataType(
|
||||
* id = "search_api_html",
|
||||
* label = @Translation("Text (Search API)")
|
||||
* label = @Translation("HTML text (Search API)")
|
||||
* )
|
||||
*/
|
||||
class Html extends Text {}
|
||||
|
||||
+15
@@ -16,4 +16,19 @@ use Drupal\search_api\DataType\DataTypePluginBase;
|
||||
*/
|
||||
class DateDataType extends DataTypePluginBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getValue($value) {
|
||||
if ((string) $value === '') {
|
||||
return NULL;
|
||||
}
|
||||
if (is_numeric($value)) {
|
||||
return (int) $value;
|
||||
}
|
||||
$timezone = new \DateTimezone('UTC');
|
||||
$date = new \Datetime($value, $timezone);
|
||||
return $date->getTimestamp();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+9
-16
@@ -809,12 +809,8 @@ class ContentEntity extends DatasourcePluginBase implements EntityDatasourceInte
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getViewModes($bundle = NULL) {
|
||||
if (isset($bundle) && $this->hasBundles()) {
|
||||
return $this->getEntityDisplayRepository()->getViewModeOptionsByBundle($this->getEntityTypeId(), $bundle);
|
||||
}
|
||||
else {
|
||||
return $this->getEntityDisplayRepository()->getViewModeOptions($this->getEntityTypeId());
|
||||
}
|
||||
return $this->getEntityDisplayRepository()
|
||||
->getViewModeOptions($this->getEntityTypeId());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -841,7 +837,8 @@ class ContentEntity extends DatasourcePluginBase implements EntityDatasourceInte
|
||||
*/
|
||||
public function viewMultipleItems(array $items, $view_mode, $langcode = NULL) {
|
||||
try {
|
||||
$view_builder = $this->getEntityTypeManager()->getViewBuilder($this->getEntityTypeId());
|
||||
$view_builder = $this->getEntityTypeManager()
|
||||
->getViewBuilder($this->getEntityTypeId());
|
||||
// Langcode passed, use that for viewing.
|
||||
if (isset($langcode)) {
|
||||
$entities = [];
|
||||
@@ -858,8 +855,8 @@ class ContentEntity extends DatasourcePluginBase implements EntityDatasourceInte
|
||||
// Otherwise, separate the items by language, keeping the keys.
|
||||
$items_by_language = [];
|
||||
foreach ($items as $i => $item) {
|
||||
if ($item instanceof EntityInterface) {
|
||||
$items_by_language[$item->language()->getId()][$i] = $item;
|
||||
if ($entity = $this->getEntity($item)) {
|
||||
$items_by_language[$entity->language()->getId()][$i] = $entity;
|
||||
}
|
||||
}
|
||||
// Then build the items for each language. We initialize $build beforehand
|
||||
@@ -969,7 +966,7 @@ class ContentEntity extends DatasourcePluginBase implements EntityDatasourceInte
|
||||
$indexes = Index::loadMultiple();
|
||||
|
||||
foreach ($indexes as $index_id => $index) {
|
||||
// Filter our indexes that don't contain the datasource in question.
|
||||
// Filter out indexes that don't contain the datasource in question.
|
||||
if (!$index->isValidDatasource($datasource_id)) {
|
||||
unset($indexes[$index_id]);
|
||||
}
|
||||
@@ -977,9 +974,7 @@ class ContentEntity extends DatasourcePluginBase implements EntityDatasourceInte
|
||||
// If the entity type supports bundles, we also have to filter out
|
||||
// indexes that exclude the entity's bundle.
|
||||
$config = $index->getDatasource($datasource_id)->getConfiguration();
|
||||
$default = !empty($config['bundles']['default']);
|
||||
$bundle_set = in_array($entity_bundle, $config['bundles']['selected']);
|
||||
if ($default == $bundle_set) {
|
||||
if (!Utility::matches($entity_bundle, $config['bundles'])) {
|
||||
unset($indexes[$index_id]);
|
||||
}
|
||||
}
|
||||
@@ -1017,8 +1012,6 @@ class ContentEntity extends DatasourcePluginBase implements EntityDatasourceInte
|
||||
if (!isset($config['languages']['selected'])) {
|
||||
return $item_ids;
|
||||
}
|
||||
$default = !empty($config['languages']['default']);
|
||||
$selected = $config['languages']['selected'];
|
||||
$always_valid = [
|
||||
LanguageInterface::LANGCODE_NOT_SPECIFIED,
|
||||
LanguageInterface::LANGCODE_NOT_APPLICABLE,
|
||||
@@ -1031,7 +1024,7 @@ class ContentEntity extends DatasourcePluginBase implements EntityDatasourceInte
|
||||
continue;
|
||||
}
|
||||
$langcode = substr($item_id, $pos + 1);
|
||||
if ($default != in_array($langcode, $selected)
|
||||
if (Utility::matches($langcode, $config['languages'])
|
||||
|| in_array($langcode, $always_valid)) {
|
||||
$valid_ids[] = $item_id;
|
||||
}
|
||||
|
||||
+2
-2
@@ -55,8 +55,8 @@ class ContentEntityTaskManager implements EventSubscriberInterface {
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getSubscribedEvents() {
|
||||
$events['search_api.task.' . static::INSERT_ITEMS_TASK_TYPE][] = ['processEvent'];
|
||||
$events['search_api.task.' . static::DELETE_ITEMS_TASK_TYPE][] = ['processEvent'];
|
||||
$events['search_api.task.' . self::INSERT_ITEMS_TASK_TYPE][] = ['processEvent'];
|
||||
$events['search_api.task.' . self::DELETE_ITEMS_TASK_TYPE][] = ['processEvent'];
|
||||
|
||||
return $events;
|
||||
}
|
||||
|
||||
+1
-1
@@ -120,7 +120,7 @@ class AddHierarchy extends ProcessorPluginBase implements PluginFormInterface {
|
||||
$property_label = $property->getLabel();
|
||||
$property = $this->getFieldsHelper()->getInnerProperty($property);
|
||||
if ($property instanceof EntityDataDefinitionInterface) {
|
||||
$options = self::findHierarchicalProperties($property, $property_label);
|
||||
$options = static::findHierarchicalProperties($property, $property_label);
|
||||
if ($options) {
|
||||
$field_options += [$field_id => []];
|
||||
$field_options[$field_id] += $options;
|
||||
|
||||
+2
-1
@@ -49,8 +49,9 @@ class AddURL extends ProcessorPluginBase {
|
||||
$url = $item->getDatasource()->getItemUrl($item->getOriginalObject());
|
||||
if ($url) {
|
||||
$url = $url->toString();
|
||||
$fields = $item->getFields(FALSE);
|
||||
$fields = $this->getFieldsHelper()
|
||||
->filterForPropertyPath($item->getFields(), NULL, 'search_api_url');
|
||||
->filterForPropertyPath($fields, NULL, 'search_api_url');
|
||||
foreach ($fields as $field) {
|
||||
$field->addValue($url);
|
||||
}
|
||||
|
||||
+24
-18
@@ -63,14 +63,14 @@ class Highlight extends ProcessorPluginBase implements PluginFormInterface {
|
||||
public function __construct(array $configuration, $plugin_id, array $plugin_definition) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
|
||||
if (!isset(self::$boundary)) {
|
||||
if (!isset(static::$boundary)) {
|
||||
$cjk = '\x{1100}-\x{11FF}\x{3040}-\x{309F}\x{30A1}-\x{318E}' .
|
||||
'\x{31A0}-\x{31B7}\x{31F0}-\x{31FF}\x{3400}-\x{4DBF}\x{4E00}-\x{9FCF}' .
|
||||
'\x{A000}-\x{A48F}\x{A4D0}-\x{A4FD}\x{A960}-\x{A97F}\x{AC00}-\x{D7FF}' .
|
||||
'\x{F900}-\x{FAFF}\x{FF21}-\x{FF3A}\x{FF41}-\x{FF5A}\x{FF66}-\x{FFDC}' .
|
||||
'\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}';
|
||||
self::$boundary = '(?:(?<=[' . Unicode::PREG_CLASS_WORD_BOUNDARY . $cjk . '])|(?=[' . Unicode::PREG_CLASS_WORD_BOUNDARY . $cjk . ']))';
|
||||
self::$split = '/[' . Unicode::PREG_CLASS_WORD_BOUNDARY . ']+/iu';
|
||||
static::$boundary = '(?:(?<=[' . Unicode::PREG_CLASS_WORD_BOUNDARY . $cjk . '])|(?=[' . Unicode::PREG_CLASS_WORD_BOUNDARY . $cjk . ']))';
|
||||
static::$split = '/[' . Unicode::PREG_CLASS_WORD_BOUNDARY . ']+/iu';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,9 +257,6 @@ class Highlight extends ProcessorPluginBase implements PluginFormInterface {
|
||||
$highlighted_fields = $this->highlightFields($result_items, $keys);
|
||||
foreach ($highlighted_fields as $item_id => $item_fields) {
|
||||
$item = $result_items[$item_id];
|
||||
// Maybe the backend or some other processor has already set highlighted
|
||||
// field values.
|
||||
$item_fields += $item->getExtraData('highlighted_fields', []);
|
||||
$item->setExtraData('highlighted_fields', $item_fields);
|
||||
}
|
||||
}
|
||||
@@ -303,19 +300,28 @@ class Highlight extends ProcessorPluginBase implements PluginFormInterface {
|
||||
* highlighted versions of the values for that field.
|
||||
*/
|
||||
protected function highlightFields(array $results, array $keys) {
|
||||
$item_fields = $this->getFulltextFields($results, NULL, $this->configuration['highlight'] == 'always');
|
||||
$highlighted_fields = [];
|
||||
foreach ($results as $item_id => $item) {
|
||||
// Maybe the backend or some other processor has already set highlighted
|
||||
// field values.
|
||||
$highlighted_fields[$item_id] = $item->getExtraData('highlighted_fields', []);
|
||||
}
|
||||
|
||||
$load = $this->configuration['highlight'] == 'always';
|
||||
$item_fields = $this->getFulltextFields($results, NULL, $load);
|
||||
foreach ($item_fields as $item_id => $fields) {
|
||||
foreach ($fields as $field_id => $values) {
|
||||
$change = FALSE;
|
||||
foreach ($values as $i => $value) {
|
||||
$values[$i] = $this->highlightField($value, $keys);
|
||||
if ($values[$i] !== $value) {
|
||||
$change = TRUE;
|
||||
if (empty($highlighted_fields[$item_id][$field_id])) {
|
||||
$change = FALSE;
|
||||
foreach ($values as $i => $value) {
|
||||
$values[$i] = $this->highlightField($value, $keys);
|
||||
if ($values[$i] !== $value) {
|
||||
$change = TRUE;
|
||||
}
|
||||
}
|
||||
if ($change) {
|
||||
$highlighted_fields[$item_id][$field_id] = $values;
|
||||
}
|
||||
}
|
||||
if ($change) {
|
||||
$highlighted_fields[$item_id][$field_id] = $values;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -373,7 +379,7 @@ class Highlight extends ProcessorPluginBase implements PluginFormInterface {
|
||||
return $this->flattenKeysArray($keys);
|
||||
}
|
||||
|
||||
$keywords_in = preg_split(self::$split, $keys);
|
||||
$keywords_in = preg_split(static::$split, $keys);
|
||||
// Assure there are no duplicates. (This is actually faster than
|
||||
// array_unique() by a factor of 3 to 4.)
|
||||
// Remove quotes from keywords.
|
||||
@@ -474,7 +480,7 @@ class Highlight extends ProcessorPluginBase implements PluginFormInterface {
|
||||
|
||||
if (!$this->configuration['highlight_partial']) {
|
||||
$found_position = FALSE;
|
||||
$regex = '/' . self::$boundary . preg_quote($key, '/') . self::$boundary . '/iu';
|
||||
$regex = '/' . static::$boundary . preg_quote($key, '/') . static::$boundary . '/iu';
|
||||
if (preg_match($regex, ' ' . $text . ' ', $matches, PREG_OFFSET_CAPTURE, $look_start[$key])) {
|
||||
$found_position = $matches[0][1];
|
||||
}
|
||||
@@ -602,7 +608,7 @@ class Highlight extends ProcessorPluginBase implements PluginFormInterface {
|
||||
$keys = implode('|', array_map('preg_quote', $keys, array_fill(0, count($keys), '/')));
|
||||
// If "Highlight partial matches" is disabled, we only want to highlight
|
||||
// matches that are complete words. Otherwise, we want all of them.
|
||||
$boundary = !$this->configuration['highlight_partial'] ? self::$boundary : '';
|
||||
$boundary = !$this->configuration['highlight_partial'] ? static::$boundary : '';
|
||||
$regex = '/' . $boundary . '(?:' . $keys . ')' . $boundary . '/iu';
|
||||
$replace = $this->configuration['prefix'] . '\0' . $this->configuration['suffix'];
|
||||
$text = preg_replace($regex, $replace, ' ' . $text . ' ');
|
||||
|
||||
+1
-2
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Drupal\search_api\Plugin\search_api\processor;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\search_api\Item\FieldInterface;
|
||||
use Drupal\search_api\Plugin\search_api\data_type\value\TextValueInterface;
|
||||
use Drupal\search_api\Processor\FieldsProcessorPluginBase;
|
||||
@@ -42,7 +41,7 @@ class IgnoreCase extends FieldsProcessorPluginBase {
|
||||
protected function process(&$value) {
|
||||
// We don't touch integers, NULL values or the like.
|
||||
if (is_string($value)) {
|
||||
$value = Unicode::strtolower($value);
|
||||
$value = mb_strtolower($value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -205,7 +205,7 @@ class Tokenizer extends FieldsProcessorPluginBase {
|
||||
|
||||
$value = [];
|
||||
foreach ($arr as $token) {
|
||||
if (is_numeric($token) || Unicode::strlen($token) >= $this->configuration['minimum_word_size']) {
|
||||
if (is_numeric($token) || mb_strlen($token) >= $this->configuration['minimum_word_size']) {
|
||||
$value[] = Utility::createTextToken($token);
|
||||
}
|
||||
}
|
||||
@@ -277,7 +277,7 @@ class Tokenizer extends FieldsProcessorPluginBase {
|
||||
protected function expandCjk(array $matches) {
|
||||
$min = $this->configuration['minimum_word_size'];
|
||||
$str = $matches[0];
|
||||
$length = Unicode::strlen($str);
|
||||
$length = mb_strlen($str);
|
||||
// If the text is shorter than the minimum word size, don't tokenize it.
|
||||
if ($length <= $min) {
|
||||
return ' ' . $str . ' ';
|
||||
@@ -287,7 +287,7 @@ class Tokenizer extends FieldsProcessorPluginBase {
|
||||
$chars = [];
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
// Add the next character off the beginning of the string to the queue.
|
||||
$current = Unicode::substr($str, 0, 1);
|
||||
$current = mb_substr($str, 0, 1);
|
||||
$str = substr($str, strlen($current));
|
||||
$chars[] = $current;
|
||||
if ($i >= $min - 1) {
|
||||
|
||||
@@ -271,7 +271,7 @@ class Basic extends TrackerPluginBase implements PluginFormInterface {
|
||||
// (Otherwise, an item that's regularly being updated might never get
|
||||
// indexed.)
|
||||
if ($this->configuration['indexing_order'] === 'fifo') {
|
||||
$update->condition('status', static::STATUS_INDEXED);
|
||||
$update->condition('status', self::STATUS_INDEXED);
|
||||
}
|
||||
$update->execute();
|
||||
}
|
||||
|
||||
@@ -78,14 +78,9 @@ class SearchApiDate extends Date {
|
||||
];
|
||||
}
|
||||
|
||||
// Store this because it will get overwritten by the grandparent, and the
|
||||
// parent doesn't always restore it correctly.
|
||||
$type = $this->value['type'];
|
||||
$return = parent::acceptExposedInput($input);
|
||||
|
||||
if (!$return) {
|
||||
// If the parent returns FALSE, it doesn't restore the "type" key.
|
||||
$this->value['type'] = $type;
|
||||
// Override for the "(not) empty" operators.
|
||||
$operators = $this->operators();
|
||||
if ($operators[$this->operator]['values'] == 0) {
|
||||
|
||||
+23
-6
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Drupal\search_api\Plugin\views\filter;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Render\Element;
|
||||
use Drupal\search_api\Entity\Index;
|
||||
@@ -123,11 +122,11 @@ class SearchApiFulltext extends FilterPluginBase {
|
||||
public function defineOptions() {
|
||||
$options = parent::defineOptions();
|
||||
|
||||
$options['parse_mode'] = ['default' => 'terms'];
|
||||
$options['operator']['default'] = 'and';
|
||||
|
||||
$options['min_length']['default'] = '';
|
||||
$options['fields']['default'] = [];
|
||||
$options['parse_mode'] = ['default' => 'terms'];
|
||||
$options['min_length'] = ['default' => ''];
|
||||
$options['fields'] = ['default' => []];
|
||||
$options['expose']['contains']['placeholder'] = ['default' => ''];
|
||||
|
||||
return $options;
|
||||
}
|
||||
@@ -188,6 +187,21 @@ class SearchApiFulltext extends FilterPluginBase {
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildExposeForm(&$form, FormStateInterface $form_state) {
|
||||
parent::buildExposeForm($form, $form_state);
|
||||
|
||||
$form['expose']['placeholder'] = [
|
||||
'#type' => 'textfield',
|
||||
'#default_value' => $this->options['expose']['placeholder'],
|
||||
'#title' => $this->t('Placeholder'),
|
||||
'#size' => 40,
|
||||
'#description' => $this->t('Hint text that appears inside the field when empty.'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -200,6 +214,9 @@ class SearchApiFulltext extends FilterPluginBase {
|
||||
'#size' => 30,
|
||||
'#default_value' => $this->value,
|
||||
];
|
||||
if (!empty($this->options['expose']['placeholder'])) {
|
||||
$form['value']['#attributes']['placeholder'] = $this->options['expose']['placeholder'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -254,7 +271,7 @@ class SearchApiFulltext extends FilterPluginBase {
|
||||
|
||||
$words = preg_split('/\s+/', $input);
|
||||
foreach ($words as $i => $word) {
|
||||
if (Unicode::strlen($word) < $this->options['min_length']) {
|
||||
if (mb_strlen($word) < $this->options['min_length']) {
|
||||
unset($words[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ class SearchApiLanguage extends LanguageFilter {
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query() {
|
||||
$substitutions = self::queryLanguageSubstitutions();
|
||||
$substitutions = static::queryLanguageSubstitutions();
|
||||
foreach ($this->value as $i => $value) {
|
||||
if (isset($substitutions[$value])) {
|
||||
$this->value[$i] = $substitutions[$value];
|
||||
|
||||
+33
-1
@@ -9,6 +9,7 @@ use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\search_api\Entity\Index;
|
||||
use Drupal\search_api\LoggerTrait;
|
||||
@@ -115,6 +116,13 @@ class SearchApiQuery extends QueryPluginBase {
|
||||
*/
|
||||
protected $moduleHandler;
|
||||
|
||||
/**
|
||||
* The messenger.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface|null
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -123,6 +131,7 @@ class SearchApiQuery extends QueryPluginBase {
|
||||
$plugin = parent::create($container, $configuration, $plugin_id, $plugin_definition);
|
||||
|
||||
$plugin->setModuleHandler($container->get('module_handler'));
|
||||
$plugin->setMessenger($container->get('messenger'));
|
||||
$plugin->setLogger($container->get('logger.channel.search_api'));
|
||||
|
||||
return $plugin;
|
||||
@@ -208,6 +217,29 @@ class SearchApiQuery extends QueryPluginBase {
|
||||
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}
|
||||
*/
|
||||
@@ -427,7 +459,7 @@ class SearchApiQuery extends QueryPluginBase {
|
||||
if ($this->shouldAbort()) {
|
||||
if (error_displayable()) {
|
||||
foreach ($this->errors as $msg) {
|
||||
drupal_set_message(Html::escape($msg), 'error');
|
||||
$this->getMessenger()->addError(Html::escape($msg));
|
||||
}
|
||||
}
|
||||
$view->result = [];
|
||||
|
||||
+3
-3
@@ -427,9 +427,9 @@ abstract class FieldsProcessorPluginBase extends ProcessorPluginBase implements
|
||||
// value can't be in the index – but that's irrelevant for (NOT)
|
||||
// BETWEEN conditions, as any value between the two bounds could still
|
||||
// be included. We therefore never remove a (NOT) BETWEEN condition
|
||||
// and also ignore it when one of the two values got removed. (Note
|
||||
// that this check will also catch empty strings.) Processors who need
|
||||
// different behavior have to override this method.
|
||||
// and also ignore it when one of the two values got removed.
|
||||
// Processors who need different behavior have to override this
|
||||
// method.
|
||||
$between_operator = in_array($condition->getOperator(), ['BETWEEN', 'NOT BETWEEN']);
|
||||
if ($between_operator && (!is_array($value) || count($value) < 2)) {
|
||||
continue;
|
||||
|
||||
@@ -176,6 +176,13 @@ class Query implements QueryInterface {
|
||||
*/
|
||||
protected $queryHelper;
|
||||
|
||||
/**
|
||||
* The original query before preprocessing.
|
||||
*
|
||||
* @var static|null
|
||||
*/
|
||||
protected $originalQuery;
|
||||
|
||||
/**
|
||||
* Constructs a Query object.
|
||||
*
|
||||
@@ -465,7 +472,7 @@ class Query implements QueryInterface {
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAbortMessage() {
|
||||
return is_bool($this->aborted) ? $this->aborted : NULL;
|
||||
return !is_bool($this->aborted) ? $this->aborted : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -511,6 +518,9 @@ class Query implements QueryInterface {
|
||||
if (!$this->wasAborted() && $this->languages !== []) {
|
||||
return FALSE;
|
||||
}
|
||||
if (!$this->originalQuery) {
|
||||
$this->originalQuery = clone $this;
|
||||
}
|
||||
$this->postExecute();
|
||||
return TRUE;
|
||||
}
|
||||
@@ -521,9 +531,15 @@ class Query implements QueryInterface {
|
||||
public function preExecute() {
|
||||
// Make sure to only execute this once per query, and not for queries with
|
||||
// the "none" processing level.
|
||||
if (!$this->preExecuteRan && $this->processingLevel != self::PROCESSING_NONE) {
|
||||
if (!$this->preExecuteRan) {
|
||||
$this->originalQuery = clone $this;
|
||||
$this->originalQuery->executed = FALSE;
|
||||
$this->preExecuteRan = TRUE;
|
||||
|
||||
if ($this->processingLevel == self::PROCESSING_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Preprocess query.
|
||||
$this->index->preprocessSearchQuery($this);
|
||||
|
||||
@@ -673,12 +689,22 @@ class Query implements QueryInterface {
|
||||
return $this->tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getOriginalQuery() {
|
||||
return $this->originalQuery ?: clone $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __clone() {
|
||||
$this->results = $this->getResults()->getCloneForQuery($this);
|
||||
$this->conditionGroup = clone $this->conditionGroup;
|
||||
if ($this->originalQuery) {
|
||||
$this->originalQuery = clone $this->originalQuery;
|
||||
}
|
||||
if ($this->parseMode) {
|
||||
$this->parseMode = clone $this->parseMode;
|
||||
}
|
||||
@@ -707,19 +733,6 @@ class Query implements QueryInterface {
|
||||
$this->indexId = NULL;
|
||||
}
|
||||
|
||||
// Sanitize the service IDs saved by the serialization trait to guard
|
||||
// against incomplete service containers. Doesn't need to happen when the
|
||||
// trait's __wakeup() method will return early anyways, though.
|
||||
// @todo Remove once #2909164 gets fixed in Core (and we depend on that Core
|
||||
// version).
|
||||
if (!isset($GLOBALS['__PHPUNIT_BOOTSTRAP']) || \Drupal::hasContainer()) {
|
||||
$container = \Drupal::getContainer();
|
||||
foreach ($this->_serviceIds as $key => $service_id) {
|
||||
if (!$container->has($service_id)) {
|
||||
unset($this->_serviceIds[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->traitWakeup();
|
||||
}
|
||||
|
||||
|
||||
@@ -286,6 +286,11 @@ interface QueryInterface extends ConditionSetInterface {
|
||||
/**
|
||||
* Executes this search query.
|
||||
*
|
||||
* The results of the search will be cached on the query, so subsequent calls
|
||||
* of this method will always return the same result set (even if conditions
|
||||
* were changed in between). If you want to re-execute a query, use
|
||||
* getOriginalQuery().
|
||||
*
|
||||
* @return \Drupal\search_api\Query\ResultSetInterface
|
||||
* The results of the search.
|
||||
*
|
||||
@@ -520,4 +525,14 @@ interface QueryInterface extends ConditionSetInterface {
|
||||
*/
|
||||
public function &getTags();
|
||||
|
||||
/**
|
||||
* Retrieves the original version of the query, before preprocessing occurred.
|
||||
*
|
||||
* Will be a clone of this query if preprocessing has not already run.
|
||||
*
|
||||
* @return \Drupal\search_api\Query\Query
|
||||
* The original, unpreprocessed version of this query.
|
||||
*/
|
||||
public function getOriginalQuery();
|
||||
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ class IndexTaskManager implements IndexTaskManagerInterface, EventSubscriberInte
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getSubscribedEvents() {
|
||||
$events['search_api.task.' . static::TRACK_ITEMS_TASK_TYPE][] = ['trackItems'];
|
||||
$events['search_api.task.' . self::TRACK_ITEMS_TASK_TYPE][] = ['trackItems'];
|
||||
|
||||
return $events;
|
||||
}
|
||||
@@ -161,7 +161,7 @@ class IndexTaskManager implements IndexTaskManagerInterface, EventSubscriberInte
|
||||
|
||||
if ($reschedule) {
|
||||
++$data['page'];
|
||||
$this->taskManager->addTask(static::TRACK_ITEMS_TASK_TYPE, NULL, $index, $data);
|
||||
$this->taskManager->addTask(self::TRACK_ITEMS_TASK_TYPE, NULL, $index, $data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ class IndexTaskManager implements IndexTaskManagerInterface, EventSubscriberInte
|
||||
'datasource' => $datasource_id,
|
||||
'page' => 0,
|
||||
];
|
||||
$this->taskManager->addTask(static::TRACK_ITEMS_TASK_TYPE, NULL, $index, $data);
|
||||
$this->taskManager->addTask(self::TRACK_ITEMS_TASK_TYPE, NULL, $index, $data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,7 +193,7 @@ class IndexTaskManager implements IndexTaskManagerInterface, EventSubscriberInte
|
||||
*/
|
||||
protected function getTaskConditions(IndexInterface $index) {
|
||||
return [
|
||||
'type' => static::TRACK_ITEMS_TASK_TYPE,
|
||||
'type' => self::TRACK_ITEMS_TASK_TYPE,
|
||||
'index_id' => $index->id(),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Drupal\search_api\Task;
|
||||
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\Core\StringTranslation\StringTranslationTrait;
|
||||
use Drupal\Core\StringTranslation\TranslationInterface;
|
||||
use Drupal\search_api\IndexInterface;
|
||||
@@ -58,6 +59,13 @@ class TaskManager implements TaskManagerInterface {
|
||||
*/
|
||||
protected $eventDispatcher;
|
||||
|
||||
/**
|
||||
* The messenger service.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* Constructs a TaskManager object.
|
||||
*
|
||||
@@ -67,11 +75,14 @@ class TaskManager implements TaskManagerInterface {
|
||||
* The event dispatcher.
|
||||
* @param \Drupal\Core\StringTranslation\TranslationInterface $translation
|
||||
* The string translation service.
|
||||
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
|
||||
* The messenger.
|
||||
*/
|
||||
public function __construct(EntityTypeManagerInterface $entity_type_manager, EventDispatcherInterface $event_dispatcher, TranslationInterface $translation) {
|
||||
public function __construct(EntityTypeManagerInterface $entity_type_manager, EventDispatcherInterface $event_dispatcher, TranslationInterface $translation, MessengerInterface $messenger) {
|
||||
$this->entityTypeManager = $entity_type_manager;
|
||||
$this->eventDispatcher = $event_dispatcher;
|
||||
$this->setStringTranslation($translation);
|
||||
$this->messenger = $messenger;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -267,6 +278,9 @@ class TaskManager implements TaskManagerInterface {
|
||||
];
|
||||
// Schedule the batch.
|
||||
batch_set($batch_definition);
|
||||
if (function_exists('drush_backend_batch_process')) {
|
||||
drush_backend_batch_process();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -335,11 +349,11 @@ class TaskManager implements TaskManagerInterface {
|
||||
'Successfully executed @count pending task.',
|
||||
'Successfully executed @count pending tasks.'
|
||||
);
|
||||
drupal_set_message($message);
|
||||
$this->messenger->addStatus($message);
|
||||
}
|
||||
else {
|
||||
// Notify the user about the batch job failure.
|
||||
drupal_set_message($this->t('An error occurred while trying to execute tasks. Check the logs for details.'), 'error');
|
||||
$this->messenger->addError($this->t('An error occurred while trying to execute tasks. Check the logs for details.'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ use Drupal\search_api\Processor\ProcessorInterface;
|
||||
use Drupal\search_api\Query\QueryInterface;
|
||||
use Drupal\search_api\Query\ResultSetInterface;
|
||||
use Drupal\search_api\Tracker\TrackerInterface;
|
||||
use Drupal\user\SharedTempStore;
|
||||
use Drupal\Core\TempStore\SharedTempStore;
|
||||
|
||||
/**
|
||||
* Represents a configuration of an index that was not yet permanently saved.
|
||||
@@ -31,7 +31,7 @@ class UnsavedIndexConfiguration implements IndexInterface, UnsavedConfigurationI
|
||||
/**
|
||||
* The shared temporary storage to use.
|
||||
*
|
||||
* @var \Drupal\user\SharedTempStore
|
||||
* @var \Drupal\Core\TempStore\SharedTempStore
|
||||
*/
|
||||
protected $tempStore;
|
||||
|
||||
@@ -61,7 +61,7 @@ class UnsavedIndexConfiguration implements IndexInterface, UnsavedConfigurationI
|
||||
*
|
||||
* @param \Drupal\search_api\IndexInterface $index
|
||||
* The index to proxy.
|
||||
* @param \Drupal\user\SharedTempStore $temp_store
|
||||
* @param \Drupal\Core\TempStore\SharedTempStore $temp_store
|
||||
* The shared temporary storage to use.
|
||||
* @param int|string $current_user_id
|
||||
* Either the UID of the currently logged-in user, or the session ID (for
|
||||
|
||||
@@ -490,4 +490,11 @@ class FieldsHelper implements FieldsHelperInterface {
|
||||
return $fieldId;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compareFieldLabels(FieldInterface $a, FieldInterface $b) {
|
||||
return strnatcasecmp($a->getLabel(), $b->getLabel());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -257,4 +257,18 @@ interface FieldsHelperInterface {
|
||||
*/
|
||||
public function getNewFieldId(IndexInterface $index, $propertyPath);
|
||||
|
||||
/**
|
||||
* Compares two fields for alphabetic sorting according to their labels.
|
||||
*
|
||||
* @param \Drupal\search_api\Item\FieldInterface $a
|
||||
* The first field.
|
||||
* @param \Drupal\search_api\Item\FieldInterface $b
|
||||
* The second field.
|
||||
*
|
||||
* @return int
|
||||
* -1, 0 or 1 if the first field should, respectively, be considered less
|
||||
* than, equal to or greater than the second.
|
||||
*/
|
||||
public function compareFieldLabels(FieldInterface $a, FieldInterface $b);
|
||||
|
||||
}
|
||||
|
||||
@@ -3,16 +3,15 @@
|
||||
namespace Drupal\search_api\Utility;
|
||||
|
||||
use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
|
||||
use Drupal\Core\DestructableInterface;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\search_api\LoggerTrait;
|
||||
use Drupal\search_api\SearchApiException;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
|
||||
/**
|
||||
* Provides a service for indexing items at the end of the page request.
|
||||
*/
|
||||
class PostRequestIndexing implements PostRequestIndexingInterface, EventSubscriberInterface {
|
||||
class PostRequestIndexing implements PostRequestIndexingInterface, DestructableInterface {
|
||||
|
||||
use LoggerTrait;
|
||||
|
||||
@@ -46,20 +45,7 @@ class PostRequestIndexing implements PostRequestIndexingInterface, EventSubscrib
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getSubscribedEvents() {
|
||||
$events[KernelEvents::TERMINATE][] = ['onKernelTerminate'];
|
||||
|
||||
return $events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indexes all items that were registered for indexing in this page request.
|
||||
*
|
||||
* Invoked by the terminate kernel event.
|
||||
*
|
||||
* @see \Symfony\Component\HttpKernel\Event\PostResponseEvent
|
||||
*/
|
||||
public function onKernelTerminate() {
|
||||
public function destruct() {
|
||||
foreach ($this->operations as $index_id => $item_ids) {
|
||||
try {
|
||||
$storage = $this->entityTypeManager->getStorage('search_api_index');
|
||||
|
||||
@@ -3,12 +3,11 @@
|
||||
namespace Drupal\search_api\Utility;
|
||||
|
||||
use Drupal\Component\Utility\NestedArray;
|
||||
use Drupal\Core\Config\ConfigFactoryOverrideInterface;
|
||||
use Drupal\Core\Config\Config;
|
||||
use Drupal\Core\Config\Entity\ConfigEntityTypeInterface;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\search_api\IndexInterface;
|
||||
use Drupal\search_api\Plugin\search_api\data_type\value\TextToken;
|
||||
use Symfony\Component\DependencyInjection\TaggedContainerInterface;
|
||||
|
||||
/**
|
||||
* Contains utility methods for the Search API.
|
||||
@@ -167,31 +166,43 @@ class Utility {
|
||||
}
|
||||
|
||||
$config_key = $entity_type->getConfigPrefix() . '.' . $entity->id();
|
||||
$overrides = [];
|
||||
|
||||
// Overrides from tagged services.
|
||||
$container = \Drupal::getContainer();
|
||||
if ($container instanceof TaggedContainerInterface) {
|
||||
$tags = $container->findTaggedServiceIds('config.factory.override');
|
||||
foreach (array_keys($tags) as $service_id) {
|
||||
$override = $container->get($service_id);
|
||||
if ($override instanceof ConfigFactoryOverrideInterface) {
|
||||
$service_overrides = $override->loadOverrides([$config_key]);
|
||||
if (!empty($service_overrides[$config_key])) {
|
||||
// Existing overrides take precedence since these will have been
|
||||
// added by events with a higher priority.
|
||||
$arrays = [$service_overrides[$config_key], $overrides];
|
||||
$overrides = NestedArray::mergeDeepArray($arrays, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
$config = \Drupal::config($config_key);
|
||||
if (!$config->hasOverrides()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Overrides from settings.php. (This takes precedence over overrides from
|
||||
// services.)
|
||||
if (isset($GLOBALS['config'][$config_key])) {
|
||||
$arrays = [$overrides, $GLOBALS['config'][$config_key]];
|
||||
$overrides = NestedArray::mergeDeepArray($arrays, TRUE);
|
||||
return static::collectOverrides($config, $config->get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects overrides from a config object.
|
||||
*
|
||||
* @param \Drupal\Core\Config\Config $config
|
||||
* The config object.
|
||||
* @param array $values
|
||||
* The array of values for the given $prefix.
|
||||
* @param array $overrides
|
||||
* (optional) The overrides collected so far. Internal use only.
|
||||
* @param string $prefix
|
||||
* (optional) The config key prefix for the current call level. Internal
|
||||
* use only.
|
||||
*
|
||||
* @return array
|
||||
* An associative array mapping property names to their overridden values.
|
||||
*/
|
||||
protected static function collectOverrides(Config $config, array $values, array $overrides = [], $prefix = '') {
|
||||
foreach ($values as $key => $value) {
|
||||
$key = "$prefix$key";
|
||||
if (!$config->hasOverrides($key)) {
|
||||
continue;
|
||||
}
|
||||
if (is_array($value)) {
|
||||
NestedArray::setValue($overrides, explode('.', $key), []);
|
||||
$overrides = static::collectOverrides($config, $value, $overrides, "$key.");
|
||||
}
|
||||
else {
|
||||
NestedArray::setValue($overrides, explode('.', $key), $value);
|
||||
}
|
||||
}
|
||||
|
||||
return $overrides;
|
||||
@@ -207,4 +218,34 @@ class Utility {
|
||||
return php_sapi_name() === 'cli';
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a certain value matches the configuration.
|
||||
*
|
||||
* This unifies checking for matches with the common configuration pattern of
|
||||
* having one "All except those selected"/"Only the selected" option
|
||||
* ("default") and a list of options to select.
|
||||
*
|
||||
* @param mixed $value
|
||||
* The value to check.
|
||||
* @param array $settings
|
||||
* The settings to check against, as an associative array with the following
|
||||
* keys:
|
||||
* - default: Boolean defining the default for not-selected items. TRUE
|
||||
* means "All except those selected", FALSE means "Only the selected".
|
||||
* Defaults to TRUE.
|
||||
* - selected: A numerically indexed array of the selected options. Defaults
|
||||
* to an empty array.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the value matches according to the configuration, FALSE
|
||||
* otherwise.
|
||||
*/
|
||||
public static function matches($value, array $settings) {
|
||||
$settings += [
|
||||
'default' => TRUE,
|
||||
'selected' => [],
|
||||
];
|
||||
return in_array($value, $settings['selected']) != $settings['default'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -7,8 +7,8 @@ dependencies:
|
||||
# core: 8.x
|
||||
hidden: true
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-02-23
|
||||
version: '8.x-1.7'
|
||||
# Information added by Drupal.org packaging script on 2018-07-19
|
||||
version: '8.x-1.9'
|
||||
core: '8.x'
|
||||
project: 'search_api'
|
||||
datestamp: 1519387691
|
||||
datestamp: 1531985591
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ backend: search_api_db
|
||||
backend_config:
|
||||
database: 'default:default'
|
||||
min_chars: 3
|
||||
partial_matches: false
|
||||
matching: words
|
||||
status: true
|
||||
langcode: en
|
||||
dependencies:
|
||||
|
||||
+3
-3
@@ -8,8 +8,8 @@ dependencies:
|
||||
# core: 8.x
|
||||
hidden: true
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-02-23
|
||||
version: '8.x-1.7'
|
||||
# Information added by Drupal.org packaging script on 2018-07-19
|
||||
version: '8.x-1.9'
|
||||
core: '8.x'
|
||||
project: 'search_api'
|
||||
datestamp: 1519387691
|
||||
datestamp: 1531985591
|
||||
|
||||
+3
-3
@@ -7,8 +7,8 @@ dependencies:
|
||||
# core: 8.x
|
||||
hidden: true
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-02-23
|
||||
version: '8.x-1.7'
|
||||
# Information added by Drupal.org packaging script on 2018-07-19
|
||||
version: '8.x-1.9'
|
||||
core: '8.x'
|
||||
project: 'search_api'
|
||||
datestamp: 1519387691
|
||||
datestamp: 1531985591
|
||||
|
||||
+3
-3
@@ -7,8 +7,8 @@ dependencies:
|
||||
# core: 8.x
|
||||
hidden: true
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-02-23
|
||||
version: '8.x-1.7'
|
||||
# Information added by Drupal.org packaging script on 2018-07-19
|
||||
version: '8.x-1.9'
|
||||
core: '8.x'
|
||||
project: 'search_api'
|
||||
datestamp: 1519387691
|
||||
datestamp: 1531985591
|
||||
|
||||
+3
-3
@@ -7,8 +7,8 @@ dependencies:
|
||||
# core: 8.x
|
||||
hidden: true
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-02-23
|
||||
version: '8.x-1.7'
|
||||
# Information added by Drupal.org packaging script on 2018-07-19
|
||||
version: '8.x-1.9'
|
||||
core: '8.x'
|
||||
project: 'search_api'
|
||||
datestamp: 1519387691
|
||||
datestamp: 1531985591
|
||||
|
||||
+1
-1
@@ -31,5 +31,5 @@ function search_api_test_hooks_search_api_query_andrew_hill_alter(QueryInterface
|
||||
* Implements hook_search_api_results_TAG_alter().
|
||||
*/
|
||||
function search_api_test_hooks_search_api_results_andrew_hill_alter(ResultSetInterface &$results) {
|
||||
drupal_set_message('Llama');
|
||||
\Drupal::messenger()->addStatus('Llama');
|
||||
}
|
||||
|
||||
+6
-6
@@ -70,22 +70,22 @@ function search_api_test_hooks_search_api_displays_alter(array &$displays) {
|
||||
*/
|
||||
function search_api_test_hooks_search_api_index_items_alter(IndexInterface $index, array &$items) {
|
||||
unset($items['entity:node/1:en']);
|
||||
drupal_set_message('Stormy');
|
||||
\Drupal::messenger()->addStatus('Stormy');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_search_api_items_indexed().
|
||||
*/
|
||||
function search_api_test_hooks_search_api_items_indexed(IndexInterface $index, array $item_ids) {
|
||||
drupal_set_message('Please set me at ease');
|
||||
\Drupal::messenger()->addStatus('Please set me at ease');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_search_api_query_alter().
|
||||
*/
|
||||
function search_api_test_hooks_search_api_query_alter(QueryInterface &$query) {
|
||||
drupal_set_message('Funky blue note');
|
||||
drupal_set_message(sprintf('Search id: %s', $query->getSearchId(FALSE)));
|
||||
\Drupal::messenger()->addStatus('Funky blue note');
|
||||
\Drupal::messenger()->addStatus("Search id: {$query->getSearchId(FALSE)}");
|
||||
$query->addTag('andrew_hill');
|
||||
}
|
||||
|
||||
@@ -93,14 +93,14 @@ function search_api_test_hooks_search_api_query_alter(QueryInterface &$query) {
|
||||
* Implements hook_search_api_results_alter().
|
||||
*/
|
||||
function search_api_test_hooks_search_api_results_alter(ResultSetInterface &$results) {
|
||||
drupal_set_message('Stepping into tomorrow');
|
||||
\Drupal::messenger()->addStatus('Stepping into tomorrow');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_search_api_index_reindex().
|
||||
*/
|
||||
function search_api_test_hooks_search_api_index_reindex(IndexInterface $index, $clear = FALSE) {
|
||||
drupal_set_message('Montara');
|
||||
\Drupal::messenger()->addStatus('Montara');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
id: inconsistent_search_index
|
||||
name: 'Inconsistent search index'
|
||||
description: 'An index used for testing'
|
||||
read_only: false
|
||||
field_settings:
|
||||
unknown_property:
|
||||
label: 'Unknown property'
|
||||
type: integer
|
||||
datasource_id: 'entity:entity_test_mulrev_changed'
|
||||
property_path: unknown_property
|
||||
processor_settings:
|
||||
add_url:
|
||||
weights:
|
||||
preprocess_index: -30
|
||||
aggregated_field:
|
||||
weights:
|
||||
add_properties: 20
|
||||
search_api_test: { }
|
||||
options:
|
||||
cron_limit: -1
|
||||
index_directly: false
|
||||
datasource_settings:
|
||||
'entity:entity_test_mulrev_changed': { }
|
||||
tracker_settings:
|
||||
'default': { }
|
||||
server: inconsistent_search_server
|
||||
status: true
|
||||
langcode: en
|
||||
dependencies:
|
||||
config:
|
||||
- search_api.server.inconsistent_search_server
|
||||
module:
|
||||
- entity_test
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
id: inconsistent_search_server
|
||||
name: 'Inconsistent search server'
|
||||
description: 'A server used for testing'
|
||||
backend: search_api_test
|
||||
backend_config: { }
|
||||
status: false
|
||||
langcode: en
|
||||
dependencies:
|
||||
module:
|
||||
- search_api_test
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
name: 'Search API Inconsistent Configs Test'
|
||||
type: module
|
||||
description: 'Support module for Search API tests'
|
||||
package: Search
|
||||
dependencies:
|
||||
- search_api:search_api
|
||||
- search_api:search_api_test
|
||||
# core: 8.x
|
||||
hidden: true
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-07-19
|
||||
version: '8.x-1.9'
|
||||
core: '8.x'
|
||||
project: 'search_api'
|
||||
datestamp: 1531985591
|
||||
+3
-3
@@ -7,8 +7,8 @@ dependencies:
|
||||
# core: 8.x
|
||||
hidden: true
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-02-23
|
||||
version: '8.x-1.7'
|
||||
# Information added by Drupal.org packaging script on 2018-07-19
|
||||
version: '8.x-1.9'
|
||||
core: '8.x'
|
||||
project: 'search_api'
|
||||
datestamp: 1519387691
|
||||
datestamp: 1531985591
|
||||
|
||||
+4
-3
@@ -6,12 +6,13 @@ dependencies:
|
||||
- search_api:search_api
|
||||
- search_api:search_api_test_db
|
||||
- drupal:node
|
||||
- drupal:rest
|
||||
- drupal:views
|
||||
# core: 8.x
|
||||
hidden: true
|
||||
|
||||
# Information added by Drupal.org packaging script on 2018-02-23
|
||||
version: '8.x-1.7'
|
||||
# Information added by Drupal.org packaging script on 2018-07-19
|
||||
version: '8.x-1.9'
|
||||
core: '8.x'
|
||||
project: 'search_api'
|
||||
datestamp: 1519387691
|
||||
datestamp: 1531985591
|
||||
|
||||
+1
-1
@@ -22,6 +22,6 @@ function search_api_test_views_search_api_query_alter(QueryInterface $query) {
|
||||
$message[] = "'$combined_property_path'";
|
||||
}
|
||||
}
|
||||
drupal_set_message(implode(' ', $message));
|
||||
\Drupal::messenger()->addStatus(implode(' ', $message));
|
||||
}
|
||||
}
|
||||
|
||||
+13
-3
@@ -17,6 +17,13 @@ trait ExampleContentTrait {
|
||||
*/
|
||||
protected $entities = [];
|
||||
|
||||
/**
|
||||
* The Search API item IDs of the generated entities.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $ids = [];
|
||||
|
||||
/**
|
||||
* Sets up the necessary bundles on the test entity type.
|
||||
*/
|
||||
@@ -82,10 +89,12 @@ trait ExampleContentTrait {
|
||||
* The created entity.
|
||||
*/
|
||||
protected function addTestEntity($id, array $values) {
|
||||
$storage = \Drupal::entityTypeManager()->getStorage('entity_test_mulrev_changed');
|
||||
$entity_type = 'entity_test_mulrev_changed';
|
||||
$storage = \Drupal::entityTypeManager()->getStorage($entity_type);
|
||||
$values['id'] = $id;
|
||||
$this->entities[$id] = $storage->create($values);
|
||||
$this->entities[$id]->save();
|
||||
$this->ids[$id] = Utility::createCombinedId("entity:$entity_type", "$id:en");
|
||||
return $this->entities[$id];
|
||||
}
|
||||
|
||||
@@ -114,8 +123,9 @@ trait ExampleContentTrait {
|
||||
* An array of item IDs.
|
||||
*/
|
||||
protected function getItemIds(array $entity_ids) {
|
||||
$translate_ids = function ($entity_id) {
|
||||
return Utility::createCombinedId('entity:entity_test_mulrev_changed', $entity_id . ':en');
|
||||
$map = $this->ids;
|
||||
$translate_ids = function ($entity_id) use ($map) {
|
||||
return $map[$entity_id];
|
||||
};
|
||||
return array_map($translate_ids, $entity_ids);
|
||||
}
|
||||
|
||||
@@ -1206,6 +1206,7 @@ class IntegrationTest extends SearchApiBrowserTestBase {
|
||||
$this->submitForm($edit, 'Save');
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
$this->assertSession()->pageTextContains('All content was scheduled for reindexing so the new settings can take effect.');
|
||||
$this->assertSession()->responseContains($this->getIndex()->toUrl()->toString());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,7 +31,6 @@ class ViewsTest extends SearchApiBrowserTestBase {
|
||||
public static $modules = [
|
||||
'block',
|
||||
'language',
|
||||
'rest',
|
||||
'search_api_test_views',
|
||||
'views_ui',
|
||||
];
|
||||
|
||||
@@ -86,9 +86,8 @@ class BasicTrackerTest extends KernelTestBase {
|
||||
public function testTracking($indexing_order) {
|
||||
// Add a logger that throws an exception when used, so a caught exception
|
||||
// within any of the tracker methods will still cause a test fail.
|
||||
// @todo Change to createMock() once we depend on Drupal 8.5+. See #2930839.
|
||||
/** @var \PHPUnit_Framework_MockObject_MockObject|\Psr\Log\LoggerInterface $logger */
|
||||
$logger = $this->getMock(LoggerInterface::class);
|
||||
$logger = $this->createMock(LoggerInterface::class);
|
||||
$logger->method('log')
|
||||
->willReturnCallback(function ($level, $message, array $variables) {
|
||||
$error = 'Tracking operation threw ';
|
||||
@@ -318,7 +317,7 @@ class BasicTrackerTest extends KernelTestBase {
|
||||
$this->tracker->setDatabaseConnection($connection);
|
||||
|
||||
/** @var \PHPUnit_Framework_MockObject_MockObject|\Psr\Log\LoggerInterface $logger */
|
||||
$logger = $this->getMock(LoggerInterface::class);
|
||||
$logger = $this->createMock(LoggerInterface::class);
|
||||
$log = [];
|
||||
$logger->method('log')->willReturnCallback(function () use (&$log) {
|
||||
$log[] = func_get_args();
|
||||
|
||||
+6
-4
@@ -197,7 +197,12 @@ class ConfigOverrideKernelTest extends KernelTestBase {
|
||||
// Verify that overriding "status" prevents the server's indexes from being
|
||||
// disabled when attempting to disable the server.
|
||||
$GLOBALS['config']['search_api.server.test_server']['status'] = TRUE;
|
||||
$this->server->disable()->save();
|
||||
\Drupal::configFactory()->clearStaticCache();
|
||||
/** @var \Drupal\search_api\Entity\SearchApiConfigEntityStorage $server_storage */
|
||||
$server_storage = \Drupal::entityTypeManager()
|
||||
->getStorage('search_api_server');
|
||||
$server = $server_storage->loadOverrideFree($server->id());
|
||||
$server->disable()->save();
|
||||
\Drupal::configFactory()->clearStaticCache();
|
||||
$index = Index::load($this->index->id());
|
||||
$this->assertTrue($index->status());
|
||||
@@ -206,9 +211,6 @@ class ConfigOverrideKernelTest extends KernelTestBase {
|
||||
|
||||
// Verify that overrides are not present when loading the server
|
||||
// override-free.
|
||||
/** @var \Drupal\search_api\Entity\SearchApiConfigEntityStorage $server_storage */
|
||||
$server_storage = \Drupal::entityTypeManager()
|
||||
->getStorage('search_api_server');
|
||||
$server = $server_storage->loadOverrideFree($server->id());
|
||||
$this->assertEquals('Test server', $server->label());
|
||||
}
|
||||
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\search_api\Kernel\ConfigEntity;
|
||||
|
||||
use Drupal\Core\Serialization\Yaml;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\search_api\Entity\Index;
|
||||
use Drupal\search_api\Entity\Server;
|
||||
use Drupal\search_api_test\PluginTestTrait;
|
||||
|
||||
/**
|
||||
* Tests that installing config entities from an extension works correctly.
|
||||
*
|
||||
* @group search_api
|
||||
*/
|
||||
class DefaultConfigEntityInstallationTest extends KernelTestBase {
|
||||
|
||||
use PluginTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
'entity_test',
|
||||
'search_api',
|
||||
'search_api_test',
|
||||
'search_api_test_inconsistent_config',
|
||||
'system',
|
||||
'user',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->installEntitySchema('entity_test_mulrev_changed');
|
||||
$this->installEntitySchema('search_api_task');
|
||||
$this->installConfig('search_api');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that installing config entities from an extension works correctly.
|
||||
*/
|
||||
public function testExtensionInstallation() {
|
||||
$this->installConfig('search_api_test_inconsistent_config');
|
||||
|
||||
$index = Index::load('inconsistent_search_index');
|
||||
$this->assertNotNull($index);
|
||||
$values = $index->toArray();
|
||||
|
||||
// Make sure the index was not processed at all upon saving.
|
||||
$this->assertTrue($index->status());
|
||||
$this->assertArrayNotHasKey('rendered_item', $values['processor_settings']);
|
||||
$this->assertArrayHasKey('unknown_property', $values['field_settings']);
|
||||
$methods = $this->getCalledMethods('processor');
|
||||
$this->assertNotContains('preIndexSave', $methods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that creating new config entities directly works correctly.
|
||||
*/
|
||||
public function testNormalEntityCreation() {
|
||||
$dir = __DIR__ . '/../../../search_api_test_inconsistent_config/config/install/';
|
||||
$yaml_file = $dir . 'search_api.server.inconsistent_search_server.yml';
|
||||
$values = Yaml::decode(file_get_contents($yaml_file));
|
||||
Server::create($values)->save();
|
||||
$yaml_file = $dir . 'search_api.index.inconsistent_search_index.yml';
|
||||
$values = Yaml::decode(file_get_contents($yaml_file));
|
||||
Index::create($values)->save();
|
||||
|
||||
$index = Index::load('inconsistent_search_index');
|
||||
$this->assertNotNull($index);
|
||||
$values = $index->toArray();
|
||||
|
||||
// Make sure the index was not processed at all upon saving.
|
||||
$this->assertFalse($index->status());
|
||||
$this->assertArrayHasKey('rendered_item', $values['processor_settings']);
|
||||
$this->assertArrayNotHasKey('unknown_property', $values['field_settings']);
|
||||
$methods = $this->getCalledMethods('processor');
|
||||
$this->assertContains('preIndexSave', $methods);
|
||||
}
|
||||
|
||||
}
|
||||
+4
-2
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Drupal\Tests\search_api\Kernel\ConfigEntity;
|
||||
|
||||
use Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface;
|
||||
use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface;
|
||||
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
@@ -304,8 +306,8 @@ class DependencyRemovalTest extends KernelTestBase {
|
||||
// store (the index will purge any unsaved configuration of it upon
|
||||
// deletion, which uses a "user-shared temp store", which in turn uses a
|
||||
// key/value store).
|
||||
$mock = $this->getMock('Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface');
|
||||
$mock_factory = $this->getMock('Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface');
|
||||
$mock = $this->createMock(KeyValueStoreExpirableInterface::class);
|
||||
$mock_factory = $this->createMock(KeyValueExpirableFactoryInterface::class);
|
||||
$mock_factory->method('get')->willReturn($mock);
|
||||
$this->container->set('keyvalue.expirable', $mock_factory);
|
||||
|
||||
|
||||
+55
@@ -169,6 +169,61 @@ class ContentEntityDatasourceTest extends KernelTestBase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests viewing of items.
|
||||
*
|
||||
* @covers ::viewItem
|
||||
* @covers ::viewMultipleItems
|
||||
*/
|
||||
public function testItemViewing() {
|
||||
$loaded_items = $this->datasource->loadMultiple($this->allItemIds);
|
||||
$builder = \Drupal::entityTypeManager()
|
||||
->getViewBuilder('entity_test_mulrev_changed');
|
||||
|
||||
$item = $loaded_items['1:l0'];
|
||||
$build = $this->datasource->viewItem($item, 'foobar');
|
||||
$expected = [
|
||||
'#entity_test_mulrev_changed' => $item->getValue(),
|
||||
'#view_mode' => 'foobar',
|
||||
'#cache' => [
|
||||
'tags' => [
|
||||
'entity_test_mulrev_changed:1',
|
||||
'entity_test_mulrev_changed_view',
|
||||
],
|
||||
'contexts' => [],
|
||||
'max-age' => -1,
|
||||
],
|
||||
'#weight' => 0,
|
||||
'#pre_render' => [
|
||||
[$builder, 'build'],
|
||||
],
|
||||
];
|
||||
$this->assertEquals($expected, $build);
|
||||
|
||||
$build = $this->datasource->viewMultipleItems($loaded_items, 'foobar');
|
||||
$this->assertTrue($build['#sorted']);
|
||||
$this->assertEquals([[$builder, 'buildMultiple']], $build['#pre_render']);
|
||||
foreach ($loaded_items as $item_id => $item) {
|
||||
/** @var \Drupal\Core\Entity\EntityInterface $entity */
|
||||
$entity = $item->getValue();
|
||||
$expected = [
|
||||
'#entity_test_mulrev_changed' => $entity,
|
||||
'#view_mode' => 'foobar',
|
||||
'#cache' => [
|
||||
'tags' => [
|
||||
'entity_test_mulrev_changed:' . $entity->id(),
|
||||
'entity_test_mulrev_changed_view',
|
||||
],
|
||||
'contexts' => [],
|
||||
'max-age' => -1,
|
||||
],
|
||||
];
|
||||
$this->assertArrayHasKey('#weight', $build[$item_id]);
|
||||
unset($build[$item_id]['#weight']);
|
||||
$this->assertEquals($expected, $build[$item_id]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that paged item discovery works correctly.
|
||||
*
|
||||
|
||||
@@ -93,6 +93,9 @@ class IndexImportTest extends KernelTestBase {
|
||||
];
|
||||
$sync->write('search_api.index.database_search_index', $import_config);
|
||||
|
||||
// The system.site key is required for import validation.
|
||||
$sync->write('system.site', []);
|
||||
|
||||
// Import the test configuration.
|
||||
$config_importer = $this->configImporter();
|
||||
$this->assertTrue($config_importer->hasUnprocessedConfigurationChanges(), 'Import prepared');
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ trait PostRequestIndexingTrait {
|
||||
*/
|
||||
protected function triggerPostRequestIndexing() {
|
||||
\Drupal::getContainer()->get('search_api.post_request_indexing')
|
||||
->onKernelTerminate();
|
||||
->destruct();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\search_api\Kernel\Processor;
|
||||
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\search_api\Item\Field;
|
||||
use Drupal\search_api\Utility\Utility;
|
||||
|
||||
/**
|
||||
* Tests the "Add URL" processor at a higher level.
|
||||
*
|
||||
* @group search_api
|
||||
*
|
||||
* @coversDefaultClass \Drupal\search_api\Plugin\search_api\processor\AddURL
|
||||
*/
|
||||
class AddURLKernelTest extends ProcessorTestBase {
|
||||
|
||||
/**
|
||||
* The nodes created for testing.
|
||||
*
|
||||
* @var \Drupal\node\Entity\Node[]
|
||||
*/
|
||||
protected $nodes;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setUp($processor = NULL) {
|
||||
parent::setUp('add_url');
|
||||
|
||||
$url_field = new Field($this->index, 'url');
|
||||
$url_field->setType('string');
|
||||
$url_field->setPropertyPath('search_api_url');
|
||||
$url_field->setLabel('Item URL');
|
||||
$this->index->addField($url_field);
|
||||
$this->index->save();
|
||||
|
||||
$this->nodes[0] = Node::create([
|
||||
'title' => 'Test',
|
||||
'type' => 'article',
|
||||
]);
|
||||
$this->nodes[0]->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests extracting the field for a search item.
|
||||
*
|
||||
* @covers ::addFieldValues
|
||||
*/
|
||||
public function testItemFieldExtraction() {
|
||||
$node = $this->nodes[0];
|
||||
$id = Utility::createCombinedId('entity:node', $node->id() . ':en');
|
||||
$item = \Drupal::getContainer()
|
||||
->get('search_api.fields_helper')
|
||||
->createItemFromObject($this->index, $node->getTypedData(), $id);
|
||||
|
||||
// Extract field values and check the value of the URL field.
|
||||
$fields = $item->getFields();
|
||||
$expected = [$node->toUrl('canonical')->toString()];
|
||||
$this->assertEquals($expected, $fields['url']->getValues());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Drupal\Tests\search_api\Kernel\System;
|
||||
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\search_api\Entity\Index;
|
||||
use Drupal\search_api\Entity\Server;
|
||||
@@ -102,18 +103,15 @@ class QueryTest extends KernelTestBase {
|
||||
$this->assertEquals($level, $query->getProcessingLevel());
|
||||
$query->addTag('andrew_hill');
|
||||
|
||||
// @todo Use \Drupal::messenger() once we depend on Drupal 8.5+. See
|
||||
// #2931730.
|
||||
drupal_get_messages();
|
||||
\Drupal::messenger()->deleteAll();
|
||||
$query->execute();
|
||||
$messages = drupal_get_messages();
|
||||
$messages = \Drupal::messenger()->all();
|
||||
\Drupal::messenger()->deleteAll();
|
||||
|
||||
$methods = $this->getCalledMethods('processor');
|
||||
if ($hooks_and_processors_invoked) {
|
||||
// @todo Replace "status" with MessengerInterface::TYPE_STATUS once we
|
||||
// depend on Drupal 8.5+. See #2931730.
|
||||
$expected = [
|
||||
'status' => [
|
||||
MessengerInterface::TYPE_STATUS => [
|
||||
'Funky blue note',
|
||||
'Search id: ',
|
||||
'Stepping into tomorrow',
|
||||
@@ -225,4 +223,31 @@ class QueryTest extends KernelTestBase {
|
||||
$this->assertInstanceOf('Drupal\search_api_test\Plugin\search_api\display\TestDisplay', $query->getDisplayPlugin());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the getOriginalQuery() method.
|
||||
*/
|
||||
public function testGetOriginalQuery() {
|
||||
$this->getCalledMethods('backend');
|
||||
|
||||
$query = $this->index->query()
|
||||
->addCondition('search_api_id', 2, '<>');
|
||||
$query_clone_1 = $query->getOriginalQuery();
|
||||
$this->assertEquals($query, $query_clone_1);
|
||||
$this->assertNotSame($query, $query_clone_1);
|
||||
|
||||
$query->sort('search_api_id');
|
||||
$query_clone_2 = clone $query;
|
||||
$query->execute();
|
||||
$methods = $this->getCalledMethods('backend');
|
||||
$this->assertEquals(['search'], $methods);
|
||||
$this->assertFalse($query_clone_1->hasExecuted());
|
||||
|
||||
$original_query = $query->getOriginalQuery();
|
||||
$this->assertEquals($query_clone_2, $original_query);
|
||||
$this->assertFalse($original_query->hasExecuted());
|
||||
$original_query->execute();
|
||||
$methods = $this->getCalledMethods('backend');
|
||||
$this->assertEquals(['search'], $methods);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user