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