3 namespace Drupal\entityqueue\Entity;
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;
19 * Defines the EntitySubqueue entity class.
22 * id = "entity_subqueue",
23 * label = @Translation("Entity subqueue"),
24 * bundle_label = @Translation("Entity queue"),
27 * "default" = "Drupal\entityqueue\Form\EntitySubqueueForm",
28 * "delete" = "\Drupal\entityqueue\Form\EntitySubqueueDeleteForm",
29 * "edit" = "Drupal\entityqueue\Form\EntitySubqueueForm"
31 * "access" = "Drupal\entityqueue\EntitySubqueueAccessControlHandler",
32 * "route_provider" = {
33 * "html" = "Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider",
35 * "list_builder" = "Drupal\entityqueue\EntitySubqueueListBuilder",
36 * "views_data" = "Drupal\views\EntityViewsData",
38 * base_table = "entity_subqueue",
43 * "langcode" = "langcode",
47 * bundle_entity_type = "entity_queue",
48 * field_ui_base_route = "entity.entity_queue.edit_form",
49 * permission_granularity = "bundle",
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",
60 class EntitySubqueue extends ContentEntityBase implements EntitySubqueueInterface {
62 use EntityChangedTrait;
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);
72 return \Drupal::entityTypeManager()
73 ->getAccessControlHandler($this->entityTypeId)
74 ->access($this, $operation, $account, $return_as_object);
80 public function preSave(EntityStorageInterface $storage) {
81 parent::preSave($storage);
83 /** @var \Drupal\entityqueue\EntityQueueInterface $queue */
84 $queue = $this->getQueue();
85 $max_size = $queue->getMaximumSize();
86 $act_as_queue = $queue->getActAsQueue();
88 $items = $this->get('items')->getValue();
89 $number_of_items = count($items);
91 // Remove extra items from the front of the queue if the maximum size is
93 if ($act_as_queue && $number_of_items > $max_size) {
94 $items = array_slice($items, -$max_size);
96 $this->set('items', $items);
103 public function getQueue() {
104 return $this->get('queue')->entity;
110 public function setQueue(EntityQueueInterface $queue) {
111 $this->set('queue', $queue->id());
118 public function getTitle() {
119 return $this->get('title')->value;
125 public function setTitle($title) {
126 $this->set('title', $title);
133 public function getCreatedTime() {
134 return $this->get('created')->value;
140 public function setCreatedTime($timestamp) {
141 $this->set('created', $timestamp);
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.'))
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);
157 $fields['uuid'] = BaseFieldDefinition::create('uuid')
158 ->setLabel(t('UUID'))
159 ->setDescription(t('The subqueue UUID.'))
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')
168 $fields['title'] = BaseFieldDefinition::create('string')
169 ->setLabel(t('Title'))
171 ->setSetting('max_length', 191)
172 ->setDisplayOptions('view', [
177 ->setDisplayConfigurable('view', TRUE)
178 ->setDisplayOptions('form', [
179 'type' => 'string_textfield',
182 ->setDisplayConfigurable('form', TRUE);
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', [
194 'type' => 'entity_reference_label',
197 ->setDisplayOptions('form', [
198 'type' => 'entity_reference_autocomplete',
201 'match_operator' => 'CONTAINS',
206 ->setDisplayConfigurable('form', TRUE)
207 ->setDisplayConfigurable('view', TRUE);
209 $fields['langcode'] = BaseFieldDefinition::create('language')
210 ->setLabel(t('Language'))
211 ->setDescription(t('The subqueue language code.'))
212 ->setDisplayOptions('view', [
215 ->setDisplayOptions('form', [
216 'type' => 'language_select',
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');
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');
231 $fields['changed'] = BaseFieldDefinition::create('changed')
232 ->setLabel(t('Changed'))
233 ->setDescription(t('The time that the subqueue was last edited.'));
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());
255 public function getOwner() {
256 return $this->get('uid')->entity;
262 public function getOwnerId() {
263 return $this->getEntityKey('uid');
269 public function setOwnerId($uid) {
270 $this->set('uid', $uid);
277 public function setOwner(UserInterface $account) {
278 $this->set('uid', $account->id());
285 public function addItem(EntityInterface $entity) {
286 $this->get('items')->appendItem($entity->id());
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]);
300 $this->get('items')->setValue($subqueue_items);
305 * Default value callback for 'uid' base field definition.
307 * @see ::baseFieldDefinitions()
310 * An array of default values.
312 public static function getCurrentUserId() {
313 return [\Drupal::currentUser()->id()];
317 * Default value callback for 'created' base field definition.
319 * @see ::baseFieldDefinitions()
322 * An array of default values.
324 public static function getDefaultCreatedTime() {
331 public function toUrl($rel = 'canonical', array $options = []) {
332 $url = parent::toUrl($rel, $options);
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());
344 public function getCacheTagsToInvalidate() {
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());
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
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());