5 * Test module for the entity API providing several entity types for testing.
8 use Drupal\Core\Access\AccessResult;
9 use Drupal\Core\Database\Query\AlterableInterface;
10 use Drupal\Core\Entity\ContentEntityInterface;
11 use Drupal\Core\Entity\EntityInterface;
12 use Drupal\Core\Entity\FieldableEntityInterface;
13 use Drupal\Core\Entity\EntityTypeInterface;
14 use Drupal\Core\Field\BaseFieldDefinition;
15 use Drupal\Core\Field\FieldDefinitionInterface;
16 use Drupal\Core\Field\FieldItemListInterface;
17 use Drupal\Core\Field\FieldStorageDefinitionInterface;
18 use Drupal\Core\Form\FormStateInterface;
19 use Drupal\Core\Session\AccountInterface;
20 use Drupal\Core\Entity\Entity\EntityFormDisplay;
24 * Filter that limits test entity list to revisable ones.
26 const ENTITY_TEST_TYPES_REVISABLE = 1;
29 * Filter that limits test entity list to multilingual ones.
31 const ENTITY_TEST_TYPES_MULTILINGUAL = 2;
34 * Filter that limits test entity list to routeable ones.
36 const ENTITY_TEST_TYPES_ROUTING = 3;
39 * Returns a list of test entity types.
41 * The returned entity types are one for each available entity storage type:
42 * - The plain entity_test type supports neither revisions nor multilingual
44 * - The entity_test_mul type supports multilingual properties.
45 * - The entity_test_rev type supports revisions.
46 * - The entity_test_mulrev type supports both revisions and multilingual
50 * Either ENTITY_TEST_TYPES_REVISABLE to only return revisable entity types or
51 * ENTITY_TEST_TYPES_MULTILINGUAL to only return multilingual ones. Defaults
52 * to NULL, which returns all.
55 * List with entity_types.
57 function entity_test_entity_types($filter = NULL) {
59 if ($filter === NULL || $filter === ENTITY_TEST_TYPES_ROUTING) {
60 $types[] = 'entity_test';
62 if ($filter != ENTITY_TEST_TYPES_REVISABLE) {
63 $types[] = 'entity_test_mul';
64 $types[] = 'entity_test_mul_langcode_key';
65 $types[] = 'entity_test_mul_changed';
67 if ($filter != ENTITY_TEST_TYPES_MULTILINGUAL) {
68 $types[] = 'entity_test_rev';
70 if ($filter === ENTITY_TEST_TYPES_ROUTING) {
71 $types[] = 'entity_test_base_field_display';
72 $types[] = 'entity_test_string_id';
73 $types[] = 'entity_test_no_id';
75 $types[] = 'entity_test_mulrev';
76 $types[] = 'entity_test_mulrev_changed';
78 return array_combine($types, $types);
82 * Implements hook_entity_type_alter().
84 function entity_test_entity_type_alter(array &$entity_types) {
85 $state = \Drupal::state();
87 /** @var $entity_types \Drupal\Core\Entity\EntityTypeInterface[] */
88 foreach (entity_test_entity_types() as $entity_type) {
89 // Optionally specify a translation handler for testing translations.
90 if ($state->get('entity_test.translation')) {
91 $translation = $entity_types[$entity_type]->get('translation');
92 $translation[$entity_type] = TRUE;
93 $entity_types[$entity_type]->set('translation', $translation);
97 // Allow entity_test_rev tests to override the entity type definition.
98 $entity_types['entity_test_rev'] = $state->get('entity_test_rev.entity_type', $entity_types['entity_test_rev']);
100 // Enable the entity_test_new only when needed.
101 if (!$state->get('entity_test_new')) {
102 unset($entity_types['entity_test_new']);
107 * Implements hook_entity_base_field_info().
109 function entity_test_entity_base_field_info(EntityTypeInterface $entity_type) {
112 if ($entity_type->id() === 'entity_test' && \Drupal::state()->get('entity_test.internal_field')) {
113 $fields['internal_string_field'] = BaseFieldDefinition::create('string')
114 ->setLabel('Internal field')
117 if ($entity_type->id() === 'entity_test_mul' && \Drupal::state()->get('entity_test.required_default_field')) {
118 $fields['required_default_field'] = BaseFieldDefinition::create('string')
119 ->setLabel('Required field with default value')
121 ->setDefaultValue('this is a default value');
123 if ($entity_type->id() === 'entity_test_mul' && \Drupal::state()->get('entity_test.required_multi_default_field')) {
124 $fields['required_multi_default_field'] = BaseFieldDefinition::create('string')
125 ->setLabel('Required field with default value')
127 ->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
129 ['value' => 'this is the first default field item'],
130 ['value' => 'this is the second default value'],
131 ['value' => 'you get the idea...'],
134 if ($entity_type->id() == 'entity_test_mulrev' && \Drupal::state()->get('entity_test.field_test_item')) {
135 $fields['field_test_item'] = BaseFieldDefinition::create('field_test')
136 ->setLabel(t('Field test'))
137 ->setDescription(t('A field test.'))
138 ->setRevisionable(TRUE)
139 ->setTranslatable(TRUE);
141 if ($entity_type->id() == 'entity_test_mulrev' && \Drupal::state()->get('entity_test.multi_column')) {
142 $fields['description'] = BaseFieldDefinition::create('shape')
143 ->setLabel(t('Some custom description'))
144 ->setTranslatable(TRUE);
151 * Implements hook_entity_base_field_info_alter().
153 function entity_test_entity_base_field_info_alter(&$fields, EntityTypeInterface $entity_type) {
154 $state = \Drupal::state();
155 if ($entity_type->id() == 'entity_test_mulrev' && ($names = $state->get('entity_test.field_definitions.translatable'))) {
156 foreach ($names as $name => $value) {
157 $fields[$name]->setTranslatable($value);
160 if ($entity_type->id() == 'node' && $state->get('entity_test.node_remove_status_field')) {
161 unset($fields['status']);
163 if ($entity_type->id() == 'entity_test' && $state->get('entity_test.remove_name_field')) {
164 unset($fields['name']);
166 // In 8001 we are assuming that a new definition with multiple cardinality has
168 // @todo Remove this if we end up using state definitions at runtime. See
169 // https://www.drupal.org/node/2554235.
170 if ($entity_type->id() == 'entity_test' && $state->get('entity_test.db_updates.entity_definition_updates') == 8001) {
171 $fields['user_id']->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
176 * Creates a new bundle for entity_test entities.
178 * @param string $bundle
179 * The machine-readable name of the bundle.
180 * @param string $text
181 * (optional) The human-readable name of the bundle. If none is provided, the
182 * machine name will be used.
183 * @param string $entity_type
184 * (optional) The entity type for which the bundle is created. Defaults to
187 function entity_test_create_bundle($bundle, $text = NULL, $entity_type = 'entity_test') {
188 $bundles = \Drupal::state()->get($entity_type . '.bundles') ?: [$entity_type => ['label' => 'Entity Test Bundle']];
189 $bundles += [$bundle => ['label' => $text ? $text : $bundle]];
190 \Drupal::state()->set($entity_type . '.bundles', $bundles);
192 \Drupal::entityManager()->onBundleCreate($bundle, $entity_type);
196 * Deletes a bundle for entity_test entities.
198 * @param string $bundle
199 * The machine-readable name of the bundle to delete.
200 * @param string $entity_type
201 * (optional) The entity type for which the bundle is deleted. Defaults to
204 function entity_test_delete_bundle($bundle, $entity_type = 'entity_test') {
205 $bundles = \Drupal::state()->get($entity_type . '.bundles') ?: [$entity_type => ['label' => 'Entity Test Bundle']];
206 unset($bundles[$bundle]);
207 \Drupal::state()->set($entity_type . '.bundles', $bundles);
209 \Drupal::entityManager()->onBundleDelete($bundle, $entity_type);
213 * Implements hook_entity_bundle_info().
215 function entity_test_entity_bundle_info() {
217 $entity_types = \Drupal::entityManager()->getDefinitions();
218 foreach ($entity_types as $entity_type_id => $entity_type) {
219 if ($entity_type->getProvider() == 'entity_test' && $entity_type_id != 'entity_test_with_bundle') {
220 $bundles[$entity_type_id] = \Drupal::state()->get($entity_type_id . '.bundles') ?: [$entity_type_id => ['label' => 'Entity Test Bundle']];
227 * Implements hook_entity_bundle_info_alter().
229 function entity_test_entity_bundle_info_alter(&$bundles) {
230 $entity_info = \Drupal::entityTypeManager()->getDefinitions();
231 $state = \Drupal::state();
232 foreach ($bundles as $entity_type_id => &$all_bundle_info) {
233 if ($entity_info[$entity_type_id]->getProvider() == 'entity_test') {
234 if ($state->get('entity_test.translation')) {
235 foreach ($all_bundle_info as $bundle_name => &$bundle_info) {
236 $bundle_info['translatable'] = TRUE;
237 if ($state->get('entity_test.untranslatable_fields.default_translation_affected')) {
238 $bundle_info['untranslatable_fields.default_translation_affected'] = TRUE;
247 * Implements hook_entity_view_mode_info_alter().
249 function entity_test_entity_view_mode_info_alter(&$view_modes) {
250 $entity_info = \Drupal::entityManager()->getDefinitions();
251 foreach ($entity_info as $entity_type => $info) {
252 if ($entity_info[$entity_type]->getProvider() == 'entity_test' && !isset($view_modes[$entity_type])) {
253 $view_modes[$entity_type] = [
255 'label' => t('Full object'),
260 'label' => t('Teaser'),
270 * Implements hook_entity_form_mode_info_alter().
272 function entity_test_entity_form_mode_info_alter(&$form_modes) {
273 $entity_info = \Drupal::entityManager()->getDefinitions();
274 foreach ($entity_info as $entity_type => $info) {
275 if ($entity_info[$entity_type]->getProvider() == 'entity_test') {
276 $form_modes[$entity_type] = [
278 'label' => t('Compact version'),
287 * Implements hook_entity_extra_field_info().
289 function entity_test_entity_extra_field_info() {
290 $extra['entity_test']['bundle_with_extra_fields'] = [
292 // Note: those extra fields do not currently display anything, they are
293 // just used in \Drupal\Tests\field_ui\Kernel\EntityDisplayTest to test
294 // the behavior of entity display objects.
295 'display_extra_field' => [
296 'label' => t('Display extra field'),
297 'description' => t('An extra field on the display side.'),
301 'display_extra_field_hidden' => [
302 'label' => t('Display extra field (hidden)'),
303 'description' => t('An extra field on the display side, hidden by default.'),
313 * Implements hook_form_BASE_FORM_ID_alter().
315 function entity_test_form_entity_test_form_alter(&$form) {
316 switch (\Drupal::state()->get('entity_test.form.validate.test')) {
318 $form['#validate'][] = 'entity_test_form_entity_test_form_validate';
319 $form['#validate'][] = 'entity_test_form_entity_test_form_validate_check';
323 $form['actions']['submit']['#validate'][] = 'entity_test_form_entity_test_form_validate';
328 * Validation handler for the entity_test entity form.
330 function entity_test_form_entity_test_form_validate(array &$form, FormStateInterface $form_state) {
331 $form['#entity_test_form_validate'] = TRUE;
335 * Validation handler for the entity_test entity form.
337 function entity_test_form_entity_test_form_validate_check(array &$form, FormStateInterface $form_state) {
338 if (!empty($form['#entity_test_form_validate'])) {
339 \Drupal::state()->set('entity_test.form.validate.result', TRUE);
344 * Implements hook_form_BASE_FORM_ID_alter().
346 function entity_test_form_node_form_alter(&$form, FormStateInterface $form_state, $form_id) {
347 $langcode = $form_state->getFormObject()->getFormLangcode($form_state);
348 \Drupal::state()->set('entity_test.form_langcode', $langcode);
352 * Loads a test entity.
357 * A boolean indicating that the internal cache should be reset.
359 * @return \Drupal\entity_test\Entity\EntityTest
360 * The loaded entity object, or NULL if the entity cannot be loaded.
362 function entity_test_load($id, $reset = FALSE) {
363 $storage = \Drupal::entityTypeManager()->getStorage('entity_test');
365 $storage->resetCache([$id]);
367 return $storage->load($id);
371 * Loads a test entity.
376 * A boolean indicating that the internal cache should be reset.
378 * @return \Drupal\entity_test\Entity\EntityTestRev
379 * The loaded entity object, or NULL if the entity cannot be loaded.
381 function entity_test_rev_load($id, $reset = FALSE) {
382 $storage = \Drupal::entityTypeManager()->getStorage('entity_test_rev');
384 $storage->resetCache([$id]);
386 return $storage->load($id);
390 * Loads a test entity.
395 * A boolean indicating that the internal cache should be reset.
397 * @return \Drupal\entity_test\Entity\EntityTestMul
398 * The loaded entity object, or FALSE if the entity cannot be loaded.
400 function entity_test_mul_load($id, $reset = FALSE) {
401 $storage = \Drupal::entityTypeManager()->getStorage('entity_test_mul');
403 $storage->resetCache([$id]);
405 return $storage->load($id);
409 * Loads a test entity.
414 * A boolean indicating that the internal cache should be reset.
416 * @return \Drupal\entity_test\Entity\EntityTestMulRev
417 * The loaded entity object, or NULL if the entity cannot be loaded.
419 function entity_test_mulrev_load($id, $reset = FALSE) {
420 $storage = \Drupal::entityTypeManager()->getStorage('entity_test_mulrev');
422 $storage->resetCache([$id]);
424 return $storage->load($id);
428 * Implements hook_ENTITY_TYPE_insert() for 'entity_test'.
430 function entity_test_entity_test_insert($entity) {
431 if ($entity->name->value == 'fail_insert') {
432 throw new Exception("Test exception rollback.");
437 * Implements hook_entity_insert().
439 function entity_test_entity_insert(EntityInterface $entity) {
440 if ($entity->getEntityTypeId() == 'entity_test_mulrev' && $entity->label() == 'EntityLoadedRevisionTest') {
441 $entity->setNewRevision(FALSE);
447 * Implements hook_entity_update().
449 function entity_test_entity_update(EntityInterface $entity) {
450 if ($entity instanceof ContentEntityInterface) {
451 \Drupal::state()->set('entity_test.loadedRevisionId', $entity->getLoadedRevisionId());
456 * Implements hook_entity_field_access().
458 * @see \Drupal\system\Tests\Entity\FieldAccessTest::testFieldAccess()
460 function entity_test_entity_field_access($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
461 if ($field_definition->getName() == 'field_test_text') {
463 if ($items->value == 'no access value') {
464 return AccessResult::forbidden()->addCacheableDependency($items->getEntity());
466 elseif ($items->value == 'custom cache tag value') {
467 return AccessResult::allowed()->addCacheableDependency($items->getEntity())->addCacheTags(['entity_test_access:field_test_text']);
469 elseif ($operation == 'edit' && $items->value == 'no edit access value') {
470 return AccessResult::forbidden()->addCacheableDependency($items->getEntity());
474 if ($field = \Drupal::state()->get('views_field_access_test-field')) {
475 if ($field_definition->getName() === $field) {
476 $result = AccessResult::allowedIfHasPermission($account, 'view test entity field');
477 // For test purposes we want to actively deny access.
478 if ($result->isNeutral()) {
479 $result = AccessResult::forbidden();
486 return AccessResult::neutral();
490 * Implements hook_entity_field_access_alter().
492 * @see \Drupal\system\Tests\Entity\FieldAccessTest::testFieldAccess()
494 function entity_test_entity_field_access_alter(array &$grants, array $context) {
495 if ($context['field_definition']->getName() == 'field_test_text' && $context['items']->value == 'access alter value') {
496 $grants[':default'] = AccessResult::forbidden()->inheritCacheability($grants[':default'])->addCacheableDependency($context['items']->getEntity());
501 * Implements hook_entity_form_display_alter().
503 function entity_test_entity_form_display_alter(EntityFormDisplay $form_display, $context) {
504 // Make the field_test_text field 42 characters for entity_test_mul.
505 if ($context['entity_type'] == 'entity_test') {
506 if ($component_options = $form_display->getComponent('field_test_text')) {
507 $component_options['settings']['size'] = 42;
508 $form_display->setComponent('field_test_text', $component_options);
514 * Implements hook_entity_presave().
516 function entity_test_entity_presave(EntityInterface $entity) {
517 if (isset($GLOBALS['entity_test_throw_exception'])) {
518 throw new Exception('Entity presave exception', 1);
521 if ($entity->getEntityType()->id() == 'entity_view_display') {
522 $entity->setThirdPartySetting('entity_test', 'foo', 'bar');
527 * Implements hook_entity_predelete().
529 function entity_test_entity_predelete(EntityInterface $entity) {
530 if (isset($GLOBALS['entity_test_throw_exception'])) {
531 throw new Exception('Entity predelete exception', 2);
536 * Implements hook_entity_operation_alter().
538 function entity_test_entity_operation_alter(array &$operations, EntityInterface $entity) {
539 $valid_entity_type_ids = [
543 if (in_array($entity->getEntityTypeId(), $valid_entity_type_ids)) {
544 if (\Drupal::service('router.route_provider')->getRouteByName("entity.{$entity->getEntityTypeId()}.test_operation")) {
545 $operations['test_operation'] = [
546 'title' => format_string('Test Operation: @label', ['@label' => $entity->label()]),
547 'url' => Url::fromRoute("entity.{$entity->getEntityTypeId()}.test_operation", [$entity->getEntityTypeId() => $entity->id()]),
555 * Implements hook_entity_translation_create().
557 function entity_test_entity_translation_create(EntityInterface $translation) {
558 _entity_test_record_hooks('entity_translation_create', $translation->language()->getId());
562 * Implements hook_entity_translation_insert().
564 function entity_test_entity_translation_insert(EntityInterface $translation) {
565 _entity_test_record_hooks('entity_translation_insert', $translation->language()->getId());
569 * Implements hook_entity_translation_delete().
571 function entity_test_entity_translation_delete(EntityInterface $translation) {
572 _entity_test_record_hooks('entity_translation_delete', $translation->language()->getId());
576 * Implements hook_ENTITY_TYPE_translation_create() for 'entity_test_mul'.
578 function entity_test_entity_test_mul_translation_create(EntityInterface $translation) {
579 _entity_test_record_hooks('entity_test_mul_translation_create', $translation->language()->getId());
583 * Implements hook_ENTITY_TYPE_translation_insert() for 'entity_test_mul'.
585 function entity_test_entity_test_mul_translation_insert(EntityInterface $translation) {
586 _entity_test_record_hooks('entity_test_mul_translation_insert', $translation->language()->getId());
590 * Implements hook_ENTITY_TYPE_translation_delete() for 'entity_test_mul'.
592 function entity_test_entity_test_mul_translation_delete(EntityInterface $translation) {
593 _entity_test_record_hooks('entity_test_mul_translation_delete', $translation->language()->getId());
597 * Implements hook_ENTITY_TYPE_translation_create() for 'entity_test_mul_changed'.
599 function entity_test_entity_test_mul_changed_translation_create(EntityInterface $translation) {
600 _entity_test_record_hooks('entity_test_mul_changed_translation_create', $translation->language()->getId());
604 * Implements hook_ENTITY_TYPE_translation_insert() for 'entity_test_mul_changed'.
606 function entity_test_entity_test_mul_changed_translation_insert(EntityInterface $translation) {
607 _entity_test_record_hooks('entity_test_mul_changed_translation_insert', $translation->language()->getId());
611 * Implements hook_ENTITY_TYPE_translation_delete().
613 function entity_test_entity_test_mul_changed_translation_delete(EntityInterface $translation) {
614 _entity_test_record_hooks('entity_test_mul_changed_translation_delete', $translation->language()->getId());
618 * Implements hook_ENTITY_TYPE_translation_create().
620 function entity_test_entity_test_mulrev_translation_create(EntityInterface $translation) {
621 _entity_test_record_hooks('entity_test_mulrev_translation_create', $translation->language()->getId());
625 * Implements hook_ENTITY_TYPE_translation_insert().
627 function entity_test_entity_test_mulrev_translation_insert(EntityInterface $translation) {
628 _entity_test_record_hooks('entity_test_mulrev_translation_insert', $translation->language()->getId());
632 * Implements hook_ENTITY_TYPE_translation_delete() for 'entity_test_mulrev'.
634 function entity_test_entity_test_mulrev_translation_delete(EntityInterface $translation) {
635 _entity_test_record_hooks('entity_test_mulrev_translation_delete', $translation->language()->getId());
639 * Implements hook_ENTITY_TYPE_translation_create() for 'entity_test_mulrev_changed'.
641 function entity_test_entity_test_mulrev_changed_translation_create(EntityInterface $translation) {
642 _entity_test_record_hooks('entity_test_mulrev_changed_translation_create', $translation->language()->getId());
646 * Implements hook_ENTITY_TYPE_translation_insert() for 'entity_test_mulrev'.
648 function entity_test_entity_test_mulrev_changed_translation_insert(EntityInterface $translation) {
649 _entity_test_record_hooks('entity_test_mulrev_changed_translation_insert', $translation->language()->getId());
653 * Implements hook_ENTITY_TYPE_translation_delete().
655 function entity_test_entity_test_mulrev_changed_translation_delete(EntityInterface $translation) {
656 _entity_test_record_hooks('entity_test_mulrev_changed_translation_delete', $translation->language()->getId());
660 * Implements hook_ENTITY_TYPE_translation_create() for 'entity_test_mul_langcode_key'.
662 function entity_test_entity_test_mul_langcode_key_translation_create(EntityInterface $translation) {
663 _entity_test_record_hooks('entity_test_mul_langcode_key_translation_create', $translation->language()->getId());
667 * Implements hook_ENTITY_TYPE_translation_insert() for 'entity_test_mul_langcode_key'.
669 function entity_test_entity_test_mul_langcode_key_translation_insert(EntityInterface $translation) {
670 _entity_test_record_hooks('entity_test_mul_langcode_key_translation_insert', $translation->language()->getId());
674 * Implements hook_ENTITY_TYPE_translation_delete() for 'entity_test_mul_langcode_key'.
676 function entity_test_entity_test_mul_langcode_key_translation_delete(EntityInterface $translation) {
677 _entity_test_record_hooks('entity_test_mul_langcode_key_translation_delete', $translation->language()->getId());
681 * Field default value callback.
683 * @param \Drupal\Core\Entity\FieldableEntityInterface $entity
684 * The entity being created.
685 * @param \Drupal\Core\Field\FieldDefinitionInterface $definition
686 * The field definition.
689 * An array of default values, in the same format as the $default_value
692 * @see \Drupal\field\Entity\FieldConfig::$default_value
694 function entity_test_field_default_value(FieldableEntityInterface $entity, FieldDefinitionInterface $definition) {
695 // Include the field name and entity language in the generated values to check
696 // that they are correctly passed.
697 $string = $definition->getName() . '_' . $entity->language()->getId();
698 // Return a "default value" with multiple items.
701 'shape' => "shape:0:$string",
702 'color' => "color:0:$string",
705 'shape' => "shape:1:$string",
706 'color' => "color:1:$string",
712 * Helper function to be used to record hook invocations.
714 * @param string $hook
717 * Arbitrary data associated with the hook invocation.
719 function _entity_test_record_hooks($hook, $data) {
720 $state = \Drupal::state();
721 $key = 'entity_test.hooks';
722 $hooks = $state->get($key);
723 $hooks[$hook] = $data;
724 $state->set($key, $hooks);
728 * Implements hook_entity_prepare_view().
730 function entity_test_entity_prepare_view($entity_type, array $entities, array $displays) {
731 if ($entity_type == 'entity_test') {
732 foreach ($entities as $entity) {
733 /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
735 // Add a dummy field item attribute on field_test_text if it exists.
736 if ($entity->hasField('field_test_text') && $displays[$entity->bundle()]->getComponent('field_test_text')) {
737 foreach ($entity->get('field_test_text') as $item) {
738 $item->_attributes += ['data-field-item-attr' => 'foobar'];
742 // Add a dummy field item attribute on daterange fields if they exist.
743 $fields = $entity->getFieldDefinitions();
744 foreach ($fields as $field) {
745 if ($field->getType() === 'daterange') {
746 $item = $entity->get($field->getName());
747 $item->_attributes += ['data-field-item-attr' => 'foobar'];
755 * Implements hook_entity_display_build_alter().
757 function entity_test_entity_display_build_alter(&$build, $context) {
758 /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
759 $entity = $context['entity'];
760 if ($entity->getEntityTypeId() == 'entity_test' && $entity->bundle() == 'display_build_alter_bundle') {
761 $build['entity_display_build_alter']['#markup'] = 'Content added in hook_entity_display_build_alter for entity id ' . $entity->id();
766 * Implements hook_entity_access().
768 function entity_test_entity_access(EntityInterface $entity, $operation, AccountInterface $account) {
769 // Only apply to the 'entity_test' entities.
770 if ($entity->getEntityType()->getProvider() != 'entity_test') {
771 return AccessResult::neutral();
773 \Drupal::state()->set('entity_test_entity_access', TRUE);
775 // Attempt to allow access to entities with the title forbid_access,
776 // this will be overridden by
777 // \Drupal\entity_test\EntityTestAccessControlHandler::checkAccess().
778 if ($entity->label() == 'forbid_access') {
779 return AccessResult::allowed();
782 // Create specific labels to allow or deny access based on certain test
784 // @see \Drupal\KernelTests\Core\Entity\EntityAccessControlHandlerTest
785 if ($entity->label() == 'Accessible') {
786 return AccessResult::allowed();
788 if ($entity->label() == 'Inaccessible') {
789 return AccessResult::forbidden();
792 // Uncacheable because the access result depends on a State key-value pair and
793 // might therefore change at any time.
794 $condition = \Drupal::state()->get("entity_test_entity_access.{$operation}." . $entity->id(), FALSE);
795 return AccessResult::allowedIf($condition)->setCacheMaxAge(0);
799 * Implements hook_ENTITY_TYPE_access() for 'entity_test'.
801 function entity_test_entity_test_access(EntityInterface $entity, $operation, AccountInterface $account) {
802 \Drupal::state()->set('entity_test_entity_test_access', TRUE);
805 return AccessResult::neutral();
809 * Implements hook_entity_create_access().
811 function entity_test_entity_create_access(AccountInterface $account, $context, $entity_bundle) {
812 \Drupal::state()->set('entity_test_entity_create_access', TRUE);
813 \Drupal::state()->set('entity_test_entity_create_access_context', $context);
816 return AccessResult::neutral();
820 * Implements hook_ENTITY_TYPE_create_access() for 'entity_test'.
822 function entity_test_entity_test_create_access(AccountInterface $account, $context, $entity_bundle) {
823 \Drupal::state()->set('entity_test_entity_test_create_access', TRUE);
826 return AccessResult::neutral();
830 * Implements hook_query_entity_test_access_alter().
832 function entity_test_query_entity_test_access_alter(AlterableInterface $query) {
833 if (!\Drupal::state()->get('entity_test_query_access')) {
837 /** @var \Drupal\Core\Database\Query\Select|\Drupal\Core\Database\Query\AlterableInterface $query */
838 if (!\Drupal::currentUser()->hasPermission('view all entity_test_query_access entities')) {
839 $query->condition('entity_test_query_access.name', 'published entity');