diff --git a/core/lib/Drupal/Core/Field/EntityReferenceFieldItemList.php b/core/lib/Drupal/Core/Field/EntityReferenceFieldItemList.php index 4cc66ec..2d32c64 100644 --- a/core/lib/Drupal/Core/Field/EntityReferenceFieldItemList.php +++ b/core/lib/Drupal/Core/Field/EntityReferenceFieldItemList.php @@ -129,7 +129,14 @@ public function defaultValuesFormSubmit(array $element, array &$form, FormStateI } /** - * {@inheritdoc} + * Removes the items with a specific target id. + * + * @param int $target_id + * The target id of the item to be removed. + * + * @return $this + * + * @todo Add this to EntityReferenceFieldItemListInterface in Drupal 9.0.x. */ public function removeItemsByTargetId($target_id) { if (isset($this->list)) { diff --git a/core/lib/Drupal/Core/Field/EntityReferenceFieldItemListInterface.php b/core/lib/Drupal/Core/Field/EntityReferenceFieldItemListInterface.php index 807cb7f..4a088bf 100644 --- a/core/lib/Drupal/Core/Field/EntityReferenceFieldItemListInterface.php +++ b/core/lib/Drupal/Core/Field/EntityReferenceFieldItemListInterface.php @@ -15,14 +15,4 @@ */ public function referencedEntities(); - /** - * Removes the items with a specific target id. - * - * @param int $target_id - * The target id of the item to be removed. - * - * @return $this - */ - public function removeItemsByTargetId($target_id); - } diff --git a/core/modules/forum/src/Tests/ForumTest.php b/core/modules/forum/src/Tests/ForumTest.php index f0f123a..6733f34 100644 --- a/core/modules/forum/src/Tests/ForumTest.php +++ b/core/modules/forum/src/Tests/ForumTest.php @@ -433,7 +433,7 @@ function createForum($type, $parent = 0) { $parent_tid = $term_entity->parent->target_id; $this->assertTrue($parent == $parent_tid, 'The ' . $type . ' is linked to its container'); - $forum = $this->container->get('entity.manager')->getStorage('taxonomy_term')->load($term_entity->id()); + $forum = Term::load($term_entity->id()); $this->assertEqual(($type == 'forum container'), (bool) $forum->forum_container->value); return $term; } diff --git a/core/modules/taxonomy/src/Entity/Term.php b/core/modules/taxonomy/src/Entity/Term.php index cfddf51..8cbfdda 100644 --- a/core/modules/taxonomy/src/Entity/Term.php +++ b/core/modules/taxonomy/src/Entity/Term.php @@ -7,6 +7,7 @@ use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\BaseFieldDefinition; +use Drupal\taxonomy\TermHierarchyInterface; use Drupal\taxonomy\TermInterface; /** @@ -50,7 +51,7 @@ * permission_granularity = "bundle" * ) */ -class Term extends ContentEntityBase implements TermInterface { +class Term extends ContentEntityBase implements TermInterface, TermHierarchyInterface { use EntityChangedTrait; diff --git a/core/modules/taxonomy/src/Entity/Vocabulary.php b/core/modules/taxonomy/src/Entity/Vocabulary.php index c453475..120fee9 100644 --- a/core/modules/taxonomy/src/Entity/Vocabulary.php +++ b/core/modules/taxonomy/src/Entity/Vocabulary.php @@ -173,7 +173,15 @@ public static function postDelete(EntityStorageInterface $storage, array $entiti } /** - * {@inheritdoc} + * Gets top-level term IDs of vocabularies. + * + * @param array $vids + * Array of vocabulary IDs. + * + * @return array + * Array of top-level term IDs. + * + * @todo Add this to \Drupal\taxonomy\VocabularyInterface in Drupal 9.0.x. */ public static function getTopLevelTids($vids) { $tids = \Drupal::entityQuery('taxonomy_term') diff --git a/core/modules/taxonomy/src/TermHierarchyInterface.php b/core/modules/taxonomy/src/TermHierarchyInterface.php new file mode 100644 index 0000000..98f3054 --- /dev/null +++ b/core/modules/taxonomy/src/TermHierarchyInterface.php @@ -0,0 +1,40 @@ + + * parent that item is keyed with 0 and have NULL as value. + */ + public function getParents(); + + /** + * Returns all ancestors of this term. + * + * @return \Drupal\taxonomy\TermInterface[] + * A list of ancestor taxonomy term entities keyed by term id. + */ + public function getAncestors(); + + /** + * Returns all children terms of this term. + * + * @param string $vid + * An optional vocabulary ID to restrict the child search. + * + * @return \Drupal\taxonomy\TermInterface[] + * A list of children taxonomy term entities keyed by term id. + */ + public function getChildren($vid = NULL); + +} diff --git a/core/modules/taxonomy/src/TermInterface.php b/core/modules/taxonomy/src/TermInterface.php index 4607a46..68da4b6 100644 --- a/core/modules/taxonomy/src/TermInterface.php +++ b/core/modules/taxonomy/src/TermInterface.php @@ -7,6 +7,8 @@ /** * Provides an interface defining a taxonomy term entity. + * + * @todo Merge here \Drupal\taxonomy\TermHierarchyInterface in Drupal 9.0.x. */ interface TermInterface extends ContentEntityInterface, EntityChangedInterface { @@ -90,32 +92,4 @@ public function setWeight($weight); */ public function getVocabularyId(); - /** - * Returns a list of parents of this term. - * - * @return \Drupal\Core\Field\EntityReferenceFieldItemListInterface - * A list of references to parents taxonomy terms. If this term has a - * parent that item is keyed with 0 and have NULL as value. - */ - public function getParents(); - - /** - * Returns all ancestors of this term. - * - * @return \Drupal\taxonomy\TermInterface[] - * A list of ancestor taxonomy term entities keyed by term id. - */ - public function getAncestors(); - - /** - * Returns all children terms of this term. - * - * @param string $vid - * An optional vocabulary ID to restrict the child search. - * - * @return \Drupal\taxonomy\TermInterface[] - * A list of children taxonomy term entities keyed by term id. - */ - public function getChildren($vid = NULL); - } diff --git a/core/modules/taxonomy/src/TermStorageInterface.php b/core/modules/taxonomy/src/TermStorageInterface.php index d6213a0..4a4f396 100644 --- a/core/modules/taxonomy/src/TermStorageInterface.php +++ b/core/modules/taxonomy/src/TermStorageInterface.php @@ -16,7 +16,8 @@ * @param array $tids * Array of terms that need to be removed from hierarchy. * - * @deprecated in Drupal 8.0.x, will be removed before Drupal 8.1.0. + * @todo Remove this method in Drupal 9.0.x. Now the parent references are + * automatically cleared when deleting a taxonomy term. */ public function deleteTermHierarchy($tids); @@ -26,7 +27,8 @@ public function deleteTermHierarchy($tids); * @param \Drupal\Core\Entity\EntityInterface $term * Term entity that needs to be added to term hierarchy information. * - * @deprecated in Drupal 8.0.x, will be removed before Drupal 8.1.0. + * @todo remove this method Drupal 9.0.x. Now the parent references are + * automatically updates when when a taxonomy term is added/updated. */ public function updateTermHierarchy(EntityInterface $term); @@ -39,7 +41,7 @@ public function updateTermHierarchy(EntityInterface $term); * @return \Drupal\taxonomy\TermInterface[] * An array of term objects which are the parents of the term $tid. * - * @deprecated in Drupal 8.0.x, will be removed before Drupal 8.1.0. Use + * @deprecated in Drupal 8.2.x, will be removed in Drupal 9.0.0. Use * \Drupal\taxonomy\Entity\Term::load($tid)->getParents() instead. */ public function loadParents($tid); @@ -53,7 +55,7 @@ public function loadParents($tid); * @return \Drupal\taxonomy\TermInterface[] * An array of term objects which are the ancestors of the term $tid. * - * @deprecated in Drupal 8.0.x, will be removed before Drupal 8.1.0. Use + * @deprecated in Drupal 8.2.x, will be removed in Drupal 9.0.0. Use * \Drupal\taxonomy\Entity\Term::load($tid)->getAncestors() instead. */ public function loadAllParents($tid); @@ -69,7 +71,7 @@ public function loadAllParents($tid); * @return \Drupal\taxonomy\TermInterface[] * An array of term objects that are the children of the term $tid. * - * @deprecated in Drupal 8.0.x, will be removed before Drupal 8.1.0. Use + * @deprecated in Drupal 8.2.x, will be removed in Drupal 9.0.0. Use * \Drupal\taxonomy\Entity\Term::load($tid)->getChildren($vid) instead. */ public function loadChildren($tid, $vid = NULL); diff --git a/core/modules/taxonomy/src/TermViewsData.php b/core/modules/taxonomy/src/TermViewsData.php index 7854b2a..d9c9fb1 100644 --- a/core/modules/taxonomy/src/TermViewsData.php +++ b/core/modules/taxonomy/src/TermViewsData.php @@ -261,4 +261,4 @@ public function getViewsData() { return $data; } - } +} diff --git a/core/modules/taxonomy/src/Tests/Update/TaxonomyUpdateTest.php b/core/modules/taxonomy/src/Tests/Update/TaxonomyUpdateTest.php index a5ba473..866fa07 100644 --- a/core/modules/taxonomy/src/Tests/Update/TaxonomyUpdateTest.php +++ b/core/modules/taxonomy/src/Tests/Update/TaxonomyUpdateTest.php @@ -1,10 +1,5 @@ db = $this->container->get('database'); - $this->configFactory = $this->container->get('config.factory'); } /** - * Tests taxonomy_update_8001(). + * Tests taxonomy term parents update. * * @see taxonomy_update_8001() + * @see taxonomy_post_update_parents() */ - public function testTaxonomyUpdate8001() { + public function testTaxonomyUpdateParents() { $tids = $this->createTerms(); $vid = $this->createView(); @@ -88,7 +76,7 @@ public function testTaxonomyUpdate8001() { // Test if the view has been converted to use {taxonomy_term__parent} table // instead of {taxonomy_term_hierarchy}. - $view = $this->configFactory->get("views.view.$vid"); + $view = $this->config("views.view.$vid"); $path = 'display.default.display_options.relationships.parent.table'; $this->assertIdentical($view->get($path), 'taxonomy_term__parent'); @@ -97,7 +85,7 @@ public function testTaxonomyUpdate8001() { } /** - * Create some terms on a very low level, bypassing the API. + * Creates some terms on a very low level, bypassing the API. * * @return array * A list of created term IDs. @@ -147,12 +135,16 @@ protected function createTerms() { protected function createView() { $vid = Unicode::strtolower($this->randomMachineName()); $file = __DIR__ . '/../../../tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_parent.yml'; - - $this->configFactory->getEditable("views.view.$vid") - ->setData(Yaml::decode(file_get_contents($file))) - // Revert the change done in taxonomy_update_8001(). - ->set('display.default.display_options.relationships.parent.table', 'taxonomy_term_hierarchy') - ->save(); + $config = Yaml::decode(file_get_contents($file)); + + $this->container->get('database')->insert('config') + ->fields(['collection', 'name', 'data']) + ->values([ + 'collection' => '', + 'name' => "views.view.$vid", + 'data' => serialize($config), + ]) + ->execute(); return $vid; } diff --git a/core/modules/taxonomy/src/VocabularyInterface.php b/core/modules/taxonomy/src/VocabularyInterface.php index 9e6f9f7..ff52bec 100644 --- a/core/modules/taxonomy/src/VocabularyInterface.php +++ b/core/modules/taxonomy/src/VocabularyInterface.php @@ -39,15 +39,4 @@ public function setHierarchy($hierarchy); */ public function getDescription(); - /** - * Gets top-level term IDs of vocabularies. - * - * @param array $vids - * Array of vocabulary IDs. - * - * @return array - * Array of top-level term IDs. - */ - public static function getTopLevelTids($vids); - } diff --git a/core/modules/taxonomy/src/VocabularyStorageInterface.php b/core/modules/taxonomy/src/VocabularyStorageInterface.php index d5b6a61..3549ee0 100644 --- a/core/modules/taxonomy/src/VocabularyStorageInterface.php +++ b/core/modules/taxonomy/src/VocabularyStorageInterface.php @@ -18,7 +18,7 @@ * @return array * Array of top-level term IDs. * - * @deprecated in Drupal 8.0.x, will be removed before Drupal 8.1.0. Use + * @deprecated in Drupal 8.2.x, will be removed in Drupal 9.0.x Use * \Drupal\taxonomy\Entity\Vocabulary::getTopLevelTids($vids) instead. */ public function getToplevelTids($vids); diff --git a/core/modules/taxonomy/taxonomy.install b/core/modules/taxonomy/taxonomy.install index 2369dad..9616467 100644 --- a/core/modules/taxonomy/taxonomy.install +++ b/core/modules/taxonomy/taxonomy.install @@ -9,78 +9,28 @@ * Convert the custom taxonomy term hierarchy storage to a default storage. */ function taxonomy_update_8001(&$sandbox = NULL) { - $database = \Drupal::database(); - - if (!isset($sandbox['current'])) { - // Update entity definition. - $manager = \Drupal::entityDefinitionUpdateManager(); - /** @var \Drupal\Core\Field\BaseFieldDefinition $definition */ - $definition = $manager->getFieldStorageDefinition('parent', 'taxonomy_term'); - $definition->setCustomStorage(FALSE); - $manager->updateFieldStorageDefinition($definition); - - // Set batch ops sandbox. - $sandbox['current'] = 0; - $sandbox['max'] = $database->select('taxonomy_term_hierarchy') - ->countQuery() - ->execute() - ->fetchField(); - } - - // Save the hierarchy. - $select = $database->select('taxonomy_term_hierarchy', 'h'); - $select->join('taxonomy_term_data', 'd', 'h.tid = d.tid'); - $hierarchy = $select - ->fields('h', ['tid', 'parent']) - ->fields('d', ['vid', 'langcode']) - ->range($sandbox['current'], $sandbox['current'] + 100) - ->execute() - ->fetchAll(); - - // Restore data. - $insert = $database->insert('taxonomy_term__parent') - ->fields(['bundle', 'entity_id', 'revision_id', 'langcode', 'delta', 'parent_target_id']); - $tid = -1; - foreach ($hierarchy as $row) { - if ($row->tid !== $tid) { - $delta = 0; - $tid = $row->tid; - } - $insert->values([ - 'bundle' => $row->vid, - 'entity_id' => $row->tid, - 'revision_id' => $row->tid, - 'langcode' => $row->langcode, - 'delta' => $delta, - 'parent_target_id' => $row->parent, - ]); - $delta++; - $sandbox['current']++; - } - $insert->execute(); - - $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['current'] / $sandbox['max']); - - if ($sandbox['#finished'] >= 1) { - $factory = \Drupal::configFactory(); - // Update views with a low level API. - foreach ($factory->listAll('views.view.') as $id) { - $view = $factory->getEditable($id); - $changed = FALSE; - foreach ($view->get('display') as $display_id => &$display) { - $path = "display.$display_id.display_options.relationships.parent.table"; - if (!empty($table = $view->get($path)) && $table == 'taxonomy_term_hierarchy') { - $view->set($path, 'taxonomy_term__parent'); - $changed = TRUE; - } - } - if ($changed) { - $view->save(TRUE); + // Update entity definition. + $manager = \Drupal::entityDefinitionUpdateManager(); + /** @var \Drupal\Core\Field\BaseFieldDefinition $definition */ + $definition = $manager->getFieldStorageDefinition('parent', 'taxonomy_term'); + $definition->setCustomStorage(FALSE); + $manager->updateFieldStorageDefinition($definition); + + $factory = \Drupal::configFactory(); + // Update views with a low level API. + foreach ($factory->listAll('views.view.') as $id) { + $view = $factory->getEditable($id); + $changed = FALSE; + foreach ($view->get('display') as $display_id => &$display) { + $path = "display.$display_id.display_options.relationships.parent.table"; + if (!empty($table = $view->get($path)) && $table == 'taxonomy_term_hierarchy') { + $view->set($path, 'taxonomy_term__parent'); + $changed = TRUE; } } - - // Drop the legacy table. - $database->schema()->dropTable('taxonomy_term_hierarchy'); - return t('Taxonomy term hierarchy converted.'); + if ($changed) { + $view->save(TRUE); + } } + } diff --git a/core/modules/taxonomy/taxonomy.post_update.php b/core/modules/taxonomy/taxonomy.post_update.php new file mode 100644 index 0000000..018960d --- /dev/null +++ b/core/modules/taxonomy/taxonomy.post_update.php @@ -0,0 +1,72 @@ +select('taxonomy_term_hierarchy') + ->countQuery() + ->execute() + ->fetchField(); + } + + // Save the hierarchy. + $select = $database->select('taxonomy_term_hierarchy', 'h'); + $select->join('taxonomy_term_data', 'd', 'h.tid = d.tid'); + $hierarchy = $select + ->fields('h', ['tid', 'parent']) + ->fields('d', ['vid', 'langcode']) + ->range($sandbox['current'], $sandbox['current'] + 100) + ->execute() + ->fetchAll(); + + // Restore data. + $insert = $database->insert('taxonomy_term__parent') + ->fields(['bundle', 'entity_id', 'revision_id', 'langcode', 'delta', 'parent_target_id']); + $tid = -1; + foreach ($hierarchy as $row) { + if ($row->tid !== $tid) { + $delta = 0; + $tid = $row->tid; + } + $insert->values([ + 'bundle' => $row->vid, + 'entity_id' => $row->tid, + 'revision_id' => $row->tid, + 'langcode' => $row->langcode, + 'delta' => $delta, + 'parent_target_id' => $row->parent, + ]); + $delta++; + $sandbox['current']++; + } + $insert->execute(); + + $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['current'] / $sandbox['max']); + + if ($sandbox['#finished'] >= 1) { + // Drop the legacy table. + $database->schema()->dropTable('taxonomy_term_hierarchy'); + return t('Taxonomy term hierarchy converted.'); + } + +} + +/** + * @} End of "addtogroup updates-8.2.x". + */