Updated all the contrib modules to their latest versions.
[yaffs-website] / web / modules / contrib / entityqueue / src / Entity / EntitySubqueue.php
1 <?php
2
3 namespace Drupal\entityqueue\Entity;
4
5 use Drupal\Core\Cache\Cache;
6 use Drupal\Core\Entity\ContentEntityBase;
7 use Drupal\Core\Entity\EntityChangedTrait;
8 use Drupal\Core\Entity\EntityInterface;
9 use Drupal\Core\Entity\EntityStorageInterface;
10 use Drupal\Core\Entity\EntityTypeInterface;
11 use Drupal\Core\Field\BaseFieldDefinition;
12 use Drupal\Core\Field\FieldStorageDefinitionInterface;
13 use Drupal\Core\Session\AccountInterface;
14 use Drupal\entityqueue\EntityQueueInterface;
15 use Drupal\entityqueue\EntitySubqueueInterface;
16 use Drupal\user\UserInterface;
17
18 /**
19  * Defines the EntitySubqueue entity class.
20  *
21  * @ContentEntityType(
22  *   id = "entity_subqueue",
23  *   label = @Translation("Entity subqueue"),
24  *   bundle_label = @Translation("Entity queue"),
25  *   handlers = {
26  *     "form" = {
27  *       "default" = "Drupal\entityqueue\Form\EntitySubqueueForm",
28  *       "delete" = "\Drupal\entityqueue\Form\EntitySubqueueDeleteForm",
29  *       "edit" = "Drupal\entityqueue\Form\EntitySubqueueForm"
30  *     },
31  *     "access" = "Drupal\entityqueue\EntitySubqueueAccessControlHandler",
32  *     "route_provider" = {
33  *       "html" = "Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider",
34  *     },
35  *     "list_builder" = "Drupal\entityqueue\EntitySubqueueListBuilder",
36  *     "views_data" = "Drupal\views\EntityViewsData",
37  *   },
38  *   base_table = "entity_subqueue",
39  *   entity_keys = {
40  *     "id" = "name",
41  *     "bundle" = "queue",
42  *     "label" = "title",
43  *     "langcode" = "langcode",
44  *     "uuid" = "uuid",
45  *     "uid" = "uid"
46  *   },
47  *   bundle_entity_type = "entity_queue",
48  *   field_ui_base_route = "entity.entity_queue.edit_form",
49  *   permission_granularity = "bundle",
50  *   links = {
51  *     "edit-form" = "/admin/structure/entityqueue/{entity_queue}/{entity_subqueue}",
52  *     "delete-form" = "/admin/structure/entityqueue/{entity_queue}/{entity_subqueue}/delete",
53  *     "collection" = "/admin/structure/entityqueue/{entity_queue}/list",
54  *   },
55  *   constraints = {
56  *     "QueueSize" = {}
57  *   }
58  * )
59  */
60 class EntitySubqueue extends ContentEntityBase implements EntitySubqueueInterface {
61
62   use EntityChangedTrait;
63
64   /**
65    * {@inheritdoc}
66    */
67   public function access($operation = 'view', AccountInterface $account = NULL, $return_as_object = FALSE) {
68     if ($operation == 'create') {
69       return parent::access($operation, $account, $return_as_object);
70     }
71
72     return \Drupal::entityTypeManager()
73       ->getAccessControlHandler($this->entityTypeId)
74       ->access($this, $operation, $account, $return_as_object);
75   }
76
77   /**
78    * {@inheritdoc}
79    */
80   public function preSave(EntityStorageInterface $storage) {
81     parent::preSave($storage);
82
83     /** @var \Drupal\entityqueue\EntityQueueInterface $queue */
84     $queue = $this->getQueue();
85     $max_size = $queue->getMaximumSize();
86     $act_as_queue = $queue->getActAsQueue();
87
88     $items = $this->get('items')->getValue();
89     $number_of_items = count($items);
90
91     // Remove extra items from the front of the queue if the maximum size is
92     // exceeded.
93     if ($act_as_queue && $number_of_items > $max_size) {
94       $items = array_slice($items, -$max_size);
95
96       $this->set('items', $items);
97     }
98   }
99
100   /**
101    * {@inheritdoc}
102    */
103   public function getQueue() {
104     return $this->get('queue')->entity;
105   }
106
107   /**
108    * {@inheritdoc}
109    */
110   public function setQueue(EntityQueueInterface $queue) {
111     $this->set('queue', $queue->id());
112     return $this;
113   }
114
115   /**
116    * {@inheritdoc}
117    */
118   public function getTitle() {
119     return $this->get('title')->value;
120   }
121
122   /**
123    * {@inheritdoc}
124    */
125   public function setTitle($title) {
126     $this->set('title', $title);
127     return $this;
128   }
129
130   /**
131    * {@inheritdoc}
132    */
133   public function getCreatedTime() {
134     return $this->get('created')->value;
135   }
136
137   /**
138    * {@inheritdoc}
139    */
140   public function setCreatedTime($timestamp) {
141     $this->set('created', $timestamp);
142     return $this;
143   }
144
145   /**
146    * {@inheritdoc}
147    */
148   public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
149     $fields['name'] = BaseFieldDefinition::create('string')
150       ->setLabel(t('Name'))
151       ->setDescription(t('The name of the subqueue.'))
152       ->setReadOnly(TRUE)
153       // In order to work around the InnoDB 191 character limit on utf8mb4
154       // primary keys, we set the character set for the field to ASCII.
155       ->setSetting('is_ascii', TRUE);
156
157     $fields['uuid'] = BaseFieldDefinition::create('uuid')
158       ->setLabel(t('UUID'))
159       ->setDescription(t('The subqueue UUID.'))
160       ->setReadOnly(TRUE);
161
162     $fields['queue'] = BaseFieldDefinition::create('entity_reference')
163       ->setLabel(t('Queue'))
164       ->setDescription(t('The queue (bundle) of this subqueue.'))
165       ->setSetting('target_type', 'entity_queue')
166       ->setReadOnly(TRUE);
167
168     $fields['title'] = BaseFieldDefinition::create('string')
169       ->setLabel(t('Title'))
170       ->setRequired(TRUE)
171       ->setSetting('max_length', 191)
172       ->setDisplayOptions('view', [
173         'label' => 'hidden',
174         'type' => 'string',
175         'weight' => -10,
176       ])
177       ->setDisplayConfigurable('view', TRUE)
178       ->setDisplayOptions('form', [
179         'type' => 'string_textfield',
180         'weight' => -10,
181       ])
182       ->setDisplayConfigurable('form', TRUE);
183
184     $fields['items'] = BaseFieldDefinition::create('entity_reference')
185       ->setLabel(t('Items'))
186       ->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
187       // This setting is overridden per bundle (queue) in
188       // static::bundleFieldDefinitions(), but we need to default to a target
189       // entity type that uses strings IDs, in order to allow both integers and
190       // strings to be stored by the default entity reference field storage.
191       ->setSetting('target_type', 'entity_subqueue')
192       ->setDisplayOptions('view', [
193         'label' => 'hidden',
194         'type' => 'entity_reference_label',
195         'weight' => 0,
196       ])
197       ->setDisplayOptions('form', [
198         'type' => 'entity_reference_autocomplete',
199         'weight' => 5,
200         'settings' => [
201           'match_operator' => 'CONTAINS',
202           'size' => '60',
203           'placeholder' => '',
204         ],
205       ])
206       ->setDisplayConfigurable('form', TRUE)
207       ->setDisplayConfigurable('view', TRUE);
208
209     $fields['langcode'] = BaseFieldDefinition::create('language')
210       ->setLabel(t('Language'))
211       ->setDescription(t('The subqueue language code.'))
212       ->setDisplayOptions('view', [
213         'type' => 'hidden',
214       ])
215       ->setDisplayOptions('form', [
216         'type' => 'language_select',
217         'weight' => 2,
218       ]);
219
220     $fields['uid'] = BaseFieldDefinition::create('entity_reference')
221       ->setLabel(t('Authored by'))
222       ->setDescription(t('The username of the subqueue author.'))
223       ->setSetting('target_type', 'user')
224       ->setDefaultValueCallback('Drupal\entityqueue\Entity\EntitySubqueue::getCurrentUserId');
225
226     $fields['created'] = BaseFieldDefinition::create('created')
227       ->setLabel(t('Authored on'))
228       ->setDescription(t('The time that the subqueue was created.'))
229       ->setDefaultValueCallback('Drupal\entityqueue\Entity\EntitySubqueue::getDefaultCreatedTime');
230
231     $fields['changed'] = BaseFieldDefinition::create('changed')
232       ->setLabel(t('Changed'))
233       ->setDescription(t('The time that the subqueue was last edited.'));
234
235     return $fields;
236   }
237
238   /**
239    * {@inheritdoc}
240    */
241   public static function bundleFieldDefinitions(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
242     // Change the target type of the 'items' field to the one defined by the
243     // parent queue (i.e. bundle).
244     if ($queue = EntityQueue::load($bundle)) {
245       $fields['items'] = clone $base_field_definitions['items'];
246       $fields['items']->setSettings($queue->getEntitySettings());
247       return $fields;
248     }
249     return [];
250   }
251
252   /**
253    * {@inheritdoc}
254    */
255   public function getOwner() {
256     return $this->get('uid')->entity;
257   }
258
259   /**
260    * {@inheritdoc}
261    */
262   public function getOwnerId() {
263     return $this->getEntityKey('uid');
264   }
265
266   /**
267    * {@inheritdoc}
268    */
269   public function setOwnerId($uid) {
270     $this->set('uid', $uid);
271     return $this;
272   }
273
274   /**
275    * {@inheritdoc}
276    */
277   public function setOwner(UserInterface $account) {
278     $this->set('uid', $account->id());
279     return $this;
280   }
281
282   /**
283    * {@inheritdoc}
284    */
285   public function addItem(EntityInterface $entity) {
286     $this->get('items')->appendItem($entity->id());
287     return $this;
288   }
289
290   /**
291    * {@inheritdoc}
292    */
293   public function removeItem(EntityInterface $entity) {
294     $subqueue_items = $this->get('items')->getValue();
295     foreach ($subqueue_items as $key => $item) {
296       if ($item['target_id'] == $entity->id()) {
297         unset($subqueue_items[$key]);
298       }
299     }
300     $this->get('items')->setValue($subqueue_items);
301     return $this;
302   }
303
304   /**
305    * Default value callback for 'uid' base field definition.
306    *
307    * @see ::baseFieldDefinitions()
308    *
309    * @return array
310    *   An array of default values.
311    */
312   public static function getCurrentUserId() {
313     return [\Drupal::currentUser()->id()];
314   }
315
316   /**
317    * Default value callback for 'created' base field definition.
318    *
319    * @see ::baseFieldDefinitions()
320    *
321    * @return array
322    *   An array of default values.
323    */
324   public static function getDefaultCreatedTime() {
325     return REQUEST_TIME;
326   }
327
328   /**
329    * {@inheritdoc}
330    */
331   public function toUrl($rel = 'canonical', array $options = []) {
332     $url = parent::toUrl($rel, $options);
333
334     // The 'entity_queue' parameter is needed by the subqueue routes, so we need
335     // to add it manually.
336     $url->setRouteParameter('entity_queue', $this->bundle());
337
338     return $url;
339   }
340
341   /**
342    * {@inheritdoc}
343    */
344   public function getCacheTagsToInvalidate() {
345     $tags = [];
346
347     // Use the cache tags of the entity queue.
348     // @todo Allow queue handlers to control this?
349     if ($queue = $this->getQueue()) {
350       $tags = Cache::mergeTags(parent::getCacheTagsToInvalidate(), $queue->getCacheTags());
351
352       // Sadly, Views handlers have no way of influencing the cache tags of the
353       // views result cache plugins, so we have to invalidate the target entity
354       // type list tag.
355       // @todo Reconsider this when https://www.drupal.org/node/2710679 is fixed.
356       $target_entity_type = $this->entityTypeManager()->getDefinition($this->getQueue()->getTargetEntityTypeId());
357       $tags = Cache::mergeTags($tags, $target_entity_type->getListCacheTags());
358     }
359
360     return $tags;
361   }
362
363 }