taxonomy_entity_index.module in Taxonomy Entity Index 8
Same filename and directory in other branches
Module file for taxonomy_entity_index.
File
taxonomy_entity_index.moduleView source
<?php
/**
* @file
* Module file for taxonomy_entity_index.
*/
use Drupal\Core\Cache\Cache;
use Drupal\Core\Entity\EntityInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\taxonomy\TermInterface;
/**
* Implements hook_field_config_delete().
*/
function taxonomy_entity_index_field_config_delete(FieldConfig $instance) {
\Drupal::database()
->delete('taxonomy_entity_index')
->condition('field_name', $instance
->id())
->condition('entity_type', $instance
->getEntityTypeId())
->condition('bundle', $instance
->bundle())
->execute();
}
/**
* Implements hook_entity_delete().
*/
function taxonomy_entity_index_entity_delete(EntityInterface $entity) {
\Drupal::database()
->delete('taxonomy_entity_index')
->condition('entity_type', $entity
->getEntityTypeId())
->condition('entity_id', $entity
->id())
->execute();
}
/**
* Implements hook_ENTITY_TYPE_delete().
*/
function taxonomy_entity_index_taxonomy_term_delete(TermInterface $term) {
\Drupal::database()
->delete('taxonomy_entity_index')
->condition('tid', $term
->id())
->execute();
}
/**
* Implements hook_entity_revision_delete().
*/
function taxonomy_entity_index_entity_revision_delete(EntityInterface $entity) {
\Drupal::database()
->delete('taxonomy_entity_index')
->condition('entity_type', $entity
->getEntityTypeId())
->condition('entity_id', $entity
->id())
->condition('revision_id', $entity
->getRevisionId())
->execute();
}
/**
* Implements hook_entity_insert().
*/
function taxonomy_entity_index_entity_insert(EntityInterface $entity) {
taxonomy_entity_index_entity_update($entity);
}
/**
* Implements hook_entity_update().
*/
function taxonomy_entity_index_entity_update(EntityInterface $entity) {
$entity_type_id = $entity
->getEntityTypeId();
$config = \Drupal::config('taxonomy_entity_index.settings');
$entity_types_to_index = $config
->get('types');
if (!in_array($entity_type_id, $entity_types_to_index)) {
return;
}
$entity_id = $entity
->id();
$bundle = $entity
->bundle();
$revision_id = NULL;
if ($entity
->getEntityType()
->isRevisionable() === TRUE) {
$revision_id = $entity
->getRevisionId();
}
if (is_null($revision_id)) {
$revision_id = $entity_id;
}
if (!empty($config
->get('index_revisions'))) {
// Clear previous taxonomy index for the specific revision ID of the entity
// since we want to keep track of previous revisions.
\Drupal::database()
->delete('taxonomy_entity_index')
->condition('entity_type', $entity_type_id)
->condition('entity_id', $entity_id)
->condition('revision_id', $revision_id)
->execute();
}
else {
// Clear all prior index records for this entity.
\Drupal::database()
->delete('taxonomy_entity_index')
->condition('entity_type', $entity_type_id)
->condition('entity_id', $entity_id)
->execute();
}
$term_ref_field_names = taxonomy_entity_index_get_taxonomy_field_names($entity_type_id);
if (empty($term_ref_field_names[$bundle])) {
return;
}
$term_ref_field_names = $term_ref_field_names[$bundle];
$terms = [];
foreach ($term_ref_field_names as $field_name) {
if ($items = $entity
->get($field_name)
->getValue()) {
foreach ($items as $delta => $item) {
// Check the terms array to see if this one is already there.
$exists = array_search($item['target_id'], array_column($terms, 'tid'));
// Check config to see if we are to index each field individually.
if (!empty($config
->get('index_per_field')) || $exists === FALSE) {
$terms[] = [
'tid' => $item['target_id'],
'field_name' => $field_name,
'delta' => $delta,
];
}
}
}
}
if (!empty($terms)) {
$query = \Drupal::database()
->insert('taxonomy_entity_index');
$query
->fields([
'entity_type',
'bundle',
'entity_id',
'revision_id',
'field_name',
'delta',
'tid',
]);
foreach ($terms as $term) {
$query
->values([
'entity_type' => $entity_type_id,
'bundle' => $bundle,
'entity_id' => $entity_id,
'revision_id' => $revision_id,
'field_name' => $term['field_name'],
'delta' => $term['delta'],
'tid' => $term['tid'],
]);
}
$query
->execute();
}
}
/**
* Return all the taxonomy entity reference field names for a given entity type.
*/
function taxonomy_entity_index_get_taxonomy_field_names($entity_type_id) {
$cache_id = 'entity-taxonomy-fields_' . $entity_type_id;
$entity_ref_fields =& drupal_static($cache_id);
if (!isset($entity_ref_fields)) {
if ($cache = \Drupal::cache()
->get($cache_id)) {
$entity_ref_fields = $cache->data;
}
else {
$entity_ref_fields = [];
$entity_field_manager = \Drupal::service('entity_field.manager');
$fieldmap = $entity_field_manager
->getFieldMapByFieldType('entity_reference');
if (isset($fieldmap[$entity_type_id])) {
foreach ($fieldmap[$entity_type_id] as $field_name => $field) {
foreach ($field['bundles'] as $bundle) {
$field_definitions =& drupal_static('entity-taxonomy-field-defs' . '_' . $entity_type_id . '_' . $bundle);
if (!isset($field_definitions)) {
$field_definitions = $entity_field_manager
->getFieldDefinitions($entity_type_id, $bundle);
}
$field_definition = $field_definitions[$field_name];
$settings = $field_definition
->getSettings();
if ($settings['target_type'] === 'taxonomy_term') {
$entity_ref_fields[$bundle][] = $field_name;
}
}
}
}
\Drupal::cache()
->set($cache_id, $entity_ref_fields, Cache::PERMANENT, [
'entity_types',
'entity_field_info',
]);
}
}
return $entity_ref_fields;
}
/**
* Batch callback; re-index all the terms for a given entity type.
*/
function taxonomy_entity_index_reindex_entity_type($entity_type_id, &$context) {
$entity_type_manger = \Drupal::entityTypeManager();
$entity_type = $entity_type_manger
->getDefinition($entity_type_id);
$bundle_key = $entity_type
->getKey('bundle');
if (empty($context['sandbox'])) {
$context['sandbox'] = [];
$context['sandbox']['progress'] = 0;
$context['sandbox']['current_id'] = 0;
$context['sandbox']['bundles'] = array_keys(taxonomy_entity_index_get_taxonomy_field_names($entity_type_id));
$context['sandbox']['entity_key_id'] = $entity_type
->getKey('id');
// Clear out any records for this type.
\Drupal::database()
->delete('taxonomy_entity_index')
->condition('entity_type', $entity_type_id)
->execute();
// Calculate the maximum number of entities.
if (!empty($context['sandbox']['bundles'])) {
$query = \Drupal::entityQuery($entity_type_id);
if ($bundle_key) {
$query
->condition($bundle_key, $context['sandbox']['bundles'], 'IN');
}
$query
->condition($context['sandbox']['entity_key_id'], 0, '>');
$query
->count();
$context['sandbox']['max'] = (int) $query
->execute();
}
if (empty($context['sandbox']['max'])) {
$context['finished'] = TRUE;
return;
}
}
$entity_id_key = $context['sandbox']['entity_key_id'];
$limit = 25;
$query = \Drupal::entityQuery($entity_type_id);
if ($bundle_key) {
$query
->condition($bundle_key, $context['sandbox']['bundles'], 'IN');
}
$query
->condition($entity_id_key, $context['sandbox']['current_id'], '>');
$query
->sort($entity_id_key, 'ASC');
$query
->range(0, $limit);
$results = $query
->execute();
$entities = $entity_type_manger
->getStorage($entity_type_id)
->loadMultiple($results);
foreach ($entities as $id => $entity) {
taxonomy_entity_index_entity_update($entity);
$context['sandbox']['current_id'] = $id;
$context['message'] = t('Updating taxonomy entity index data for @type @id.', [
'@type' => $entity_type_id,
'@id' => $id,
]);
}
// In case any of the entities fail to load, increase the progress by the
// stub entity count.
$context['sandbox']['progress'] += count($results);
if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
$context['finished'] = $context['sandbox']['progress'] >= $context['sandbox']['max'];
}
}
/**
* Batch 'finished' callback.
*
* @see taxonomy_entity_index_admin_form()
* @see taxonomy_entity_index_reindex_entity_type()
*/
function taxonomy_entity_index_reindex_finished($success, $results, $operations) {
if ($success) {
\Drupal::messenger()
->addMessage(t('Taxonomy entity index rebuilt successfully.'));
}
else {
// An error occurred.
\Drupal::messenger()
->addError(t('An error occurred while processing the operation.'));
}
}
/**
* Get all entity types, which can be used in the views integration.
*
* Therefore both the entity type has to be fieldable and the base table
* has already a views integration.
*
* @return \Drupal\Core\Entity\EntityTypeInterface[]
* An array of entity types.
*/
function taxonomy_entity_index_entity_views_integrable() {
$entity_types = \Drupal::entityTypeManager()
->getDefinitions();
foreach ($entity_types as $entity_type_id => $entity_type) {
if (is_null($entity_type
->getBaseTable()) || !$entity_type
->entityClassImplements('\\Drupal\\Core\\Entity\\ContentEntityInterface')) {
unset($entity_types[$entity_type_id]);
}
}
return $entity_types;
}
/**
* Determine if the views plugins should support revisions.
*
* @param array $entity_keys
* The entity keys for the type being checked.
*
* @return bool
* True indicates revisions should be supported.
*/
function taxonomy_entity_index_entity_views_revisionable(array $entity_keys) {
// Return false if revision support isn't enabled.
$config = \Drupal::config('taxonomy_entity_index.settings');
if (empty($config
->get('index_revisions'))) {
return FALSE;
}
// Does the entity support revisions?
if (!empty($entity_keys['revision'])) {
return TRUE;
}
// Default to false.
return FALSE;
}
Functions
Name | Description |
---|---|
taxonomy_entity_index_entity_delete | Implements hook_entity_delete(). |
taxonomy_entity_index_entity_insert | Implements hook_entity_insert(). |
taxonomy_entity_index_entity_revision_delete | Implements hook_entity_revision_delete(). |
taxonomy_entity_index_entity_update | Implements hook_entity_update(). |
taxonomy_entity_index_entity_views_integrable | Get all entity types, which can be used in the views integration. |
taxonomy_entity_index_entity_views_revisionable | Determine if the views plugins should support revisions. |
taxonomy_entity_index_field_config_delete | Implements hook_field_config_delete(). |
taxonomy_entity_index_get_taxonomy_field_names | Return all the taxonomy entity reference field names for a given entity type. |
taxonomy_entity_index_reindex_entity_type | Batch callback; re-index all the terms for a given entity type. |
taxonomy_entity_index_reindex_finished | Batch 'finished' callback. |
taxonomy_entity_index_taxonomy_term_delete | Implements hook_ENTITY_TYPE_delete(). |