search_api.install in Search API 8
Same filename and directory in other branches
Install, update and uninstall functions for the Search API module.
File
search_api.installView source
<?php
/**
* @file
* Install, update and uninstall functions for the Search API module.
*/
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Database\DatabaseException;
use Drupal\Core\Link;
use Drupal\search_api\Entity\Server;
use Drupal\Core\Url;
use Drupal\search_api\Entity\TaskStorageSchema;
/**
* Implements hook_schema().
*/
function search_api_schema() {
$schema['search_api_item'] = [
'description' => 'Stores the items which should be indexed for each index, and their state.',
'fields' => [
'index_id' => [
'description' => 'The ID of the index this item belongs to',
'type' => 'varchar',
'length' => 50,
'not null' => TRUE,
],
'datasource' => [
'description' => 'The plugin ID of the datasource this item belongs to',
'type' => 'varchar',
'length' => 50,
'not null' => TRUE,
],
'item_id' => [
'description' => 'The unique identifier of this item',
'type' => 'varchar',
'length' => 150,
'not null' => TRUE,
],
'changed' => [
'description' => 'A timestamp indicating when the item was last changed',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
],
'status' => [
'description' => 'Boolean indicating the reindexation status, "1" when we need to reindex, "0" otherwise',
'type' => 'int',
'not null' => TRUE,
],
],
'indexes' => [
'indexing' => [
'index_id',
'status',
'changed',
'item_id',
],
],
'primary key' => [
'index_id',
'item_id',
],
];
return $schema;
}
/**
* Implements hook_uninstall().
*/
function search_api_uninstall() {
\Drupal::state()
->delete('search_api_use_tracking_batch');
foreach (\Drupal::configFactory()
->listAll('search_api.index.') as $index_id) {
\Drupal::state()
->delete("search_api.index.{$index_id}.has_reindexed");
}
}
/**
* Implements hook_requirements().
*/
function search_api_requirements($phase) {
if ($phase == 'runtime') {
$requirements = [];
$message = _search_api_search_module_warning();
if ($message) {
$requirements += [
'search_api_core_search' => [
'title' => t('Search API'),
'value' => $message,
'severity' => REQUIREMENT_WARNING,
],
];
}
/** @var \Drupal\search_api\ServerInterface[] $servers */
$servers = Server::loadMultiple();
$unavailable_servers = [];
foreach ($servers as $server) {
if ($server
->status() && !$server
->isAvailable()) {
$unavailable_servers[] = $server
->label();
}
}
if (!empty($unavailable_servers)) {
$requirements += [
'search_api_server_unavailable' => [
'title' => t('Search API'),
'value' => \Drupal::translation()
->formatPlural(count($unavailable_servers), 'The search server "@servers" is currently not available', 'The following search servers are not available: @servers', [
'@servers' => implode(', ', $unavailable_servers),
]),
'severity' => REQUIREMENT_ERROR,
],
];
}
$pending_tasks = \Drupal::getContainer()
->get('search_api.task_manager')
->getTasksCount();
if ($pending_tasks) {
$args['@link'] = '';
$url = Url::fromRoute('search_api.execute_tasks');
if ($url
->access()) {
$link = new Link(t('Execute now'), $url);
$link = $link
->toString();
$args['@link'] = $link;
$args['@link'] = new FormattableMarkup(' (@link)', $args);
}
$requirements['search_api_pending_tasks'] = [
'title' => t('Search API'),
'value' => \Drupal::translation()
->formatPlural($pending_tasks, 'There is @count pending Search API task. @link', 'There are @count pending Search API tasks. @link', $args),
'severity' => REQUIREMENT_WARNING,
];
}
return $requirements;
}
return [];
}
/**
* Adapts index config schema to remove an unnecessary layer for plugins.
*/
function search_api_update_8101() {
// This update function updates search indexes for the change from
// https://www.drupal.org/node/2656052.
$config_factory = \Drupal::configFactory();
$plugin_types = [
'processor',
'datasource',
'tracker',
];
foreach ($config_factory
->listAll('search_api.index.') as $index_id) {
$index = $config_factory
->getEditable($index_id);
$changed = FALSE;
foreach ($plugin_types as $plugin_type) {
$property = $plugin_type . '_settings';
$plugins = $index
->get($property);
foreach ($plugins as $id => $config) {
if (isset($config['plugin_id']) && isset($config['settings'])) {
$changed = TRUE;
$plugins[$id] = $config['settings'];
}
}
$index
->set($property, $plugins);
}
if ($changed) {
// Mark the resulting configuration as trusted data. This avoids issues
// with future schema changes.
$index
->save(TRUE);
}
}
return t('Index config schema updated.');
}
/**
* Removes unsupported cache plugins from Search API views.
*/
function search_api_update_8102() {
$config_factory = \Drupal::configFactory();
$changed = [];
foreach ($config_factory
->listAll('views.view.') as $view_config_name) {
$view = $config_factory
->getEditable($view_config_name);
$displays = $view
->get('display');
if ($displays['default']['display_options']['query']['type'] === 'search_api_query') {
$change = FALSE;
foreach ($displays as $id => $display) {
if (in_array($display['display_options']['cache']['type'] ?? '', [
'tag',
'time',
])) {
$displays[$id]['display_options']['cache']['type'] = 'none';
$change = TRUE;
}
}
if ($change) {
$view
->set('display', $displays);
// Mark the resulting configuration as trusted data. This avoids issues
// with future schema changes.
$view
->save(TRUE);
$changed[] = $view
->get('id');
}
}
}
if (!empty($changed)) {
return \Drupal::translation()
->translate('Removed incompatible cache options for the following Search API-based views: @ids', [
'@ids' => implode(', ', array_unique($changed)),
]);
}
return NULL;
}
/**
* Switches from the old "Node status" to the new "Entity status" processor.
*/
function search_api_update_8103() {
// This update function updates search indexes for the change from
// https://www.drupal.org/node/2491175.
$config_factory = \Drupal::configFactory();
foreach ($config_factory
->listAll('search_api.index.') as $index_id) {
$index = $config_factory
->getEditable($index_id);
$processors = $index
->get('processor_settings');
if (isset($processors['node_status'])) {
$processors['entity_status'] = $processors['node_status'];
unset($processors['node_status']);
$index
->set('processor_settings', $processors);
// Mark the resulting configuration as trusted data. This avoids issues
// with future schema changes.
$index
->save(TRUE);
}
}
// Clear the processor plugin cache so that if anything else indirectly tries
// to update Search API-related configuration, the plugin helper gets the most
// up-to-date plugin definitions.
\Drupal::getContainer()
->get('plugin.manager.search_api.processor')
->clearCachedDefinitions();
return t('Switched from old "Node status" to new "Entity status" processor.');
}
/**
* Update Views to use the time-based cache plugin for Search API.
*/
function search_api_update_8104() {
$config_factory = \Drupal::configFactory();
$changed = [];
foreach ($config_factory
->listAll('views.view.') as $view_config_name) {
$view = $config_factory
->getEditable($view_config_name);
$displays = $view
->get('display');
$updated = FALSE;
foreach ($displays as $id => $display) {
if (($display['display_options']['cache']['type'] ?? '') === 'search_api') {
$displays[$id]['display_options']['cache']['type'] = 'search_api_time';
$updated = TRUE;
}
}
if ($updated) {
$view
->set('display', $displays);
// Mark the resulting configuration as trusted data. This avoids issues
// with future schema changes.
$view
->save(TRUE);
$changed[] = $view
->get('id');
}
}
if (!empty($changed)) {
return \Drupal::translation()
->translate('The following views have been updated to use the time-based cache plugin: @ids', [
'@ids' => implode(', ', array_unique($changed)),
]);
}
return NULL;
}
/**
* Update the configuration schema of the "Ignore characters" processor.
*/
function search_api_update_8105() {
// This update function updates search indexes for the change from
// https://www.drupal.org/node/3007933.
$config_factory = \Drupal::configFactory();
$changes = FALSE;
foreach ($config_factory
->listAll('search_api.index.') as $index_id) {
$index = $config_factory
->getEditable($index_id);
$processors = $index
->get('processor_settings');
if (isset($processors['ignore_character'])) {
$classes = $processors['ignore_character']['strip']['character_sets'];
$classes = array_values(array_filter($classes));
$processors['ignore_character']['ignorable_classes'] = $classes;
unset($processors['ignore_character']['strip']);
$index
->set('processor_settings', $processors);
// Mark the resulting configuration as trusted data. This avoids issues
// with future schema changes.
$index
->save(TRUE);
$changes = TRUE;
}
}
if ($changes) {
return t('Updated the configuration schema of the "Ignore characters" processor.');
}
return NULL;
}
/**
* Remove remnants of the search_api_views_taxonomy module.
*/
function search_api_update_8106() {
try {
\Drupal::database()
->delete('key_value')
->condition('collection', 'system.schema')
->condition('name', 'search_api_views_taxonomy')
->execute();
} catch (DatabaseException $e) {
// The admin might have done this already to get rid of the warning
// themselves. It's not really important enough to fail on this, in any
// case. In the worst case, the warning just remains. So, just ignore any
// exception. (Site could also use an alternate key/value store.)
}
}
/**
* Add a unique index to the task entity type's storage.
*/
function search_api_update_8107() {
$manager = \Drupal::entityDefinitionUpdateManager();
$entity_type = $manager
->getEntityType('search_api_task');
$entity_type
->setHandlerClass('storage_schema', TaskStorageSchema::class);
$manager
->updateEntityType($entity_type);
}
/**
* Add configuration for boost factors.
*/
function search_api_update_8108() {
$settings = \Drupal::configFactory()
->getEditable('search_api.settings');
$data = $settings
->getRawData();
$data += [
'boost_factors' => [
0.0,
0.1,
0.2,
0.3,
0.5,
0.6,
0.7,
0.8,
0.9,
1.0,
1.1,
1.2,
1.3,
1.4,
1.5,
2.0,
3.0,
5.0,
8.0,
13.0,
21.0,
],
];
$settings
->setData($data)
->save(TRUE);
}
Functions
Name | Description |
---|---|
search_api_requirements | Implements hook_requirements(). |
search_api_schema | Implements hook_schema(). |
search_api_uninstall | Implements hook_uninstall(). |
search_api_update_8101 | Adapts index config schema to remove an unnecessary layer for plugins. |
search_api_update_8102 | Removes unsupported cache plugins from Search API views. |
search_api_update_8103 | Switches from the old "Node status" to the new "Entity status" processor. |
search_api_update_8104 | Update Views to use the time-based cache plugin for Search API. |
search_api_update_8105 | Update the configuration schema of the "Ignore characters" processor. |
search_api_update_8106 | Remove remnants of the search_api_views_taxonomy module. |
search_api_update_8107 | Add a unique index to the task entity type's storage. |
search_api_update_8108 | Add configuration for boost factors. |