Issue #2957381 by amateescu, GaëlG, alexpott, douggreen, jibran, catch: Data model problems with Vocabulary hierarchy
parent
9444c6a26a
commit
70e40101ec
|
@ -7,5 +7,4 @@ dependencies:
|
|||
name: Forums
|
||||
vid: forums
|
||||
description: 'Forum navigation vocabulary'
|
||||
hierarchy: 1
|
||||
weight: -10
|
||||
|
|
|
@ -27,9 +27,6 @@ taxonomy.vocabulary.*:
|
|||
description:
|
||||
type: label
|
||||
label: 'Description'
|
||||
hierarchy:
|
||||
type: integer
|
||||
label: 'Hierarchy'
|
||||
weight:
|
||||
type: integer
|
||||
label: 'Weight'
|
||||
|
|
|
@ -25,7 +25,6 @@ process:
|
|||
label: name
|
||||
name: name
|
||||
description: description
|
||||
hierarchy: hierarchy
|
||||
weight: weight
|
||||
destination:
|
||||
plugin: entity:taxonomy_vocabulary
|
||||
|
|
|
@ -23,7 +23,6 @@ process:
|
|||
label: name
|
||||
name: name
|
||||
description: description
|
||||
hierarchy: hierarchy
|
||||
weight: weight
|
||||
destination:
|
||||
plugin: entity:taxonomy_vocabulary
|
||||
|
|
|
@ -53,7 +53,6 @@ use Drupal\taxonomy\VocabularyInterface;
|
|||
* "name",
|
||||
* "vid",
|
||||
* "description",
|
||||
* "hierarchy",
|
||||
* "weight",
|
||||
* }
|
||||
* )
|
||||
|
@ -81,18 +80,6 @@ class Vocabulary extends ConfigEntityBundleBase implements VocabularyInterface {
|
|||
*/
|
||||
protected $description;
|
||||
|
||||
/**
|
||||
* The type of hierarchy allowed within the vocabulary.
|
||||
*
|
||||
* Possible values:
|
||||
* - VocabularyInterface::HIERARCHY_DISABLED: No parents.
|
||||
* - VocabularyInterface::HIERARCHY_SINGLE: Single parent.
|
||||
* - VocabularyInterface::HIERARCHY_MULTIPLE: Multiple parents.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $hierarchy = VocabularyInterface::HIERARCHY_DISABLED;
|
||||
|
||||
/**
|
||||
* The weight of this vocabulary in relation to other vocabularies.
|
||||
*
|
||||
|
@ -104,14 +91,16 @@ class Vocabulary extends ConfigEntityBundleBase implements VocabularyInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHierarchy() {
|
||||
return $this->hierarchy;
|
||||
@trigger_error('\Drupal\taxonomy\VocabularyInterface::getHierarchy() is deprecated in Drupal 8.7.x and will be removed before Drupal 9.0.x. Use \Drupal\taxonomy\TermStorage::getVocabularyHierarchyType() instead.', E_USER_DEPRECATED);
|
||||
return $this->entityTypeManager()->getStorage('taxonomy_term')->getVocabularyHierarchyType($this->id());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setHierarchy($hierarchy) {
|
||||
$this->hierarchy = $hierarchy;
|
||||
@trigger_error('\Drupal\taxonomy\VocabularyInterface::setHierarchy() is deprecated in Drupal 8.7.x and will be removed before Drupal 9.0.x. Reset the cache of the taxonomy_term storage controller instead.', E_USER_DEPRECATED);
|
||||
$this->entityTypeManager()->getStorage('taxonomy_term')->resetCache();
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
|
|
@ -112,6 +112,7 @@ class OverviewTerms extends FormBase {
|
|||
global $pager_page_array, $pager_total, $pager_total_items;
|
||||
|
||||
$form_state->set(['taxonomy', 'vocabulary'], $taxonomy_vocabulary);
|
||||
$vocabulary_hierarchy = $this->storageController->getVocabularyHierarchyType($taxonomy_vocabulary->id());
|
||||
$parent_fields = FALSE;
|
||||
|
||||
$page = $this->getRequest()->query->get('page') ?: 0;
|
||||
|
@ -277,7 +278,7 @@ class OverviewTerms extends FormBase {
|
|||
'#title' => $term->getName(),
|
||||
'#url' => $term->urlInfo(),
|
||||
];
|
||||
if ($taxonomy_vocabulary->getHierarchy() != VocabularyInterface::HIERARCHY_MULTIPLE && count($tree) > 1) {
|
||||
if ($vocabulary_hierarchy != VocabularyInterface::HIERARCHY_MULTIPLE && count($tree) > 1) {
|
||||
$parent_fields = TRUE;
|
||||
$form['terms'][$key]['term']['tid'] = [
|
||||
'#type' => 'hidden',
|
||||
|
@ -384,7 +385,7 @@ class OverviewTerms extends FormBase {
|
|||
];
|
||||
}
|
||||
|
||||
if (($taxonomy_vocabulary->getHierarchy() !== VocabularyInterface::HIERARCHY_MULTIPLE && count($tree) > 1) && $change_weight_access->isAllowed()) {
|
||||
if (($vocabulary_hierarchy !== VocabularyInterface::HIERARCHY_MULTIPLE && count($tree) > 1) && $change_weight_access->isAllowed()) {
|
||||
$form['actions'] = ['#type' => 'actions', '#tree' => FALSE];
|
||||
$form['actions']['submit'] = [
|
||||
'#type' => 'submit',
|
||||
|
@ -425,9 +426,6 @@ class OverviewTerms extends FormBase {
|
|||
uasort($form_state->getValue('terms'), ['Drupal\Component\Utility\SortArray', 'sortByWeightElement']);
|
||||
|
||||
$vocabulary = $form_state->get(['taxonomy', 'vocabulary']);
|
||||
// Update the current hierarchy type as we go.
|
||||
$hierarchy = VocabularyInterface::HIERARCHY_DISABLED;
|
||||
|
||||
$changed_terms = [];
|
||||
$tree = $this->storageController->loadTree($vocabulary->id(), 0, NULL, TRUE);
|
||||
|
||||
|
@ -444,7 +442,6 @@ class OverviewTerms extends FormBase {
|
|||
$changed_terms[$term->id()] = $term;
|
||||
}
|
||||
$weight++;
|
||||
$hierarchy = $term->parents[0] != 0 ? VocabularyInterface::HIERARCHY_SINGLE : $hierarchy;
|
||||
$term = $tree[$weight];
|
||||
}
|
||||
|
||||
|
@ -471,7 +468,6 @@ class OverviewTerms extends FormBase {
|
|||
$term->parent->target_id = $values['term']['parent'];
|
||||
$changed_terms[$term->id()] = $term;
|
||||
}
|
||||
$hierarchy = $term->parents[0] != 0 ? VocabularyInterface::HIERARCHY_SINGLE : $hierarchy;
|
||||
$weight++;
|
||||
}
|
||||
}
|
||||
|
@ -484,7 +480,6 @@ class OverviewTerms extends FormBase {
|
|||
$term->setWeight($weight);
|
||||
$changed_terms[$term->id()] = $term;
|
||||
}
|
||||
$hierarchy = $term->parents[0] != 0 ? VocabularyInterface::HIERARCHY_SINGLE : $hierarchy;
|
||||
}
|
||||
|
||||
// Save all updated terms.
|
||||
|
@ -492,11 +487,6 @@ class OverviewTerms extends FormBase {
|
|||
$term->save();
|
||||
}
|
||||
|
||||
// Update the vocabulary hierarchy to flat or single hierarchy.
|
||||
if ($vocabulary->getHierarchy() != $hierarchy) {
|
||||
$vocabulary->setHierarchy($hierarchy);
|
||||
$vocabulary->save();
|
||||
}
|
||||
$this->messenger()->addStatus($this->t('The configuration options have been saved.'));
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace Drupal\taxonomy\Form;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Entity\ContentEntityDeleteForm;
|
||||
use Drupal\Core\Url;
|
||||
|
||||
|
@ -43,21 +42,4 @@ class TermDeleteForm extends ContentEntityDeleteForm {
|
|||
return $this->t('Deleted term %name.', ['%name' => $this->entity->label()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
parent::submitForm($form, $form_state);
|
||||
|
||||
/** @var \Drupal\Core\Entity\ContentEntityInterface $term */
|
||||
$term = $this->getEntity();
|
||||
if ($term->isDefaultTranslation()) {
|
||||
$storage = $this->entityManager->getStorage('taxonomy_vocabulary');
|
||||
$vocabulary = $storage->load($this->entity->bundle());
|
||||
|
||||
// @todo Move to storage http://drupal.org/node/1988712
|
||||
taxonomy_check_vocabulary_hierarchy($vocabulary, ['tid' => $term->id()]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ class TermForm extends ContentEntityForm {
|
|||
public function form(array $form, FormStateInterface $form_state) {
|
||||
$term = $this->entity;
|
||||
$vocab_storage = $this->entityManager->getStorage('taxonomy_vocabulary');
|
||||
/** @var \Drupal\taxonomy\TermStorageInterface $taxonomy_storage */
|
||||
$taxonomy_storage = $this->entityManager->getStorage('taxonomy_term');
|
||||
$vocabulary = $vocab_storage->load($term->bundle());
|
||||
|
||||
|
@ -28,7 +29,7 @@ class TermForm extends ContentEntityForm {
|
|||
$form['relations'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Relations'),
|
||||
'#open' => $vocabulary->getHierarchy() == VocabularyInterface::HIERARCHY_MULTIPLE,
|
||||
'#open' => $taxonomy_storage->getVocabularyHierarchyType($vocabulary->id()) == VocabularyInterface::HIERARCHY_MULTIPLE,
|
||||
'#weight' => 10,
|
||||
];
|
||||
|
||||
|
@ -142,26 +143,11 @@ class TermForm extends ContentEntityForm {
|
|||
}
|
||||
|
||||
$current_parent_count = count($form_state->getValue('parent'));
|
||||
$previous_parent_count = count($form_state->get(['taxonomy', 'parent']));
|
||||
// Root doesn't count if it's the only parent.
|
||||
if ($current_parent_count == 1 && $form_state->hasValue(['parent', 0])) {
|
||||
$current_parent_count = 0;
|
||||
$form_state->setValue('parent', []);
|
||||
}
|
||||
|
||||
// If the number of parents has been reduced to one or none, do a check on the
|
||||
// parents of every term in the vocabulary value.
|
||||
$vocabulary = $form_state->get(['taxonomy', 'vocabulary']);
|
||||
if ($current_parent_count < $previous_parent_count && $current_parent_count < 2) {
|
||||
taxonomy_check_vocabulary_hierarchy($vocabulary, $form_state->getValues());
|
||||
}
|
||||
// If we've increased the number of parents and this is a single or flat
|
||||
// hierarchy, update the vocabulary immediately.
|
||||
elseif ($current_parent_count > $previous_parent_count && $vocabulary->getHierarchy() != VocabularyInterface::HIERARCHY_MULTIPLE) {
|
||||
$vocabulary->setHierarchy($current_parent_count == 1 ? VocabularyInterface::HIERARCHY_SINGLE : VocabularyInterface::HIERARCHY_MULTIPLE);
|
||||
$vocabulary->save();
|
||||
}
|
||||
|
||||
$form_state->setValue('tid', $term->id());
|
||||
$form_state->set('tid', $term->id());
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Drupal\taxonomy;
|
|||
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\Sql\SqlContentEntityStorage;
|
||||
use Drupal\Core\Entity\Sql\TableMappingInterface;
|
||||
|
||||
/**
|
||||
* Defines a Controller class for taxonomy terms.
|
||||
|
@ -46,6 +47,19 @@ class TermStorage extends SqlContentEntityStorage implements TermStorageInterfac
|
|||
*/
|
||||
protected $ancestors;
|
||||
|
||||
/**
|
||||
* The type of hierarchy allowed within a vocabulary.
|
||||
*
|
||||
* Possible values:
|
||||
* - VocabularyInterface::HIERARCHY_DISABLED: No parents.
|
||||
* - VocabularyInterface::HIERARCHY_SINGLE: Single parent.
|
||||
* - VocabularyInterface::HIERARCHY_MULTIPLE: Multiple parents.
|
||||
*
|
||||
* @var int[]
|
||||
* An array of one the possible values above, keyed by vocabulary ID.
|
||||
*/
|
||||
protected $vocabularyHierarchyType;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
|
@ -72,6 +86,7 @@ class TermStorage extends SqlContentEntityStorage implements TermStorageInterfac
|
|||
$this->treeParents = [];
|
||||
$this->treeTerms = [];
|
||||
$this->trees = [];
|
||||
$this->vocabularyHierarchyType = [];
|
||||
parent::resetCache($ids);
|
||||
}
|
||||
|
||||
|
@ -357,13 +372,50 @@ class TermStorage extends SqlContentEntityStorage implements TermStorageInterfac
|
|||
return $terms;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getVocabularyHierarchyType($vid) {
|
||||
// Return early if we already computed this value.
|
||||
if (isset($this->vocabularyHierarchyType[$vid])) {
|
||||
return $this->vocabularyHierarchyType[$vid];
|
||||
}
|
||||
|
||||
$parent_field_storage = $this->entityManager->getFieldStorageDefinitions($this->entityTypeId)['parent'];
|
||||
$table_mapping = $this->getTableMapping();
|
||||
|
||||
$target_id_column = $table_mapping->getFieldColumnName($parent_field_storage, 'target_id');
|
||||
$delta_column = $table_mapping->getFieldColumnName($parent_field_storage, TableMappingInterface::DELTA);
|
||||
|
||||
$query = $this->database->select($table_mapping->getFieldTableName('parent'), 'p');
|
||||
$query->addExpression("MAX($target_id_column)", 'max_parent_id');
|
||||
$query->addExpression("MAX($delta_column)", 'max_delta');
|
||||
$query->condition('bundle', $vid);
|
||||
|
||||
$result = $query->execute()->fetchAll();
|
||||
|
||||
// If all the terms have the same parent, the parent can only be root (0).
|
||||
if ((int) $result[0]->max_parent_id === 0) {
|
||||
$this->vocabularyHierarchyType[$vid] = VocabularyInterface::HIERARCHY_DISABLED;
|
||||
}
|
||||
// If no term has a delta higher than 0, no term has multiple parents.
|
||||
elseif ((int) $result[0]->max_delta === 0) {
|
||||
$this->vocabularyHierarchyType[$vid] = VocabularyInterface::HIERARCHY_SINGLE;
|
||||
}
|
||||
else {
|
||||
$this->vocabularyHierarchyType[$vid] = VocabularyInterface::HIERARCHY_MULTIPLE;
|
||||
}
|
||||
|
||||
return $this->vocabularyHierarchyType[$vid];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __sleep() {
|
||||
$vars = parent::__sleep();
|
||||
// Do not serialize static cache.
|
||||
unset($vars['ancestors'], $vars['treeChildren'], $vars['treeParents'], $vars['treeTerms'], $vars['trees']);
|
||||
unset($vars['ancestors'], $vars['treeChildren'], $vars['treeParents'], $vars['treeTerms'], $vars['trees'], $vars['vocabularyHierarchyType']);
|
||||
return $vars;
|
||||
}
|
||||
|
||||
|
@ -378,6 +430,7 @@ class TermStorage extends SqlContentEntityStorage implements TermStorageInterfac
|
|||
$this->treeParents = [];
|
||||
$this->treeTerms = [];
|
||||
$this->trees = [];
|
||||
$this->vocabularyHierarchyType = [];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -126,4 +126,19 @@ interface TermStorageInterface extends ContentEntityStorageInterface {
|
|||
*/
|
||||
public function getNodeTerms(array $nids, array $vocabs = [], $langcode = NULL);
|
||||
|
||||
/**
|
||||
* Returns the hierarchy type for a specific vocabulary ID.
|
||||
*
|
||||
* @param string $vid
|
||||
* Vocabulary ID to retrieve the hierarchy type for.
|
||||
*
|
||||
* @return int
|
||||
* The vocabulary hierarchy.
|
||||
* Possible values:
|
||||
* - VocabularyInterface::HIERARCHY_DISABLED: No parents.
|
||||
* - VocabularyInterface::HIERARCHY_SINGLE: Single parent.
|
||||
* - VocabularyInterface::HIERARCHY_MULTIPLE: Multiple parents.
|
||||
*/
|
||||
public function getVocabularyHierarchyType($vid);
|
||||
|
||||
}
|
||||
|
|
|
@ -108,4 +108,29 @@ class TermStorageSchema extends SqlContentEntityStorageSchema {
|
|||
return $schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getDedicatedTableSchema(FieldStorageDefinitionInterface $storage_definition, ContentEntityTypeInterface $entity_type = NULL) {
|
||||
$dedicated_table_schema = parent::getDedicatedTableSchema($storage_definition, $entity_type);
|
||||
|
||||
// Add an index on 'bundle', 'delta' and 'parent_target_id' columns to
|
||||
// increase the performance of the query from
|
||||
// \Drupal\taxonomy\TermStorage::getVocabularyHierarchyType().
|
||||
if ($storage_definition->getName() === 'parent') {
|
||||
/** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
|
||||
$table_mapping = $this->storage->getTableMapping();
|
||||
$dedicated_table_name = $table_mapping->getDedicatedDataTableName($storage_definition);
|
||||
|
||||
unset($dedicated_table_schema[$dedicated_table_name]['indexes']['bundle']);
|
||||
$dedicated_table_schema[$dedicated_table_name]['indexes']['bundle_delta_target_id'] = [
|
||||
'bundle',
|
||||
'delta',
|
||||
$table_mapping->getFieldColumnName($storage_definition, 'target_id'),
|
||||
];
|
||||
}
|
||||
|
||||
return $dedicated_table_schema;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,9 @@ interface VocabularyInterface extends ConfigEntityInterface {
|
|||
*
|
||||
* @return int
|
||||
* The vocabulary hierarchy.
|
||||
*
|
||||
* @deprecated in Drupal 8.7.x and will be removed before Drupal 9.0.x. Use
|
||||
* \Drupal\taxonomy\TermStorage::getVocabularyHierarchyType() instead.
|
||||
*/
|
||||
public function getHierarchy();
|
||||
|
||||
|
@ -43,6 +46,9 @@ interface VocabularyInterface extends ConfigEntityInterface {
|
|||
* - VocabularyInterface::HIERARCHY_MULTIPLE: Multiple parents.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @deprecated in Drupal 8.7.x and will be removed before Drupal 9.0.x. Reset
|
||||
* the cache of the taxonomy_term storage handler instead.
|
||||
*/
|
||||
public function setHierarchy($hierarchy);
|
||||
|
||||
|
|
|
@ -186,3 +186,12 @@ function taxonomy_update_8601() {
|
|||
|
||||
return t('The publishing status field has been added to taxonomy terms.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an index on the 'taxonomy_term__parent' field table.
|
||||
*/
|
||||
function taxonomy_update_8701() {
|
||||
$entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager();
|
||||
$storage_definition = $entity_definition_update_manager->getFieldStorageDefinition('parent', 'taxonomy_term');
|
||||
$entity_definition_update_manager->updateFieldStorageDefinition($storage_definition);
|
||||
}
|
||||
|
|
|
@ -81,8 +81,9 @@ function taxonomy_help($route_name, RouteMatchInterface $route_match) {
|
|||
|
||||
case 'entity.taxonomy_vocabulary.overview_form':
|
||||
$vocabulary = $route_match->getParameter('taxonomy_vocabulary');
|
||||
$vocabulary_hierarchy = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->getVocabularyHierarchyType($vocabulary->id());
|
||||
if (\Drupal::currentUser()->hasPermission('administer taxonomy') || \Drupal::currentUser()->hasPermission('edit terms in ' . $vocabulary->id())) {
|
||||
switch ($vocabulary->getHierarchy()) {
|
||||
switch ($vocabulary_hierarchy) {
|
||||
case VocabularyInterface::HIERARCHY_DISABLED:
|
||||
return '<p>' . t('You can reorganize the terms in %capital_name using their drag-and-drop handles, and group terms under a parent term by sliding them under and to the right of the parent.', ['%capital_name' => Unicode::ucfirst($vocabulary->label()), '%name' => $vocabulary->label()]) . '</p>';
|
||||
case VocabularyInterface::HIERARCHY_SINGLE:
|
||||
|
@ -92,7 +93,7 @@ function taxonomy_help($route_name, RouteMatchInterface $route_match) {
|
|||
}
|
||||
}
|
||||
else {
|
||||
switch ($vocabulary->getHierarchy()) {
|
||||
switch ($vocabulary_hierarchy) {
|
||||
case VocabularyInterface::HIERARCHY_DISABLED:
|
||||
return '<p>' . t('%capital_name contains the following terms.', ['%capital_name' => Unicode::ucfirst($vocabulary->label())]) . '</p>';
|
||||
case VocabularyInterface::HIERARCHY_SINGLE:
|
||||
|
@ -156,11 +157,10 @@ function taxonomy_theme() {
|
|||
}
|
||||
|
||||
/**
|
||||
* Checks and updates the hierarchy flag of a vocabulary.
|
||||
* Checks the hierarchy flag of a vocabulary.
|
||||
*
|
||||
* Checks the current parents of all terms in a vocabulary and updates the
|
||||
* vocabulary's hierarchy setting to the lowest possible level. If no term
|
||||
* has parent terms then the vocabulary will be given a hierarchy of
|
||||
* Checks the current parents of all terms in a vocabulary. If no term has
|
||||
* parent terms then the vocabulary will be given a hierarchy of
|
||||
* VocabularyInterface::HIERARCHY_DISABLED. If any term has a single parent then
|
||||
* the vocabulary will be given a hierarchy of
|
||||
* VocabularyInterface::HIERARCHY_SINGLE. If any term has multiple parents then
|
||||
|
@ -172,33 +172,15 @@ function taxonomy_theme() {
|
|||
* @param $changed_term
|
||||
* An array of the term structure that was updated.
|
||||
*
|
||||
* @return
|
||||
* @return int
|
||||
* An integer that represents the level of the vocabulary's hierarchy.
|
||||
*
|
||||
* @deprecated in Drupal 8.7.x. Will be removed before Drupal 9.0.0. Use
|
||||
* \Drupal\taxonomy\TermStorage::getVocabularyHierarchyType() instead.
|
||||
*/
|
||||
function taxonomy_check_vocabulary_hierarchy(VocabularyInterface $vocabulary, $changed_term) {
|
||||
$tree = \Drupal::entityManager()->getStorage('taxonomy_term')->loadTree($vocabulary->id());
|
||||
$hierarchy = VocabularyInterface::HIERARCHY_DISABLED;
|
||||
foreach ($tree as $term) {
|
||||
// Update the changed term with the new parent value before comparison.
|
||||
if ($term->tid == $changed_term['tid']) {
|
||||
$term = (object) $changed_term;
|
||||
$term->parents = $term->parent;
|
||||
}
|
||||
// Check this term's parent count.
|
||||
if (count($term->parents) > 1) {
|
||||
$hierarchy = VocabularyInterface::HIERARCHY_MULTIPLE;
|
||||
break;
|
||||
}
|
||||
elseif (count($term->parents) == 1 && !isset($term->parents[0])) {
|
||||
$hierarchy = VocabularyInterface::HIERARCHY_SINGLE;
|
||||
}
|
||||
}
|
||||
if ($hierarchy != $vocabulary->getHierarchy()) {
|
||||
$vocabulary->setHierarchy($hierarchy);
|
||||
$vocabulary->save();
|
||||
}
|
||||
|
||||
return $hierarchy;
|
||||
@trigger_error('taxonomy_check_vocabulary_hierarchy() is deprecated in Drupal 8.7.x and will be removed before Drupal 9.0.x. Use \Drupal\taxonomy\TermStorage::getVocabularyHierarchyType() instead.', E_USER_DEPRECATED);
|
||||
return \Drupal::entityTypeManager()->getStorage('taxonomy_term')->getVocabularyHierarchyType($vocabulary->id());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -125,3 +125,12 @@ function taxonomy_post_update_handle_publishing_status_addition_in_views(&$sandb
|
|||
return TRUE;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the 'hierarchy' property from vocabularies.
|
||||
*/
|
||||
function taxonomy_post_update_remove_hierarchy_from_vocabularies(&$sandbox = NULL) {
|
||||
\Drupal::classResolver(ConfigEntityUpdater::class)->update($sandbox, 'taxonomy_vocabulary', function () {
|
||||
return TRUE;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -54,7 +54,6 @@ abstract class VocabularyResourceTestBase extends EntityResourceTestBase {
|
|||
'dependencies' => [],
|
||||
'name' => 'Llama',
|
||||
'description' => NULL,
|
||||
'hierarchy' => 0,
|
||||
'weight' => 0,
|
||||
];
|
||||
}
|
||||
|
|
|
@ -90,11 +90,11 @@ class TermTest extends TaxonomyTestBase {
|
|||
$term2 = $this->createTerm($this->vocabulary);
|
||||
|
||||
// Get the taxonomy storage.
|
||||
$taxonomy_storage = $this->container->get('entity.manager')->getStorage('taxonomy_term');
|
||||
/** @var \Drupal\taxonomy\TermStorageInterface $taxonomy_storage */
|
||||
$taxonomy_storage = $this->container->get('entity_type.manager')->getStorage('taxonomy_term');
|
||||
|
||||
// Check that hierarchy is flat.
|
||||
$vocabulary = Vocabulary::load($this->vocabulary->id());
|
||||
$this->assertEqual(0, $vocabulary->getHierarchy(), 'Vocabulary is flat.');
|
||||
$this->assertEquals(0, $taxonomy_storage->getVocabularyHierarchyType($this->vocabulary->id()), 'Vocabulary is flat.');
|
||||
|
||||
// Edit $term2, setting $term1 as parent.
|
||||
$edit = [];
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\taxonomy\Functional\Update;
|
||||
|
||||
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
|
||||
/**
|
||||
* Tests that the 'hierarchy' property is removed from vocabularies.
|
||||
*
|
||||
* @group taxonomy
|
||||
* @group Update
|
||||
* @group legacy
|
||||
*/
|
||||
class TaxonomyVocabularyHierarchyUpdateTest extends UpdatePathTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setDatabaseDumpFiles() {
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8-rc1.filled.standard.php.gz',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the 'hierarchy' property is removed from vocabularies.
|
||||
*
|
||||
* @see taxonomy_post_update_remove_hierarchy_from_vocabularies()
|
||||
* @see taxonomy_update_8701()
|
||||
*/
|
||||
public function testTaxonomyUpdateParents() {
|
||||
$hierarchy = \Drupal::config('taxonomy.vocabulary.test_vocabulary')->get('hierarchy');
|
||||
$this->assertSame(1, $hierarchy);
|
||||
|
||||
// Run updates.
|
||||
$this->runUpdates();
|
||||
|
||||
$hierarchy = \Drupal::config('taxonomy.vocabulary.test_vocabulary')->get('hierarchy');
|
||||
$this->assertNull($hierarchy);
|
||||
|
||||
$database = \Drupal::database();
|
||||
$this->assertFalse($database->schema()->indexExists('taxonomy_term__parent', 'bundle'));
|
||||
$this->assertTrue($database->schema()->indexExists('taxonomy_term__parent', 'bundle_delta_target_id'));
|
||||
}
|
||||
|
||||
}
|
|
@ -35,13 +35,11 @@ class MigrateTaxonomyVocabularyTest extends MigrateDrupal6TestBase {
|
|||
$this->assertSame($this->getMigration('d6_taxonomy_vocabulary')->getIdMap()->lookupDestinationId([$j]), [$vocabulary->id()]);
|
||||
$this->assertSame("vocabulary $j (i=$i)", $vocabulary->label());
|
||||
$this->assertSame("description of vocabulary $j (i=$i)", $vocabulary->getDescription());
|
||||
$this->assertSame($i, $vocabulary->getHierarchy());
|
||||
$this->assertSame(4 + $i, $vocabulary->get('weight'));
|
||||
}
|
||||
$vocabulary = Vocabulary::load('vocabulary_name_much_longer_than');
|
||||
$this->assertSame('vocabulary name much longer than thirty two characters', $vocabulary->label());
|
||||
$this->assertSame('description of vocabulary name much longer than thirty two characters', $vocabulary->getDescription());
|
||||
$this->assertSame(3, $vocabulary->getHierarchy());
|
||||
$this->assertSame(7, $vocabulary->get('weight'));
|
||||
}
|
||||
|
||||
|
|
|
@ -35,18 +35,15 @@ class MigrateTaxonomyVocabularyTest extends MigrateDrupal7TestBase {
|
|||
* The label the migrated entity should have.
|
||||
* @param $expected_description
|
||||
* The description the migrated entity should have.
|
||||
* @param $expected_hierarchy
|
||||
* The hierarchy setting the migrated entity should have.
|
||||
* @param $expected_weight
|
||||
* The weight the migrated entity should have.
|
||||
*/
|
||||
protected function assertEntity($id, $expected_label, $expected_description, $expected_hierarchy, $expected_weight) {
|
||||
protected function assertEntity($id, $expected_label, $expected_description, $expected_weight) {
|
||||
/** @var \Drupal\taxonomy\VocabularyInterface $entity */
|
||||
$entity = Vocabulary::load($id);
|
||||
$this->assertTrue($entity instanceof VocabularyInterface);
|
||||
$this->assertIdentical($expected_label, $entity->label());
|
||||
$this->assertIdentical($expected_description, $entity->getDescription());
|
||||
$this->assertIdentical($expected_hierarchy, $entity->getHierarchy());
|
||||
$this->assertIdentical($expected_weight, $entity->get('weight'));
|
||||
}
|
||||
|
||||
|
@ -54,10 +51,10 @@ class MigrateTaxonomyVocabularyTest extends MigrateDrupal7TestBase {
|
|||
* Tests the Drupal 7 taxonomy vocabularies to Drupal 8 migration.
|
||||
*/
|
||||
public function testTaxonomyVocabulary() {
|
||||
$this->assertEntity('tags', 'Tags', 'Use tags to group articles on similar topics into categories.', VocabularyInterface::HIERARCHY_DISABLED, 0);
|
||||
$this->assertEntity('forums', 'Sujet de discussion', 'Forum navigation vocabulary', VocabularyInterface::HIERARCHY_SINGLE, -10);
|
||||
$this->assertEntity('test_vocabulary', 'Test Vocabulary', 'This is the vocabulary description', VocabularyInterface::HIERARCHY_SINGLE, 0);
|
||||
$this->assertEntity('vocabulary_name_much_longer_than', 'vocabulary name clearly different than machine name and much longer than thirty two characters', 'description of vocabulary name much longer than thirty two characters', VocabularyInterface::HIERARCHY_SINGLE, 0);
|
||||
$this->assertEntity('tags', 'Tags', 'Use tags to group articles on similar topics into categories.', 0);
|
||||
$this->assertEntity('forums', 'Sujet de discussion', 'Forum navigation vocabulary', -10);
|
||||
$this->assertEntity('test_vocabulary', 'Test Vocabulary', 'This is the vocabulary description', 0);
|
||||
$this->assertEntity('vocabulary_name_much_longer_than', 'vocabulary name clearly different than machine name and much longer than thirty two characters', 'description of vocabulary name much longer than thirty two characters', 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,5 +4,4 @@ dependencies: { }
|
|||
name: 'Recipe category'
|
||||
vid: recipe_category
|
||||
description: 'Use this taxonomy to group recipes of the same type together.'
|
||||
hierarchy: 0
|
||||
weight: 0
|
||||
|
|
|
@ -4,5 +4,4 @@ dependencies: { }
|
|||
name: Tags
|
||||
vid: tags
|
||||
description: 'Use tags to group articles on similar topics into categories.'
|
||||
hierarchy: 0
|
||||
weight: 0
|
||||
|
|
|
@ -4,5 +4,4 @@ dependencies: { }
|
|||
name: Tags
|
||||
vid: tags
|
||||
description: 'Use tags to group articles on similar topics into categories.'
|
||||
hierarchy: 0
|
||||
weight: 0
|
||||
|
|
Loading…
Reference in New Issue