'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 (!empty($display['display_options']['cache']['type']) && 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 (!empty($display['display_options']['cache']['type']) && $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; }