Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\taxonomy\Entity;
|
Chris@0
|
4
|
Chris@18
|
5 use Drupal\Core\Entity\EditorialContentEntityBase;
|
Chris@0
|
6 use Drupal\Core\Entity\EntityStorageInterface;
|
Chris@0
|
7 use Drupal\Core\Entity\EntityTypeInterface;
|
Chris@0
|
8 use Drupal\Core\Field\BaseFieldDefinition;
|
Chris@0
|
9 use Drupal\taxonomy\TermInterface;
|
Chris@17
|
10 use Drupal\user\StatusItem;
|
Chris@0
|
11
|
Chris@0
|
12 /**
|
Chris@0
|
13 * Defines the taxonomy term entity.
|
Chris@0
|
14 *
|
Chris@0
|
15 * @ContentEntityType(
|
Chris@0
|
16 * id = "taxonomy_term",
|
Chris@0
|
17 * label = @Translation("Taxonomy term"),
|
Chris@17
|
18 * label_collection = @Translation("Taxonomy terms"),
|
Chris@17
|
19 * label_singular = @Translation("taxonomy term"),
|
Chris@17
|
20 * label_plural = @Translation("taxonomy terms"),
|
Chris@17
|
21 * label_count = @PluralTranslation(
|
Chris@17
|
22 * singular = "@count taxonomy term",
|
Chris@17
|
23 * plural = "@count taxonomy terms",
|
Chris@17
|
24 * ),
|
Chris@0
|
25 * bundle_label = @Translation("Vocabulary"),
|
Chris@0
|
26 * handlers = {
|
Chris@0
|
27 * "storage" = "Drupal\taxonomy\TermStorage",
|
Chris@0
|
28 * "storage_schema" = "Drupal\taxonomy\TermStorageSchema",
|
Chris@14
|
29 * "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
|
Chris@14
|
30 * "list_builder" = "Drupal\Core\Entity\EntityListBuilder",
|
Chris@0
|
31 * "access" = "Drupal\taxonomy\TermAccessControlHandler",
|
Chris@0
|
32 * "views_data" = "Drupal\taxonomy\TermViewsData",
|
Chris@0
|
33 * "form" = {
|
Chris@0
|
34 * "default" = "Drupal\taxonomy\TermForm",
|
Chris@0
|
35 * "delete" = "Drupal\taxonomy\Form\TermDeleteForm"
|
Chris@0
|
36 * },
|
Chris@0
|
37 * "translation" = "Drupal\taxonomy\TermTranslationHandler"
|
Chris@0
|
38 * },
|
Chris@0
|
39 * base_table = "taxonomy_term_data",
|
Chris@0
|
40 * data_table = "taxonomy_term_field_data",
|
Chris@18
|
41 * revision_table = "taxonomy_term_revision",
|
Chris@18
|
42 * revision_data_table = "taxonomy_term_field_revision",
|
Chris@0
|
43 * uri_callback = "taxonomy_term_uri",
|
Chris@0
|
44 * translatable = TRUE,
|
Chris@0
|
45 * entity_keys = {
|
Chris@0
|
46 * "id" = "tid",
|
Chris@18
|
47 * "revision" = "revision_id",
|
Chris@0
|
48 * "bundle" = "vid",
|
Chris@0
|
49 * "label" = "name",
|
Chris@0
|
50 * "langcode" = "langcode",
|
Chris@17
|
51 * "uuid" = "uuid",
|
Chris@17
|
52 * "published" = "status",
|
Chris@0
|
53 * },
|
Chris@18
|
54 * revision_metadata_keys = {
|
Chris@18
|
55 * "revision_user" = "revision_user",
|
Chris@18
|
56 * "revision_created" = "revision_created",
|
Chris@18
|
57 * "revision_log_message" = "revision_log_message",
|
Chris@18
|
58 * },
|
Chris@0
|
59 * bundle_entity_type = "taxonomy_vocabulary",
|
Chris@0
|
60 * field_ui_base_route = "entity.taxonomy_vocabulary.overview_form",
|
Chris@0
|
61 * common_reference_target = TRUE,
|
Chris@0
|
62 * links = {
|
Chris@0
|
63 * "canonical" = "/taxonomy/term/{taxonomy_term}",
|
Chris@0
|
64 * "delete-form" = "/taxonomy/term/{taxonomy_term}/delete",
|
Chris@0
|
65 * "edit-form" = "/taxonomy/term/{taxonomy_term}/edit",
|
Chris@0
|
66 * "create" = "/taxonomy/term",
|
Chris@0
|
67 * },
|
Chris@18
|
68 * permission_granularity = "bundle",
|
Chris@18
|
69 * constraints = {
|
Chris@18
|
70 * "TaxonomyHierarchy" = {}
|
Chris@18
|
71 * }
|
Chris@0
|
72 * )
|
Chris@0
|
73 */
|
Chris@18
|
74 class Term extends EditorialContentEntityBase implements TermInterface {
|
Chris@0
|
75
|
Chris@0
|
76 /**
|
Chris@0
|
77 * {@inheritdoc}
|
Chris@0
|
78 */
|
Chris@0
|
79 public static function postDelete(EntityStorageInterface $storage, array $entities) {
|
Chris@0
|
80 parent::postDelete($storage, $entities);
|
Chris@0
|
81
|
Chris@0
|
82 // See if any of the term's children are about to be become orphans.
|
Chris@0
|
83 $orphans = [];
|
Chris@17
|
84 /** @var \Drupal\taxonomy\TermInterface $term */
|
Chris@17
|
85 foreach ($entities as $tid => $term) {
|
Chris@17
|
86 if ($children = $storage->getChildren($term)) {
|
Chris@17
|
87 /** @var \Drupal\taxonomy\TermInterface $child */
|
Chris@0
|
88 foreach ($children as $child) {
|
Chris@17
|
89 $parent = $child->get('parent');
|
Chris@17
|
90 // Update child parents item list.
|
Chris@17
|
91 $parent->filter(function ($item) use ($tid) {
|
Chris@17
|
92 return $item->target_id != $tid;
|
Chris@17
|
93 });
|
Chris@17
|
94
|
Chris@0
|
95 // If the term has multiple parents, we don't delete it.
|
Chris@17
|
96 if ($parent->count()) {
|
Chris@17
|
97 $child->save();
|
Chris@17
|
98 }
|
Chris@17
|
99 else {
|
Chris@0
|
100 $orphans[] = $child;
|
Chris@0
|
101 }
|
Chris@0
|
102 }
|
Chris@0
|
103 }
|
Chris@0
|
104 }
|
Chris@0
|
105
|
Chris@0
|
106 if (!empty($orphans)) {
|
Chris@0
|
107 $storage->delete($orphans);
|
Chris@0
|
108 }
|
Chris@0
|
109 }
|
Chris@0
|
110
|
Chris@0
|
111 /**
|
Chris@0
|
112 * {@inheritdoc}
|
Chris@0
|
113 */
|
Chris@17
|
114 public function preSave(EntityStorageInterface $storage) {
|
Chris@17
|
115 parent::preSave($storage);
|
Chris@17
|
116 // Terms with no parents are mandatory children of <root>.
|
Chris@17
|
117 if (!$this->get('parent')->count()) {
|
Chris@17
|
118 $this->parent->target_id = 0;
|
Chris@0
|
119 }
|
Chris@0
|
120 }
|
Chris@0
|
121
|
Chris@0
|
122 /**
|
Chris@0
|
123 * {@inheritdoc}
|
Chris@0
|
124 */
|
Chris@0
|
125 public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
|
Chris@0
|
126 /** @var \Drupal\Core\Field\BaseFieldDefinition[] $fields */
|
Chris@0
|
127 $fields = parent::baseFieldDefinitions($entity_type);
|
Chris@0
|
128
|
Chris@17
|
129 // @todo Remove the usage of StatusItem in
|
Chris@17
|
130 // https://www.drupal.org/project/drupal/issues/2936864.
|
Chris@17
|
131 $fields['status']->getItemDefinition()->setClass(StatusItem::class);
|
Chris@17
|
132
|
Chris@0
|
133 $fields['tid']->setLabel(t('Term ID'))
|
Chris@0
|
134 ->setDescription(t('The term ID.'));
|
Chris@0
|
135
|
Chris@0
|
136 $fields['uuid']->setDescription(t('The term UUID.'));
|
Chris@0
|
137
|
Chris@0
|
138 $fields['vid']->setLabel(t('Vocabulary'))
|
Chris@0
|
139 ->setDescription(t('The vocabulary to which the term is assigned.'));
|
Chris@0
|
140
|
Chris@0
|
141 $fields['langcode']->setDescription(t('The term language code.'));
|
Chris@0
|
142
|
Chris@0
|
143 $fields['name'] = BaseFieldDefinition::create('string')
|
Chris@0
|
144 ->setLabel(t('Name'))
|
Chris@0
|
145 ->setTranslatable(TRUE)
|
Chris@18
|
146 ->setRevisionable(TRUE)
|
Chris@0
|
147 ->setRequired(TRUE)
|
Chris@0
|
148 ->setSetting('max_length', 255)
|
Chris@0
|
149 ->setDisplayOptions('view', [
|
Chris@0
|
150 'label' => 'hidden',
|
Chris@0
|
151 'type' => 'string',
|
Chris@0
|
152 'weight' => -5,
|
Chris@0
|
153 ])
|
Chris@0
|
154 ->setDisplayOptions('form', [
|
Chris@0
|
155 'type' => 'string_textfield',
|
Chris@0
|
156 'weight' => -5,
|
Chris@0
|
157 ])
|
Chris@0
|
158 ->setDisplayConfigurable('form', TRUE);
|
Chris@0
|
159
|
Chris@0
|
160 $fields['description'] = BaseFieldDefinition::create('text_long')
|
Chris@0
|
161 ->setLabel(t('Description'))
|
Chris@0
|
162 ->setTranslatable(TRUE)
|
Chris@18
|
163 ->setRevisionable(TRUE)
|
Chris@0
|
164 ->setDisplayOptions('view', [
|
Chris@0
|
165 'label' => 'hidden',
|
Chris@0
|
166 'type' => 'text_default',
|
Chris@0
|
167 'weight' => 0,
|
Chris@0
|
168 ])
|
Chris@0
|
169 ->setDisplayConfigurable('view', TRUE)
|
Chris@0
|
170 ->setDisplayOptions('form', [
|
Chris@0
|
171 'type' => 'text_textfield',
|
Chris@0
|
172 'weight' => 0,
|
Chris@0
|
173 ])
|
Chris@0
|
174 ->setDisplayConfigurable('form', TRUE);
|
Chris@0
|
175
|
Chris@0
|
176 $fields['weight'] = BaseFieldDefinition::create('integer')
|
Chris@0
|
177 ->setLabel(t('Weight'))
|
Chris@0
|
178 ->setDescription(t('The weight of this term in relation to other terms.'))
|
Chris@0
|
179 ->setDefaultValue(0);
|
Chris@0
|
180
|
Chris@0
|
181 $fields['parent'] = BaseFieldDefinition::create('entity_reference')
|
Chris@0
|
182 ->setLabel(t('Term Parents'))
|
Chris@0
|
183 ->setDescription(t('The parents of this term.'))
|
Chris@0
|
184 ->setSetting('target_type', 'taxonomy_term')
|
Chris@17
|
185 ->setCardinality(BaseFieldDefinition::CARDINALITY_UNLIMITED);
|
Chris@0
|
186
|
Chris@0
|
187 $fields['changed'] = BaseFieldDefinition::create('changed')
|
Chris@0
|
188 ->setLabel(t('Changed'))
|
Chris@0
|
189 ->setDescription(t('The time that the term was last edited.'))
|
Chris@18
|
190 ->setTranslatable(TRUE)
|
Chris@18
|
191 ->setRevisionable(TRUE);
|
Chris@18
|
192
|
Chris@18
|
193 // @todo Keep this field hidden until we have a revision UI for terms.
|
Chris@18
|
194 // @see https://www.drupal.org/project/drupal/issues/2936995
|
Chris@18
|
195 $fields['revision_log_message']->setDisplayOptions('form', [
|
Chris@18
|
196 'region' => 'hidden',
|
Chris@18
|
197 ]);
|
Chris@0
|
198
|
Chris@0
|
199 return $fields;
|
Chris@0
|
200 }
|
Chris@0
|
201
|
Chris@0
|
202 /**
|
Chris@0
|
203 * {@inheritdoc}
|
Chris@0
|
204 */
|
Chris@17
|
205 public static function bundleFieldDefinitions(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
|
Chris@17
|
206 // Only terms in the same bundle can be a parent.
|
Chris@17
|
207 $fields['parent'] = clone $base_field_definitions['parent'];
|
Chris@17
|
208 $fields['parent']->setSetting('handler_settings', ['target_bundles' => [$bundle => $bundle]]);
|
Chris@17
|
209 return $fields;
|
Chris@17
|
210 }
|
Chris@17
|
211
|
Chris@17
|
212 /**
|
Chris@17
|
213 * {@inheritdoc}
|
Chris@17
|
214 */
|
Chris@0
|
215 public function getDescription() {
|
Chris@0
|
216 return $this->get('description')->value;
|
Chris@0
|
217 }
|
Chris@0
|
218
|
Chris@0
|
219 /**
|
Chris@0
|
220 * {@inheritdoc}
|
Chris@0
|
221 */
|
Chris@0
|
222 public function setDescription($description) {
|
Chris@0
|
223 $this->set('description', $description);
|
Chris@0
|
224 return $this;
|
Chris@0
|
225 }
|
Chris@0
|
226
|
Chris@0
|
227 /**
|
Chris@0
|
228 * {@inheritdoc}
|
Chris@0
|
229 */
|
Chris@0
|
230 public function getFormat() {
|
Chris@0
|
231 return $this->get('description')->format;
|
Chris@0
|
232 }
|
Chris@0
|
233
|
Chris@0
|
234 /**
|
Chris@0
|
235 * {@inheritdoc}
|
Chris@0
|
236 */
|
Chris@0
|
237 public function setFormat($format) {
|
Chris@0
|
238 $this->get('description')->format = $format;
|
Chris@0
|
239 return $this;
|
Chris@0
|
240 }
|
Chris@0
|
241
|
Chris@0
|
242 /**
|
Chris@0
|
243 * {@inheritdoc}
|
Chris@0
|
244 */
|
Chris@0
|
245 public function getName() {
|
Chris@0
|
246 return $this->label();
|
Chris@0
|
247 }
|
Chris@0
|
248
|
Chris@0
|
249 /**
|
Chris@0
|
250 * {@inheritdoc}
|
Chris@0
|
251 */
|
Chris@0
|
252 public function setName($name) {
|
Chris@0
|
253 $this->set('name', $name);
|
Chris@0
|
254 return $this;
|
Chris@0
|
255 }
|
Chris@0
|
256
|
Chris@0
|
257 /**
|
Chris@0
|
258 * {@inheritdoc}
|
Chris@0
|
259 */
|
Chris@0
|
260 public function getWeight() {
|
Chris@0
|
261 return $this->get('weight')->value;
|
Chris@0
|
262 }
|
Chris@0
|
263
|
Chris@0
|
264 /**
|
Chris@0
|
265 * {@inheritdoc}
|
Chris@0
|
266 */
|
Chris@0
|
267 public function setWeight($weight) {
|
Chris@0
|
268 $this->set('weight', $weight);
|
Chris@0
|
269 return $this;
|
Chris@0
|
270 }
|
Chris@0
|
271
|
Chris@0
|
272 /**
|
Chris@0
|
273 * {@inheritdoc}
|
Chris@0
|
274 */
|
Chris@0
|
275 public function getVocabularyId() {
|
Chris@0
|
276 @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);
|
Chris@0
|
277 return $this->bundle();
|
Chris@0
|
278 }
|
Chris@0
|
279
|
Chris@0
|
280 }
|