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\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;
18 * Defines the EntitySubqueue entity class.
21 * id = "entity_subqueue",
22 * label = @Translation("Entity subqueue"),
23 * bundle_label = @Translation("Entity queue"),
26 * "default" = "Drupal\entityqueue\Form\EntitySubqueueForm",
27 * "delete" = "\Drupal\entityqueue\Form\EntitySubqueueDeleteForm",
28 * "edit" = "Drupal\entityqueue\Form\EntitySubqueueForm"
30 * "access" = "Drupal\entityqueue\EntitySubqueueAccessControlHandler",
31 * "route_provider" = {
32 * "html" = "Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider",
34 * "list_builder" = "Drupal\entityqueue\EntitySubqueueListBuilder",
35 * "views_data" = "Drupal\views\EntityViewsData",
37 * base_table = "entity_subqueue",
42 * "langcode" = "langcode",
46 * bundle_entity_type = "entity_queue",
47 * field_ui_base_route = "entity.entity_queue.edit_form",
48 * permission_granularity = "bundle",
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",
59 class EntitySubqueue extends ContentEntityBase implements EntitySubqueueInterface {
61 use EntityChangedTrait;
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);
71 return \Drupal::entityTypeManager()
72 ->getAccessControlHandler($this->entityTypeId)
73 ->access($this, $operation, $account, $return_as_object);
79 public function preSave(EntityStorageInterface $storage) {
80 parent::preSave($storage);
82 /** @var \Drupal\entityqueue\EntityQueueInterface $queue */
83 $queue = $this->getQueue();
84 $max_size = $queue->getMaximumSize();
85 $act_as_queue = $queue->getActAsQueue();
87 $items = $this->get('items')->getValue();
88 $number_of_items = count($items);
90 // Remove extra items from the front of the queue if the maximum size is
92 if ($act_as_queue && $number_of_items > $max_size) {
93 $items = array_slice($items, -$max_size);
95 $this->set('items', $items);
102 public function getQueue() {
103 return $this->get('queue')->entity;
109 public function setQueue(EntityQueueInterface $queue) {
110 $this->set('queue', $queue->id());
117 public function getTitle() {
118 return $this->get('title')->value;
124 public function setTitle($title) {
125 $this->set('title', $title);
132 public function getCreatedTime() {
133 return $this->get('created')->value;
139 public function setCreatedTime($timestamp) {
140 $this->set('created', $timestamp);
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.'))
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);
156 $fields['uuid'] = BaseFieldDefinition::create('uuid')
157 ->setLabel(t('UUID'))
158 ->setDescription(t('The subqueue UUID.'))
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')
167 $fields['title'] = BaseFieldDefinition::create('string')
168 ->setLabel(t('Title'))
170 ->setSetting('max_length', 191)
171 ->setDisplayOptions('view', array(
176 ->setDisplayOptions('form', array(
177 'type' => 'string_textfield',
180 ->setDisplayConfigurable('form', TRUE);
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(
192 'type' => 'entity_reference_label',
195 ->setDisplayOptions('form', array(
196 'type' => 'entity_reference_autocomplete',
199 'match_operator' => 'CONTAINS',
204 ->setDisplayConfigurable('form', TRUE)
205 ->setDisplayConfigurable('view', TRUE);
207 $fields['langcode'] = BaseFieldDefinition::create('language')
208 ->setLabel(t('Language'))
209 ->setDescription(t('The subqueue language code.'))
210 ->setDisplayOptions('view', array(
213 ->setDisplayOptions('form', array(
214 'type' => 'language_select',
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');
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');
229 $fields['changed'] = BaseFieldDefinition::create('changed')
230 ->setLabel(t('Changed'))
231 ->setDescription(t('The time that the subqueue was last edited.'));
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());
253 public function getOwner() {
254 return $this->get('uid')->entity;
260 public function getOwnerId() {
261 return $this->getEntityKey('uid');
267 public function setOwnerId($uid) {
268 $this->set('uid', $uid);
275 public function setOwner(UserInterface $account) {
276 $this->set('uid', $account->id());
281 * Default value callback for 'uid' base field definition.
283 * @see ::baseFieldDefinitions()
286 * An array of default values.
288 public static function getCurrentUserId() {
289 return array(\Drupal::currentUser()->id());
293 * Default value callback for 'created' base field definition.
295 * @see ::baseFieldDefinitions()
298 * An array of default values.
300 public static function getDefaultCreatedTime() {
307 public function toUrl($rel = 'canonical', array $options = []) {
308 $url = parent::toUrl($rel, $options);
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());
320 public function getCacheTagsToInvalidate() {
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());
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
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());