From 0bbdda654647b7123cd25d3f8ddfab0c4dbebe9b Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Thu, 6 Feb 2025 10:17:56 -0500 Subject: [PATCH 01/53] Splitting entity related hooks into separate class, adding build_node_index and delete_node_index as private methods. --- .../taxonomy/src/Hook/TaxonomyEntityHooks.php | 190 ++++++++++++++++++ .../taxonomy/src/Hook/TaxonomyHooks.php | 83 -------- 2 files changed, 190 insertions(+), 83 deletions(-) create mode 100644 core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php new file mode 100644 index 000000000000..ab2a5b6ef806 --- /dev/null +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -0,0 +1,190 @@ +<?php + +namespace Drupal\taxonomy\Hook; + +use Drupal\taxonomy\Entity\Term; +use Drupal\Core\Config\ConfigFactoryInterface; +use Drupal\Core\Hook\Attribute\Hook; +use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Entity\Sql\SqlContentEntityStorage; +use Drupal\Core\Url; + +/** + * Hook implementations for taxonomy. + */ +class TaxonomyEntityHooks { + + /** + * A config factory for retrieving required config settings. + * + * @var \Drupal\Core\Config\ConfigFactoryInterface + */ + protected $configFactory; + + /** + * A config factory for retrieving required config settings. + * + * @property \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager + */ + protected $entityTypeManager; + + /** + * Constructs TaxonomyEntityHooks. + * + * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory + * The configuration factory. + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager + * The entity type manager. + */ + public function __construct(ConfigFactoryInterface $configFactory, EntityTypeManagerInterface $entityTypeManager) { + $this->configFactory = $configFactory; + $this->entityTypeManager = $entityTypeManager; + } + + /** + * Builds and inserts taxonomy index entries for a given node. + * + * The index lists all terms that are related to a given node entity, and is + * therefore maintained at the entity level. + * + * @param \Drupal\node\Entity\Node $node + * The node entity. + */ + protected function build_node_index($node) { + // We maintain a denormalized table of term/node relationships, containing + // only data for current, published nodes. + if (!\Drupal::config('taxonomy.settings')->get('maintain_index_table') || !($this->entityTypeManager->getStorage('node') instanceof SqlContentEntityStorage)) { + return; + } + + $status = $node->isPublished(); + $sticky = (int) $node->isSticky(); + // We only maintain the taxonomy index for published nodes. + if ($status && $node->isDefaultRevision()) { + // Collect a unique list of all the term IDs from all node fields. + $tid_all = []; + $entity_reference_class = 'Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem'; + foreach ($node->getFieldDefinitions() as $field) { + $field_name = $field->getName(); + $class = $field->getItemDefinition()->getClass(); + $is_entity_reference_class = ($class === $entity_reference_class) || is_subclass_of($class, $entity_reference_class); + if ($is_entity_reference_class && $field->getSetting('target_type') == 'taxonomy_term') { + foreach ($node->getTranslationLanguages() as $language) { + foreach ($node->getTranslation($language->getId())->$field_name as $item) { + if (!$item->isEmpty()) { + $tid_all[$item->target_id] = $item->target_id; + } + } + } + } + } + // Insert index entries for all the node's terms. + if (!empty($tid_all)) { + $connection = \Drupal::database(); + foreach ($tid_all as $tid) { + $connection->merge('taxonomy_index') + ->keys(['nid' => $node->id(), 'tid' => $tid, 'status' => $node->isPublished()]) + ->fields(['sticky' => $sticky, 'created' => $node->getCreatedTime()]) + ->execute(); + } + } + } + } + + /** + * Deletes taxonomy index entries for a given node. + * + * @param \Drupal\Core\Entity\EntityInterface $node + * The node entity. + */ + protected function delete_node_index(EntityInterface $node) { + if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) { + \Drupal::database()->delete('taxonomy_index')->condition('nid', $node->id())->execute(); + } + } + + /** + * Implements hook_entity_operation(). + */ + #[Hook('entity_operation')] + public function entityOperation(EntityInterface $term): array { + $operations = []; + if ($term instanceof Term && $term->access('create')) { + $operations['add-child'] = [ + 'title' => t('Add child'), + 'weight' => 10, + 'url' => Url::fromRoute('entity.taxonomy_term.add_form', [ + 'taxonomy_vocabulary' => $term->bundle(), + ], [ + 'query' => [ + 'parent' => $term->id(), + ], + ]), + ]; + } + return $operations; + } + + /** + * @defgroup taxonomy_index Taxonomy indexing + * @{ + * Functions to maintain taxonomy indexing. + * + * Taxonomy uses default field storage to store canonical relationships + * between terms and fieldable entities. However its most common use case + * requires listing all content associated with a term or group of terms + * sorted by creation date. To avoid slow queries due to joining across + * multiple node and field tables with various conditions and order by + * criteria, we maintain a denormalized table with all relationships between + * terms, published nodes and common sort criteria such as status, sticky and + * created. When using other field storage engines or alternative methods of + * denormalizing this data you should set the + * taxonomy.settings:maintain_index_table to '0' to avoid unnecessary writes + * in SQL. + */ + + /** + * Implements hook_ENTITY_TYPE_insert() for node entities. + */ + #[Hook('node_insert')] + public function nodeInsert(EntityInterface $node): void { + // Add taxonomy index entries for the node. + $this->build_node_index($node); + } + + /** + * Implements hook_ENTITY_TYPE_update() for node entities. + */ + #[Hook('node_update')] + public function nodeUpdate(EntityInterface $node): void { + // If we're not dealing with the default revision of the node, do not make any + // change to the taxonomy index. + if (!$node->isDefaultRevision()) { + return; + } + $this->delete_node_index($node); + $this->build_node_index($node); + } + + /** + * Implements hook_ENTITY_TYPE_predelete() for node entities. + */ + #[Hook('node_predelete')] + public function nodePredelete(EntityInterface $node): void { + // Clean up the {taxonomy_index} table when nodes are deleted. + $this->delete_node_index($node); + } + + /** + * Implements hook_ENTITY_TYPE_delete() for taxonomy_term entities. + */ + #[Hook('taxonomy_term_delete')] + public function taxonomyTermDelete(Term $term): void { + if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) { + // Clean up the {taxonomy_index} table when terms are deleted. + \Drupal::database()->delete('taxonomy_index')->condition('tid', $term->id())->execute(); + } + } + +} diff --git a/core/modules/taxonomy/src/Hook/TaxonomyHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyHooks.php index fcbc82172927..e9e037c426e6 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyHooks.php @@ -93,87 +93,4 @@ public function localTasksAlter(&$local_tasks): void { } } - /** - * Implements hook_entity_operation(). - */ - #[Hook('entity_operation')] - public function entityOperation(EntityInterface $term): array { - $operations = []; - if ($term instanceof Term && $term->access('create')) { - $operations['add-child'] = [ - 'title' => t('Add child'), - 'weight' => 10, - 'url' => Url::fromRoute('entity.taxonomy_term.add_form', [ - 'taxonomy_vocabulary' => $term->bundle(), - ], [ - 'query' => [ - 'parent' => $term->id(), - ], - ]), - ]; - } - return $operations; - } - - /** - * @defgroup taxonomy_index Taxonomy indexing - * @{ - * Functions to maintain taxonomy indexing. - * - * Taxonomy uses default field storage to store canonical relationships - * between terms and fieldable entities. However its most common use case - * requires listing all content associated with a term or group of terms - * sorted by creation date. To avoid slow queries due to joining across - * multiple node and field tables with various conditions and order by - * criteria, we maintain a denormalized table with all relationships between - * terms, published nodes and common sort criteria such as status, sticky and - * created. When using other field storage engines or alternative methods of - * denormalizing this data you should set the - * taxonomy.settings:maintain_index_table to '0' to avoid unnecessary writes - * in SQL. - */ - - /** - * Implements hook_ENTITY_TYPE_insert() for node entities. - */ - #[Hook('node_insert')] - public function nodeInsert(EntityInterface $node) { - // Add taxonomy index entries for the node. - taxonomy_build_node_index($node); - } - - /** - * Implements hook_ENTITY_TYPE_update() for node entities. - */ - #[Hook('node_update')] - public function nodeUpdate(EntityInterface $node) { - // If we're not dealing with the default revision of the node, do not make any - // change to the taxonomy index. - if (!$node->isDefaultRevision()) { - return; - } - taxonomy_delete_node_index($node); - taxonomy_build_node_index($node); - } - - /** - * Implements hook_ENTITY_TYPE_predelete() for node entities. - */ - #[Hook('node_predelete')] - public function nodePredelete(EntityInterface $node) { - // Clean up the {taxonomy_index} table when nodes are deleted. - taxonomy_delete_node_index($node); - } - - /** - * Implements hook_ENTITY_TYPE_delete() for taxonomy_term entities. - */ - #[Hook('taxonomy_term_delete')] - public function taxonomyTermDelete(Term $term) { - if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) { - // Clean up the {taxonomy_index} table when terms are deleted. - \Drupal::database()->delete('taxonomy_index')->condition('tid', $term->id())->execute(); - } - } - } -- GitLab From 1989963a674932b2d074e0ceace9ae1118365b11 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Thu, 6 Feb 2025 10:26:07 -0500 Subject: [PATCH 02/53] Fixing PHPSTAN errors --- core/modules/taxonomy/src/Hook/TaxonomyHooks.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyHooks.php index e9e037c426e6..38637cd81b42 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyHooks.php @@ -2,8 +2,6 @@ namespace Drupal\taxonomy\Hook; -use Drupal\taxonomy\Entity\Term; -use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Url; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Hook\Attribute\Hook; -- GitLab From 096ae5514ef98cc7cfdf6d66b7697cc6d0a8574d Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Thu, 6 Feb 2025 12:01:48 -0500 Subject: [PATCH 03/53] Updating baseline. --- core/.phpstan-baseline.php | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/core/.phpstan-baseline.php b/core/.phpstan-baseline.php index d6347f6b7225..bb46e2ba72dd 100644 --- a/core/.phpstan-baseline.php +++ b/core/.phpstan-baseline.php @@ -40155,30 +40155,6 @@ 'count' => 1, 'path' => __DIR__ . '/modules/taxonomy/src/Hook/TaxonomyHooks.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\taxonomy\\\\Hook\\\\TaxonomyHooks\\:\\:nodeInsert\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/modules/taxonomy/src/Hook/TaxonomyHooks.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\taxonomy\\\\Hook\\\\TaxonomyHooks\\:\\:nodePredelete\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/modules/taxonomy/src/Hook/TaxonomyHooks.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\taxonomy\\\\Hook\\\\TaxonomyHooks\\:\\:nodeUpdate\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/modules/taxonomy/src/Hook/TaxonomyHooks.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\taxonomy\\\\Hook\\\\TaxonomyHooks\\:\\:taxonomyTermDelete\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/modules/taxonomy/src/Hook/TaxonomyHooks.php', -]; $ignoreErrors[] = [ 'message' => '#^Method Drupal\\\\taxonomy\\\\Plugin\\\\Validation\\\\Constraint\\\\TaxonomyTermHierarchyConstraintValidator\\:\\:create\\(\\) has no return type specified\\.$#', 'identifier' => 'missingType.return', -- GitLab From 56025e14aff8e45deaba1832527e941b9de5ea48 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Thu, 6 Feb 2025 12:10:55 -0500 Subject: [PATCH 04/53] Adding return types for delete_node_index and build_node_index. --- core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index ab2a5b6ef806..dd02924e3366 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -51,7 +51,7 @@ public function __construct(ConfigFactoryInterface $configFactory, EntityTypeMan * @param \Drupal\node\Entity\Node $node * The node entity. */ - protected function build_node_index($node) { + protected function build_node_index($node): void { // We maintain a denormalized table of term/node relationships, containing // only data for current, published nodes. if (!\Drupal::config('taxonomy.settings')->get('maintain_index_table') || !($this->entityTypeManager->getStorage('node') instanceof SqlContentEntityStorage)) { @@ -98,7 +98,7 @@ protected function build_node_index($node) { * @param \Drupal\Core\Entity\EntityInterface $node * The node entity. */ - protected function delete_node_index(EntityInterface $node) { + protected function delete_node_index(EntityInterface $node): void { if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) { \Drupal::database()->delete('taxonomy_index')->condition('nid', $node->id())->execute(); } -- GitLab From 599aae7d8d1ab85b554a6c3eed8ea71f815060f0 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Thu, 6 Feb 2025 10:17:56 -0500 Subject: [PATCH 05/53] Splitting entity related hooks into separate class, adding build_node_index and delete_node_index as private methods. --- .../taxonomy/src/Hook/TaxonomyEntityHooks.php | 190 ++++++++++++++++++ .../taxonomy/src/Hook/TaxonomyHooks.php | 83 -------- 2 files changed, 190 insertions(+), 83 deletions(-) create mode 100644 core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php new file mode 100644 index 000000000000..ab2a5b6ef806 --- /dev/null +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -0,0 +1,190 @@ +<?php + +namespace Drupal\taxonomy\Hook; + +use Drupal\taxonomy\Entity\Term; +use Drupal\Core\Config\ConfigFactoryInterface; +use Drupal\Core\Hook\Attribute\Hook; +use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Entity\Sql\SqlContentEntityStorage; +use Drupal\Core\Url; + +/** + * Hook implementations for taxonomy. + */ +class TaxonomyEntityHooks { + + /** + * A config factory for retrieving required config settings. + * + * @var \Drupal\Core\Config\ConfigFactoryInterface + */ + protected $configFactory; + + /** + * A config factory for retrieving required config settings. + * + * @property \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager + */ + protected $entityTypeManager; + + /** + * Constructs TaxonomyEntityHooks. + * + * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory + * The configuration factory. + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager + * The entity type manager. + */ + public function __construct(ConfigFactoryInterface $configFactory, EntityTypeManagerInterface $entityTypeManager) { + $this->configFactory = $configFactory; + $this->entityTypeManager = $entityTypeManager; + } + + /** + * Builds and inserts taxonomy index entries for a given node. + * + * The index lists all terms that are related to a given node entity, and is + * therefore maintained at the entity level. + * + * @param \Drupal\node\Entity\Node $node + * The node entity. + */ + protected function build_node_index($node) { + // We maintain a denormalized table of term/node relationships, containing + // only data for current, published nodes. + if (!\Drupal::config('taxonomy.settings')->get('maintain_index_table') || !($this->entityTypeManager->getStorage('node') instanceof SqlContentEntityStorage)) { + return; + } + + $status = $node->isPublished(); + $sticky = (int) $node->isSticky(); + // We only maintain the taxonomy index for published nodes. + if ($status && $node->isDefaultRevision()) { + // Collect a unique list of all the term IDs from all node fields. + $tid_all = []; + $entity_reference_class = 'Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem'; + foreach ($node->getFieldDefinitions() as $field) { + $field_name = $field->getName(); + $class = $field->getItemDefinition()->getClass(); + $is_entity_reference_class = ($class === $entity_reference_class) || is_subclass_of($class, $entity_reference_class); + if ($is_entity_reference_class && $field->getSetting('target_type') == 'taxonomy_term') { + foreach ($node->getTranslationLanguages() as $language) { + foreach ($node->getTranslation($language->getId())->$field_name as $item) { + if (!$item->isEmpty()) { + $tid_all[$item->target_id] = $item->target_id; + } + } + } + } + } + // Insert index entries for all the node's terms. + if (!empty($tid_all)) { + $connection = \Drupal::database(); + foreach ($tid_all as $tid) { + $connection->merge('taxonomy_index') + ->keys(['nid' => $node->id(), 'tid' => $tid, 'status' => $node->isPublished()]) + ->fields(['sticky' => $sticky, 'created' => $node->getCreatedTime()]) + ->execute(); + } + } + } + } + + /** + * Deletes taxonomy index entries for a given node. + * + * @param \Drupal\Core\Entity\EntityInterface $node + * The node entity. + */ + protected function delete_node_index(EntityInterface $node) { + if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) { + \Drupal::database()->delete('taxonomy_index')->condition('nid', $node->id())->execute(); + } + } + + /** + * Implements hook_entity_operation(). + */ + #[Hook('entity_operation')] + public function entityOperation(EntityInterface $term): array { + $operations = []; + if ($term instanceof Term && $term->access('create')) { + $operations['add-child'] = [ + 'title' => t('Add child'), + 'weight' => 10, + 'url' => Url::fromRoute('entity.taxonomy_term.add_form', [ + 'taxonomy_vocabulary' => $term->bundle(), + ], [ + 'query' => [ + 'parent' => $term->id(), + ], + ]), + ]; + } + return $operations; + } + + /** + * @defgroup taxonomy_index Taxonomy indexing + * @{ + * Functions to maintain taxonomy indexing. + * + * Taxonomy uses default field storage to store canonical relationships + * between terms and fieldable entities. However its most common use case + * requires listing all content associated with a term or group of terms + * sorted by creation date. To avoid slow queries due to joining across + * multiple node and field tables with various conditions and order by + * criteria, we maintain a denormalized table with all relationships between + * terms, published nodes and common sort criteria such as status, sticky and + * created. When using other field storage engines or alternative methods of + * denormalizing this data you should set the + * taxonomy.settings:maintain_index_table to '0' to avoid unnecessary writes + * in SQL. + */ + + /** + * Implements hook_ENTITY_TYPE_insert() for node entities. + */ + #[Hook('node_insert')] + public function nodeInsert(EntityInterface $node): void { + // Add taxonomy index entries for the node. + $this->build_node_index($node); + } + + /** + * Implements hook_ENTITY_TYPE_update() for node entities. + */ + #[Hook('node_update')] + public function nodeUpdate(EntityInterface $node): void { + // If we're not dealing with the default revision of the node, do not make any + // change to the taxonomy index. + if (!$node->isDefaultRevision()) { + return; + } + $this->delete_node_index($node); + $this->build_node_index($node); + } + + /** + * Implements hook_ENTITY_TYPE_predelete() for node entities. + */ + #[Hook('node_predelete')] + public function nodePredelete(EntityInterface $node): void { + // Clean up the {taxonomy_index} table when nodes are deleted. + $this->delete_node_index($node); + } + + /** + * Implements hook_ENTITY_TYPE_delete() for taxonomy_term entities. + */ + #[Hook('taxonomy_term_delete')] + public function taxonomyTermDelete(Term $term): void { + if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) { + // Clean up the {taxonomy_index} table when terms are deleted. + \Drupal::database()->delete('taxonomy_index')->condition('tid', $term->id())->execute(); + } + } + +} diff --git a/core/modules/taxonomy/src/Hook/TaxonomyHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyHooks.php index fcbc82172927..e9e037c426e6 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyHooks.php @@ -93,87 +93,4 @@ public function localTasksAlter(&$local_tasks): void { } } - /** - * Implements hook_entity_operation(). - */ - #[Hook('entity_operation')] - public function entityOperation(EntityInterface $term): array { - $operations = []; - if ($term instanceof Term && $term->access('create')) { - $operations['add-child'] = [ - 'title' => t('Add child'), - 'weight' => 10, - 'url' => Url::fromRoute('entity.taxonomy_term.add_form', [ - 'taxonomy_vocabulary' => $term->bundle(), - ], [ - 'query' => [ - 'parent' => $term->id(), - ], - ]), - ]; - } - return $operations; - } - - /** - * @defgroup taxonomy_index Taxonomy indexing - * @{ - * Functions to maintain taxonomy indexing. - * - * Taxonomy uses default field storage to store canonical relationships - * between terms and fieldable entities. However its most common use case - * requires listing all content associated with a term or group of terms - * sorted by creation date. To avoid slow queries due to joining across - * multiple node and field tables with various conditions and order by - * criteria, we maintain a denormalized table with all relationships between - * terms, published nodes and common sort criteria such as status, sticky and - * created. When using other field storage engines or alternative methods of - * denormalizing this data you should set the - * taxonomy.settings:maintain_index_table to '0' to avoid unnecessary writes - * in SQL. - */ - - /** - * Implements hook_ENTITY_TYPE_insert() for node entities. - */ - #[Hook('node_insert')] - public function nodeInsert(EntityInterface $node) { - // Add taxonomy index entries for the node. - taxonomy_build_node_index($node); - } - - /** - * Implements hook_ENTITY_TYPE_update() for node entities. - */ - #[Hook('node_update')] - public function nodeUpdate(EntityInterface $node) { - // If we're not dealing with the default revision of the node, do not make any - // change to the taxonomy index. - if (!$node->isDefaultRevision()) { - return; - } - taxonomy_delete_node_index($node); - taxonomy_build_node_index($node); - } - - /** - * Implements hook_ENTITY_TYPE_predelete() for node entities. - */ - #[Hook('node_predelete')] - public function nodePredelete(EntityInterface $node) { - // Clean up the {taxonomy_index} table when nodes are deleted. - taxonomy_delete_node_index($node); - } - - /** - * Implements hook_ENTITY_TYPE_delete() for taxonomy_term entities. - */ - #[Hook('taxonomy_term_delete')] - public function taxonomyTermDelete(Term $term) { - if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) { - // Clean up the {taxonomy_index} table when terms are deleted. - \Drupal::database()->delete('taxonomy_index')->condition('tid', $term->id())->execute(); - } - } - } -- GitLab From 86a2d95248f7ce909b3a3c84dda4943f97b66f17 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Thu, 6 Feb 2025 10:26:07 -0500 Subject: [PATCH 06/53] Fixing PHPSTAN errors --- core/modules/taxonomy/src/Hook/TaxonomyHooks.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyHooks.php index e9e037c426e6..38637cd81b42 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyHooks.php @@ -2,8 +2,6 @@ namespace Drupal\taxonomy\Hook; -use Drupal\taxonomy\Entity\Term; -use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Url; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Hook\Attribute\Hook; -- GitLab From 1c4473b75c31d6e75d5c80ddfd95db92bfb7805b Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Thu, 6 Feb 2025 12:01:48 -0500 Subject: [PATCH 07/53] Updating baseline. --- core/.phpstan-baseline.php | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/core/.phpstan-baseline.php b/core/.phpstan-baseline.php index 8e9b084c392e..26f15bb279b6 100644 --- a/core/.phpstan-baseline.php +++ b/core/.phpstan-baseline.php @@ -40071,30 +40071,6 @@ 'count' => 1, 'path' => __DIR__ . '/modules/taxonomy/src/Hook/TaxonomyHooks.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\taxonomy\\\\Hook\\\\TaxonomyHooks\\:\\:nodeInsert\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/modules/taxonomy/src/Hook/TaxonomyHooks.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\taxonomy\\\\Hook\\\\TaxonomyHooks\\:\\:nodePredelete\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/modules/taxonomy/src/Hook/TaxonomyHooks.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\taxonomy\\\\Hook\\\\TaxonomyHooks\\:\\:nodeUpdate\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/modules/taxonomy/src/Hook/TaxonomyHooks.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\taxonomy\\\\Hook\\\\TaxonomyHooks\\:\\:taxonomyTermDelete\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/modules/taxonomy/src/Hook/TaxonomyHooks.php', -]; $ignoreErrors[] = [ 'message' => '#^Method Drupal\\\\taxonomy\\\\Plugin\\\\Validation\\\\Constraint\\\\TaxonomyTermHierarchyConstraintValidator\\:\\:create\\(\\) has no return type specified\\.$#', 'identifier' => 'missingType.return', -- GitLab From 86f61a02323b43940d814348eedcc2ada4acf8c5 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Thu, 6 Feb 2025 12:10:55 -0500 Subject: [PATCH 08/53] Adding return types for delete_node_index and build_node_index. --- core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index ab2a5b6ef806..dd02924e3366 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -51,7 +51,7 @@ public function __construct(ConfigFactoryInterface $configFactory, EntityTypeMan * @param \Drupal\node\Entity\Node $node * The node entity. */ - protected function build_node_index($node) { + protected function build_node_index($node): void { // We maintain a denormalized table of term/node relationships, containing // only data for current, published nodes. if (!\Drupal::config('taxonomy.settings')->get('maintain_index_table') || !($this->entityTypeManager->getStorage('node') instanceof SqlContentEntityStorage)) { @@ -98,7 +98,7 @@ protected function build_node_index($node) { * @param \Drupal\Core\Entity\EntityInterface $node * The node entity. */ - protected function delete_node_index(EntityInterface $node) { + protected function delete_node_index(EntityInterface $node): void { if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) { \Drupal::database()->delete('taxonomy_index')->condition('nid', $node->id())->execute(); } -- GitLab From 06ef25afb0372bb6d55fc7d41875a058a3c5b1ee Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Thu, 6 Feb 2025 10:17:56 -0500 Subject: [PATCH 09/53] Splitting entity related hooks into separate class, adding build_node_index and delete_node_index as private methods. --- .../taxonomy/src/Hook/TaxonomyEntityHooks.php | 190 ++++++++++++++++++ .../taxonomy/src/Hook/TaxonomyHooks.php | 83 -------- 2 files changed, 190 insertions(+), 83 deletions(-) create mode 100644 core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php new file mode 100644 index 000000000000..ab2a5b6ef806 --- /dev/null +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -0,0 +1,190 @@ +<?php + +namespace Drupal\taxonomy\Hook; + +use Drupal\taxonomy\Entity\Term; +use Drupal\Core\Config\ConfigFactoryInterface; +use Drupal\Core\Hook\Attribute\Hook; +use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Entity\Sql\SqlContentEntityStorage; +use Drupal\Core\Url; + +/** + * Hook implementations for taxonomy. + */ +class TaxonomyEntityHooks { + + /** + * A config factory for retrieving required config settings. + * + * @var \Drupal\Core\Config\ConfigFactoryInterface + */ + protected $configFactory; + + /** + * A config factory for retrieving required config settings. + * + * @property \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager + */ + protected $entityTypeManager; + + /** + * Constructs TaxonomyEntityHooks. + * + * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory + * The configuration factory. + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager + * The entity type manager. + */ + public function __construct(ConfigFactoryInterface $configFactory, EntityTypeManagerInterface $entityTypeManager) { + $this->configFactory = $configFactory; + $this->entityTypeManager = $entityTypeManager; + } + + /** + * Builds and inserts taxonomy index entries for a given node. + * + * The index lists all terms that are related to a given node entity, and is + * therefore maintained at the entity level. + * + * @param \Drupal\node\Entity\Node $node + * The node entity. + */ + protected function build_node_index($node) { + // We maintain a denormalized table of term/node relationships, containing + // only data for current, published nodes. + if (!\Drupal::config('taxonomy.settings')->get('maintain_index_table') || !($this->entityTypeManager->getStorage('node') instanceof SqlContentEntityStorage)) { + return; + } + + $status = $node->isPublished(); + $sticky = (int) $node->isSticky(); + // We only maintain the taxonomy index for published nodes. + if ($status && $node->isDefaultRevision()) { + // Collect a unique list of all the term IDs from all node fields. + $tid_all = []; + $entity_reference_class = 'Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem'; + foreach ($node->getFieldDefinitions() as $field) { + $field_name = $field->getName(); + $class = $field->getItemDefinition()->getClass(); + $is_entity_reference_class = ($class === $entity_reference_class) || is_subclass_of($class, $entity_reference_class); + if ($is_entity_reference_class && $field->getSetting('target_type') == 'taxonomy_term') { + foreach ($node->getTranslationLanguages() as $language) { + foreach ($node->getTranslation($language->getId())->$field_name as $item) { + if (!$item->isEmpty()) { + $tid_all[$item->target_id] = $item->target_id; + } + } + } + } + } + // Insert index entries for all the node's terms. + if (!empty($tid_all)) { + $connection = \Drupal::database(); + foreach ($tid_all as $tid) { + $connection->merge('taxonomy_index') + ->keys(['nid' => $node->id(), 'tid' => $tid, 'status' => $node->isPublished()]) + ->fields(['sticky' => $sticky, 'created' => $node->getCreatedTime()]) + ->execute(); + } + } + } + } + + /** + * Deletes taxonomy index entries for a given node. + * + * @param \Drupal\Core\Entity\EntityInterface $node + * The node entity. + */ + protected function delete_node_index(EntityInterface $node) { + if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) { + \Drupal::database()->delete('taxonomy_index')->condition('nid', $node->id())->execute(); + } + } + + /** + * Implements hook_entity_operation(). + */ + #[Hook('entity_operation')] + public function entityOperation(EntityInterface $term): array { + $operations = []; + if ($term instanceof Term && $term->access('create')) { + $operations['add-child'] = [ + 'title' => t('Add child'), + 'weight' => 10, + 'url' => Url::fromRoute('entity.taxonomy_term.add_form', [ + 'taxonomy_vocabulary' => $term->bundle(), + ], [ + 'query' => [ + 'parent' => $term->id(), + ], + ]), + ]; + } + return $operations; + } + + /** + * @defgroup taxonomy_index Taxonomy indexing + * @{ + * Functions to maintain taxonomy indexing. + * + * Taxonomy uses default field storage to store canonical relationships + * between terms and fieldable entities. However its most common use case + * requires listing all content associated with a term or group of terms + * sorted by creation date. To avoid slow queries due to joining across + * multiple node and field tables with various conditions and order by + * criteria, we maintain a denormalized table with all relationships between + * terms, published nodes and common sort criteria such as status, sticky and + * created. When using other field storage engines or alternative methods of + * denormalizing this data you should set the + * taxonomy.settings:maintain_index_table to '0' to avoid unnecessary writes + * in SQL. + */ + + /** + * Implements hook_ENTITY_TYPE_insert() for node entities. + */ + #[Hook('node_insert')] + public function nodeInsert(EntityInterface $node): void { + // Add taxonomy index entries for the node. + $this->build_node_index($node); + } + + /** + * Implements hook_ENTITY_TYPE_update() for node entities. + */ + #[Hook('node_update')] + public function nodeUpdate(EntityInterface $node): void { + // If we're not dealing with the default revision of the node, do not make any + // change to the taxonomy index. + if (!$node->isDefaultRevision()) { + return; + } + $this->delete_node_index($node); + $this->build_node_index($node); + } + + /** + * Implements hook_ENTITY_TYPE_predelete() for node entities. + */ + #[Hook('node_predelete')] + public function nodePredelete(EntityInterface $node): void { + // Clean up the {taxonomy_index} table when nodes are deleted. + $this->delete_node_index($node); + } + + /** + * Implements hook_ENTITY_TYPE_delete() for taxonomy_term entities. + */ + #[Hook('taxonomy_term_delete')] + public function taxonomyTermDelete(Term $term): void { + if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) { + // Clean up the {taxonomy_index} table when terms are deleted. + \Drupal::database()->delete('taxonomy_index')->condition('tid', $term->id())->execute(); + } + } + +} diff --git a/core/modules/taxonomy/src/Hook/TaxonomyHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyHooks.php index fcbc82172927..e9e037c426e6 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyHooks.php @@ -93,87 +93,4 @@ public function localTasksAlter(&$local_tasks): void { } } - /** - * Implements hook_entity_operation(). - */ - #[Hook('entity_operation')] - public function entityOperation(EntityInterface $term): array { - $operations = []; - if ($term instanceof Term && $term->access('create')) { - $operations['add-child'] = [ - 'title' => t('Add child'), - 'weight' => 10, - 'url' => Url::fromRoute('entity.taxonomy_term.add_form', [ - 'taxonomy_vocabulary' => $term->bundle(), - ], [ - 'query' => [ - 'parent' => $term->id(), - ], - ]), - ]; - } - return $operations; - } - - /** - * @defgroup taxonomy_index Taxonomy indexing - * @{ - * Functions to maintain taxonomy indexing. - * - * Taxonomy uses default field storage to store canonical relationships - * between terms and fieldable entities. However its most common use case - * requires listing all content associated with a term or group of terms - * sorted by creation date. To avoid slow queries due to joining across - * multiple node and field tables with various conditions and order by - * criteria, we maintain a denormalized table with all relationships between - * terms, published nodes and common sort criteria such as status, sticky and - * created. When using other field storage engines or alternative methods of - * denormalizing this data you should set the - * taxonomy.settings:maintain_index_table to '0' to avoid unnecessary writes - * in SQL. - */ - - /** - * Implements hook_ENTITY_TYPE_insert() for node entities. - */ - #[Hook('node_insert')] - public function nodeInsert(EntityInterface $node) { - // Add taxonomy index entries for the node. - taxonomy_build_node_index($node); - } - - /** - * Implements hook_ENTITY_TYPE_update() for node entities. - */ - #[Hook('node_update')] - public function nodeUpdate(EntityInterface $node) { - // If we're not dealing with the default revision of the node, do not make any - // change to the taxonomy index. - if (!$node->isDefaultRevision()) { - return; - } - taxonomy_delete_node_index($node); - taxonomy_build_node_index($node); - } - - /** - * Implements hook_ENTITY_TYPE_predelete() for node entities. - */ - #[Hook('node_predelete')] - public function nodePredelete(EntityInterface $node) { - // Clean up the {taxonomy_index} table when nodes are deleted. - taxonomy_delete_node_index($node); - } - - /** - * Implements hook_ENTITY_TYPE_delete() for taxonomy_term entities. - */ - #[Hook('taxonomy_term_delete')] - public function taxonomyTermDelete(Term $term) { - if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) { - // Clean up the {taxonomy_index} table when terms are deleted. - \Drupal::database()->delete('taxonomy_index')->condition('tid', $term->id())->execute(); - } - } - } -- GitLab From 92ed19965a4a8e2a7496c4ff00026658e966ce0a Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Thu, 6 Feb 2025 10:26:07 -0500 Subject: [PATCH 10/53] Fixing PHPSTAN errors --- core/modules/taxonomy/src/Hook/TaxonomyHooks.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyHooks.php index e9e037c426e6..38637cd81b42 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyHooks.php @@ -2,8 +2,6 @@ namespace Drupal\taxonomy\Hook; -use Drupal\taxonomy\Entity\Term; -use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Url; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Hook\Attribute\Hook; -- GitLab From 538b1a7e5c440c5d9d9adea81672e43a599b68c2 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Thu, 6 Feb 2025 12:01:48 -0500 Subject: [PATCH 11/53] Updating baseline. --- core/.phpstan-baseline.php | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/core/.phpstan-baseline.php b/core/.phpstan-baseline.php index 8e9b084c392e..26f15bb279b6 100644 --- a/core/.phpstan-baseline.php +++ b/core/.phpstan-baseline.php @@ -40071,30 +40071,6 @@ 'count' => 1, 'path' => __DIR__ . '/modules/taxonomy/src/Hook/TaxonomyHooks.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\taxonomy\\\\Hook\\\\TaxonomyHooks\\:\\:nodeInsert\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/modules/taxonomy/src/Hook/TaxonomyHooks.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\taxonomy\\\\Hook\\\\TaxonomyHooks\\:\\:nodePredelete\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/modules/taxonomy/src/Hook/TaxonomyHooks.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\taxonomy\\\\Hook\\\\TaxonomyHooks\\:\\:nodeUpdate\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/modules/taxonomy/src/Hook/TaxonomyHooks.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\taxonomy\\\\Hook\\\\TaxonomyHooks\\:\\:taxonomyTermDelete\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/modules/taxonomy/src/Hook/TaxonomyHooks.php', -]; $ignoreErrors[] = [ 'message' => '#^Method Drupal\\\\taxonomy\\\\Plugin\\\\Validation\\\\Constraint\\\\TaxonomyTermHierarchyConstraintValidator\\:\\:create\\(\\) has no return type specified\\.$#', 'identifier' => 'missingType.return', -- GitLab From c4c15539736e9e0cd3a5e0d5ca131c00b55ad47c Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Thu, 6 Feb 2025 12:10:55 -0500 Subject: [PATCH 12/53] Adding return types for delete_node_index and build_node_index. --- core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index ab2a5b6ef806..dd02924e3366 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -51,7 +51,7 @@ public function __construct(ConfigFactoryInterface $configFactory, EntityTypeMan * @param \Drupal\node\Entity\Node $node * The node entity. */ - protected function build_node_index($node) { + protected function build_node_index($node): void { // We maintain a denormalized table of term/node relationships, containing // only data for current, published nodes. if (!\Drupal::config('taxonomy.settings')->get('maintain_index_table') || !($this->entityTypeManager->getStorage('node') instanceof SqlContentEntityStorage)) { @@ -98,7 +98,7 @@ protected function build_node_index($node) { * @param \Drupal\Core\Entity\EntityInterface $node * The node entity. */ - protected function delete_node_index(EntityInterface $node) { + protected function delete_node_index(EntityInterface $node): void { if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) { \Drupal::database()->delete('taxonomy_index')->condition('nid', $node->id())->execute(); } -- GitLab From 433f920483587ffa2345012237c1a6a1149c2f45 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Mon, 10 Feb 2025 13:15:21 -0500 Subject: [PATCH 13/53] Setting up TaxonomyHelp class. --- .../taxonomy/src/Hook/TaxonomyHelp.php | 88 +++++++++++++++++++ .../taxonomy/src/Hook/TaxonomyHooks.php | 58 ------------ 2 files changed, 88 insertions(+), 58 deletions(-) create mode 100644 core/modules/taxonomy/src/Hook/TaxonomyHelp.php diff --git a/core/modules/taxonomy/src/Hook/TaxonomyHelp.php b/core/modules/taxonomy/src/Hook/TaxonomyHelp.php new file mode 100644 index 000000000000..2425a6499cae --- /dev/null +++ b/core/modules/taxonomy/src/Hook/TaxonomyHelp.php @@ -0,0 +1,88 @@ +<?php + +namespace Drupal\taxonomy\Hook; + +use Drupal\Core\Url; +use Drupal\Core\Routing\RouteMatchInterface; +use Drupal\Core\Hook\Attribute\Hook; +use Drupal\Core\StringTranslation\StringTranslationTrait; +use Drupal\Core\StringTranslation\TranslationInterface; + +/** + * Implements hook_help(). + */ +#[Hook('help')] +class TaxonomyHelp { + + use StringTranslationTrait; + + /** + * Constructs TaxonomyHelp. + * + * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation + * The translation service. + */ + public function __construct(TranslationInterface $string_translation) { + $this->stringTranslation = $string_translation; + } + + /** + * Implements hook_help(). + */ + public function __invoke($route_name, RouteMatchInterface $route_match): string { + switch ($route_name) { + case 'help.page.taxonomy': + $field_ui_url = \Drupal::moduleHandler()->moduleExists('field_ui') ? Url::fromRoute('help.page', ['name' => 'field_ui'])->toString() : '#'; + $output = ''; + $output .= '<h2>' . $this->t('About') . '</h2>'; + $output .= '<p>' . $this->t('The Taxonomy module allows users who have permission to create and edit content to categorize (tag) content of that type. Users who have the <em>Administer vocabularies and terms</em> <a href=":permissions" title="Taxonomy module permissions">permission</a> can add <em>vocabularies</em> that contain a set of related <em>terms</em>. The terms in a vocabulary can either be pre-set by an administrator or built gradually as content is added and edited. Terms may be organized hierarchically if desired.', [ + ':permissions' => Url::fromRoute('user.admin_permissions.module', [ + 'modules' => 'taxonomy', + ])->toString(), + ]) . '</p>'; + $output .= '<p>' . $this->t('For more information, see the <a href=":taxonomy">online documentation for the Taxonomy module</a>.', [':taxonomy' => 'https://www.drupal.org/docs/8/core/modules/taxonomy']) . '</p>'; + $output .= '<h2>' . $this->t('Uses') . '</h2>'; + $output .= '<dl>'; + $output .= '<dt>' . $this->t('Managing vocabularies') . '</dt>'; + $output .= '<dd>' . $this->t('Users who have the <em>Administer vocabularies and terms</em> permission can add and edit vocabularies from the <a href=":taxonomy_admin">Taxonomy administration page</a>. Vocabularies can be deleted from their <em>Edit vocabulary</em> page. Users with the <em>Taxonomy term: Administer fields</em> permission may add additional fields for terms in that vocabulary using the <a href=":field_ui">Field UI module</a>.', [ + ':taxonomy_admin' => Url::fromRoute('entity.taxonomy_vocabulary.collection')->toString(), + ':field_ui' => $field_ui_url, + ]) . '</dd>'; + $output .= '<dt>' . $this->t('Managing terms') . '</dt>'; + $output .= '<dd>' . $this->t('Users who have the <em>Administer vocabularies and terms</em> permission or the <em>Edit terms</em> permission for a particular vocabulary can add, edit, and organize the terms in a vocabulary from a vocabulary\'s term listing page, which can be accessed by going to the <a href=":taxonomy_admin">Taxonomy administration page</a> and clicking <em>List terms</em> in the <em>Operations</em> column. Users must have the <em>Administer vocabularies and terms</em> permission or the <em>Delete terms</em> permission for a particular vocabulary to delete terms.', [ + ':taxonomy_admin' => Url::fromRoute('entity.taxonomy_vocabulary.collection')->toString(), + ]) . ' </dd>'; + $output .= '<dt>' . $this->t('Classifying entity content') . '</dt>'; + $output .= '<dd>' . $this->t('A user with the <em>Administer fields</em> permission for a certain entity type may add <em>Taxonomy term</em> reference fields to the entity type, which will allow entities to be classified using taxonomy terms. See the <a href=":entity_reference">Entity Reference help</a> for more information about reference fields. See the <a href=":field">Field module help</a> and the <a href=":field_ui">Field UI help</a> pages for general information on fields and how to create and manage them.', [ + ':field_ui' => $field_ui_url, + ':field' => Url::fromRoute('help.page', [ + 'name' => 'field', + ])->toString(), + ':entity_reference' => Url::fromRoute('help.page', [ + 'name' => 'entity_reference', + ])->toString(), + ]) . '</dd>'; + $output .= '<dt>' . $this->t('Adding new terms during content creation') . '</dt>'; + $output .= '<dd>' . $this->t("Allowing users to add new terms gradually builds a vocabulary as content is added and edited. Users can add new terms if either of the two <em>Autocomplete</em> widgets is chosen for the Taxonomy term reference field in the <em>Manage form display</em> page for the field. You will also need to enable the <em>Create referenced entities if they don't already exist</em> option, and restrict the field to one vocabulary.") . '</dd>'; + $output .= '<dt>' . $this->t('Configuring displays and form displays') . '</dt>'; + $output .= '<dd>' . $this->t('See the <a href=":entity_reference">Entity Reference help</a> page for the field widgets and formatters that can be configured for any reference field on the <em>Manage display</em> and <em>Manage form display</em> pages. Taxonomy additionally provides an <em>RSS category</em> formatter that displays nothing when the entity item is displayed as HTML, but displays an RSS category instead of a list when the entity item is displayed in an RSS feed.', [ + ':entity_reference' => Url::fromRoute('help.page', [ + 'name' => 'entity_reference', + ])->toString(), + ]) . '</li>'; + $output .= '</ul>'; + $output .= '</dd>'; + $output .= '</dl>'; + return $output; + + case 'entity.taxonomy_vocabulary.collection': + $output = '<p>' . $this->t('Taxonomy is for categorizing content. Terms are grouped into vocabularies. For example, a vocabulary called "Fruit" would contain the terms "Apple" and "Banana".') . '</p>'; + return $output; + + default: + $output = ''; + return $output; + } + } + +} diff --git a/core/modules/taxonomy/src/Hook/TaxonomyHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyHooks.php index 38637cd81b42..88399198fae2 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyHooks.php @@ -2,8 +2,6 @@ namespace Drupal\taxonomy\Hook; -use Drupal\Core\Url; -use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Hook\Attribute\Hook; /** @@ -11,62 +9,6 @@ */ class TaxonomyHooks { - /** - * Implements hook_help(). - */ - #[Hook('help')] - public function help($route_name, RouteMatchInterface $route_match) { - switch ($route_name) { - case 'help.page.taxonomy': - $field_ui_url = \Drupal::moduleHandler()->moduleExists('field_ui') ? Url::fromRoute('help.page', ['name' => 'field_ui'])->toString() : '#'; - $output = ''; - $output .= '<h2>' . t('About') . '</h2>'; - $output .= '<p>' . t('The Taxonomy module allows users who have permission to create and edit content to categorize (tag) content of that type. Users who have the <em>Administer vocabularies and terms</em> <a href=":permissions" title="Taxonomy module permissions">permission</a> can add <em>vocabularies</em> that contain a set of related <em>terms</em>. The terms in a vocabulary can either be pre-set by an administrator or built gradually as content is added and edited. Terms may be organized hierarchically if desired.', [ - ':permissions' => Url::fromRoute('user.admin_permissions.module', [ - 'modules' => 'taxonomy', - ])->toString(), - ]) . '</p>'; - $output .= '<p>' . t('For more information, see the <a href=":taxonomy">online documentation for the Taxonomy module</a>.', [':taxonomy' => 'https://www.drupal.org/docs/8/core/modules/taxonomy']) . '</p>'; - $output .= '<h2>' . t('Uses') . '</h2>'; - $output .= '<dl>'; - $output .= '<dt>' . t('Managing vocabularies') . '</dt>'; - $output .= '<dd>' . t('Users who have the <em>Administer vocabularies and terms</em> permission can add and edit vocabularies from the <a href=":taxonomy_admin">Taxonomy administration page</a>. Vocabularies can be deleted from their <em>Edit vocabulary</em> page. Users with the <em>Taxonomy term: Administer fields</em> permission may add additional fields for terms in that vocabulary using the <a href=":field_ui">Field UI module</a>.', [ - ':taxonomy_admin' => Url::fromRoute('entity.taxonomy_vocabulary.collection')->toString(), - ':field_ui' => $field_ui_url, - ]) . '</dd>'; - $output .= '<dt>' . t('Managing terms') . '</dt>'; - $output .= '<dd>' . t('Users who have the <em>Administer vocabularies and terms</em> permission or the <em>Edit terms</em> permission for a particular vocabulary can add, edit, and organize the terms in a vocabulary from a vocabulary\'s term listing page, which can be accessed by going to the <a href=":taxonomy_admin">Taxonomy administration page</a> and clicking <em>List terms</em> in the <em>Operations</em> column. Users must have the <em>Administer vocabularies and terms</em> permission or the <em>Delete terms</em> permission for a particular vocabulary to delete terms.', [ - ':taxonomy_admin' => Url::fromRoute('entity.taxonomy_vocabulary.collection')->toString(), - ]) . ' </dd>'; - $output .= '<dt>' . t('Classifying entity content') . '</dt>'; - $output .= '<dd>' . t('A user with the <em>Administer fields</em> permission for a certain entity type may add <em>Taxonomy term</em> reference fields to the entity type, which will allow entities to be classified using taxonomy terms. See the <a href=":entity_reference">Entity Reference help</a> for more information about reference fields. See the <a href=":field">Field module help</a> and the <a href=":field_ui">Field UI help</a> pages for general information on fields and how to create and manage them.', [ - ':field_ui' => $field_ui_url, - ':field' => Url::fromRoute('help.page', [ - 'name' => 'field', - ])->toString(), - ':entity_reference' => Url::fromRoute('help.page', [ - 'name' => 'entity_reference', - ])->toString(), - ]) . '</dd>'; - $output .= '<dt>' . t('Adding new terms during content creation') . '</dt>'; - $output .= '<dd>' . t("Allowing users to add new terms gradually builds a vocabulary as content is added and edited. Users can add new terms if either of the two <em>Autocomplete</em> widgets is chosen for the Taxonomy term reference field in the <em>Manage form display</em> page for the field. You will also need to enable the <em>Create referenced entities if they don't already exist</em> option, and restrict the field to one vocabulary.") . '</dd>'; - $output .= '<dt>' . t('Configuring displays and form displays') . '</dt>'; - $output .= '<dd>' . t('See the <a href=":entity_reference">Entity Reference help</a> page for the field widgets and formatters that can be configured for any reference field on the <em>Manage display</em> and <em>Manage form display</em> pages. Taxonomy additionally provides an <em>RSS category</em> formatter that displays nothing when the entity item is displayed as HTML, but displays an RSS category instead of a list when the entity item is displayed in an RSS feed.', [ - ':entity_reference' => Url::fromRoute('help.page', [ - 'name' => 'entity_reference', - ])->toString(), - ]) . '</li>'; - $output .= '</ul>'; - $output .= '</dd>'; - $output .= '</dl>'; - return $output; - - case 'entity.taxonomy_vocabulary.collection': - $output = '<p>' . t('Taxonomy is for categorizing content. Terms are grouped into vocabularies. For example, a vocabulary called "Fruit" would contain the terms "Apple" and "Banana".') . '</p>'; - return $output; - } - } - /** * Implements hook_theme(). */ -- GitLab From cf857a6507c0b5f6e699e622f6b39ea204a58d07 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Mon, 10 Feb 2025 13:21:06 -0500 Subject: [PATCH 14/53] Updating baseline. --- core/.phpstan-baseline.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/core/.phpstan-baseline.php b/core/.phpstan-baseline.php index 34b8d822b660..e5127801c51a 100644 --- a/core/.phpstan-baseline.php +++ b/core/.phpstan-baseline.php @@ -40035,12 +40035,6 @@ 'count' => 1, 'path' => __DIR__ . '/modules/taxonomy/src/Form/VocabularyResetForm.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Method Drupal\\\\taxonomy\\\\Hook\\\\TaxonomyHooks\\:\\:help\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/modules/taxonomy/src/Hook/TaxonomyHooks.php', -]; $ignoreErrors[] = [ 'message' => '#^Method Drupal\\\\taxonomy\\\\Plugin\\\\Validation\\\\Constraint\\\\TaxonomyTermHierarchyConstraintValidator\\:\\:create\\(\\) has no return type specified\\.$#', 'identifier' => 'missingType.return', -- GitLab From f976191b3c8ecc8ebc6abb03262a52ac4f3e6d44 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Mon, 10 Feb 2025 14:09:45 -0500 Subject: [PATCH 15/53] Taxonomy Theme Hook class. --- .../modules/taxonomy/src/Hook/TaxonomyHooks.php | 8 -------- .../modules/taxonomy/src/Hook/TaxonomyTheme.php | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 core/modules/taxonomy/src/Hook/TaxonomyTheme.php diff --git a/core/modules/taxonomy/src/Hook/TaxonomyHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyHooks.php index 88399198fae2..be0484965937 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyHooks.php @@ -9,14 +9,6 @@ */ class TaxonomyHooks { - /** - * Implements hook_theme(). - */ - #[Hook('theme')] - public function theme() : array { - return ['taxonomy_term' => ['render element' => 'elements']]; - } - /** * Implements hook_local_tasks_alter(). * diff --git a/core/modules/taxonomy/src/Hook/TaxonomyTheme.php b/core/modules/taxonomy/src/Hook/TaxonomyTheme.php new file mode 100644 index 000000000000..2f7dba8a2ee2 --- /dev/null +++ b/core/modules/taxonomy/src/Hook/TaxonomyTheme.php @@ -0,0 +1,17 @@ +<?php + +namespace Drupal\taxonomy\Hook; + +use Drupal\Core\Hook\Attribute\Hook; + +/** + * Implements hook_theme(). + */ +#[Hook('theme')] +class TaxonomyTheme { + + public function __invoke() : array { + return ['taxonomy_term' => ['render element' => 'elements']]; + } + +} -- GitLab From 85f2a01653781a07689b984324e46e4e5352a1ed Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Wed, 26 Feb 2025 13:33:07 -0500 Subject: [PATCH 16/53] Fixing merge conflict. --- .../taxonomy/src/Hook/TaxonomyHooks.php | 162 ------------------ 1 file changed, 162 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyHooks.php index 778b2019e7fd..4cd838b6a535 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyHooks.php @@ -2,14 +2,6 @@ namespace Drupal\taxonomy\Hook; -<<<<<<< HEAD -======= -use Drupal\Core\StringTranslation\StringTranslationTrait; -use Drupal\taxonomy\Entity\Term; -use Drupal\Core\Entity\EntityInterface; -use Drupal\Core\Url; -use Drupal\Core\Routing\RouteMatchInterface; ->>>>>>> 11.x use Drupal\Core\Hook\Attribute\Hook; /** @@ -20,74 +12,6 @@ class TaxonomyHooks { use StringTranslationTrait; /** -<<<<<<< HEAD -======= - * Implements hook_help(). - */ - #[Hook('help')] - public function help($route_name, RouteMatchInterface $route_match): ?string { - switch ($route_name) { - case 'help.page.taxonomy': - $field_ui_url = \Drupal::moduleHandler()->moduleExists('field_ui') ? Url::fromRoute('help.page', ['name' => 'field_ui'])->toString() : '#'; - $output = ''; - $output .= '<h2>' . $this->t('About') . '</h2>'; - $output .= '<p>' . $this->t('The Taxonomy module allows users who have permission to create and edit content to categorize (tag) content of that type. Users who have the <em>Administer vocabularies and terms</em> <a href=":permissions" title="Taxonomy module permissions">permission</a> can add <em>vocabularies</em> that contain a set of related <em>terms</em>. The terms in a vocabulary can either be pre-set by an administrator or built gradually as content is added and edited. Terms may be organized hierarchically if desired.', [ - ':permissions' => Url::fromRoute('user.admin_permissions.module', [ - 'modules' => 'taxonomy', - ])->toString(), - ]) . '</p>'; - $output .= '<p>' . $this->t('For more information, see the <a href=":taxonomy">online documentation for the Taxonomy module</a>.', [':taxonomy' => 'https://www.drupal.org/docs/8/core/modules/taxonomy']) . '</p>'; - $output .= '<h2>' . $this->t('Uses') . '</h2>'; - $output .= '<dl>'; - $output .= '<dt>' . $this->t('Managing vocabularies') . '</dt>'; - $output .= '<dd>' . $this->t('Users who have the <em>Administer vocabularies and terms</em> permission can add and edit vocabularies from the <a href=":taxonomy_admin">Taxonomy administration page</a>. Vocabularies can be deleted from their <em>Edit vocabulary</em> page. Users with the <em>Taxonomy term: Administer fields</em> permission may add additional fields for terms in that vocabulary using the <a href=":field_ui">Field UI module</a>.', [ - ':taxonomy_admin' => Url::fromRoute('entity.taxonomy_vocabulary.collection')->toString(), - ':field_ui' => $field_ui_url, - ]) . '</dd>'; - $output .= '<dt>' . $this->t('Managing terms') . '</dt>'; - $output .= '<dd>' . $this->t('Users who have the <em>Administer vocabularies and terms</em> permission or the <em>Edit terms</em> permission for a particular vocabulary can add, edit, and organize the terms in a vocabulary from a vocabulary\'s term listing page, which can be accessed by going to the <a href=":taxonomy_admin">Taxonomy administration page</a> and clicking <em>List terms</em> in the <em>Operations</em> column. Users must have the <em>Administer vocabularies and terms</em> permission or the <em>Delete terms</em> permission for a particular vocabulary to delete terms.', [ - ':taxonomy_admin' => Url::fromRoute('entity.taxonomy_vocabulary.collection')->toString(), - ]) . ' </dd>'; - $output .= '<dt>' . $this->t('Classifying entity content') . '</dt>'; - $output .= '<dd>' . $this->t('A user with the <em>Administer fields</em> permission for a certain entity type may add <em>Taxonomy term</em> reference fields to the entity type, which will allow entities to be classified using taxonomy terms. See the <a href=":entity_reference">Entity Reference help</a> for more information about reference fields. See the <a href=":field">Field module help</a> and the <a href=":field_ui">Field UI help</a> pages for general information on fields and how to create and manage them.', [ - ':field_ui' => $field_ui_url, - ':field' => Url::fromRoute('help.page', [ - 'name' => 'field', - ])->toString(), - ':entity_reference' => Url::fromRoute('help.page', [ - 'name' => 'entity_reference', - ])->toString(), - ]) . '</dd>'; - $output .= '<dt>' . $this->t('Adding new terms during content creation') . '</dt>'; - $output .= '<dd>' . $this->t("Allowing users to add new terms gradually builds a vocabulary as content is added and edited. Users can add new terms if either of the two <em>Autocomplete</em> widgets is chosen for the Taxonomy term reference field in the <em>Manage form display</em> page for the field. You will also need to enable the <em>Create referenced entities if they don't already exist</em> option, and restrict the field to one vocabulary.") . '</dd>'; - $output .= '<dt>' . $this->t('Configuring displays and form displays') . '</dt>'; - $output .= '<dd>' . $this->t('See the <a href=":entity_reference">Entity Reference help</a> page for the field widgets and formatters that can be configured for any reference field on the <em>Manage display</em> and <em>Manage form display</em> pages. Taxonomy additionally provides an <em>RSS category</em> formatter that displays nothing when the entity item is displayed as HTML, but displays an RSS category instead of a list when the entity item is displayed in an RSS feed.', [ - ':entity_reference' => Url::fromRoute('help.page', [ - 'name' => 'entity_reference', - ])->toString(), - ]) . '</li>'; - $output .= '</ul>'; - $output .= '</dd>'; - $output .= '</dl>'; - return $output; - - case 'entity.taxonomy_vocabulary.collection': - $output = '<p>' . $this->t('Taxonomy is for categorizing content. Terms are grouped into vocabularies. For example, a vocabulary called "Fruit" would contain the terms "Apple" and "Banana".') . '</p>'; - return $output; - } - return NULL; - } - - /** - * Implements hook_theme(). - */ - #[Hook('theme')] - public function theme() : array { - return ['taxonomy_term' => ['render element' => 'elements']]; - } - - /** ->>>>>>> 11.x * Implements hook_local_tasks_alter(). * * @todo Evaluate removing as part of https://www.drupal.org/node/2358923. @@ -103,90 +27,4 @@ public function localTasksAlter(&$local_tasks): void { } } -<<<<<<< HEAD -======= - /** - * Implements hook_entity_operation(). - */ - #[Hook('entity_operation')] - public function entityOperation(EntityInterface $term): array { - $operations = []; - if ($term instanceof Term && $term->access('create')) { - $operations['add-child'] = [ - 'title' => $this->t('Add child'), - 'weight' => 10, - 'url' => Url::fromRoute('entity.taxonomy_term.add_form', [ - 'taxonomy_vocabulary' => $term->bundle(), - ], [ - 'query' => [ - 'parent' => $term->id(), - ], - ]), - ]; - } - return $operations; - } - - /** - * @defgroup taxonomy_index Taxonomy indexing - * @{ - * Functions to maintain taxonomy indexing. - * - * Taxonomy uses default field storage to store canonical relationships - * between terms and fieldable entities. However its most common use case - * requires listing all content associated with a term or group of terms - * sorted by creation date. To avoid slow queries due to joining across - * multiple node and field tables with various conditions and order by - * criteria, we maintain a denormalized table with all relationships between - * terms, published nodes and common sort criteria such as status, sticky and - * created. When using other field storage engines or alternative methods of - * denormalizing this data you should set the - * taxonomy.settings:maintain_index_table to '0' to avoid unnecessary writes - * in SQL. - */ - - /** - * Implements hook_ENTITY_TYPE_insert() for node entities. - */ - #[Hook('node_insert')] - public function nodeInsert(EntityInterface $node): void { - // Add taxonomy index entries for the node. - taxonomy_build_node_index($node); - } - - /** - * Implements hook_ENTITY_TYPE_update() for node entities. - */ - #[Hook('node_update')] - public function nodeUpdate(EntityInterface $node): void { - // If we're not dealing with the default revision of the node, do not make - // any change to the taxonomy index. - if (!$node->isDefaultRevision()) { - return; - } - taxonomy_delete_node_index($node); - taxonomy_build_node_index($node); - } - - /** - * Implements hook_ENTITY_TYPE_predelete() for node entities. - */ - #[Hook('node_predelete')] - public function nodePredelete(EntityInterface $node): void { - // Clean up the {taxonomy_index} table when nodes are deleted. - taxonomy_delete_node_index($node); - } - - /** - * Implements hook_ENTITY_TYPE_delete() for taxonomy_term entities. - */ - #[Hook('taxonomy_term_delete')] - public function taxonomyTermDelete(Term $term): void { - if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) { - // Clean up the {taxonomy_index} table when terms are deleted. - \Drupal::database()->delete('taxonomy_index')->condition('tid', $term->id())->execute(); - } - } - ->>>>>>> 11.x } -- GitLab From 805b5adc11c3baba62cf36caef7701b8c0f04921 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Wed, 26 Feb 2025 15:06:07 -0500 Subject: [PATCH 17/53] Adding dependency injection for translation. --- .../taxonomy/src/Hook/TaxonomyEntityHooks.php | 13 ++++++++++--- core/modules/taxonomy/src/Hook/TaxonomyHooks.php | 2 -- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index dd02924e3366..002a02977b05 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -8,6 +8,8 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Entity\Sql\SqlContentEntityStorage; +use Drupal\Core\StringTranslation\StringTranslationTrait; +use Drupal\Core\StringTranslation\TranslationInterface; use Drupal\Core\Url; /** @@ -15,6 +17,8 @@ */ class TaxonomyEntityHooks { + use stringTranslationTrait; + /** * A config factory for retrieving required config settings. * @@ -25,7 +29,7 @@ class TaxonomyEntityHooks { /** * A config factory for retrieving required config settings. * - * @property \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager + * @var \Drupal\Core\Entity\EntityTypeManagerInterface */ protected $entityTypeManager; @@ -36,10 +40,13 @@ class TaxonomyEntityHooks { * The configuration factory. * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager * The entity type manager. + * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation + * The translation service. */ - public function __construct(ConfigFactoryInterface $configFactory, EntityTypeManagerInterface $entityTypeManager) { + public function __construct(ConfigFactoryInterface $configFactory, EntityTypeManagerInterface $entityTypeManager, TranslationInterface $string_translation) { $this->configFactory = $configFactory; $this->entityTypeManager = $entityTypeManager; + $this->stringTranslation = $string_translation; } /** @@ -112,7 +119,7 @@ public function entityOperation(EntityInterface $term): array { $operations = []; if ($term instanceof Term && $term->access('create')) { $operations['add-child'] = [ - 'title' => t('Add child'), + 'title' => $this->t('Add child'), 'weight' => 10, 'url' => Url::fromRoute('entity.taxonomy_term.add_form', [ 'taxonomy_vocabulary' => $term->bundle(), diff --git a/core/modules/taxonomy/src/Hook/TaxonomyHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyHooks.php index 4cd838b6a535..be0484965937 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyHooks.php @@ -9,8 +9,6 @@ */ class TaxonomyHooks { - use StringTranslationTrait; - /** * Implements hook_local_tasks_alter(). * -- GitLab From a17b8869328faeb1bf77ceef58411c072698463c Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Wed, 26 Feb 2025 15:32:26 -0500 Subject: [PATCH 18/53] Converting helper functions to camelCase, cleaning up constructor. --- .../taxonomy/src/Hook/TaxonomyEntityHooks.php | 45 +++++-------------- 1 file changed, 11 insertions(+), 34 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index 002a02977b05..b26e7cd6e3f3 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -19,34 +19,11 @@ class TaxonomyEntityHooks { use stringTranslationTrait; - /** - * A config factory for retrieving required config settings. - * - * @var \Drupal\Core\Config\ConfigFactoryInterface - */ - protected $configFactory; - - /** - * A config factory for retrieving required config settings. - * - * @var \Drupal\Core\Entity\EntityTypeManagerInterface - */ - protected $entityTypeManager; - - /** - * Constructs TaxonomyEntityHooks. - * - * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory - * The configuration factory. - * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager - * The entity type manager. - * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation - * The translation service. - */ - public function __construct(ConfigFactoryInterface $configFactory, EntityTypeManagerInterface $entityTypeManager, TranslationInterface $string_translation) { - $this->configFactory = $configFactory; - $this->entityTypeManager = $entityTypeManager; - $this->stringTranslation = $string_translation; + public function __construct( + protected ConfigFactoryInterface $configFactory, + protected EntityTypeManagerInterface $entityTypeManager, + protected TranslationInterface $string_translation + ) { } /** @@ -58,7 +35,7 @@ public function __construct(ConfigFactoryInterface $configFactory, EntityTypeMan * @param \Drupal\node\Entity\Node $node * The node entity. */ - protected function build_node_index($node): void { + protected function buildNodeIndex($node): void { // We maintain a denormalized table of term/node relationships, containing // only data for current, published nodes. if (!\Drupal::config('taxonomy.settings')->get('maintain_index_table') || !($this->entityTypeManager->getStorage('node') instanceof SqlContentEntityStorage)) { @@ -105,7 +82,7 @@ protected function build_node_index($node): void { * @param \Drupal\Core\Entity\EntityInterface $node * The node entity. */ - protected function delete_node_index(EntityInterface $node): void { + protected function deleteNodeIndex(EntityInterface $node): void { if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) { \Drupal::database()->delete('taxonomy_index')->condition('nid', $node->id())->execute(); } @@ -157,7 +134,7 @@ public function entityOperation(EntityInterface $term): array { #[Hook('node_insert')] public function nodeInsert(EntityInterface $node): void { // Add taxonomy index entries for the node. - $this->build_node_index($node); + $this->buildNodeIndex($node); } /** @@ -170,8 +147,8 @@ public function nodeUpdate(EntityInterface $node): void { if (!$node->isDefaultRevision()) { return; } - $this->delete_node_index($node); - $this->build_node_index($node); + $this->deleteNodeIndex($node); + $this->buildNodeIndex($node); } /** @@ -180,7 +157,7 @@ public function nodeUpdate(EntityInterface $node): void { #[Hook('node_predelete')] public function nodePredelete(EntityInterface $node): void { // Clean up the {taxonomy_index} table when nodes are deleted. - $this->delete_node_index($node); + $this->deleteNodeIndex($node); } /** -- GitLab From 5589891c67c90126d1ed75fff6e8ca266200410c Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Wed, 26 Feb 2025 15:35:48 -0500 Subject: [PATCH 19/53] Fixing PHPCS errors. --- core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index b26e7cd6e3f3..072beeb3738e 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -20,9 +20,9 @@ class TaxonomyEntityHooks { use stringTranslationTrait; public function __construct( - protected ConfigFactoryInterface $configFactory, - protected EntityTypeManagerInterface $entityTypeManager, - protected TranslationInterface $string_translation + protected ConfigFactoryInterface $configFactory, + protected EntityTypeManagerInterface $entityTypeManager, + protected TranslationInterface $string_translation, ) { } -- GitLab From 1f1d479c6ff7403b805c5ea8f42410c8d31ebc5c Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Wed, 26 Feb 2025 16:41:09 -0500 Subject: [PATCH 20/53] Adding NodeInterface type for helper functions. --- core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index 072beeb3738e..aeb2f811b566 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -8,6 +8,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Entity\Sql\SqlContentEntityStorage; +use Drupal\node\NodeInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\StringTranslation\TranslationInterface; use Drupal\Core\Url; @@ -32,10 +33,10 @@ public function __construct( * The index lists all terms that are related to a given node entity, and is * therefore maintained at the entity level. * - * @param \Drupal\node\Entity\Node $node + * @param \Drupal\node\NodeInterface $node * The node entity. */ - protected function buildNodeIndex($node): void { + protected function buildNodeIndex(NodeInterface $node): void { // We maintain a denormalized table of term/node relationships, containing // only data for current, published nodes. if (!\Drupal::config('taxonomy.settings')->get('maintain_index_table') || !($this->entityTypeManager->getStorage('node') instanceof SqlContentEntityStorage)) { @@ -79,10 +80,10 @@ protected function buildNodeIndex($node): void { /** * Deletes taxonomy index entries for a given node. * - * @param \Drupal\Core\Entity\EntityInterface $node + * @param \Drupal\node\NodeInterface $node * The node entity. */ - protected function deleteNodeIndex(EntityInterface $node): void { + protected function deleteNodeIndex(NodeInterface $node): void { if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) { \Drupal::database()->delete('taxonomy_index')->condition('nid', $node->id())->execute(); } -- GitLab From f7ebf00480bdf79ebf0bd3d35dd72834e5b51175 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Thu, 27 Feb 2025 06:44:44 -0500 Subject: [PATCH 21/53] Adding dependency injection for database connection. --- core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index aeb2f811b566..ff0ddc30d898 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -4,6 +4,7 @@ use Drupal\taxonomy\Entity\Term; use Drupal\Core\Config\ConfigFactoryInterface; +use Drupal\Core\Database\Connection; use Drupal\Core\Hook\Attribute\Hook; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; @@ -22,6 +23,7 @@ class TaxonomyEntityHooks { public function __construct( protected ConfigFactoryInterface $configFactory, + protected Connection $database, protected EntityTypeManagerInterface $entityTypeManager, protected TranslationInterface $string_translation, ) { @@ -66,9 +68,8 @@ protected function buildNodeIndex(NodeInterface $node): void { } // Insert index entries for all the node's terms. if (!empty($tid_all)) { - $connection = \Drupal::database(); foreach ($tid_all as $tid) { - $connection->merge('taxonomy_index') + $this->database->merge('taxonomy_index') ->keys(['nid' => $node->id(), 'tid' => $tid, 'status' => $node->isPublished()]) ->fields(['sticky' => $sticky, 'created' => $node->getCreatedTime()]) ->execute(); @@ -85,7 +86,7 @@ protected function buildNodeIndex(NodeInterface $node): void { */ protected function deleteNodeIndex(NodeInterface $node): void { if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) { - \Drupal::database()->delete('taxonomy_index')->condition('nid', $node->id())->execute(); + $this->database->delete('taxonomy_index')->condition('nid', $node->id())->execute(); } } @@ -168,7 +169,7 @@ public function nodePredelete(EntityInterface $node): void { public function taxonomyTermDelete(Term $term): void { if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) { // Clean up the {taxonomy_index} table when terms are deleted. - \Drupal::database()->delete('taxonomy_index')->condition('tid', $term->id())->execute(); + $this->database->delete('taxonomy_index')->condition('tid', $term->id())->execute(); } } -- GitLab From 4cb4f0c89e3749a0d718535e18b5d94af910c46c Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Thu, 27 Feb 2025 07:27:27 -0500 Subject: [PATCH 22/53] Adding dependency injection for config. --- core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index ff0ddc30d898..ad3362d9b5ce 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -41,7 +41,8 @@ public function __construct( protected function buildNodeIndex(NodeInterface $node): void { // We maintain a denormalized table of term/node relationships, containing // only data for current, published nodes. - if (!\Drupal::config('taxonomy.settings')->get('maintain_index_table') || !($this->entityTypeManager->getStorage('node') instanceof SqlContentEntityStorage)) { + $config = $this->configFactory->get('taxonomy.settings'); + if (!$config->get('maintain_index_table') || !($this->entityTypeManager->getStorage('node') instanceof SqlContentEntityStorage)) { return; } @@ -85,7 +86,8 @@ protected function buildNodeIndex(NodeInterface $node): void { * The node entity. */ protected function deleteNodeIndex(NodeInterface $node): void { - if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) { + $config = $this->configFactory->get('taxonomy.settings'); + if ($config->get('maintain_index_table')) { $this->database->delete('taxonomy_index')->condition('nid', $node->id())->execute(); } } @@ -167,7 +169,8 @@ public function nodePredelete(EntityInterface $node): void { */ #[Hook('taxonomy_term_delete')] public function taxonomyTermDelete(Term $term): void { - if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) { + $config = $this->configFactory->get('taxonomy.settings'); + if ($config->get('maintain_index_table')) { // Clean up the {taxonomy_index} table when terms are deleted. $this->database->delete('taxonomy_index')->condition('tid', $term->id())->execute(); } -- GitLab From 639d7d9bc168fc1af49a29858cff5035f134e654 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Thu, 27 Feb 2025 09:37:42 -0500 Subject: [PATCH 23/53] Converting taxonomy_theme_suggestions_taxonomy_term, adding to theme hooks, updating theme hooks. --- .../taxonomy/src/Hook/TaxonomyTheme.php | 17 --------- .../taxonomy/src/Hook/TaxonomyThemeHooks.php | 36 +++++++++++++++++++ core/modules/taxonomy/taxonomy.module | 15 -------- 3 files changed, 36 insertions(+), 32 deletions(-) delete mode 100644 core/modules/taxonomy/src/Hook/TaxonomyTheme.php create mode 100644 core/modules/taxonomy/src/Hook/TaxonomyThemeHooks.php diff --git a/core/modules/taxonomy/src/Hook/TaxonomyTheme.php b/core/modules/taxonomy/src/Hook/TaxonomyTheme.php deleted file mode 100644 index 2f7dba8a2ee2..000000000000 --- a/core/modules/taxonomy/src/Hook/TaxonomyTheme.php +++ /dev/null @@ -1,17 +0,0 @@ -<?php - -namespace Drupal\taxonomy\Hook; - -use Drupal\Core\Hook\Attribute\Hook; - -/** - * Implements hook_theme(). - */ -#[Hook('theme')] -class TaxonomyTheme { - - public function __invoke() : array { - return ['taxonomy_term' => ['render element' => 'elements']]; - } - -} diff --git a/core/modules/taxonomy/src/Hook/TaxonomyThemeHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyThemeHooks.php new file mode 100644 index 000000000000..ead2f34f2b4a --- /dev/null +++ b/core/modules/taxonomy/src/Hook/TaxonomyThemeHooks.php @@ -0,0 +1,36 @@ +<?php + +namespace Drupal\taxonomy\Hook; + +use Drupal\Core\Hook\Attribute\Hook; + +/** + * Implements hook_theme(). + */ +class TaxonomyThemeHooks { + + /** + * Implements hook_theme(). + */ + #[Hook('theme')] + public function taxonomyTheme($existing, $type, $theme, $path): array { + return ['taxonomy_term' => ['render element' => 'elements']]; + } + + /** + * Implements hook_theme_suggestions_HOOK(). + */ + #[Hook('theme_suggestions_taxonomy_term')] + public function themeSuggestionsTaxonomyTerm(array $variables): array { + $suggestions = []; + + /** @var \Drupal\taxonomy\TermInterface $term */ + $term = $variables['elements']['#taxonomy_term']; + + $suggestions[] = 'taxonomy_term__' . $term->bundle(); + $suggestions[] = 'taxonomy_term__' . $term->id(); + + return $suggestions; + } + +} diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module index bbced8262a60..c6512d623112 100644 --- a/core/modules/taxonomy/taxonomy.module +++ b/core/modules/taxonomy/taxonomy.module @@ -9,21 +9,6 @@ use Drupal\Core\Render\Element; use Drupal\taxonomy\Entity\Term; -/** - * Implements hook_theme_suggestions_HOOK(). - */ -function taxonomy_theme_suggestions_taxonomy_term(array $variables): array { - $suggestions = []; - - /** @var \Drupal\taxonomy\TermInterface $term */ - $term = $variables['elements']['#taxonomy_term']; - - $suggestions[] = 'taxonomy_term__' . $term->bundle(); - $suggestions[] = 'taxonomy_term__' . $term->id(); - - return $suggestions; -} - /** * Prepares variables for taxonomy term templates. * -- GitLab From 49dfd1d8215cd1793f682060075f52e395ff9b6b Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Thu, 27 Feb 2025 11:00:30 -0500 Subject: [PATCH 24/53] Cleaning up translation implementation. --- .../modules/taxonomy/src/Hook/TaxonomyEntityHooks.php | 2 -- core/modules/taxonomy/src/Hook/TaxonomyHelp.php | 11 ----------- 2 files changed, 13 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index ad3362d9b5ce..bc1ab56d995f 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -11,7 +11,6 @@ use Drupal\Core\Entity\Sql\SqlContentEntityStorage; use Drupal\node\NodeInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; -use Drupal\Core\StringTranslation\TranslationInterface; use Drupal\Core\Url; /** @@ -25,7 +24,6 @@ public function __construct( protected ConfigFactoryInterface $configFactory, protected Connection $database, protected EntityTypeManagerInterface $entityTypeManager, - protected TranslationInterface $string_translation, ) { } diff --git a/core/modules/taxonomy/src/Hook/TaxonomyHelp.php b/core/modules/taxonomy/src/Hook/TaxonomyHelp.php index 2425a6499cae..4fc29b3174dc 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyHelp.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyHelp.php @@ -6,7 +6,6 @@ use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Hook\Attribute\Hook; use Drupal\Core\StringTranslation\StringTranslationTrait; -use Drupal\Core\StringTranslation\TranslationInterface; /** * Implements hook_help(). @@ -16,16 +15,6 @@ class TaxonomyHelp { use StringTranslationTrait; - /** - * Constructs TaxonomyHelp. - * - * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation - * The translation service. - */ - public function __construct(TranslationInterface $string_translation) { - $this->stringTranslation = $string_translation; - } - /** * Implements hook_help(). */ -- GitLab From 291c58f27d332fa92e79730c866b6ef0b7a010df Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Thu, 27 Feb 2025 11:06:10 -0500 Subject: [PATCH 25/53] Setting config in constructor. --- core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index bc1ab56d995f..c158b390c234 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -25,6 +25,7 @@ public function __construct( protected Connection $database, protected EntityTypeManagerInterface $entityTypeManager, ) { + $this->config = configFactory->get('taxonomy.settings'); } /** @@ -39,8 +40,7 @@ public function __construct( protected function buildNodeIndex(NodeInterface $node): void { // We maintain a denormalized table of term/node relationships, containing // only data for current, published nodes. - $config = $this->configFactory->get('taxonomy.settings'); - if (!$config->get('maintain_index_table') || !($this->entityTypeManager->getStorage('node') instanceof SqlContentEntityStorage)) { + if (!$this->config->get('maintain_index_table') || !($this->entityTypeManager->getStorage('node') instanceof SqlContentEntityStorage)) { return; } @@ -84,8 +84,7 @@ protected function buildNodeIndex(NodeInterface $node): void { * The node entity. */ protected function deleteNodeIndex(NodeInterface $node): void { - $config = $this->configFactory->get('taxonomy.settings'); - if ($config->get('maintain_index_table')) { + if ($this->config->get('maintain_index_table')) { $this->database->delete('taxonomy_index')->condition('nid', $node->id())->execute(); } } @@ -167,8 +166,7 @@ public function nodePredelete(EntityInterface $node): void { */ #[Hook('taxonomy_term_delete')] public function taxonomyTermDelete(Term $term): void { - $config = $this->configFactory->get('taxonomy.settings'); - if ($config->get('maintain_index_table')) { + if ($this->config->get('maintain_index_table')) { // Clean up the {taxonomy_index} table when terms are deleted. $this->database->delete('taxonomy_index')->condition('tid', $term->id())->execute(); } -- GitLab From 1af1bdf5058fcfc421bd3582be72d1a94f48a77c Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Fri, 28 Feb 2025 09:43:53 -0500 Subject: [PATCH 26/53] Reverting setting of config in constructor. --- core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index c158b390c234..bc1ab56d995f 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -25,7 +25,6 @@ public function __construct( protected Connection $database, protected EntityTypeManagerInterface $entityTypeManager, ) { - $this->config = configFactory->get('taxonomy.settings'); } /** @@ -40,7 +39,8 @@ public function __construct( protected function buildNodeIndex(NodeInterface $node): void { // We maintain a denormalized table of term/node relationships, containing // only data for current, published nodes. - if (!$this->config->get('maintain_index_table') || !($this->entityTypeManager->getStorage('node') instanceof SqlContentEntityStorage)) { + $config = $this->configFactory->get('taxonomy.settings'); + if (!$config->get('maintain_index_table') || !($this->entityTypeManager->getStorage('node') instanceof SqlContentEntityStorage)) { return; } @@ -84,7 +84,8 @@ protected function buildNodeIndex(NodeInterface $node): void { * The node entity. */ protected function deleteNodeIndex(NodeInterface $node): void { - if ($this->config->get('maintain_index_table')) { + $config = $this->configFactory->get('taxonomy.settings'); + if ($config->get('maintain_index_table')) { $this->database->delete('taxonomy_index')->condition('nid', $node->id())->execute(); } } @@ -166,7 +167,8 @@ public function nodePredelete(EntityInterface $node): void { */ #[Hook('taxonomy_term_delete')] public function taxonomyTermDelete(Term $term): void { - if ($this->config->get('maintain_index_table')) { + $config = $this->configFactory->get('taxonomy.settings'); + if ($config->get('maintain_index_table')) { // Clean up the {taxonomy_index} table when terms are deleted. $this->database->delete('taxonomy_index')->condition('tid', $term->id())->execute(); } -- GitLab From 8a679153485c090b5f8a8254337da8fa76206c49 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Fri, 28 Feb 2025 10:45:40 -0500 Subject: [PATCH 27/53] Adding depency injection for ModuleHandler. --- core/modules/taxonomy/src/Hook/TaxonomyHelp.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyHelp.php b/core/modules/taxonomy/src/Hook/TaxonomyHelp.php index 4fc29b3174dc..c63b6d99b4ba 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyHelp.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyHelp.php @@ -2,26 +2,30 @@ namespace Drupal\taxonomy\Hook; +use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Url; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Hook\Attribute\Hook; use Drupal\Core\StringTranslation\StringTranslationTrait; /** - * Implements hook_help(). + * Help hook implementation for taxonomy(). */ -#[Hook('help')] class TaxonomyHelp { use StringTranslationTrait; + public function __construct(protected ModuleHandlerInterface $moduleHandler) { + } + /** * Implements hook_help(). */ - public function __invoke($route_name, RouteMatchInterface $route_match): string { + #[Hook('help')] + public function help($route_name, RouteMatchInterface $route_match): string { switch ($route_name) { case 'help.page.taxonomy': - $field_ui_url = \Drupal::moduleHandler()->moduleExists('field_ui') ? Url::fromRoute('help.page', ['name' => 'field_ui'])->toString() : '#'; + $field_ui_url = $this->moduleHandler->moduleExists('field_ui') ? Url::fromRoute('help.page', ['name' => 'field_ui'])->toString() : '#'; $output = ''; $output .= '<h2>' . $this->t('About') . '</h2>'; $output .= '<p>' . $this->t('The Taxonomy module allows users who have permission to create and edit content to categorize (tag) content of that type. Users who have the <em>Administer vocabularies and terms</em> <a href=":permissions" title="Taxonomy module permissions">permission</a> can add <em>vocabularies</em> that contain a set of related <em>terms</em>. The terms in a vocabulary can either be pre-set by an administrator or built gradually as content is added and edited. Terms may be organized hierarchically if desired.', [ -- GitLab From 04b2cd48474a2054f958103fa1fe03ad68046d60 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Fri, 28 Feb 2025 11:18:33 -0500 Subject: [PATCH 28/53] Setting config in the constructor. --- .../taxonomy/src/Hook/TaxonomyEntityHooks.php | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index bc1ab56d995f..81dfa3d3e892 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -4,6 +4,7 @@ use Drupal\taxonomy\Entity\Term; use Drupal\Core\Config\ConfigFactoryInterface; +use Drupal\Core\Config\ImmutableConfig; use Drupal\Core\Database\Connection; use Drupal\Core\Hook\Attribute\Hook; use Drupal\Core\Entity\EntityInterface; @@ -20,11 +21,19 @@ class TaxonomyEntityHooks { use stringTranslationTrait; + /** + * The configuration settings of this module. + * + * @var \Drupal\Core\Config\ImmutableConfig + */ + protected ImmutableConfig $config; + public function __construct( - protected ConfigFactoryInterface $configFactory, + configFactoryInterface $config, protected Connection $database, protected EntityTypeManagerInterface $entityTypeManager, ) { + $this->config = $config->get('taxonomy.settings'); } /** @@ -39,8 +48,7 @@ public function __construct( protected function buildNodeIndex(NodeInterface $node): void { // We maintain a denormalized table of term/node relationships, containing // only data for current, published nodes. - $config = $this->configFactory->get('taxonomy.settings'); - if (!$config->get('maintain_index_table') || !($this->entityTypeManager->getStorage('node') instanceof SqlContentEntityStorage)) { + if (!$this->config->get('maintain_index_table') || !($this->entityTypeManager->getStorage('node') instanceof SqlContentEntityStorage)) { return; } @@ -84,8 +92,7 @@ protected function buildNodeIndex(NodeInterface $node): void { * The node entity. */ protected function deleteNodeIndex(NodeInterface $node): void { - $config = $this->configFactory->get('taxonomy.settings'); - if ($config->get('maintain_index_table')) { + if ($this->config->get('maintain_index_table')) { $this->database->delete('taxonomy_index')->condition('nid', $node->id())->execute(); } } @@ -167,8 +174,7 @@ public function nodePredelete(EntityInterface $node): void { */ #[Hook('taxonomy_term_delete')] public function taxonomyTermDelete(Term $term): void { - $config = $this->configFactory->get('taxonomy.settings'); - if ($config->get('maintain_index_table')) { + if ($this->config->get('maintain_index_table')) { // Clean up the {taxonomy_index} table when terms are deleted. $this->database->delete('taxonomy_index')->condition('tid', $term->id())->execute(); } -- GitLab From bbacb9ccfe24daa3da823ed7c7f94a24758d3cfa Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Fri, 28 Feb 2025 16:08:42 -0500 Subject: [PATCH 29/53] Removing config from constructor, adding helper function. --- .../taxonomy/src/Hook/TaxonomyEntityHooks.php | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index 81dfa3d3e892..0a22219067c8 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -4,7 +4,6 @@ use Drupal\taxonomy\Entity\Term; use Drupal\Core\Config\ConfigFactoryInterface; -use Drupal\Core\Config\ImmutableConfig; use Drupal\Core\Database\Connection; use Drupal\Core\Hook\Attribute\Hook; use Drupal\Core\Entity\EntityInterface; @@ -21,19 +20,25 @@ class TaxonomyEntityHooks { use stringTranslationTrait; - /** - * The configuration settings of this module. - * - * @var \Drupal\Core\Config\ImmutableConfig - */ - protected ImmutableConfig $config; - public function __construct( - configFactoryInterface $config, + protected configFactoryInterface $config, protected Connection $database, protected EntityTypeManagerInterface $entityTypeManager, ) { - $this->config = $config->get('taxonomy.settings'); + } + + /** + * Returns the module configuration object. + * + * @return \Drupal\Core\Config\Config|\Drupal\Core\Config\ImmutableConfig + * The module configuration object. + */ + protected function getConfig() { + if ($this->config === NULL) { + // Get module config. + $this->config = $this->config->get('taxonomy.settings'); + } + return $this->config; } /** @@ -48,7 +53,7 @@ public function __construct( protected function buildNodeIndex(NodeInterface $node): void { // We maintain a denormalized table of term/node relationships, containing // only data for current, published nodes. - if (!$this->config->get('maintain_index_table') || !($this->entityTypeManager->getStorage('node') instanceof SqlContentEntityStorage)) { + if (!$this->getConfig()->get('maintain_index_table') || !($this->entityTypeManager->getStorage('node') instanceof SqlContentEntityStorage)) { return; } @@ -92,7 +97,7 @@ protected function buildNodeIndex(NodeInterface $node): void { * The node entity. */ protected function deleteNodeIndex(NodeInterface $node): void { - if ($this->config->get('maintain_index_table')) { + if ($this->getConfig()->get('maintain_index_table')) { $this->database->delete('taxonomy_index')->condition('nid', $node->id())->execute(); } } @@ -174,7 +179,7 @@ public function nodePredelete(EntityInterface $node): void { */ #[Hook('taxonomy_term_delete')] public function taxonomyTermDelete(Term $term): void { - if ($this->config->get('maintain_index_table')) { + if ($this->getConfig()->get('maintain_index_table')) { // Clean up the {taxonomy_index} table when terms are deleted. $this->database->delete('taxonomy_index')->condition('tid', $term->id())->execute(); } -- GitLab From 609958f1eb0d876a420391bc8821362450f577a7 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Thu, 20 Mar 2025 13:23:18 -0400 Subject: [PATCH 30/53] Fixing config-related pieces and use statement. --- .../taxonomy/src/Hook/TaxonomyEntityHooks.php | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index 0a22219067c8..86b52e563d5d 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -18,10 +18,10 @@ */ class TaxonomyEntityHooks { - use stringTranslationTrait; + use StringTranslationTrait; public function __construct( - protected configFactoryInterface $config, + protected ConfigFactoryInterface $configFactory, protected Connection $database, protected EntityTypeManagerInterface $entityTypeManager, ) { @@ -29,16 +29,13 @@ public function __construct( /** * Returns the module configuration object. - * - * @return \Drupal\Core\Config\Config|\Drupal\Core\Config\ImmutableConfig - * The module configuration object. */ protected function getConfig() { - if ($this->config === NULL) { + if ($this->configFactory === NULL) { // Get module config. - $this->config = $this->config->get('taxonomy.settings'); + $this->configFactory = $this->configFactory->get('taxonomy.settings'); } - return $this->config; + return $this->configFactory; } /** -- GitLab From 126ee214eec0b3eceb650dd02e58ef6ab51a692d Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Thu, 20 Mar 2025 13:44:54 -0400 Subject: [PATCH 31/53] Adding back docblock comment. --- core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index 86b52e563d5d..2cfc9d1170be 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -29,6 +29,9 @@ public function __construct( /** * Returns the module configuration object. + * + * @return \Drupal\Core\Config\Config|\Drupal\Core\Config\ImmutableConfig + * The module configuration object. */ protected function getConfig() { if ($this->configFactory === NULL) { -- GitLab From 7c594280a744dc50c838f8537de6bce8d6c486c2 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Thu, 20 Mar 2025 14:17:40 -0400 Subject: [PATCH 32/53] Updating TaxonomyHelpHooks and TaxonomyMenuHooks organiztion outlined in Meta issue. --- .../src/Hook/{TaxonomyHelp.php => TaxonomyHelpHooks.php} | 2 +- .../src/Hook/{TaxonomyHooks.php => TaxonomyMenuHooks.php} | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename core/modules/taxonomy/src/Hook/{TaxonomyHelp.php => TaxonomyHelpHooks.php} (99%) rename core/modules/taxonomy/src/Hook/{TaxonomyHooks.php => TaxonomyMenuHooks.php} (92%) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyHelp.php b/core/modules/taxonomy/src/Hook/TaxonomyHelpHooks.php similarity index 99% rename from core/modules/taxonomy/src/Hook/TaxonomyHelp.php rename to core/modules/taxonomy/src/Hook/TaxonomyHelpHooks.php index c63b6d99b4ba..a674256e5e4f 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyHelp.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyHelpHooks.php @@ -11,7 +11,7 @@ /** * Help hook implementation for taxonomy(). */ -class TaxonomyHelp { +class TaxonomyHelpHooks { use StringTranslationTrait; diff --git a/core/modules/taxonomy/src/Hook/TaxonomyHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyMenuHooks.php similarity index 92% rename from core/modules/taxonomy/src/Hook/TaxonomyHooks.php rename to core/modules/taxonomy/src/Hook/TaxonomyMenuHooks.php index be0484965937..a5f457e76dbc 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyMenuHooks.php @@ -5,9 +5,9 @@ use Drupal\Core\Hook\Attribute\Hook; /** - * Hook implementations for taxonomy. + * Menu hook implementations for taxonomy. */ -class TaxonomyHooks { +class TaxonomyMenuHooks { /** * Implements hook_local_tasks_alter(). -- GitLab From e784e2606fbdbf0f74655bcedcf266ef288dbb5b Mon Sep 17 00:00:00 2001 From: Mike McGovern <26519-mcgovernm@users.noreply.drupalcode.org> Date: Thu, 20 Mar 2025 19:16:26 +0000 Subject: [PATCH 33/53] Apply 2 suggestion(s) to 2 file(s) Co-authored-by: nicxvan <29861-nicxvan@users.noreply.drupalcode.org> --- core/modules/taxonomy/src/Hook/TaxonomyHelpHooks.php | 3 +-- core/modules/taxonomy/src/Hook/TaxonomyThemeHooks.php | 6 +++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyHelpHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyHelpHooks.php index a674256e5e4f..9daa7908d379 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyHelpHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyHelpHooks.php @@ -15,8 +15,7 @@ class TaxonomyHelpHooks { use StringTranslationTrait; - public function __construct(protected ModuleHandlerInterface $moduleHandler) { - } + public function __construct(protected ModuleHandlerInterface $moduleHandler) {} /** * Implements hook_help(). diff --git a/core/modules/taxonomy/src/Hook/TaxonomyThemeHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyThemeHooks.php index ead2f34f2b4a..a9b024b5f48e 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyThemeHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyThemeHooks.php @@ -14,7 +14,11 @@ class TaxonomyThemeHooks { */ #[Hook('theme')] public function taxonomyTheme($existing, $type, $theme, $path): array { - return ['taxonomy_term' => ['render element' => 'elements']]; + return [ + 'taxonomy_term' => [ + 'render element' => 'elements', + ], + ]; } /** -- GitLab From ce9132e79bfceaf008508a9700be636573f8544e Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Fri, 21 Mar 2025 09:00:21 -0400 Subject: [PATCH 34/53] Replacing getconfig() with shouldMaintainIndexTable() and cleaning up implementation. --- .../taxonomy/src/Hook/TaxonomyEntityHooks.php | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index 2cfc9d1170be..cadb741008f9 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -28,17 +28,11 @@ public function __construct( } /** - * Returns the module configuration object. - * - * @return \Drupal\Core\Config\Config|\Drupal\Core\Config\ImmutableConfig - * The module configuration object. + * Returns the maintain_index_table configuration value. */ - protected function getConfig() { - if ($this->configFactory === NULL) { - // Get module config. - $this->configFactory = $this->configFactory->get('taxonomy.settings'); - } - return $this->configFactory; + protected function shouldMaintainIndexTable(): boolean { + $taxonomy_config = $this->configFactory->get('taxonomy.settings'); + return $taxonomy_config->get('maintain_index_table'); } /** @@ -53,7 +47,7 @@ protected function getConfig() { protected function buildNodeIndex(NodeInterface $node): void { // We maintain a denormalized table of term/node relationships, containing // only data for current, published nodes. - if (!$this->getConfig()->get('maintain_index_table') || !($this->entityTypeManager->getStorage('node') instanceof SqlContentEntityStorage)) { + if (!$this->shouldMaintainIndexTable() || !($this->entityTypeManager->getStorage('node') instanceof SqlContentEntityStorage)) { return; } @@ -97,7 +91,7 @@ protected function buildNodeIndex(NodeInterface $node): void { * The node entity. */ protected function deleteNodeIndex(NodeInterface $node): void { - if ($this->getConfig()->get('maintain_index_table')) { + if ($this->shouldMaintainIndexTable()) { $this->database->delete('taxonomy_index')->condition('nid', $node->id())->execute(); } } @@ -179,7 +173,7 @@ public function nodePredelete(EntityInterface $node): void { */ #[Hook('taxonomy_term_delete')] public function taxonomyTermDelete(Term $term): void { - if ($this->getConfig()->get('maintain_index_table')) { + if ($this->shouldMaintainIndexTable()) { // Clean up the {taxonomy_index} table when terms are deleted. $this->database->delete('taxonomy_index')->condition('tid', $term->id())->execute(); } -- GitLab From 0132c4e1c9816d5adc87413e2109192855ccccb0 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Fri, 21 Mar 2025 09:04:53 -0400 Subject: [PATCH 35/53] Fixing return type. --- core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index cadb741008f9..da47af9cae2d 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -30,7 +30,7 @@ public function __construct( /** * Returns the maintain_index_table configuration value. */ - protected function shouldMaintainIndexTable(): boolean { + protected function shouldMaintainIndexTable(): bool { $taxonomy_config = $this->configFactory->get('taxonomy.settings'); return $taxonomy_config->get('maintain_index_table'); } -- GitLab From 03b60ecac8b520cc01eda64eb001d6f486574b37 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Fri, 21 Mar 2025 11:19:20 -0400 Subject: [PATCH 36/53] Fixing return on shouldMaintainIndexTable(). --- core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index da47af9cae2d..ea29e967357c 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -32,6 +32,9 @@ public function __construct( */ protected function shouldMaintainIndexTable(): bool { $taxonomy_config = $this->configFactory->get('taxonomy.settings'); + if($taxonomy_config->get('maintain_index_table') == NULL){ + return FALSE; + } return $taxonomy_config->get('maintain_index_table'); } -- GitLab From b06ec6199c98a15614427756e6f8dbcf70544542 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Fri, 21 Mar 2025 11:23:08 -0400 Subject: [PATCH 37/53] Fixing phpcs errors. --- core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index ea29e967357c..41d15f257b20 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -32,7 +32,7 @@ public function __construct( */ protected function shouldMaintainIndexTable(): bool { $taxonomy_config = $this->configFactory->get('taxonomy.settings'); - if($taxonomy_config->get('maintain_index_table') == NULL){ + if ($taxonomy_config->get('maintain_index_table') == NULL) { return FALSE; } return $taxonomy_config->get('maintain_index_table'); -- GitLab From 7f20ef56acb0bd656960f52736851c156a4f6d87 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Fri, 21 Mar 2025 11:39:35 -0400 Subject: [PATCH 38/53] Removing taxonomy_build_node_index and taxonomy_delete_node_index from taxonomy.module. --- core/modules/taxonomy/taxonomy.module | 68 --------------------------- 1 file changed, 68 deletions(-) diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module index c6512d623112..2496048588af 100644 --- a/core/modules/taxonomy/taxonomy.module +++ b/core/modules/taxonomy/taxonomy.module @@ -4,8 +4,6 @@ * @file */ -use Drupal\Core\Entity\EntityInterface; -use Drupal\Core\Entity\Sql\SqlContentEntityStorage; use Drupal\Core\Render\Element; use Drupal\taxonomy\Entity\Term; @@ -73,69 +71,3 @@ function taxonomy_term_is_page(Term $term) { } return FALSE; } - -/** - * Builds and inserts taxonomy index entries for a given node. - * - * The index lists all terms that are related to a given node entity, and is - * therefore maintained at the entity level. - * - * @param \Drupal\node\NodeInterface $node - * The node entity. - */ -function taxonomy_build_node_index($node) { - // We maintain a denormalized table of term/node relationships, containing - // only data for current, published nodes. - if (!\Drupal::config('taxonomy.settings')->get('maintain_index_table') || !(\Drupal::entityTypeManager()->getStorage('node') instanceof SqlContentEntityStorage)) { - return; - } - - $status = $node->isPublished(); - $sticky = (int) $node->isSticky(); - // We only maintain the taxonomy index for published nodes. - if ($status && $node->isDefaultRevision()) { - // Collect a unique list of all the term IDs from all node fields. - $tid_all = []; - $entity_reference_class = 'Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem'; - foreach ($node->getFieldDefinitions() as $field) { - $field_name = $field->getName(); - $class = $field->getItemDefinition()->getClass(); - $is_entity_reference_class = ($class === $entity_reference_class) || is_subclass_of($class, $entity_reference_class); - if ($is_entity_reference_class && $field->getSetting('target_type') == 'taxonomy_term') { - foreach ($node->getTranslationLanguages() as $language) { - foreach ($node->getTranslation($language->getId())->$field_name as $item) { - if (!$item->isEmpty()) { - $tid_all[$item->target_id] = $item->target_id; - } - } - } - } - } - // Insert index entries for all the node's terms. - if (!empty($tid_all)) { - $connection = \Drupal::database(); - foreach ($tid_all as $tid) { - $connection->merge('taxonomy_index') - ->keys(['nid' => $node->id(), 'tid' => $tid, 'status' => $node->isPublished()]) - ->fields(['sticky' => $sticky, 'created' => $node->getCreatedTime()]) - ->execute(); - } - } - } -} - -/** - * Deletes taxonomy index entries for a given node. - * - * @param \Drupal\Core\Entity\EntityInterface $node - * The node entity. - */ -function taxonomy_delete_node_index(EntityInterface $node) { - if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) { - \Drupal::database()->delete('taxonomy_index')->condition('nid', $node->id())->execute(); - } -} - -/** - * @} End of "defgroup taxonomy_index". - */ -- GitLab From 7b351458299448ba69f8c6c15303ec4393e8db0e Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Fri, 21 Mar 2025 11:59:58 -0400 Subject: [PATCH 39/53] Revert "Removing taxonomy_build_node_index and taxonomy_delete_node_index from taxonomy.module." This reverts commit 7f20ef56acb0bd656960f52736851c156a4f6d87. --- core/modules/taxonomy/taxonomy.module | 68 +++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module index 2496048588af..c6512d623112 100644 --- a/core/modules/taxonomy/taxonomy.module +++ b/core/modules/taxonomy/taxonomy.module @@ -4,6 +4,8 @@ * @file */ +use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\Sql\SqlContentEntityStorage; use Drupal\Core\Render\Element; use Drupal\taxonomy\Entity\Term; @@ -71,3 +73,69 @@ function taxonomy_term_is_page(Term $term) { } return FALSE; } + +/** + * Builds and inserts taxonomy index entries for a given node. + * + * The index lists all terms that are related to a given node entity, and is + * therefore maintained at the entity level. + * + * @param \Drupal\node\NodeInterface $node + * The node entity. + */ +function taxonomy_build_node_index($node) { + // We maintain a denormalized table of term/node relationships, containing + // only data for current, published nodes. + if (!\Drupal::config('taxonomy.settings')->get('maintain_index_table') || !(\Drupal::entityTypeManager()->getStorage('node') instanceof SqlContentEntityStorage)) { + return; + } + + $status = $node->isPublished(); + $sticky = (int) $node->isSticky(); + // We only maintain the taxonomy index for published nodes. + if ($status && $node->isDefaultRevision()) { + // Collect a unique list of all the term IDs from all node fields. + $tid_all = []; + $entity_reference_class = 'Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem'; + foreach ($node->getFieldDefinitions() as $field) { + $field_name = $field->getName(); + $class = $field->getItemDefinition()->getClass(); + $is_entity_reference_class = ($class === $entity_reference_class) || is_subclass_of($class, $entity_reference_class); + if ($is_entity_reference_class && $field->getSetting('target_type') == 'taxonomy_term') { + foreach ($node->getTranslationLanguages() as $language) { + foreach ($node->getTranslation($language->getId())->$field_name as $item) { + if (!$item->isEmpty()) { + $tid_all[$item->target_id] = $item->target_id; + } + } + } + } + } + // Insert index entries for all the node's terms. + if (!empty($tid_all)) { + $connection = \Drupal::database(); + foreach ($tid_all as $tid) { + $connection->merge('taxonomy_index') + ->keys(['nid' => $node->id(), 'tid' => $tid, 'status' => $node->isPublished()]) + ->fields(['sticky' => $sticky, 'created' => $node->getCreatedTime()]) + ->execute(); + } + } + } +} + +/** + * Deletes taxonomy index entries for a given node. + * + * @param \Drupal\Core\Entity\EntityInterface $node + * The node entity. + */ +function taxonomy_delete_node_index(EntityInterface $node) { + if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) { + \Drupal::database()->delete('taxonomy_index')->condition('nid', $node->id())->execute(); + } +} + +/** + * @} End of "defgroup taxonomy_index". + */ -- GitLab From 7512ff7bef7aa791b015183267d19f0d2a010d44 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Fri, 21 Mar 2025 15:06:01 -0400 Subject: [PATCH 40/53] Fixing logic in shouldMaintainIndexTable. --- core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index 41d15f257b20..b8b103f4200c 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -32,10 +32,8 @@ public function __construct( */ protected function shouldMaintainIndexTable(): bool { $taxonomy_config = $this->configFactory->get('taxonomy.settings'); - if ($taxonomy_config->get('maintain_index_table') == NULL) { - return FALSE; - } - return $taxonomy_config->get('maintain_index_table'); + $maintain_index_table = $taxonomy_config->get('maintain_index_table'); + return $maintain_index_table; } /** -- GitLab From 363bd8099cc740692824ec5a947ee2eee3e47d78 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Fri, 21 Mar 2025 16:03:07 -0400 Subject: [PATCH 41/53] Adding return type to comment. --- core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index b8b103f4200c..283223e970cc 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -29,6 +29,9 @@ public function __construct( /** * Returns the maintain_index_table configuration value. + * + * @return bool + * Whether or not the index table should be maintained. */ protected function shouldMaintainIndexTable(): bool { $taxonomy_config = $this->configFactory->get('taxonomy.settings'); -- GitLab From 0e83e6cdbf1772922f1f0637a6b689320f03024b Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Fri, 21 Mar 2025 16:06:43 -0400 Subject: [PATCH 42/53] Fixing phpcs error. --- core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index 283223e970cc..5ed995bb0174 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -29,7 +29,7 @@ public function __construct( /** * Returns the maintain_index_table configuration value. - * + * * @return bool * Whether or not the index table should be maintained. */ -- GitLab From f90f2474b40463c4fc345605a4aa8a8faf90a746 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Fri, 21 Mar 2025 16:53:06 -0400 Subject: [PATCH 43/53] Casting return value as bool. --- core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index 5ed995bb0174..834fa6cdfa49 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -30,13 +30,11 @@ public function __construct( /** * Returns the maintain_index_table configuration value. * - * @return bool - * Whether or not the index table should be maintained. */ protected function shouldMaintainIndexTable(): bool { $taxonomy_config = $this->configFactory->get('taxonomy.settings'); $maintain_index_table = $taxonomy_config->get('maintain_index_table'); - return $maintain_index_table; + return (bool) $maintain_index_table; } /** -- GitLab From f25a3f10cc1ee58a55ce1bca48681242c78bf8ba Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Fri, 21 Mar 2025 16:57:02 -0400 Subject: [PATCH 44/53] Fixing phpcs error. --- core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php | 1 - 1 file changed, 1 deletion(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index 834fa6cdfa49..8a45a6ea411e 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -29,7 +29,6 @@ public function __construct( /** * Returns the maintain_index_table configuration value. - * */ protected function shouldMaintainIndexTable(): bool { $taxonomy_config = $this->configFactory->get('taxonomy.settings'); -- GitLab From 77ada68d7bae59017ac5033d038a9f24f4c40545 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Wed, 26 Mar 2025 11:23:54 -0400 Subject: [PATCH 45/53] Moving node index functionality to a service and deprecating taxonomy_build_node_index() and taxonomy_delete_node_index(). --- .../taxonomy/src/Hook/TaxonomyEntityHooks.php | 82 +----------- core/modules/taxonomy/src/NodeIndex.php | 123 ++++++++++++++++++ core/modules/taxonomy/taxonomy.module | 54 ++------ core/modules/taxonomy/taxonomy.services.yml | 5 + 4 files changed, 145 insertions(+), 119 deletions(-) create mode 100644 core/modules/taxonomy/src/NodeIndex.php diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index 8a45a6ea411e..27e5371b7a29 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -8,8 +8,6 @@ use Drupal\Core\Hook\Attribute\Hook; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\Entity\Sql\SqlContentEntityStorage; -use Drupal\node\NodeInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\Url; @@ -27,76 +25,6 @@ public function __construct( ) { } - /** - * Returns the maintain_index_table configuration value. - */ - protected function shouldMaintainIndexTable(): bool { - $taxonomy_config = $this->configFactory->get('taxonomy.settings'); - $maintain_index_table = $taxonomy_config->get('maintain_index_table'); - return (bool) $maintain_index_table; - } - - /** - * Builds and inserts taxonomy index entries for a given node. - * - * The index lists all terms that are related to a given node entity, and is - * therefore maintained at the entity level. - * - * @param \Drupal\node\NodeInterface $node - * The node entity. - */ - protected function buildNodeIndex(NodeInterface $node): void { - // We maintain a denormalized table of term/node relationships, containing - // only data for current, published nodes. - if (!$this->shouldMaintainIndexTable() || !($this->entityTypeManager->getStorage('node') instanceof SqlContentEntityStorage)) { - return; - } - - $status = $node->isPublished(); - $sticky = (int) $node->isSticky(); - // We only maintain the taxonomy index for published nodes. - if ($status && $node->isDefaultRevision()) { - // Collect a unique list of all the term IDs from all node fields. - $tid_all = []; - $entity_reference_class = 'Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem'; - foreach ($node->getFieldDefinitions() as $field) { - $field_name = $field->getName(); - $class = $field->getItemDefinition()->getClass(); - $is_entity_reference_class = ($class === $entity_reference_class) || is_subclass_of($class, $entity_reference_class); - if ($is_entity_reference_class && $field->getSetting('target_type') == 'taxonomy_term') { - foreach ($node->getTranslationLanguages() as $language) { - foreach ($node->getTranslation($language->getId())->$field_name as $item) { - if (!$item->isEmpty()) { - $tid_all[$item->target_id] = $item->target_id; - } - } - } - } - } - // Insert index entries for all the node's terms. - if (!empty($tid_all)) { - foreach ($tid_all as $tid) { - $this->database->merge('taxonomy_index') - ->keys(['nid' => $node->id(), 'tid' => $tid, 'status' => $node->isPublished()]) - ->fields(['sticky' => $sticky, 'created' => $node->getCreatedTime()]) - ->execute(); - } - } - } - } - - /** - * Deletes taxonomy index entries for a given node. - * - * @param \Drupal\node\NodeInterface $node - * The node entity. - */ - protected function deleteNodeIndex(NodeInterface $node): void { - if ($this->shouldMaintainIndexTable()) { - $this->database->delete('taxonomy_index')->condition('nid', $node->id())->execute(); - } - } - /** * Implements hook_entity_operation(). */ @@ -143,7 +71,7 @@ public function entityOperation(EntityInterface $term): array { #[Hook('node_insert')] public function nodeInsert(EntityInterface $node): void { // Add taxonomy index entries for the node. - $this->buildNodeIndex($node); + \Drupal::service('taxonomy.node_index')->buildNodeIndex($node); } /** @@ -156,8 +84,8 @@ public function nodeUpdate(EntityInterface $node): void { if (!$node->isDefaultRevision()) { return; } - $this->deleteNodeIndex($node); - $this->buildNodeIndex($node); + \Drupal::service('taxonomy.node_index')->deleteNodeIndex($node); + \Drupal::service('taxonomy.node_index')->buildNodeIndex($node); } /** @@ -166,7 +94,7 @@ public function nodeUpdate(EntityInterface $node): void { #[Hook('node_predelete')] public function nodePredelete(EntityInterface $node): void { // Clean up the {taxonomy_index} table when nodes are deleted. - $this->deleteNodeIndex($node); + \Drupal::service('taxonomy.node_index')->deleteNodeIndex($node); } /** @@ -174,7 +102,7 @@ public function nodePredelete(EntityInterface $node): void { */ #[Hook('taxonomy_term_delete')] public function taxonomyTermDelete(Term $term): void { - if ($this->shouldMaintainIndexTable()) { + if (\Drupal::service('taxonomy.node_index')->shouldMaintainIndexTable()) { // Clean up the {taxonomy_index} table when terms are deleted. $this->database->delete('taxonomy_index')->condition('tid', $term->id())->execute(); } diff --git a/core/modules/taxonomy/src/NodeIndex.php b/core/modules/taxonomy/src/NodeIndex.php new file mode 100644 index 000000000000..340cef51c9b2 --- /dev/null +++ b/core/modules/taxonomy/src/NodeIndex.php @@ -0,0 +1,123 @@ +<?php + +namespace Drupal\taxonomy; + +use Drupal\Core\Config\ConfigFactoryInterface; +use Drupal\Core\Database\Connection; +use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Entity\Sql\SqlContentEntityStorage; +use Drupal\node\NodeInterface; + +/** + * Defines a Controller class for maintaining the taxonomy node index. + */ +class NodeIndex { + + /** + * The database connection. + * + * @var \Drupal\Core\Database\Connection + */ + protected $database; + + /** + * The config factory. + * + * @var \Drupal\Core\Config\ConfigFactoryInterface + */ + protected $configFactory; + + /** + * The entity type manager. + * + * @var \Drupal\Core\Entity\EntityTypeManagerInterface + */ + protected $entityTypeManager; + + /** + * Constructs the NodeIndex. + * + * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory + * The config factory. + * @param \Drupal\Core\Database\Connection $database + * The database connection. + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager + * The entity type manager. + */ + public function __construct(ConfigFactoryInterface $config_factory, Connection $database, EntityTypeManagerInterface $entity_type_manager) { + $this->configFactory = $config_factory; + $this->database = $database; + $this->entityTypeManager = $entity_type_manager; + } + + /** + * Returns the maintain_index_table configuration value. + */ + public function shouldMaintainIndexTable(): bool { + $taxonomy_config = $this->configFactory->get('taxonomy.settings'); + $maintain_index_table = $taxonomy_config->get('maintain_index_table'); + return (bool) $maintain_index_table; + } + + /** + * Builds and inserts taxonomy index entries for a given node. + * + * The index lists all terms that are related to a given node entity, and is + * therefore maintained at the entity level. + * + * @param \Drupal\node\NodeInterface $node + * The node entity. + */ + public function buildNodeIndex(NodeInterface $node): void { + // We maintain a denormalized table of term/node relationships, containing + // only data for current, published nodes. + if (!$this->shouldMaintainIndexTable() || !($this->entityTypeManager->getStorage('node') instanceof SqlContentEntityStorage)) { + return; + } + + $status = $node->isPublished(); + $sticky = (int) $node->isSticky(); + // We only maintain the taxonomy index for published nodes. + if ($status && $node->isDefaultRevision()) { + // Collect a unique list of all the term IDs from all node fields. + $tid_all = []; + $entity_reference_class = 'Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem'; + foreach ($node->getFieldDefinitions() as $field) { + $field_name = $field->getName(); + $class = $field->getItemDefinition()->getClass(); + $is_entity_reference_class = ($class === $entity_reference_class) || is_subclass_of($class, $entity_reference_class); + if ($is_entity_reference_class && $field->getSetting('target_type') == 'taxonomy_term') { + foreach ($node->getTranslationLanguages() as $language) { + foreach ($node->getTranslation($language->getId())->$field_name as $item) { + if (!$item->isEmpty()) { + $tid_all[$item->target_id] = $item->target_id; + } + } + } + } + } + // Insert index entries for all the node's terms. + if (!empty($tid_all)) { + foreach ($tid_all as $tid) { + $this->database->merge('taxonomy_index') + ->keys(['nid' => $node->id(), 'tid' => $tid, 'status' => $node->isPublished()]) + ->fields(['sticky' => $sticky, 'created' => $node->getCreatedTime()]) + ->execute(); + } + } + } + } + + /** + * Deletes taxonomy index entries for a given node. + * + * @param \Drupal\node\NodeInterface $node + * The node entity. + */ + public function deleteNodeIndex(NodeInterface $node): void { + if ($this->shouldMaintainIndexTable()) { + $this->database->delete('taxonomy_index')->condition('nid', $node->id())->execute(); + } + } + +} diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module index c6512d623112..adb088a99c5f 100644 --- a/core/modules/taxonomy/taxonomy.module +++ b/core/modules/taxonomy/taxonomy.module @@ -5,7 +5,6 @@ */ use Drupal\Core\Entity\EntityInterface; -use Drupal\Core\Entity\Sql\SqlContentEntityStorage; use Drupal\Core\Render\Element; use Drupal\taxonomy\Entity\Term; @@ -82,46 +81,14 @@ function taxonomy_term_is_page(Term $term) { * * @param \Drupal\node\NodeInterface $node * The node entity. + * + * @deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. Use + * \Drupal::service('taxonomy.node_index')->buildNodeIndex($node); + * @see https://www.drupal.org/node/3515362 */ function taxonomy_build_node_index($node) { - // We maintain a denormalized table of term/node relationships, containing - // only data for current, published nodes. - if (!\Drupal::config('taxonomy.settings')->get('maintain_index_table') || !(\Drupal::entityTypeManager()->getStorage('node') instanceof SqlContentEntityStorage)) { - return; - } - - $status = $node->isPublished(); - $sticky = (int) $node->isSticky(); - // We only maintain the taxonomy index for published nodes. - if ($status && $node->isDefaultRevision()) { - // Collect a unique list of all the term IDs from all node fields. - $tid_all = []; - $entity_reference_class = 'Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem'; - foreach ($node->getFieldDefinitions() as $field) { - $field_name = $field->getName(); - $class = $field->getItemDefinition()->getClass(); - $is_entity_reference_class = ($class === $entity_reference_class) || is_subclass_of($class, $entity_reference_class); - if ($is_entity_reference_class && $field->getSetting('target_type') == 'taxonomy_term') { - foreach ($node->getTranslationLanguages() as $language) { - foreach ($node->getTranslation($language->getId())->$field_name as $item) { - if (!$item->isEmpty()) { - $tid_all[$item->target_id] = $item->target_id; - } - } - } - } - } - // Insert index entries for all the node's terms. - if (!empty($tid_all)) { - $connection = \Drupal::database(); - foreach ($tid_all as $tid) { - $connection->merge('taxonomy_index') - ->keys(['nid' => $node->id(), 'tid' => $tid, 'status' => $node->isPublished()]) - ->fields(['sticky' => $sticky, 'created' => $node->getCreatedTime()]) - ->execute(); - } - } - } + @trigger_error('taxonomy_build_node_index() is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. Use \Drupal::service(\'taxonomy.node_index\')->buildNodeIndex($node). See https://www.drupal.org/node/3515362', E_USER_DEPRECATED); + \Drupal::service('taxonomy.node_index')->buildNodeIndex($node); } /** @@ -129,11 +96,14 @@ function taxonomy_build_node_index($node) { * * @param \Drupal\Core\Entity\EntityInterface $node * The node entity. + * + * @deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. Use + * \Drupal::service('taxonomy.node_index')->deleteNodeIndex($node) instead. + * @see https://www.drupal.org/node/3515362 */ function taxonomy_delete_node_index(EntityInterface $node) { - if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) { - \Drupal::database()->delete('taxonomy_index')->condition('nid', $node->id())->execute(); - } + @trigger_error('taxonomy_delete_node_index() is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. Use \Drupal::service(\'taxonomy.node_index\')->deleteNodeIndex($node). See https://www.drupal.org/node/3515362', E_USER_DEPRECATED); + \Drupal::service('taxonomy.node_index')->deleteNodeIndex($node); } /** diff --git a/core/modules/taxonomy/taxonomy.services.yml b/core/modules/taxonomy/taxonomy.services.yml index 91a333ec9773..97f513fa2f5b 100644 --- a/core/modules/taxonomy/taxonomy.services.yml +++ b/core/modules/taxonomy/taxonomy.services.yml @@ -11,3 +11,8 @@ services: arguments: ['@current_route_match'] tags: - { name: 'context_provider' } + taxonomy.node_index: + class: Drupal\taxonomy\NodeIndex + arguments: ['@config.factory', '@database', '@entity_type.manager'] + tags: + - { name: 'node_index'} -- GitLab From 1f9742072eafa1d470db8cb8de29899f8e67acdf Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Wed, 26 Mar 2025 11:55:38 -0400 Subject: [PATCH 46/53] Adding alias for taxonomy.node_index service. --- core/modules/taxonomy/taxonomy.services.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/core/modules/taxonomy/taxonomy.services.yml b/core/modules/taxonomy/taxonomy.services.yml index 97f513fa2f5b..2a5fa8fba95d 100644 --- a/core/modules/taxonomy/taxonomy.services.yml +++ b/core/modules/taxonomy/taxonomy.services.yml @@ -16,3 +16,4 @@ services: arguments: ['@config.factory', '@database', '@entity_type.manager'] tags: - { name: 'node_index'} + Drupal\taxonomy\NodeIndex: '@taxonomy.node_index' -- GitLab From 38b1ddfb5ee1f011b00abc334d813ab6eddb006b Mon Sep 17 00:00:00 2001 From: Mike McGovern <26519-mcgovernm@users.noreply.drupalcode.org> Date: Thu, 27 Mar 2025 12:09:34 +0000 Subject: [PATCH 47/53] Apply 6 suggestion(s) to 2 file(s) Co-authored-by: nicxvan <29861-nicxvan@users.noreply.drupalcode.org> --- .../taxonomy/src/Hook/TaxonomyEntityHooks.php | 15 +++---- core/modules/taxonomy/src/NodeIndex.php | 40 ++----------------- 2 files changed, 12 insertions(+), 43 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index 27e5371b7a29..4f7b4b416476 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -3,6 +3,7 @@ namespace Drupal\taxonomy\Hook; use Drupal\taxonomy\Entity\Term; +use Drupal\taxonomy\NodeIndex; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Database\Connection; use Drupal\Core\Hook\Attribute\Hook; @@ -22,8 +23,8 @@ public function __construct( protected ConfigFactoryInterface $configFactory, protected Connection $database, protected EntityTypeManagerInterface $entityTypeManager, - ) { - } + protected NodeIndex $nodeIndex, + ) {} /** * Implements hook_entity_operation(). @@ -71,7 +72,7 @@ public function entityOperation(EntityInterface $term): array { #[Hook('node_insert')] public function nodeInsert(EntityInterface $node): void { // Add taxonomy index entries for the node. - \Drupal::service('taxonomy.node_index')->buildNodeIndex($node); + $this->nodeIndex->buildNodeIndex($node); } /** @@ -84,8 +85,8 @@ public function nodeUpdate(EntityInterface $node): void { if (!$node->isDefaultRevision()) { return; } - \Drupal::service('taxonomy.node_index')->deleteNodeIndex($node); - \Drupal::service('taxonomy.node_index')->buildNodeIndex($node); + $this->nodeIndex->deleteNodeIndex($node); + $this->nodeIndex->buildNodeIndex($node); } /** @@ -94,7 +95,7 @@ public function nodeUpdate(EntityInterface $node): void { #[Hook('node_predelete')] public function nodePredelete(EntityInterface $node): void { // Clean up the {taxonomy_index} table when nodes are deleted. - \Drupal::service('taxonomy.node_index')->deleteNodeIndex($node); + $this->nodeIndex->deleteNodeIndex($node); } /** @@ -102,7 +103,7 @@ public function nodePredelete(EntityInterface $node): void { */ #[Hook('taxonomy_term_delete')] public function taxonomyTermDelete(Term $term): void { - if (\Drupal::service('taxonomy.node_index')->shouldMaintainIndexTable()) { + if ($this->nodeIndex->shouldMaintainIndexTable()) { // Clean up the {taxonomy_index} table when terms are deleted. $this->database->delete('taxonomy_index')->condition('tid', $term->id())->execute(); } diff --git a/core/modules/taxonomy/src/NodeIndex.php b/core/modules/taxonomy/src/NodeIndex.php index 340cef51c9b2..21e57d08c1be 100644 --- a/core/modules/taxonomy/src/NodeIndex.php +++ b/core/modules/taxonomy/src/NodeIndex.php @@ -13,42 +13,10 @@ */ class NodeIndex { - /** - * The database connection. - * - * @var \Drupal\Core\Database\Connection - */ - protected $database; - - /** - * The config factory. - * - * @var \Drupal\Core\Config\ConfigFactoryInterface - */ - protected $configFactory; - - /** - * The entity type manager. - * - * @var \Drupal\Core\Entity\EntityTypeManagerInterface - */ - protected $entityTypeManager; - - /** - * Constructs the NodeIndex. - * - * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory - * The config factory. - * @param \Drupal\Core\Database\Connection $database - * The database connection. - * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager - * The entity type manager. - */ - public function __construct(ConfigFactoryInterface $config_factory, Connection $database, EntityTypeManagerInterface $entity_type_manager) { - $this->configFactory = $config_factory; - $this->database = $database; - $this->entityTypeManager = $entity_type_manager; - } + public function __construct( + protected readonly ConfigFactoryInterface $configFactory, + protected readonly Connection $database, + protected readonly EntityTypeManagerInterface $entityTypeManager) {} /** * Returns the maintain_index_table configuration value. -- GitLab From eef4ba29e40a26d0db09110233366acfacbc5203 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Thu, 27 Mar 2025 08:18:47 -0400 Subject: [PATCH 48/53] Fixing PHPCS error. --- core/modules/taxonomy/src/NodeIndex.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/modules/taxonomy/src/NodeIndex.php b/core/modules/taxonomy/src/NodeIndex.php index 21e57d08c1be..6627c677a173 100644 --- a/core/modules/taxonomy/src/NodeIndex.php +++ b/core/modules/taxonomy/src/NodeIndex.php @@ -16,7 +16,8 @@ class NodeIndex { public function __construct( protected readonly ConfigFactoryInterface $configFactory, protected readonly Connection $database, - protected readonly EntityTypeManagerInterface $entityTypeManager) {} + protected readonly EntityTypeManagerInterface $entityTypeManager, + ) {} /** * Returns the maintain_index_table configuration value. -- GitLab From 13b5437bdac9333f2a9fd7675f23c4c28ef05902 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Thu, 27 Mar 2025 10:17:56 -0400 Subject: [PATCH 49/53] Revert "Moving node index functionality to a service and deprecating taxonomy_build_node_index() and taxonomy_delete_node_index()." This reverts commit 77ada68d7bae59017ac5033d038a9f24f4c40545. --- .../taxonomy/src/Hook/TaxonomyEntityHooks.php | 84 +++++++++++++++-- core/modules/taxonomy/src/NodeIndex.php | 92 ------------------- core/modules/taxonomy/taxonomy.module | 56 ++++++++--- core/modules/taxonomy/taxonomy.services.yml | 6 -- 4 files changed, 121 insertions(+), 117 deletions(-) delete mode 100644 core/modules/taxonomy/src/NodeIndex.php diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index 4f7b4b416476..b41b01315dc8 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -3,12 +3,13 @@ namespace Drupal\taxonomy\Hook; use Drupal\taxonomy\Entity\Term; -use Drupal\taxonomy\NodeIndex; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Database\Connection; use Drupal\Core\Hook\Attribute\Hook; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Entity\Sql\SqlContentEntityStorage; +use Drupal\node\NodeInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\Url; @@ -23,9 +24,78 @@ public function __construct( protected ConfigFactoryInterface $configFactory, protected Connection $database, protected EntityTypeManagerInterface $entityTypeManager, - protected NodeIndex $nodeIndex, ) {} + /** + * Returns the maintain_index_table configuration value. + */ + protected function shouldMaintainIndexTable(): bool { + $taxonomy_config = $this->configFactory->get('taxonomy.settings'); + $maintain_index_table = $taxonomy_config->get('maintain_index_table'); + return (bool) $maintain_index_table; + } + + /** + * Builds and inserts taxonomy index entries for a given node. + * + * The index lists all terms that are related to a given node entity, and is + * therefore maintained at the entity level. + * + * @param \Drupal\node\NodeInterface $node + * The node entity. + */ + protected function buildNodeIndex(NodeInterface $node): void { + // We maintain a denormalized table of term/node relationships, containing + // only data for current, published nodes. + if (!$this->shouldMaintainIndexTable() || !($this->entityTypeManager->getStorage('node') instanceof SqlContentEntityStorage)) { + return; + } + + $status = $node->isPublished(); + $sticky = (int) $node->isSticky(); + // We only maintain the taxonomy index for published nodes. + if ($status && $node->isDefaultRevision()) { + // Collect a unique list of all the term IDs from all node fields. + $tid_all = []; + $entity_reference_class = 'Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem'; + foreach ($node->getFieldDefinitions() as $field) { + $field_name = $field->getName(); + $class = $field->getItemDefinition()->getClass(); + $is_entity_reference_class = ($class === $entity_reference_class) || is_subclass_of($class, $entity_reference_class); + if ($is_entity_reference_class && $field->getSetting('target_type') == 'taxonomy_term') { + foreach ($node->getTranslationLanguages() as $language) { + foreach ($node->getTranslation($language->getId())->$field_name as $item) { + if (!$item->isEmpty()) { + $tid_all[$item->target_id] = $item->target_id; + } + } + } + } + } + // Insert index entries for all the node's terms. + if (!empty($tid_all)) { + foreach ($tid_all as $tid) { + $this->database->merge('taxonomy_index') + ->keys(['nid' => $node->id(), 'tid' => $tid, 'status' => $node->isPublished()]) + ->fields(['sticky' => $sticky, 'created' => $node->getCreatedTime()]) + ->execute(); + } + } + } + } + + /** + * Deletes taxonomy index entries for a given node. + * + * @param \Drupal\node\NodeInterface $node + * The node entity. + */ + protected function deleteNodeIndex(NodeInterface $node): void { + if ($this->shouldMaintainIndexTable()) { + $this->database->delete('taxonomy_index')->condition('nid', $node->id())->execute(); + } + } + /** * Implements hook_entity_operation(). */ @@ -72,7 +142,7 @@ public function entityOperation(EntityInterface $term): array { #[Hook('node_insert')] public function nodeInsert(EntityInterface $node): void { // Add taxonomy index entries for the node. - $this->nodeIndex->buildNodeIndex($node); + $this->buildNodeIndex($node); } /** @@ -85,8 +155,8 @@ public function nodeUpdate(EntityInterface $node): void { if (!$node->isDefaultRevision()) { return; } - $this->nodeIndex->deleteNodeIndex($node); - $this->nodeIndex->buildNodeIndex($node); + $this->deleteNodeIndex($node); + $this->buildNodeIndex($node); } /** @@ -95,7 +165,7 @@ public function nodeUpdate(EntityInterface $node): void { #[Hook('node_predelete')] public function nodePredelete(EntityInterface $node): void { // Clean up the {taxonomy_index} table when nodes are deleted. - $this->nodeIndex->deleteNodeIndex($node); + $this->deleteNodeIndex($node); } /** @@ -103,7 +173,7 @@ public function nodePredelete(EntityInterface $node): void { */ #[Hook('taxonomy_term_delete')] public function taxonomyTermDelete(Term $term): void { - if ($this->nodeIndex->shouldMaintainIndexTable()) { + if ($this->shouldMaintainIndexTable()) { // Clean up the {taxonomy_index} table when terms are deleted. $this->database->delete('taxonomy_index')->condition('tid', $term->id())->execute(); } diff --git a/core/modules/taxonomy/src/NodeIndex.php b/core/modules/taxonomy/src/NodeIndex.php deleted file mode 100644 index 6627c677a173..000000000000 --- a/core/modules/taxonomy/src/NodeIndex.php +++ /dev/null @@ -1,92 +0,0 @@ -<?php - -namespace Drupal\taxonomy; - -use Drupal\Core\Config\ConfigFactoryInterface; -use Drupal\Core\Database\Connection; -use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\Entity\Sql\SqlContentEntityStorage; -use Drupal\node\NodeInterface; - -/** - * Defines a Controller class for maintaining the taxonomy node index. - */ -class NodeIndex { - - public function __construct( - protected readonly ConfigFactoryInterface $configFactory, - protected readonly Connection $database, - protected readonly EntityTypeManagerInterface $entityTypeManager, - ) {} - - /** - * Returns the maintain_index_table configuration value. - */ - public function shouldMaintainIndexTable(): bool { - $taxonomy_config = $this->configFactory->get('taxonomy.settings'); - $maintain_index_table = $taxonomy_config->get('maintain_index_table'); - return (bool) $maintain_index_table; - } - - /** - * Builds and inserts taxonomy index entries for a given node. - * - * The index lists all terms that are related to a given node entity, and is - * therefore maintained at the entity level. - * - * @param \Drupal\node\NodeInterface $node - * The node entity. - */ - public function buildNodeIndex(NodeInterface $node): void { - // We maintain a denormalized table of term/node relationships, containing - // only data for current, published nodes. - if (!$this->shouldMaintainIndexTable() || !($this->entityTypeManager->getStorage('node') instanceof SqlContentEntityStorage)) { - return; - } - - $status = $node->isPublished(); - $sticky = (int) $node->isSticky(); - // We only maintain the taxonomy index for published nodes. - if ($status && $node->isDefaultRevision()) { - // Collect a unique list of all the term IDs from all node fields. - $tid_all = []; - $entity_reference_class = 'Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem'; - foreach ($node->getFieldDefinitions() as $field) { - $field_name = $field->getName(); - $class = $field->getItemDefinition()->getClass(); - $is_entity_reference_class = ($class === $entity_reference_class) || is_subclass_of($class, $entity_reference_class); - if ($is_entity_reference_class && $field->getSetting('target_type') == 'taxonomy_term') { - foreach ($node->getTranslationLanguages() as $language) { - foreach ($node->getTranslation($language->getId())->$field_name as $item) { - if (!$item->isEmpty()) { - $tid_all[$item->target_id] = $item->target_id; - } - } - } - } - } - // Insert index entries for all the node's terms. - if (!empty($tid_all)) { - foreach ($tid_all as $tid) { - $this->database->merge('taxonomy_index') - ->keys(['nid' => $node->id(), 'tid' => $tid, 'status' => $node->isPublished()]) - ->fields(['sticky' => $sticky, 'created' => $node->getCreatedTime()]) - ->execute(); - } - } - } - } - - /** - * Deletes taxonomy index entries for a given node. - * - * @param \Drupal\node\NodeInterface $node - * The node entity. - */ - public function deleteNodeIndex(NodeInterface $node): void { - if ($this->shouldMaintainIndexTable()) { - $this->database->delete('taxonomy_index')->condition('nid', $node->id())->execute(); - } - } - -} diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module index 1bd7194c97b2..c01e428cc1e9 100644 --- a/core/modules/taxonomy/taxonomy.module +++ b/core/modules/taxonomy/taxonomy.module @@ -5,6 +5,7 @@ */ use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\Sql\SqlContentEntityStorage; use Drupal\Core\Render\Element; use Drupal\taxonomy\Entity\Term; @@ -81,14 +82,47 @@ function taxonomy_term_is_page(Term $term) { * * @param \Drupal\node\NodeInterface $node * The node entity. - * - * @deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. Use - * \Drupal::service('taxonomy.node_index')->buildNodeIndex($node); - * @see https://www.drupal.org/node/3515362 */ function taxonomy_build_node_index($node): void { - @trigger_error('taxonomy_build_node_index() is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. Use \Drupal::service(\'taxonomy.node_index\')->buildNodeIndex($node). See https://www.drupal.org/node/3515362', E_USER_DEPRECATED); - \Drupal::service('taxonomy.node_index')->buildNodeIndex($node); + @trigger_error('taxonomy_build_node_index() is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. See https://www.drupal.org/node/3515362', E_USER_DEPRECATED); + // We maintain a denormalized table of term/node relationships, containing + // only data for current, published nodes. + if (!\Drupal::config('taxonomy.settings')->get('maintain_index_table') || !(\Drupal::entityTypeManager()->getStorage('node') instanceof SqlContentEntityStorage)) { + return; + } + + $status = $node->isPublished(); + $sticky = (int) $node->isSticky(); + // We only maintain the taxonomy index for published nodes. + if ($status && $node->isDefaultRevision()) { + // Collect a unique list of all the term IDs from all node fields. + $tid_all = []; + $entity_reference_class = 'Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem'; + foreach ($node->getFieldDefinitions() as $field) { + $field_name = $field->getName(); + $class = $field->getItemDefinition()->getClass(); + $is_entity_reference_class = ($class === $entity_reference_class) || is_subclass_of($class, $entity_reference_class); + if ($is_entity_reference_class && $field->getSetting('target_type') == 'taxonomy_term') { + foreach ($node->getTranslationLanguages() as $language) { + foreach ($node->getTranslation($language->getId())->$field_name as $item) { + if (!$item->isEmpty()) { + $tid_all[$item->target_id] = $item->target_id; + } + } + } + } + } + // Insert index entries for all the node's terms. + if (!empty($tid_all)) { + $connection = \Drupal::database(); + foreach ($tid_all as $tid) { + $connection->merge('taxonomy_index') + ->keys(['nid' => $node->id(), 'tid' => $tid, 'status' => $node->isPublished()]) + ->fields(['sticky' => $sticky, 'created' => $node->getCreatedTime()]) + ->execute(); + } + } + } } /** @@ -96,14 +130,12 @@ function taxonomy_build_node_index($node): void { * * @param \Drupal\Core\Entity\EntityInterface $node * The node entity. - * - * @deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. Use - * \Drupal::service('taxonomy.node_index')->deleteNodeIndex($node) instead. - * @see https://www.drupal.org/node/3515362 */ function taxonomy_delete_node_index(EntityInterface $node): void { - @trigger_error('taxonomy_delete_node_index() is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. Use \Drupal::service(\'taxonomy.node_index\')->deleteNodeIndex($node). See https://www.drupal.org/node/3515362', E_USER_DEPRECATED); - \Drupal::service('taxonomy.node_index')->deleteNodeIndex($node); + @trigger_error('taxonomy_delete_node_index() is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. See https://www.drupal.org/node/3515362', E_USER_DEPRECATED); + if (\Drupal::config('taxonomy.settings')->get('maintain_index_table')) { + \Drupal::database()->delete('taxonomy_index')->condition('nid', $node->id())->execute(); + } } /** diff --git a/core/modules/taxonomy/taxonomy.services.yml b/core/modules/taxonomy/taxonomy.services.yml index 2a5fa8fba95d..91a333ec9773 100644 --- a/core/modules/taxonomy/taxonomy.services.yml +++ b/core/modules/taxonomy/taxonomy.services.yml @@ -11,9 +11,3 @@ services: arguments: ['@current_route_match'] tags: - { name: 'context_provider' } - taxonomy.node_index: - class: Drupal\taxonomy\NodeIndex - arguments: ['@config.factory', '@database', '@entity_type.manager'] - tags: - - { name: 'node_index'} - Drupal\taxonomy\NodeIndex: '@taxonomy.node_index' -- GitLab From fb7562dd86ee6fd3af2fabf370505ed9193efdfe Mon Sep 17 00:00:00 2001 From: Mike McGovern <26519-mcgovernm@users.noreply.drupalcode.org> Date: Fri, 9 May 2025 13:21:27 +0000 Subject: [PATCH 50/53] Apply 6 suggestion(s) to 4 file(s) Co-authored-by: Derek Wright <12223-dww@users.noreply.drupalcode.org> --- core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php | 6 ++---- core/modules/taxonomy/src/Hook/TaxonomyHelpHooks.php | 4 ++-- core/modules/taxonomy/src/Hook/TaxonomyMenuHooks.php | 2 +- core/modules/taxonomy/src/Hook/TaxonomyThemeHooks.php | 2 +- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index b41b01315dc8..ae35a8bb4ad7 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -14,7 +14,7 @@ use Drupal\Core\Url; /** - * Hook implementations for taxonomy. + * Entity hook implementations for taxonomy. */ class TaxonomyEntityHooks { @@ -30,9 +30,7 @@ public function __construct( * Returns the maintain_index_table configuration value. */ protected function shouldMaintainIndexTable(): bool { - $taxonomy_config = $this->configFactory->get('taxonomy.settings'); - $maintain_index_table = $taxonomy_config->get('maintain_index_table'); - return (bool) $maintain_index_table; + return (bool) $this->configFactory->get('taxonomy.settings')->get('maintain_index_table'); } /** diff --git a/core/modules/taxonomy/src/Hook/TaxonomyHelpHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyHelpHooks.php index 9daa7908d379..2692e0d4e22d 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyHelpHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyHelpHooks.php @@ -9,7 +9,7 @@ use Drupal\Core\StringTranslation\StringTranslationTrait; /** - * Help hook implementation for taxonomy(). + * Help hook implementation for the Taxonomy module. */ class TaxonomyHelpHooks { @@ -21,7 +21,7 @@ public function __construct(protected ModuleHandlerInterface $moduleHandler) {} * Implements hook_help(). */ #[Hook('help')] - public function help($route_name, RouteMatchInterface $route_match): string { + public function help(string $route_name, RouteMatchInterface $route_match): string { switch ($route_name) { case 'help.page.taxonomy': $field_ui_url = $this->moduleHandler->moduleExists('field_ui') ? Url::fromRoute('help.page', ['name' => 'field_ui'])->toString() : '#'; diff --git a/core/modules/taxonomy/src/Hook/TaxonomyMenuHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyMenuHooks.php index a5f457e76dbc..65e949cde151 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyMenuHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyMenuHooks.php @@ -15,7 +15,7 @@ class TaxonomyMenuHooks { * @todo Evaluate removing as part of https://www.drupal.org/node/2358923. */ #[Hook('local_tasks_alter')] - public function localTasksAlter(&$local_tasks): void { + public function localTasksAlter(array &$local_tasks): void { $local_task_key = 'config_translation.local_tasks:entity.taxonomy_vocabulary.config_translation_overview'; if (isset($local_tasks[$local_task_key])) { // The config_translation module expects the base route to be diff --git a/core/modules/taxonomy/src/Hook/TaxonomyThemeHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyThemeHooks.php index a9b024b5f48e..9a74574c4fa9 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyThemeHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyThemeHooks.php @@ -5,7 +5,7 @@ use Drupal\Core\Hook\Attribute\Hook; /** - * Implements hook_theme(). + * Implements theme hook implementations for the Taxonomy module. */ class TaxonomyThemeHooks { -- GitLab From 2781d81afb4d1c8bc4bec00ca3bcb431e75b877d Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Fri, 9 May 2025 10:14:16 -0400 Subject: [PATCH 51/53] Fix defgroup open and close that were separated during hook conversion. --- core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php | 6 +++++- core/modules/taxonomy/taxonomy.module | 4 ---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index ae35a8bb4ad7..260fc1320685 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -176,5 +176,9 @@ public function taxonomyTermDelete(Term $term): void { $this->database->delete('taxonomy_index')->condition('tid', $term->id())->execute(); } } - + + // phpcs:ignore Drupal.Commenting.InlineComment.DocBlock + /** + * @} End of "defgroup taxonomy_index". + */ } diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module index c01e428cc1e9..ecc5fa0c4dbe 100644 --- a/core/modules/taxonomy/taxonomy.module +++ b/core/modules/taxonomy/taxonomy.module @@ -137,7 +137,3 @@ function taxonomy_delete_node_index(EntityInterface $node): void { \Drupal::database()->delete('taxonomy_index')->condition('nid', $node->id())->execute(); } } - -/** - * @} End of "defgroup taxonomy_index". - */ -- GitLab From 6ac20ba274b66dd70dd780e484eb03017b70e000 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Fri, 9 May 2025 10:22:44 -0400 Subject: [PATCH 52/53] Fixing PHPCS error. --- core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php index 260fc1320685..f1b031d4a265 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyEntityHooks.php @@ -176,7 +176,7 @@ public function taxonomyTermDelete(Term $term): void { $this->database->delete('taxonomy_index')->condition('tid', $term->id())->execute(); } } - + // phpcs:ignore Drupal.Commenting.InlineComment.DocBlock /** * @} End of "defgroup taxonomy_index". -- GitLab From 111b9feb7d96676fdde31cdfed85f78f02659c02 Mon Sep 17 00:00:00 2001 From: Mike McGovern <mcgovernm@566364.no-reply.drupal.org> Date: Fri, 9 May 2025 10:51:32 -0400 Subject: [PATCH 53/53] Removing arguments from theme hook. --- core/modules/taxonomy/src/Hook/TaxonomyThemeHooks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modules/taxonomy/src/Hook/TaxonomyThemeHooks.php b/core/modules/taxonomy/src/Hook/TaxonomyThemeHooks.php index 9a74574c4fa9..e62ba91ee791 100644 --- a/core/modules/taxonomy/src/Hook/TaxonomyThemeHooks.php +++ b/core/modules/taxonomy/src/Hook/TaxonomyThemeHooks.php @@ -13,7 +13,7 @@ class TaxonomyThemeHooks { * Implements hook_theme(). */ #[Hook('theme')] - public function taxonomyTheme($existing, $type, $theme, $path): array { + public function taxonomyTheme(): array { return [ 'taxonomy_term' => [ 'render element' => 'elements', -- GitLab