Version 1
[yaffs-website] / web / core / modules / taxonomy / src / Entity / Term.php
1 <?php
2
3 namespace Drupal\taxonomy\Entity;
4
5 use Drupal\Core\Entity\ContentEntityBase;
6 use Drupal\Core\Entity\EntityChangedTrait;
7 use Drupal\Core\Entity\EntityStorageInterface;
8 use Drupal\Core\Entity\EntityTypeInterface;
9 use Drupal\Core\Field\BaseFieldDefinition;
10 use Drupal\taxonomy\TermInterface;
11
12 /**
13  * Defines the taxonomy term entity.
14  *
15  * @ContentEntityType(
16  *   id = "taxonomy_term",
17  *   label = @Translation("Taxonomy term"),
18  *   bundle_label = @Translation("Vocabulary"),
19  *   handlers = {
20  *     "storage" = "Drupal\taxonomy\TermStorage",
21  *     "storage_schema" = "Drupal\taxonomy\TermStorageSchema",
22  *     "view_builder" = "Drupal\taxonomy\TermViewBuilder",
23  *     "access" = "Drupal\taxonomy\TermAccessControlHandler",
24  *     "views_data" = "Drupal\taxonomy\TermViewsData",
25  *     "form" = {
26  *       "default" = "Drupal\taxonomy\TermForm",
27  *       "delete" = "Drupal\taxonomy\Form\TermDeleteForm"
28  *     },
29  *     "translation" = "Drupal\taxonomy\TermTranslationHandler"
30  *   },
31  *   base_table = "taxonomy_term_data",
32  *   data_table = "taxonomy_term_field_data",
33  *   uri_callback = "taxonomy_term_uri",
34  *   translatable = TRUE,
35  *   entity_keys = {
36  *     "id" = "tid",
37  *     "bundle" = "vid",
38  *     "label" = "name",
39  *     "langcode" = "langcode",
40  *     "uuid" = "uuid"
41  *   },
42  *   bundle_entity_type = "taxonomy_vocabulary",
43  *   field_ui_base_route = "entity.taxonomy_vocabulary.overview_form",
44  *   common_reference_target = TRUE,
45  *   links = {
46  *     "canonical" = "/taxonomy/term/{taxonomy_term}",
47  *     "delete-form" = "/taxonomy/term/{taxonomy_term}/delete",
48  *     "edit-form" = "/taxonomy/term/{taxonomy_term}/edit",
49  *   },
50  *   permission_granularity = "bundle"
51  * )
52  */
53 class Term extends ContentEntityBase implements TermInterface {
54
55   use EntityChangedTrait;
56
57   /**
58    * {@inheritdoc}
59    */
60   public static function postDelete(EntityStorageInterface $storage, array $entities) {
61     parent::postDelete($storage, $entities);
62
63     // See if any of the term's children are about to be become orphans.
64     $orphans = [];
65     foreach (array_keys($entities) as $tid) {
66       if ($children = $storage->loadChildren($tid)) {
67         foreach ($children as $child) {
68           // If the term has multiple parents, we don't delete it.
69           $parents = $storage->loadParents($child->id());
70           if (empty($parents)) {
71             $orphans[] = $child;
72           }
73         }
74       }
75     }
76
77     // Delete term hierarchy information after looking up orphans but before
78     // deleting them so that their children/parent information is consistent.
79     $storage->deleteTermHierarchy(array_keys($entities));
80
81     if (!empty($orphans)) {
82       $storage->delete($orphans);
83     }
84   }
85
86   /**
87    * {@inheritdoc}
88    */
89   public function postSave(EntityStorageInterface $storage, $update = TRUE) {
90     parent::postSave($storage, $update);
91
92     // Only change the parents if a value is set, keep the existing values if
93     // not.
94     if (isset($this->parent->target_id)) {
95       $storage->deleteTermHierarchy([$this->id()]);
96       $storage->updateTermHierarchy($this);
97     }
98   }
99
100   /**
101    * {@inheritdoc}
102    */
103   public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
104     /** @var \Drupal\Core\Field\BaseFieldDefinition[] $fields */
105     $fields = parent::baseFieldDefinitions($entity_type);
106
107     $fields['tid']->setLabel(t('Term ID'))
108       ->setDescription(t('The term ID.'));
109
110     $fields['uuid']->setDescription(t('The term UUID.'));
111
112     $fields['vid']->setLabel(t('Vocabulary'))
113       ->setDescription(t('The vocabulary to which the term is assigned.'));
114
115     $fields['langcode']->setDescription(t('The term language code.'));
116
117     $fields['name'] = BaseFieldDefinition::create('string')
118       ->setLabel(t('Name'))
119       ->setTranslatable(TRUE)
120       ->setRequired(TRUE)
121       ->setSetting('max_length', 255)
122       ->setDisplayOptions('view', [
123         'label' => 'hidden',
124         'type' => 'string',
125         'weight' => -5,
126       ])
127       ->setDisplayOptions('form', [
128         'type' => 'string_textfield',
129         'weight' => -5,
130       ])
131       ->setDisplayConfigurable('form', TRUE);
132
133     $fields['description'] = BaseFieldDefinition::create('text_long')
134       ->setLabel(t('Description'))
135       ->setTranslatable(TRUE)
136       ->setDisplayOptions('view', [
137         'label' => 'hidden',
138         'type' => 'text_default',
139         'weight' => 0,
140       ])
141       ->setDisplayConfigurable('view', TRUE)
142       ->setDisplayOptions('form', [
143         'type' => 'text_textfield',
144         'weight' => 0,
145       ])
146       ->setDisplayConfigurable('form', TRUE);
147
148     $fields['weight'] = BaseFieldDefinition::create('integer')
149       ->setLabel(t('Weight'))
150       ->setDescription(t('The weight of this term in relation to other terms.'))
151       ->setDefaultValue(0);
152
153     $fields['parent'] = BaseFieldDefinition::create('entity_reference')
154       ->setLabel(t('Term Parents'))
155       ->setDescription(t('The parents of this term.'))
156       ->setSetting('target_type', 'taxonomy_term')
157       ->setCardinality(BaseFieldDefinition::CARDINALITY_UNLIMITED)
158       ->setCustomStorage(TRUE);
159
160     $fields['changed'] = BaseFieldDefinition::create('changed')
161       ->setLabel(t('Changed'))
162       ->setDescription(t('The time that the term was last edited.'))
163       ->setTranslatable(TRUE);
164
165     return $fields;
166   }
167
168   /**
169    * {@inheritdoc}
170    */
171   public function getDescription() {
172     return $this->get('description')->value;
173   }
174
175   /**
176    * {@inheritdoc}
177    */
178   public function setDescription($description) {
179     $this->set('description', $description);
180     return $this;
181   }
182
183   /**
184    * {@inheritdoc}
185    */
186   public function getFormat() {
187     return $this->get('description')->format;
188   }
189
190   /**
191    * {@inheritdoc}
192    */
193   public function setFormat($format) {
194     $this->get('description')->format = $format;
195     return $this;
196   }
197
198   /**
199    * {@inheritdoc}
200    */
201   public function getName() {
202     return $this->label();
203   }
204
205   /**
206    * {@inheritdoc}
207    */
208   public function setName($name) {
209     $this->set('name', $name);
210     return $this;
211   }
212
213   /**
214    * {@inheritdoc}
215    */
216   public function getWeight() {
217     return $this->get('weight')->value;
218   }
219
220   /**
221    * {@inheritdoc}
222    */
223   public function setWeight($weight) {
224     $this->set('weight', $weight);
225     return $this;
226   }
227
228   /**
229    * {@inheritdoc}
230    */
231   public function getVocabularyId() {
232     return $this->get('vid')->target_id;
233   }
234
235   /**
236    * {@inheritdoc}
237    */
238   protected function getFieldsToSkipFromTranslationChangesCheck() {
239     // @todo the current implementation of the parent field makes it impossible
240     // for ::hasTranslationChanges() to correctly check the field for changes,
241     // so it is currently skipped from the comparision and has to be fixed by
242     // https://www.drupal.org/node/2843060.
243     $fields = parent::getFieldsToSkipFromTranslationChangesCheck();
244     $fields[] = 'parent';
245     return $fields;
246   }
247
248 }