From 6f0f2212a7c6fa33547bf165fd046001e9f69869 Mon Sep 17 00:00:00 2001 From: Andrei Mateescu <andrei@amateescu.me> Date: Tue, 31 May 2022 20:32:11 +0300 Subject: [PATCH] Make the list of trash-enabled entity types configurable. --- README.md | 3 - config/install/trash.settings.yml | 1 + config/schema/trash.schema.yml | 8 ++ src/Entity/Query/QueryTrait.php | 10 +- src/EventSubscriber/TrashConfigSubscriber.php | 77 +++++++++++ src/Form/TrashSettingsForm.php | 130 ++++++++++++++++++ src/TrashEntityTypeManager.php | 11 +- src/TrashManager.php | 107 ++++++++++++++ src/TrashManagerInterface.php | 52 +++++++ src/TrashStorageTrait.php | 2 +- src/ViewsQueryAlter.php | 8 +- .../trash_test/src/Entity/TrashTest.php | 12 -- tests/src/Kernel/EntityQueryTest.php | 4 +- tests/src/Kernel/TrashKernelTest.php | 4 +- tests/src/Kernel/TrashKernelTestBase.php | 8 +- trash.install | 37 ----- trash.module | 48 +------ trash.services.yml | 10 ++ 18 files changed, 413 insertions(+), 119 deletions(-) create mode 100644 config/install/trash.settings.yml create mode 100644 config/schema/trash.schema.yml create mode 100644 src/EventSubscriber/TrashConfigSubscriber.php create mode 100644 src/Form/TrashSettingsForm.php create mode 100644 src/TrashManager.php create mode 100644 src/TrashManagerInterface.php diff --git a/README.md b/README.md index 8e620b2..fec02eb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,3 @@ -## Core patch(es) needed -* https://www.drupal.org/project/drupal/issues/3065207 - ## Areas to work on * Storage: diff --git a/config/install/trash.settings.yml b/config/install/trash.settings.yml new file mode 100644 index 0000000..798f8c3 --- /dev/null +++ b/config/install/trash.settings.yml @@ -0,0 +1 @@ +enabled_entity_types: { } diff --git a/config/schema/trash.schema.yml b/config/schema/trash.schema.yml new file mode 100644 index 0000000..f7ec0d9 --- /dev/null +++ b/config/schema/trash.schema.yml @@ -0,0 +1,8 @@ +trash.settings: + type: config_object + mapping: + enabled_entity_types: + label: Enabled entity types + type: sequence + sequence: + type: string diff --git a/src/Entity/Query/QueryTrait.php b/src/Entity/Query/QueryTrait.php index 6a471b5..140c5b5 100644 --- a/src/Entity/Query/QueryTrait.php +++ b/src/Entity/Query/QueryTrait.php @@ -38,14 +38,12 @@ trait QueryTrait { public function prepare() { parent::prepare(); - if (!in_array($this->entityTypeId, _trash_supported_entity_types(), TRUE)) { + if (!\Drupal::service('trash.manager')->isEntityTypeEnabled($this->entityType)) { return $this; } - assert($this->entityType->hasKey('deleted')); - $revision_key = $this->entityType->getKey('revision'); - $deleted_key = $this->entityType->getKey('deleted'); + $deleted_key = 'deleted'; $skip_deleted_filter = FALSE; // Skip adding a deleted flag for revisions as well as an explicit filter // on deleted, so you can still list deleted content, if needed. @@ -64,10 +62,10 @@ trait QueryTrait { // @todo Do we need support for listing deleted and not deleted entities // at the same time? if ($this->isDeleted) { - $this->condition($deleted_key, 0, '>'); + $this->exists($deleted_key); } else { - $this->condition($deleted_key, 0); + $this->notExists($deleted_key); } } return $this; diff --git a/src/EventSubscriber/TrashConfigSubscriber.php b/src/EventSubscriber/TrashConfigSubscriber.php new file mode 100644 index 0000000..bab82b1 --- /dev/null +++ b/src/EventSubscriber/TrashConfigSubscriber.php @@ -0,0 +1,77 @@ +<?php + +namespace Drupal\trash\EventSubscriber; + +use Drupal\Core\Config\ConfigCrudEvent; +use Drupal\Core\Config\ConfigEvents; +use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\trash\TrashManagerInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * Listens to the config save event for trash.settings. + */ +class TrashConfigSubscriber implements EventSubscriberInterface { + + /** + * The entity type manager. + * + * @var \Drupal\Core\Entity\EntityTypeManagerInterface + */ + protected $entityTypeManager; + + /** + * The Trash manager. + * + * @var \Drupal\trash\TrashManagerInterface + */ + protected $trashManager; + + /** + * Constructs the TrashConfigSubscriber. + * + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager + * The entity type manager. + * @param \Drupal\trash\TrashManagerInterface $trash_manager + * The trash manager. + */ + public function __construct(EntityTypeManagerInterface $entity_type_manager, TrashManagerInterface $trash_manager) { + $this->entityTypeManager = $entity_type_manager; + $this->trashManager = $trash_manager; + } + + /** + * Updates entity type definitions and ensures routes are rebuilt when needed. + * + * @param \Drupal\Core\Config\ConfigCrudEvent $event + * The ConfigCrudEvent to process. + */ + public function onSave(ConfigCrudEvent $event) { + $entity_types = $this->entityTypeManager->getDefinitions(); + if ($event->getConfig()->getName() === 'trash.settings' && $event->isChanged('enabled_entity_types')) { + $enabled_entity_types = $event->getConfig()->get('enabled_entity_types'); + $original_enabled_entity_types = $event->getConfig()->getOriginal('enabled_entity_types') ?? []; + + foreach ($enabled_entity_types as $entity_type_id) { + if (!in_array($entity_type_id, $original_enabled_entity_types, TRUE)) { + $this->trashManager->enableEntityType($entity_types[$entity_type_id]); + } + } + + foreach ($original_enabled_entity_types as $entity_type_id) { + if (!in_array($entity_type_id, $enabled_entity_types, TRUE)) { + $this->trashManager->disableEntityType($entity_types[$entity_type_id]); + } + } + } + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + $events[ConfigEvents::SAVE][] = ['onSave']; + return $events; + } + +} diff --git a/src/Form/TrashSettingsForm.php b/src/Form/TrashSettingsForm.php new file mode 100644 index 0000000..b007f87 --- /dev/null +++ b/src/Form/TrashSettingsForm.php @@ -0,0 +1,130 @@ +<?php + +namespace Drupal\trash\Form; + +use Drupal\Core\Config\ConfigFactoryInterface; +use Drupal\Core\Entity\EntityFieldManagerInterface; +use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Entity\Sql\SqlEntityStorageInterface; +use Drupal\Core\Form\ConfigFormBase; +use Drupal\Core\Form\FormStateInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * Configure Trash settings for this site. + */ +class TrashSettingsForm extends ConfigFormBase { + + /** + * The entity type manager. + * + * @var \Drupal\Core\Entity\EntityTypeManagerInterface + */ + protected $entityTypeManager; + + /** + * The entity field manager. + * + * @var \Drupal\Core\Entity\EntityFieldManagerInterface + */ + protected $entityFieldManager; + + /** + * Constructs a PathautoSettingsForm. + * + * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory + * Defines the configuration object factory. + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager + * Manages entity type plugin definitions. + * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager + * Manages the discovery of entity fields. + */ + public function __construct(ConfigFactoryInterface $config_factory, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager) { + parent::__construct($config_factory); + $this->entityTypeManager = $entity_type_manager; + $this->entityFieldManager = $entity_field_manager; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('config.factory'), + $container->get('entity_type.manager'), + $container->get('entity_field.manager')); + } + + /** + * {@inheritdoc} + */ + public function getFormId() { + return 'trash_settings_form'; + } + + /** + * {@inheritdoc} + */ + protected function getEditableConfigNames() { + return ['trash.settings']; + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state) { + $config = $this->config('trash.settings'); + + $form['enabled_entity_types'] = [ + '#type' => 'details', + '#open' => TRUE, + '#title' => $this->t('Enabled entity types'), + '#description' => $this->t('Enable to add a deleted field and allow to define alias patterns for the given type. Disabled types already define a path field themselves or currently have a pattern.'), + '#tree' => TRUE, + ]; + + // Get all applicable entity types. + foreach ($this->entityTypeManager->getDefinitions() as $entity_type_id => $entity_type) { + if (is_subclass_of($entity_type->getStorageClass(), SqlEntityStorageInterface::class)) { + $field_definitions = $this->entityFieldManager->getBaseFieldDefinitions($entity_type_id); + $form['enabled_entity_types'][$entity_type_id] = [ + '#type' => 'checkbox', + '#title' => $entity_type->getLabel(), + '#default_value' => isset($field_definitions['deleted']) || in_array($entity_type_id, $config->get('enabled_entity_types')), + '#disabled' => isset($field_definitions['deleted']) && ($field_definitions['deleted']->getProvider() !== 'trash'), + ]; + } + } + + return parent::buildForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + $config = $this->config('trash.settings'); + $form_state->cleanValues(); + + foreach ($form_state->getValues() as $key => $value) { + if ($key == 'enabled_entity_types') { + $enabled_entity_types = []; + foreach ($value as $entity_type_id => $enabled) { + $field_definitions = $this->entityFieldManager->getBaseFieldDefinitions($entity_type_id); + // Verify that the entity type is enabled and that it is not defined + // or defined by us before adding it to the configuration, so that + // we do not store an entity type that cannot be enabled or disabled. + if ($enabled && (!isset($field_definitions['deleted']) || ($field_definitions['deleted']->getProvider() === 'trash'))) { + $enabled_entity_types[] = $entity_type_id; + } + } + $value = $enabled_entity_types; + } + $config->set($key, $value); + } + $config->save(); + + parent::submitForm($form, $form_state); + } + +} diff --git a/src/TrashEntityTypeManager.php b/src/TrashEntityTypeManager.php index ffdad88..3cc95cc 100644 --- a/src/TrashEntityTypeManager.php +++ b/src/TrashEntityTypeManager.php @@ -5,7 +5,6 @@ namespace Drupal\trash; use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\PhpStorage\PhpStorageFactory; use Drupal\Core\Plugin\DefaultPluginManager; use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -22,13 +21,6 @@ class TrashEntityTypeManager extends DefaultPluginManager implements EntityTypeM */ protected $entityTypeManager; - /** - * The PhpStorage object used for storing the generated storage classes. - * - * @var \Drupal\Component\PhpStorage\PhpStorageInterface - */ - protected $storage; - /** * Contains instantiated storage handlers keyed by entity type. * @@ -41,7 +33,6 @@ class TrashEntityTypeManager extends DefaultPluginManager implements EntityTypeM */ public function __construct(EntityTypeManagerInterface $entity_type_manager) { $this->entityTypeManager = $entity_type_manager; - $this->storage = PhpStorageFactory::get('trash'); } /** @@ -170,7 +161,7 @@ class TrashEntityTypeManager extends DefaultPluginManager implements EntityTypeM * {@inheritdoc} */ public function createHandlerInstance($class, EntityTypeInterface $definition = NULL) { - if ($definition->hasKey('deleted')) { + if (\Drupal::service('trash.manager')->isEntityTypeEnabled($definition)) { $class = _trash_generate_storage_class($class); } diff --git a/src/TrashManager.php b/src/TrashManager.php new file mode 100644 index 0000000..887a888 --- /dev/null +++ b/src/TrashManager.php @@ -0,0 +1,107 @@ +<?php + +namespace Drupal\trash; + +use Drupal\Core\Config\ConfigFactoryInterface; +use Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface; +use Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface; +use Drupal\Core\Entity\EntityTypeInterface; +use Drupal\Core\Entity\Sql\SqlEntityStorageInterface; +use Drupal\Core\Field\BaseFieldDefinition; + +/** + * Provides the Trash manager. + */ +class TrashManager implements TrashManagerInterface { + + /** + * The entity definition update manager. + * + * @var \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface + */ + protected $entityDefinitionUpdateManager; + + /** + * The last installed schema definitions. + * + * @var \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface + */ + protected $entityLastInstalledSchemaRepository; + + /** + * The config factory service. + * + * @var \Drupal\Core\Config\ConfigFactoryInterface + */ + protected $configFactory; + + /** + * Constructs a new TrashManager. + * + * @param \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface $entity_definition_update_manager + * The entity definition update manager. + * @param \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface $entity_last_installed_schema_repository + * The last installed schema repository service. + * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory + * The config factory service. + */ + public function __construct(EntityDefinitionUpdateManagerInterface $entity_definition_update_manager, EntityLastInstalledSchemaRepositoryInterface $entity_last_installed_schema_repository, ConfigFactoryInterface $config_factory) { + $this->entityDefinitionUpdateManager = $entity_definition_update_manager; + $this->entityLastInstalledSchemaRepository = $entity_last_installed_schema_repository; + $this->configFactory = $config_factory; + } + + /** + * {@inheritdoc} + */ + public function isEntityTypeSupported(EntityTypeInterface $entity_type) : bool { + return is_subclass_of($entity_type->getStorageClass(), SqlEntityStorageInterface::class); + } + + /** + * {@inheritdoc} + */ + public function isEntityTypeEnabled(EntityTypeInterface $entity_type) : bool { + return in_array($entity_type->id(), $this->configFactory->get('trash.settings')->get('enabled_entity_types'), TRUE); + } + + /** + * {@inheritdoc} + */ + public function enableEntityType(EntityTypeInterface $entity_type) { + $field_storage_definitions = $this->entityLastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions($entity_type->id()); + + if (!$this->isEntityTypeSupported($entity_type)) { + throw new \InvalidArgumentException("Trash integration can not be enabled for the {$entity_type->id()} entity type."); + } + + if (isset($field_storage_definitions['deleted'])) { + if ($field_storage_definitions['deleted']->getProvider() !== 'trash') { + throw new \InvalidArgumentException("The {$entity_type->id()} entity type already has a 'deleted' field."); + } + else { + throw new \InvalidArgumentException("Trash integration is already enabled for the {$entity_type->id()} entity type."); + } + } + + $storage_definition = BaseFieldDefinition::create('timestamp') + ->setLabel(t('Deleted')) + ->setDescription(t('Time when the item got deleted')) + ->setInternal(TRUE) + ->setTranslatable(FALSE) + ->setRevisionable(TRUE); + + $this->entityDefinitionUpdateManager->installFieldStorageDefinition('deleted', $entity_type->id(), 'trash', $storage_definition); + } + + /** + * {@inheritdoc} + */ + public function disableEntityType(EntityTypeInterface $entity_type) { + $field_storage_definitions = $this->entityLastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions($entity_type->id()); + if (isset($field_storage_definitions['deleted'])) { + $this->entityDefinitionUpdateManager->uninstallFieldStorageDefinition($field_storage_definitions['deleted']); + } + } + +} diff --git a/src/TrashManagerInterface.php b/src/TrashManagerInterface.php new file mode 100644 index 0000000..0837b2f --- /dev/null +++ b/src/TrashManagerInterface.php @@ -0,0 +1,52 @@ +<?php + +namespace Drupal\trash; + +use Drupal\Core\Entity\EntityTypeInterface; + +/** + * Provides an interface for the Trash manager. + */ +interface TrashManagerInterface { + + /** + * Determines whether an entity type is supported by Trash. + * + * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type + * An entity type object. + * + * @return bool + */ + public function isEntityTypeSupported(EntityTypeInterface $entity_type) : bool; + + /** + * Determines whether Trash integration is enabled for an entity type. + * + * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type + * An entity type object. + * + * @return bool + */ + public function isEntityTypeEnabled(EntityTypeInterface $entity_type) : bool; + + /** + * Enables Trash integration for an entity type. + * + * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type + * An entity type object. + * + * @throws \InvalidArgumentException + * Thrown when Trash integration can not be enabled or is already enabled + * for an entity type. + */ + public function enableEntityType(EntityTypeInterface $entity_type); + + /** + * Disables Trash integration for an entity type. + * + * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type + * An entity type object. + */ + public function disableEntityType(EntityTypeInterface $entity_type); + +} diff --git a/src/TrashStorageTrait.php b/src/TrashStorageTrait.php index 86962be..e4b4b9d 100644 --- a/src/TrashStorageTrait.php +++ b/src/TrashStorageTrait.php @@ -8,7 +8,7 @@ trait TrashStorageTrait { * {@inheritdoc} */ public function delete(array $entities) { - $field_name = $this->getEntityType()->getKey('deleted'); + $field_name = 'deleted'; $revisionable = $this->getEntityType()->isRevisionable(); foreach ($entities as $entity) { diff --git a/src/ViewsQueryAlter.php b/src/ViewsQueryAlter.php index 126f2d7..33576f7 100644 --- a/src/ViewsQueryAlter.php +++ b/src/ViewsQueryAlter.php @@ -102,7 +102,7 @@ class ViewsQueryAlter implements ContainerInjectionInterface { $entity_type_definitions = $this->entityTypeManager->getDefinitions(); foreach ($entity_type_ids as $entity_type_id) { - if (in_array($entity_type_id, _trash_supported_entity_types(), TRUE)) { + if (\Drupal::service('trash.manager')->isEntityTypeEnabled($entity_type_definitions[$entity_type_id])) { $this->alterQueryForEntityType($query, $entity_type_definitions[$entity_type_id]); } } @@ -120,7 +120,7 @@ class ViewsQueryAlter implements ContainerInjectionInterface { * The entity type definition. */ protected function alterQueryForEntityType(Sql $query, EntityTypeInterface $entity_type) { - $table_mapping = $this->entityTypeManager->getStorage($entity_type->id())->getTableMapping(); + $table_mapping = $this->entityTypeManager->getStorage($entity_type->id())->getTableMapping(); assert($table_mapping instanceof DefaultTableMapping); $field_storage_definitions = $this->entityFieldManager->getFieldStorageDefinitions($entity_type->id()); @@ -129,8 +129,8 @@ class ViewsQueryAlter implements ContainerInjectionInterface { // Try to find out whether any filter (normal or conditional filter) filters // by the delete column. In case it does opt out of adding a specific // delete column. - $deleted_table_name = $table_mapping->getFieldTableName($entity_type->getKey('deleted')); - $deleted_table_column = $table_mapping->getFieldColumnName($field_storage_definitions[$entity_type->getKey('deleted')], 'value'); + $deleted_table_name = $table_mapping->getFieldTableName('deleted'); + $deleted_table_column = $table_mapping->getFieldColumnName($field_storage_definitions['deleted'], 'value'); foreach ($query->where as $group_index => $group) { if (!empty($group['conditions'])) { foreach ($group['conditions'] as $condition_index => $condition) { diff --git a/tests/modules/trash_test/src/Entity/TrashTest.php b/tests/modules/trash_test/src/Entity/TrashTest.php index c2b9ee3..03010d8 100644 --- a/tests/modules/trash_test/src/Entity/TrashTest.php +++ b/tests/modules/trash_test/src/Entity/TrashTest.php @@ -30,7 +30,6 @@ use Drupal\Core\Entity\ContentEntityBase; * "revision" = "revision", * "label" = "label", * "uuid" = "uuid", - * "deleted" = "deleted", * }, * links = { * "canonical" = "/trash_test/{trash_test}", @@ -41,15 +40,4 @@ use Drupal\Core\Entity\ContentEntityBase; */ class TrashTest extends ContentEntityBase { - /** - * {@inheritdoc} - */ - public function getEntityKey($key) { - // Typically this protected method is used internally by entity classes and - // exposed publicly through more specific getter methods. So that test cases - // are able to set and access entity keys dynamically, update the visibility - // of this method to public. - return parent::getEntityKey($key); - } - } diff --git a/tests/src/Kernel/EntityQueryTest.php b/tests/src/Kernel/EntityQueryTest.php index cdc92a9..5e76ae8 100644 --- a/tests/src/Kernel/EntityQueryTest.php +++ b/tests/src/Kernel/EntityQueryTest.php @@ -67,7 +67,7 @@ class EntityQueryTest extends TrashKernelTestBase { $query = $entity_storage->getQuery(); assert($query instanceof Query); $query->accessCheck(FALSE); - $query->condition($entity_type->getKey('deleted'), 0, '>'); + $query->condition('deleted', 0, '>'); $this->assertCount(3, $query->execute()); // Try to fetch not deleted content. @@ -81,7 +81,7 @@ class EntityQueryTest extends TrashKernelTestBase { $query = $entity_storage->getQuery(); assert($query instanceof Query); $query->accessCheck(FALSE); - $query->condition($entity_type->getKey('deleted'), 0, '>'); + $query->condition('deleted', 0, '>'); $this->assertCount(3, $query->execute()); } diff --git a/tests/src/Kernel/TrashKernelTest.php b/tests/src/Kernel/TrashKernelTest.php index 44336b4..b29bfee 100644 --- a/tests/src/Kernel/TrashKernelTest.php +++ b/tests/src/Kernel/TrashKernelTest.php @@ -19,14 +19,14 @@ class TrashKernelTest extends TrashKernelTestBase { $entity->save(); $this->assertNotNull(TrashTest::load($entity->id())); - $this->assertEquals(0, $entity->getEntityKey('deleted')); + $this->assertEquals(0, $entity->get('deleted')->value); $entity->delete(); $entity = TrashTest::load($entity->id()); assert($entity instanceof ContentEntityInterface); $this->assertNotNull($entity, "Ensure that deleting an entity doesn't actually deletes it."); - $this->assertEquals(\Drupal::time()->getRequestTime(), $entity->getEntityKey('deleted')); + $this->assertEquals(\Drupal::time()->getRequestTime(), $entity->get('deleted')->value); } } diff --git a/tests/src/Kernel/TrashKernelTestBase.php b/tests/src/Kernel/TrashKernelTestBase.php index cdd425f..c49a7f1 100644 --- a/tests/src/Kernel/TrashKernelTestBase.php +++ b/tests/src/Kernel/TrashKernelTestBase.php @@ -22,8 +22,14 @@ abstract class TrashKernelTestBase extends KernelTestBase { protected function setUp() { parent::setUp(); + $this->installConfig(['trash', 'trash_test']); $this->installEntitySchema('trash_test_entity'); - $this->installConfig('trash_test'); + + $config = \Drupal::configFactory()->getEditable('trash.settings'); + $enabled_entity_types = $config->get('enabled_entity_types'); + $enabled_entity_types[] = 'trash_test_entity'; + $config->set('enabled_entity_types', $enabled_entity_types); + $config->save(); } } diff --git a/trash.install b/trash.install index 6b3aa28..6355a8f 100644 --- a/trash.install +++ b/trash.install @@ -4,40 +4,3 @@ * @file * Install, update, and uninstall functions for the Trash module. */ - -/** - * Implements hook_module_preinstall(). - */ -function trash_module_preinstall($module) { - if ($module !== 'trash') { - return; - } - - $entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager(); - foreach ($entity_definition_update_manager->getEntityTypes() as $entity_type) { - if (in_array($entity_type->id(), _trash_supported_entity_types(), TRUE)) { - $entity_keys = $entity_type->getKeys(); - if (!isset($entity_keys['deleted'])) { - $entity_keys['deleted'] = 'deleted'; - - $entity_type->set('entity_keys', $entity_keys); - $entity_definition_update_manager->updateEntityType($entity_type); - } - } - } -} - -/** - * Implements hook_uninstall(). - */ -function trash_uninstall() { - $entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager(); - foreach ($entity_definition_update_manager->getEntityTypes() as $entity_type) { - if (in_array($entity_type->id(), _trash_supported_entity_types(), TRUE)) { - $entity_keys = $entity_type->getKeys(); - unset($entity_keys['deleted']); - $entity_type->set('entity_keys', $entity_keys); - $entity_definition_update_manager->updateEntityType($entity_type); - } - } -} diff --git a/trash.module b/trash.module index d565a5f..c5b14c8 100644 --- a/trash.module +++ b/trash.module @@ -7,57 +7,23 @@ use Drupal\trash\ViewsQueryAlter; use Drupal\views\Plugin\views\query\QueryPluginBase; use Drupal\views\ViewExecutable; -/** - * Implements hook_entity_type_build(). - */ -function trash_entity_type_build(array &$entity_types) { - foreach ($entity_types as $entity_type) { - if (in_array($entity_type->id(), _trash_supported_entity_types(), TRUE)) { - // Add the required entity key. - $entity_keys = $entity_type->getKeys(); - if (!isset($entity_keys['deleted'])) { - $entity_keys['deleted'] = 'deleted'; - - $entity_type->set('entity_keys', $entity_keys); - } - } - } -} - /** * Implements hook_entity_base_field_info(). */ function trash_entity_base_field_info(EntityTypeInterface $entity_type) { // Add the 'deleted' base field. - /** @var \Drupal\Core\Entity\ContentEntityType $entity_type */ - if ($entity_type->hasKey('deleted')) { - $field_name = $entity_type->getKey('deleted'); - $base_field_definitions[$field_name] = BaseFieldDefinition::create('timestamp') - ->setLabel(t('Deleted')) - ->setDescription(t('Time when the item got deleted')) - ->setInternal(TRUE) - ->setTranslatable(FALSE) - ->setRevisionable(TRUE); + if (\Drupal::service('trash.manager')->isEntityTypeEnabled($entity_type)) { + $base_field_definitions['deleted'] = BaseFieldDefinition::create('timestamp') + ->setLabel(t('Deleted')) + ->setDescription(t('Time when the item got deleted')) + ->setInternal(TRUE) + ->setTranslatable(FALSE) + ->setRevisionable(TRUE); return $base_field_definitions; } } -/** - * Returns the entity types supported by the Trash module. - * - * @return array - */ -function _trash_supported_entity_types() { - // @todo How to expand this list? - return [ -// 'node', -// 'media', -// 'taxonomy_term', - 'trash_test_entity', - ]; -} - /** * Implements hook_views_query_alter(). */ diff --git a/trash.services.yml b/trash.services.yml index 45bbe31..dcbc7bc 100644 --- a/trash.services.yml +++ b/trash.services.yml @@ -1,4 +1,14 @@ services: + trash.manager: + class: Drupal\trash\TrashManager + arguments: ['@entity.definition_update_manager', '@entity.last_installed_schema.repository', '@config.factory'] + + trash.config_subscriber: + class: Drupal\trash\EventSubscriber\TrashConfigSubscriber + arguments: ['@entity_type.manager', '@trash.manager'] + tags: + - { name: event_subscriber } + trash.entity.query.sql: class: Drupal\trash\Entity\Query\Sql\QueryFactory public: false -- GitLab