public function ContentEntityTrackingManager::indexUpdate in Search API 8
Implements hook_ENTITY_TYPE_update() for type "search_api_index".
Detects changes in the selected bundles or languages and adds/removes items to/from tracking accordingly.
Parameters
\Drupal\search_api\IndexInterface $index: The index that was updated.
Throws
\Drupal\Component\Plugin\Exception\PluginNotFoundException Thrown if a datasource referenced an unknown entity type.
\Drupal\search_api\SearchApiException Never thrown, but static analysis tools think it could be.
See also
search_api_search_api_index_update()
File
- src/
Plugin/ search_api/ datasource/ ContentEntityTrackingManager.php, line 286
Class
- ContentEntityTrackingManager
- Provides hook implementations on behalf of the Content Entity datasource.
Namespace
Drupal\search_api\Plugin\search_api\datasourceCode
public function indexUpdate(IndexInterface $index) {
if (!$index
->status()) {
return;
}
/** @var \Drupal\search_api\IndexInterface $original */
$original = $index->original ?? NULL;
if (!$original || !$original
->status()) {
return;
}
foreach ($index
->getDatasources() as $datasource_id => $datasource) {
if ($datasource
->getBaseId() != 'entity' || !$original
->isValidDatasource($datasource_id)) {
continue;
}
$old_datasource = $original
->getDatasource($datasource_id);
$old_config = $old_datasource
->getConfiguration();
$new_config = $datasource
->getConfiguration();
if ($old_config != $new_config) {
// Bundles and languages share the same structure, so changes can be
// processed in a unified way.
$tasks = [];
$insert_task = ContentEntityTaskManager::INSERT_ITEMS_TASK_TYPE;
$delete_task = ContentEntityTaskManager::DELETE_ITEMS_TASK_TYPE;
$settings = [];
$entity_type = $this->entityTypeManager
->getDefinition($datasource
->getEntityTypeId());
if ($entity_type
->hasKey('bundle')) {
$settings['bundles'] = $datasource
->getBundles();
}
if ($entity_type
->isTranslatable()) {
$settings['languages'] = $this->languageManager
->getLanguages();
}
// Determine which bundles/languages have been newly selected or
// deselected and then assign them to the appropriate actions depending
// on the current "default" setting.
foreach ($settings as $setting => $all) {
$old_selected = array_flip($old_config[$setting]['selected']);
$new_selected = array_flip($new_config[$setting]['selected']);
// First, check if the "default" setting changed and invert the checked
// items for the old config, so the following comparison makes sense.
if ($old_config[$setting]['default'] != $new_config[$setting]['default']) {
$old_selected = array_diff_key($all, $old_selected);
}
$newly_selected = array_keys(array_diff_key($new_selected, $old_selected));
$newly_unselected = array_keys(array_diff_key($old_selected, $new_selected));
if ($new_config[$setting]['default']) {
$tasks[$insert_task][$setting] = $newly_unselected;
$tasks[$delete_task][$setting] = $newly_selected;
}
else {
$tasks[$insert_task][$setting] = $newly_selected;
$tasks[$delete_task][$setting] = $newly_unselected;
}
}
// This will keep only those tasks where at least one of "bundles" or
// "languages" is non-empty.
$tasks = array_filter($tasks, 'array_filter');
foreach ($tasks as $task => $data) {
$data += [
'datasource' => $datasource_id,
'page' => 0,
];
$this->taskManager
->addTask($task, NULL, $index, $data);
}
// If we added any new tasks, set a batch for them. (If we aren't in a
// form submission, this will just be ignored.)
if ($tasks) {
$this->taskManager
->setTasksBatch([
'index_id' => $index
->id(),
'type' => array_keys($tasks),
]);
}
}
}
}