Security update for Core, with self-updated composer
[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  *     "create" = "/taxonomy/term",
50  *   },
51  *   permission_granularity = "bundle"
52  * )
53  */
54 class Term extends ContentEntityBase implements TermInterface {
55
56   use EntityChangedTrait;
57
58   /**
59    * {@inheritdoc}
60    */
61   public static function postDelete(EntityStorageInterface $storage, array $entities) {
62     parent::postDelete($storage, $entities);
63
64     // See if any of the term's children are about to be become orphans.
65     $orphans = [];
66     foreach (array_keys($entities) as $tid) {
67       if ($children = $storage->loadChildren($tid)) {
68         foreach ($children as $child) {
69           // If the term has multiple parents, we don't delete it.
70           $parents = $storage->loadParents($child->id());
71           if (empty($parents)) {
72             $orphans[] = $child;
73           }
74         }
75       }
76     }
77
78     // Delete term hierarchy information after looking up orphans but before
79     // deleting them so that their children/parent information is consistent.
80     $storage->deleteTermHierarchy(array_keys($entities));
81
82     if (!empty($orphans)) {
83       $storage->delete($orphans);
84     }
85   }
86
87   /**
88    * {@inheritdoc}
89    */
90   public function postSave(EntityStorageInterface $storage, $update = TRUE) {
91     parent::postSave($storage, $update);
92
93     // Only change the parents if a value is set, keep the existing values if
94     // not.
95     if (isset($this->parent->target_id)) {
96       $storage->deleteTermHierarchy([$this->id()]);
97       $storage->updateTermHierarchy($this);
98     }
99   }
100
101   /**
102    * {@inheritdoc}
103    */
104   public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
105     /** @var \Drupal\Core\Field\BaseFieldDefinition[] $fields */
106     $fields = parent::baseFieldDefinitions($entity_type);
107
108     $fields['tid']->setLabel(t('Term ID'))
109       ->setDescription(t('The term ID.'));
110
111     $fields['uuid']->setDescription(t('The term UUID.'));
112
113     $fields['vid']->setLabel(t('Vocabulary'))
114       ->setDescription(t('The vocabulary to which the term is assigned.'));
115
116     $fields['langcode']->setDescription(t('The term language code.'));
117
118     $fields['name'] = BaseFieldDefinition::create('string')
119       ->setLabel(t('Name'))
120       ->setTranslatable(TRUE)
121       ->setRequired(TRUE)
122       ->setSetting('max_length', 255)
123       ->setDisplayOptions('view', [
124         'label' => 'hidden',
125         'type' => 'string',
126         'weight' => -5,
127       ])
128       ->setDisplayOptions('form', [
129         'type' => 'string_textfield',
130         'weight' => -5,
131       ])
132       ->setDisplayConfigurable('form', TRUE);
133
134     $fields['description'] = BaseFieldDefinition::create('text_long')
135       ->setLabel(t('Description'))
136       ->setTranslatable(TRUE)
137       ->setDisplayOptions('view', [
138         'label' => 'hidden',
139         'type' => 'text_default',
140         'weight' => 0,
141       ])
142       ->setDisplayConfigurable('view', TRUE)
143       ->setDisplayOptions('form', [
144         'type' => 'text_textfield',
145         'weight' => 0,
146       ])
147       ->setDisplayConfigurable('form', TRUE);
148
149     $fields['weight'] = BaseFieldDefinition::create('integer')
150       ->setLabel(t('Weight'))
151       ->setDescription(t('The weight of this term in relation to other terms.'))
152       ->setDefaultValue(0);
153
154     $fields['parent'] = BaseFieldDefinition::create('entity_reference')
155       ->setLabel(t('Term Parents'))
156       ->setDescription(t('The parents of this term.'))
157       ->setSetting('target_type', 'taxonomy_term')
158       ->setCardinality(BaseFieldDefinition::CARDINALITY_UNLIMITED)
159       ->setCustomStorage(TRUE);
160
161     $fields['changed'] = BaseFieldDefinition::create('changed')
162       ->setLabel(t('Changed'))
163       ->setDescription(t('The time that the term was last edited.'))
164       ->setTranslatable(TRUE);
165
166     return $fields;
167   }
168
169   /**
170    * {@inheritdoc}
171    */
172   public function getDescription() {
173     return $this->get('description')->value;
174   }
175
176   /**
177    * {@inheritdoc}
178    */
179   public function setDescription($description) {
180     $this->set('description', $description);
181     return $this;
182   }
183
184   /**
185    * {@inheritdoc}
186    */
187   public function getFormat() {
188     return $this->get('description')->format;
189   }
190
191   /**
192    * {@inheritdoc}
193    */
194   public function setFormat($format) {
195     $this->get('description')->format = $format;
196     return $this;
197   }
198
199   /**
200    * {@inheritdoc}
201    */
202   public function getName() {
203     return $this->label();
204   }
205
206   /**
207    * {@inheritdoc}
208    */
209   public function setName($name) {
210     $this->set('name', $name);
211     return $this;
212   }
213
214   /**
215    * {@inheritdoc}
216    */
217   public function getWeight() {
218     return $this->get('weight')->value;
219   }
220
221   /**
222    * {@inheritdoc}
223    */
224   public function setWeight($weight) {
225     $this->set('weight', $weight);
226     return $this;
227   }
228
229   /**
230    * {@inheritdoc}
231    */
232   public function getVocabularyId() {
233     @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);
234     return $this->bundle();
235   }
236
237   /**
238    * {@inheritdoc}
239    */
240   protected function getFieldsToSkipFromTranslationChangesCheck() {
241     // @todo the current implementation of the parent field makes it impossible
242     // for ::hasTranslationChanges() to correctly check the field for changes,
243     // so it is currently skipped from the comparision and has to be fixed by
244     // https://www.drupal.org/node/2843060.
245     $fields = parent::getFieldsToSkipFromTranslationChangesCheck();
246     $fields[] = 'parent';
247     return $fields;
248   }
249
250 }