.../EntityResource/Term/TermResourceTestBase.php | 10 +++ .../XmlEntityNormalizationQuirksTrait.php | 2 +- core/modules/taxonomy/src/Entity/Term.php | 72 +---------------- .../taxonomy/src/TermHierarchyInterface.php | 39 --------- core/modules/taxonomy/src/TermInterface.php | 3 - core/modules/taxonomy/src/TermStorage.php | 94 +++++++++++++++++++++- core/modules/taxonomy/src/TermStorageInterface.php | 9 --- 7 files changed, 104 insertions(+), 125 deletions(-) diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Term/TermResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/Term/TermResourceTestBase.php index 8a0cffb..e0e8eef 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/Term/TermResourceTestBase.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/Term/TermResourceTestBase.php @@ -318,6 +318,16 @@ public function testGetTermWithParent(array $parent_term_ids) { $this->setUpAuthorization('GET'); $response = $this->request('GET', $url, $request_options); $expected = $this->getExpectedNormalizedEntity(); + $expected += [ + 'field_rest_test_multivalue' => [ + 0 => [ + 'value' => 'One', + ], + 1 => [ + 'value' => 'Two', + ], + ] + ]; static::recursiveKSort($expected); $actual = $this->serializer->decode((string) $response->getBody(), static::$format); static::recursiveKSort($actual); diff --git a/core/modules/rest/tests/src/Functional/EntityResource/XmlEntityNormalizationQuirksTrait.php b/core/modules/rest/tests/src/Functional/EntityResource/XmlEntityNormalizationQuirksTrait.php index 962d8e9..b69394b 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/XmlEntityNormalizationQuirksTrait.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/XmlEntityNormalizationQuirksTrait.php @@ -99,7 +99,7 @@ protected function applyXmlFieldDecodingQuirks(array $normalization) { } } - if (!empty($normalization[$field_name])) { + if (count($normalization[$field_name]) === 1) { $normalization[$field_name] = $normalization[$field_name][0]; } } diff --git a/core/modules/taxonomy/src/Entity/Term.php b/core/modules/taxonomy/src/Entity/Term.php index 0f0c778..acde65a 100644 --- a/core/modules/taxonomy/src/Entity/Term.php +++ b/core/modules/taxonomy/src/Entity/Term.php @@ -7,7 +7,6 @@ use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\BaseFieldDefinition; -use Drupal\taxonomy\TermHierarchyInterface; use Drupal\taxonomy\TermInterface; /** @@ -53,18 +52,11 @@ * permission_granularity = "bundle" * ) */ -class Term extends ContentEntityBase implements TermInterface, TermHierarchyInterface { +class Term extends ContentEntityBase implements TermInterface { use EntityChangedTrait; /** - * Array of all loaded term ancestry keyed by ancestor term ID. - * - * @var \Drupal\taxonomy\TermInterface[] - */ - protected $ancestors; - - /** * {@inheritdoc} */ public static function postDelete(EntityStorageInterface $storage, array $entities) { @@ -74,7 +66,7 @@ public static function postDelete(EntityStorageInterface $storage, array $entiti $orphans = []; /** @var \Drupal\taxonomy\TermInterface $term */ foreach ($entities as $tid => $term) { - if ($children = $term->getChildren()) { + if ($children = $storage->getChildren($term)) { /** @var \Drupal\taxonomy\TermInterface $child */ foreach ($children as $child) { $parent = $child->get('parent'); @@ -256,64 +248,4 @@ protected function getFieldsToSkipFromTranslationChangesCheck() { return $fields; } - /** - * {@inheritdoc} - */ - public function getParents() { - $parents = $ids = []; - // Cannot use $this->get('parent')->referencedEntities() here because that - // strips out the '0' reference. - foreach ($this->get('parent') as $item) { - if ($item->target_id == static::ROOT_ID) { - // The parent. - $parents[0] = NULL; - continue; - } - $ids[] = $item->target_id; - } - - // @todo Better way to do this? AND handle the NULL/0 parent? - // Querying the terms again so that the same access checks are run when - // getParents() is called as in Drupal version prior to 8.3. - $loaded_parents = []; - - if ($ids) { - $query = \Drupal::entityQuery('taxonomy_term') - ->condition('tid', $ids, 'IN'); - - $loaded_parents = static::loadMultiple($query->execute()); - } - - return $parents + $loaded_parents; - } - - /** - * {@inheritdoc} - */ - public function getAncestors() { - if (!isset($this->ancestors)) { - $this->ancestors = [$this->id() => $this]; - $search[] = $this->id(); - - while ($tid = array_shift($search)) { - foreach (static::load($tid)->getParents() as $id => $parent) { - if ($parent && !isset($this->ancestors[$id])) { - $this->ancestors[$id] = $parent; - $search[] = $id; - } - } - } - } - return $this->ancestors; - } - - /** - * {@inheritdoc} - */ - public function getChildren() { - $query = \Drupal::entityQuery('taxonomy_term') - ->condition('parent', $this->id()); - return static::loadMultiple($query->execute()); - } - } diff --git a/core/modules/taxonomy/src/TermHierarchyInterface.php b/core/modules/taxonomy/src/TermHierarchyInterface.php deleted file mode 100644 index 9c46546..0000000 --- a/core/modules/taxonomy/src/TermHierarchyInterface.php +++ /dev/null @@ -1,39 +0,0 @@ - parent, that item is keyed with ROOT_ID and will 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. - * - * @return \Drupal\taxonomy\TermInterface[] - * A list of children taxonomy term entities keyed by term ID. - */ - public function getChildren(); - -} diff --git a/core/modules/taxonomy/src/TermInterface.php b/core/modules/taxonomy/src/TermInterface.php index 9120a61..cfba19d 100644 --- a/core/modules/taxonomy/src/TermInterface.php +++ b/core/modules/taxonomy/src/TermInterface.php @@ -7,9 +7,6 @@ /** * Provides an interface defining a taxonomy term entity. - * - * @todo Merge here \Drupal\taxonomy\TermHierarchyInterface in Drupal 9.0.x. - * https://www.drupal.org/node/2785685 */ interface TermInterface extends ContentEntityInterface, EntityChangedInterface { diff --git a/core/modules/taxonomy/src/TermStorage.php b/core/modules/taxonomy/src/TermStorage.php index 113286b..2db0392 100644 --- a/core/modules/taxonomy/src/TermStorage.php +++ b/core/modules/taxonomy/src/TermStorage.php @@ -39,6 +39,14 @@ class TermStorage extends SqlContentEntityStorage implements TermStorageInterfac protected $trees = []; /** + * Array of all loaded term ancestry keyed by ancestor term ID, keyed by term + * ID. + * + * @var \Drupal\taxonomy\TermInterface[][] + */ + protected $ancestors; + + /** * {@inheritdoc} * * @param array $values @@ -83,7 +91,7 @@ public function loadParents($tid) { $terms = []; /** @var \Drupal\taxonomy\TermInterface $term */ if ($tid && $term = $this->load($tid)) { - foreach ($term->getParents() as $id => $parent) { + foreach ($this->getParents($term) as $id => $parent) { // This method currently doesn't return the parent. // @see https://www.drupal.org/node/2019905 if (!empty($id)) { @@ -96,11 +104,76 @@ public function loadParents($tid) { } /** + * Returns a list of parents of this term. + * + * @return \Drupal\taxonomy\TermInterface[] + * The parent taxonomy term entities keyed by term ID. If this term has a + * parent, that item is keyed with ROOT_ID and will have NULL as + * value. + * + * @internal + * @todo Refactor away when TreeInterface is introduced. + */ + protected function getParents(TermInterface $term) { + $parents = $ids = []; + // Cannot use $this->get('parent')->referencedEntities() here because that + // strips out the '0' reference. + foreach ($term->get('parent') as $item) { + if ($item->target_id == $term::ROOT_ID) { + // The parent. + $parents[0] = NULL; + continue; + } + $ids[] = $item->target_id; + } + + // @todo Better way to do this? AND handle the NULL/0 parent? + // Querying the terms again so that the same access checks are run when + // getParents() is called as in Drupal version prior to 8.3. + $loaded_parents = []; + + if ($ids) { + $query = \Drupal::entityQuery('taxonomy_term') + ->condition('tid', $ids, 'IN'); + + $loaded_parents = static::loadMultiple($query->execute()); + } + + return $parents + $loaded_parents; + } + + /** * {@inheritdoc} */ public function loadAllParents($tid) { /** @var \Drupal\taxonomy\TermInterface $term */ - return (!empty($tid) && $term = $this->load($tid)) ? $term->getAncestors() : []; + return (!empty($tid) && $term = $this->load($tid)) ? $this->getAncestors($term) : []; + } + + /** + * Returns all ancestors of this term. + * + * @return \Drupal\taxonomy\TermInterface[] + * A list of ancestor taxonomy term entities keyed by term ID. + * + * @internal + * @todo Refactor away when TreeInterface is introduced. + */ + protected function getAncestors(TermInterface $term) { + if (!isset($this->ancestors[$term->id()])) { + $this->ancestors[$term->id()] = [$term->id() => $term]; + $search[] = $term->id(); + + while ($tid = array_shift($search)) { + foreach ($this->getParents(static::load($tid)) as $id => $parent) { + if ($parent && !isset($this->ancestors[$term->id()][$id])) { + $this->ancestors[$term->id()][$id] = $parent; + $search[] = $id; + } + } + } + } + return $this->ancestors[$term->id()]; } /** @@ -108,7 +181,22 @@ public function loadAllParents($tid) { */ public function loadChildren($tid, $vid = NULL) { /** @var \Drupal\taxonomy\TermInterface $term */ - return (!empty($tid) && $term = $this->load($tid)) ? $term->getChildren() : []; + return (!empty($tid) && $term = $this->load($tid)) ? $this->getChildren($term) : []; + } + + /** + * Returns all children terms of this term. + * + * @return \Drupal\taxonomy\TermInterface[] + * A list of children taxonomy term entities keyed by term ID. + * + * @internal + * @todo Refactor away when TreeInterface is introduced. + */ + public function getChildren(TermInterface $term) { + $query = \Drupal::entityQuery('taxonomy_term') + ->condition('parent', $term->id()); + return static::loadMultiple($query->execute()); } /** diff --git a/core/modules/taxonomy/src/TermStorageInterface.php b/core/modules/taxonomy/src/TermStorageInterface.php index 227919d..4d7b5cc 100644 --- a/core/modules/taxonomy/src/TermStorageInterface.php +++ b/core/modules/taxonomy/src/TermStorageInterface.php @@ -42,9 +42,6 @@ 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.3.x, will be removed in Drupal 9.0.0. Use - * \Drupal\taxonomy\Entity\Term::load($tid)->getParents() instead. */ public function loadParents($tid); @@ -56,9 +53,6 @@ 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.3.x, will be removed in Drupal 9.0.0. Use - * \Drupal\taxonomy\Entity\Term::load($tid)->getAncestors() instead. */ public function loadAllParents($tid); @@ -72,9 +66,6 @@ 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.3.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);