comparison core/modules/taxonomy/src/Entity/Term.php @ 17:129ea1e6d783

Update, including to Drupal core 8.6.10
author Chris Cannam
date Thu, 28 Feb 2019 13:21:36 +0000
parents 1fec387a4317
children af1871eacc83
comparison
equal deleted inserted replaced
16:c2387f117808 17:129ea1e6d783
2 2
3 namespace Drupal\taxonomy\Entity; 3 namespace Drupal\taxonomy\Entity;
4 4
5 use Drupal\Core\Entity\ContentEntityBase; 5 use Drupal\Core\Entity\ContentEntityBase;
6 use Drupal\Core\Entity\EntityChangedTrait; 6 use Drupal\Core\Entity\EntityChangedTrait;
7 use Drupal\Core\Entity\EntityPublishedTrait;
7 use Drupal\Core\Entity\EntityStorageInterface; 8 use Drupal\Core\Entity\EntityStorageInterface;
8 use Drupal\Core\Entity\EntityTypeInterface; 9 use Drupal\Core\Entity\EntityTypeInterface;
9 use Drupal\Core\Field\BaseFieldDefinition; 10 use Drupal\Core\Field\BaseFieldDefinition;
10 use Drupal\taxonomy\TermInterface; 11 use Drupal\taxonomy\TermInterface;
12 use Drupal\user\StatusItem;
11 13
12 /** 14 /**
13 * Defines the taxonomy term entity. 15 * Defines the taxonomy term entity.
14 * 16 *
15 * @ContentEntityType( 17 * @ContentEntityType(
16 * id = "taxonomy_term", 18 * id = "taxonomy_term",
17 * label = @Translation("Taxonomy term"), 19 * label = @Translation("Taxonomy term"),
20 * label_collection = @Translation("Taxonomy terms"),
21 * label_singular = @Translation("taxonomy term"),
22 * label_plural = @Translation("taxonomy terms"),
23 * label_count = @PluralTranslation(
24 * singular = "@count taxonomy term",
25 * plural = "@count taxonomy terms",
26 * ),
18 * bundle_label = @Translation("Vocabulary"), 27 * bundle_label = @Translation("Vocabulary"),
19 * handlers = { 28 * handlers = {
20 * "storage" = "Drupal\taxonomy\TermStorage", 29 * "storage" = "Drupal\taxonomy\TermStorage",
21 * "storage_schema" = "Drupal\taxonomy\TermStorageSchema", 30 * "storage_schema" = "Drupal\taxonomy\TermStorageSchema",
22 * "view_builder" = "Drupal\Core\Entity\EntityViewBuilder", 31 * "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
36 * entity_keys = { 45 * entity_keys = {
37 * "id" = "tid", 46 * "id" = "tid",
38 * "bundle" = "vid", 47 * "bundle" = "vid",
39 * "label" = "name", 48 * "label" = "name",
40 * "langcode" = "langcode", 49 * "langcode" = "langcode",
41 * "uuid" = "uuid" 50 * "uuid" = "uuid",
51 * "published" = "status",
42 * }, 52 * },
43 * bundle_entity_type = "taxonomy_vocabulary", 53 * bundle_entity_type = "taxonomy_vocabulary",
44 * field_ui_base_route = "entity.taxonomy_vocabulary.overview_form", 54 * field_ui_base_route = "entity.taxonomy_vocabulary.overview_form",
45 * common_reference_target = TRUE, 55 * common_reference_target = TRUE,
46 * links = { 56 * links = {
53 * ) 63 * )
54 */ 64 */
55 class Term extends ContentEntityBase implements TermInterface { 65 class Term extends ContentEntityBase implements TermInterface {
56 66
57 use EntityChangedTrait; 67 use EntityChangedTrait;
68 use EntityPublishedTrait;
58 69
59 /** 70 /**
60 * {@inheritdoc} 71 * {@inheritdoc}
61 */ 72 */
62 public static function postDelete(EntityStorageInterface $storage, array $entities) { 73 public static function postDelete(EntityStorageInterface $storage, array $entities) {
63 parent::postDelete($storage, $entities); 74 parent::postDelete($storage, $entities);
64 75
65 // See if any of the term's children are about to be become orphans. 76 // See if any of the term's children are about to be become orphans.
66 $orphans = []; 77 $orphans = [];
67 foreach (array_keys($entities) as $tid) { 78 /** @var \Drupal\taxonomy\TermInterface $term */
68 if ($children = $storage->loadChildren($tid)) { 79 foreach ($entities as $tid => $term) {
80 if ($children = $storage->getChildren($term)) {
81 /** @var \Drupal\taxonomy\TermInterface $child */
69 foreach ($children as $child) { 82 foreach ($children as $child) {
83 $parent = $child->get('parent');
84 // Update child parents item list.
85 $parent->filter(function ($item) use ($tid) {
86 return $item->target_id != $tid;
87 });
88
70 // If the term has multiple parents, we don't delete it. 89 // If the term has multiple parents, we don't delete it.
71 $parents = $storage->loadParents($child->id()); 90 if ($parent->count()) {
72 if (empty($parents)) { 91 $child->save();
92 }
93 else {
73 $orphans[] = $child; 94 $orphans[] = $child;
74 } 95 }
75 } 96 }
76 } 97 }
77 } 98 }
78 99
79 // Delete term hierarchy information after looking up orphans but before
80 // deleting them so that their children/parent information is consistent.
81 $storage->deleteTermHierarchy(array_keys($entities));
82
83 if (!empty($orphans)) { 100 if (!empty($orphans)) {
84 $storage->delete($orphans); 101 $storage->delete($orphans);
85 } 102 }
86 } 103 }
87 104
88 /** 105 /**
89 * {@inheritdoc} 106 * {@inheritdoc}
90 */ 107 */
91 public function postSave(EntityStorageInterface $storage, $update = TRUE) { 108 public function preSave(EntityStorageInterface $storage) {
92 parent::postSave($storage, $update); 109 parent::preSave($storage);
93 110 // Terms with no parents are mandatory children of <root>.
94 // Only change the parents if a value is set, keep the existing values if 111 if (!$this->get('parent')->count()) {
95 // not. 112 $this->parent->target_id = 0;
96 if (isset($this->parent->target_id)) {
97 $storage->deleteTermHierarchy([$this->id()]);
98 $storage->updateTermHierarchy($this);
99 } 113 }
100 } 114 }
101 115
102 /** 116 /**
103 * {@inheritdoc} 117 * {@inheritdoc}
104 */ 118 */
105 public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { 119 public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
106 /** @var \Drupal\Core\Field\BaseFieldDefinition[] $fields */ 120 /** @var \Drupal\Core\Field\BaseFieldDefinition[] $fields */
107 $fields = parent::baseFieldDefinitions($entity_type); 121 $fields = parent::baseFieldDefinitions($entity_type);
122
123 // Add the published field.
124 $fields += static::publishedBaseFieldDefinitions($entity_type);
125 // @todo Remove the usage of StatusItem in
126 // https://www.drupal.org/project/drupal/issues/2936864.
127 $fields['status']->getItemDefinition()->setClass(StatusItem::class);
108 128
109 $fields['tid']->setLabel(t('Term ID')) 129 $fields['tid']->setLabel(t('Term ID'))
110 ->setDescription(t('The term ID.')); 130 ->setDescription(t('The term ID.'));
111 131
112 $fields['uuid']->setDescription(t('The term UUID.')); 132 $fields['uuid']->setDescription(t('The term UUID.'));
154 174
155 $fields['parent'] = BaseFieldDefinition::create('entity_reference') 175 $fields['parent'] = BaseFieldDefinition::create('entity_reference')
156 ->setLabel(t('Term Parents')) 176 ->setLabel(t('Term Parents'))
157 ->setDescription(t('The parents of this term.')) 177 ->setDescription(t('The parents of this term.'))
158 ->setSetting('target_type', 'taxonomy_term') 178 ->setSetting('target_type', 'taxonomy_term')
159 ->setCardinality(BaseFieldDefinition::CARDINALITY_UNLIMITED) 179 ->setCardinality(BaseFieldDefinition::CARDINALITY_UNLIMITED);
160 ->setCustomStorage(TRUE);
161 180
162 $fields['changed'] = BaseFieldDefinition::create('changed') 181 $fields['changed'] = BaseFieldDefinition::create('changed')
163 ->setLabel(t('Changed')) 182 ->setLabel(t('Changed'))
164 ->setDescription(t('The time that the term was last edited.')) 183 ->setDescription(t('The time that the term was last edited.'))
165 ->setTranslatable(TRUE); 184 ->setTranslatable(TRUE);
168 } 187 }
169 188
170 /** 189 /**
171 * {@inheritdoc} 190 * {@inheritdoc}
172 */ 191 */
192 public static function bundleFieldDefinitions(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
193 // Only terms in the same bundle can be a parent.
194 $fields['parent'] = clone $base_field_definitions['parent'];
195 $fields['parent']->setSetting('handler_settings', ['target_bundles' => [$bundle => $bundle]]);
196 return $fields;
197 }
198
199 /**
200 * {@inheritdoc}
201 */
173 public function getDescription() { 202 public function getDescription() {
174 return $this->get('description')->value; 203 return $this->get('description')->value;
175 } 204 }
176 205
177 /** 206 /**
233 public function getVocabularyId() { 262 public function getVocabularyId() {
234 @trigger_error('The ' . __METHOD__ . ' method is deprecated since version 8.4.0 and will be removed before 9.0.0. Use ' . __CLASS__ . '::bundle() instead to get the vocabulary ID.', E_USER_DEPRECATED); 263 @trigger_error('The ' . __METHOD__ . ' method is deprecated since version 8.4.0 and will be removed before 9.0.0. Use ' . __CLASS__ . '::bundle() instead to get the vocabulary ID.', E_USER_DEPRECATED);
235 return $this->bundle(); 264 return $this->bundle();
236 } 265 }
237 266
238 /**
239 * {@inheritdoc}
240 */
241 protected function getFieldsToSkipFromTranslationChangesCheck() {
242 // @todo the current implementation of the parent field makes it impossible
243 // for ::hasTranslationChanges() to correctly check the field for changes,
244 // so it is currently skipped from the comparision and has to be fixed by
245 // https://www.drupal.org/node/2843060.
246 $fields = parent::getFieldsToSkipFromTranslationChangesCheck();
247 $fields[] = 'parent';
248 return $fields;
249 }
250
251 } 267 }