From 5b3be42ee114dc118e937c282dbb5a7f2a06612a Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Tue, 23 Jul 2024 10:57:23 -0300 Subject: [PATCH 01/17] Missing use? --- islandora_spreadsheet_ingest.module | 1 + 1 file changed, 1 insertion(+) diff --git a/islandora_spreadsheet_ingest.module b/islandora_spreadsheet_ingest.module index 85762ee..1aa0f35 100644 --- a/islandora_spreadsheet_ingest.module +++ b/islandora_spreadsheet_ingest.module @@ -6,6 +6,7 @@ */ use Drupal\Component\Utility\NestedArray; +use Drupal\Core\Access\AccessResult; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Url; From e4d586631e5af558000ca097e30f66086652e5bc Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Tue, 23 Jul 2024 11:00:42 -0300 Subject: [PATCH 02/17] Dropped config, can render as content. --- islandora_spreadsheet_ingest.install | 54 ++++++++ src/BaseRequestInterface.php | 46 +++++++ src/Controller/RequestListBuilder.php | 6 +- src/Entity/Request.php | 187 ++++++++++++++------------ src/Form/Admin.php | 2 +- src/RequestInterface.php | 38 +----- src/RequestStorage.php | 9 ++ 7 files changed, 218 insertions(+), 124 deletions(-) create mode 100644 src/BaseRequestInterface.php create mode 100644 src/RequestStorage.php diff --git a/islandora_spreadsheet_ingest.install b/islandora_spreadsheet_ingest.install index dd4d4c6..21f24ed 100644 --- a/islandora_spreadsheet_ingest.install +++ b/islandora_spreadsheet_ingest.install @@ -5,6 +5,9 @@ * Installation hooks. */ +use Drupal\Core\Config\Entity\ConfigEntityType; +use Drupal\islandora_spreadsheet_ingest\Entity\Request; + /** * Drop old, disused tables. */ @@ -37,3 +40,54 @@ function islandora_spreadsheet_ingest_update_9001() { return t('The "isi_request" config entity is already installed.'); } } + +/** + * Replace config entity with content entity. + */ +function islandora_spreadsheet_ingest_update_9002() { + $etm = \Drupal::entityTypeManager(); + $upm = \Drupal::entityDefinitionUpdateManager(); + $config_entity_base_definition = [ + "label" => \t("Islandora Spreadsheet Ingest Request"), + "handlers" => [ + "list_builder" => "Drupal\islandora_spreadsheet_ingest\Controller\RequestListBuilder", + "form" => [ + "process" => "Drupal\islandora_spreadsheet_ingest\Form\Ingest\Review", + "add" => "Drupal\islandora_spreadsheet_ingest\Form\Ingest\FileUpload", + "delete" => "Drupal\islandora_spreadsheet_ingest\Form\RequestDeleteForm", + "edit" => "Drupal\islandora_spreadsheet_ingest\Form\Ingest\FileUpload", + "view" => "Drupal\islandora_spreadsheet_ingest\Form\Ingest\Review", + ], + "access" => "Drupal\islandora_spreadsheet_ingest\RequestAccessControlHandler", + "view_builder" => "Drupal\islandora_spreadsheet_ingest\RequestViewBuilder", + ], + "config_prefix" => "request", + "admin_permission" => "administer islandora_spreadsheet_ingest requests", + "entity_keys" => [ + "id" => "id", + "label" => "label", + ], + "config_export" => [ + "id", + "label", + "sheet", + "originalMapping", + "mappings", + "active", + "owner", + ], + "links" => [ + "canonical" => "/admin/content/islandora_spreadsheet_ingest/{isi_request}", + "process-form" => "/admin/content/islandora_spreadsheet_ingest/{isi_request}/process", + "edit-form" => "/admin/content/islandora_spreadsheet_ingest/{isi_request}/edit", + "map-form" => "/admin/content/islandora_spreadsheet_ingest/{isi_request}/mapping", + "delete-form" => "/admin/content/islandora_spreadsheet_ingest/{isi_request}/delete", + ], + ]; + $upm->uninstallEntityType(new class(['id' => 'isi_request'] + $config_entity_base_definition) extends ConfigEntityType { + + // All from the extended class. + }); + $definition = $etm->getDefinition('isi_request'); + $upm->installFieldableEntityType($definition, Request::baseFieldDefinitions($definition)); +} diff --git a/src/BaseRequestInterface.php b/src/BaseRequestInterface.php new file mode 100644 index 0000000..664ee85 --- /dev/null +++ b/src/BaseRequestInterface.php @@ -0,0 +1,46 @@ +toLink(NULL, 'edit-form'); if (!$row['label']->getUrl()->access()) { $row['label'] = $entity->label(); diff --git a/src/Entity/Request.php b/src/Entity/Request.php index f6fb2e1..df4771d 100644 --- a/src/Entity/Request.php +++ b/src/Entity/Request.php @@ -2,18 +2,23 @@ namespace Drupal\islandora_spreadsheet_ingest\Entity; -use Drupal\Core\Config\Entity\ConfigEntityBase; +use Drupal\Core\Entity\ContentEntityBase; +use Drupal\Core\Entity\EntityTypeInterface; +use Drupal\Core\Field\BaseFieldDefinition; use Drupal\islandora_spreadsheet_ingest\RequestInterface; +use Drupal\user\EntityOwnerInterface; +use Drupal\user\EntityOwnerTrait; /** * Defines the Request entity. * - * @ConfigEntityType( + * @ContentEntityType( * id = "isi_request", * label = @Translation("Islandora Spreadsheet Ingest Request"), * handlers = { * "list_builder" = "Drupal\islandora_spreadsheet_ingest\Controller\RequestListBuilder", * "form" = { + * "storage" = "Drupal\islandora_spreadsheet_ingest\RequestStorage", * "process" = "Drupal\islandora_spreadsheet_ingest\Form\Ingest\Review", * "add" = "Drupal\islandora_spreadsheet_ingest\Form\Ingest\FileUpload", * "delete" = "Drupal\islandora_spreadsheet_ingest\Form\RequestDeleteForm", @@ -23,20 +28,13 @@ * "access" = "Drupal\islandora_spreadsheet_ingest\RequestAccessControlHandler", * "view_builder" = "Drupal\islandora_spreadsheet_ingest\RequestViewBuilder", * }, - * config_prefix = "request", * admin_permission = "administer islandora_spreadsheet_ingest requests", + * base_table = "islandora_spreadsheet_ingest_request", + * data_table = "islandora_spreadsheet_ingest_request_data", * entity_keys = { * "id" = "id", * "label" = "label", - * }, - * config_export = { - * "id", - * "label", - * "sheet", - * "originalMapping", - * "mappings", - * "active", - * "owner", + * "owner" = "owner", * }, * links = { * "canonical" = "/admin/content/islandora_spreadsheet_ingest/{isi_request}", @@ -47,107 +45,48 @@ * } * ) */ -class Request extends ConfigEntityBase implements RequestInterface { - - /** - * The ID of the request. - * - * @var string - */ - protected $id; - - /** - * The request's label. - * - * @var string - */ - protected $label; - - /** - * Coordinates for where to find the particular worksheet. - * - * Includes: - * - sheet: The name of the worksheet. - * - file: An array of file IDs... though there should just be one. - * - * @var array - */ - protected $sheet; - - /** - * A representation of the original mapping. - * - * Should only ever be a "migration_group:*" kind of thing... - * - * @var string - */ - protected $originalMapping = 'migration_group:isi'; - - /** - * The associative array of mappings. - * - * Mapping migration names to: - * - original_migration_id: The name of the original migration - * - mappings: An associative array mapping field/property names to an - * associative array containing: - * - pipeline: The array of process plugin definitions. - * - * May be NULL if not yet set. - * - * @var array|null - */ - protected $mappings = NULL; +class Request extends ContentEntityBase implements EntityOwnerInterface, RequestInterface { - /** - * Whether this request should be eligible to be processed. - * - * @var bool - * - * @todo Review whether or not the core ConfigEntityBase's "status" may cover - * the same situation. - */ - protected $active = FALSE; - - /** - * The creator/owner of this request. - * - * @var string - */ - protected $owner = NULL; + use EntityOwnerTrait { + getOwner as traitGetOwner; + } /** * {@inheritdoc} */ public function getOriginalMapping() { - return $this->originalMapping; + return $this->get('original_mapping')->getValue(); } /** * {@inheritdoc} */ public function getActive() { - return $this->active; + return $this->get('active')->getValue(); } /** * {@inheritdoc} */ public function getSheet() { - return $this->sheet; + return [ + 'file' => $this->get('sheet_file')->getValue(), + 'sheet' => $this->get('sheet_sheet')->getValue(), + ]; } /** * {@inheritdoc} */ public function getMappings() { - return $this->mappings; + return $this->get('mappings')->getValue(); } /** * {@inheritdoc} */ public function getOwner() { - return $this->owner; + return $this->traitGetOwner()->id(); } /** @@ -159,7 +98,7 @@ public function calculateDependencies() { $storage = $this->entityTypeManager()->getStorage('migration'); // XXX: We expect the module to be accounted for in the "migration_group" - // config entity, an so need need deal with it specifically for the + // config entity, and so no need deal with it specifically for the // migration plugin. foreach (array_column($this->getMappings(), 'original_migration_id') as $original_migration_id) { if ($storage->load($original_migration_id)) { @@ -173,7 +112,7 @@ public function calculateDependencies() { break; default: - throw new Exception(strtr('Unknown type of original mapping: "!type"', [ + throw new \Exception(strtr('Unknown type of original mapping: "!type"', [ '!type' => $type, ])); @@ -182,4 +121,82 @@ public function calculateDependencies() { return $this; } + /** + * {@inheritDoc} + */ + public function set($name, $value, $notify = TRUE) { + if ($name === 'sheet') { + \trigger_deprecation('discoverygarden/islandora_spreadsheet_ingest', '4.0.0', 'Setting `sheet` directly is deprecated as of 4.0.0; instead set `sheet_file` and `sheet_sheet` individually.'); + return $this->set('sheet_file', $value['file'] ?? [], $notify) + ->set('sheet_sheet', $value['sheet'] ?? '', $notify); + } + if ($name === 'originalMapping') { + \trigger_deprecation('discoverygarden/islandora_spreadsheet_ingest', '4.0.0', '`originalMapping` has been renamed to `original_mapping` as of 4.0.0.'); + return $this->set('original_mapping', $value, $notify); + } + return parent::set($name, $value, $notify); + } + + /** + * {@inheritDoc} + */ + public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { + $fields = parent::baseFieldDefinitions($entity_type); + $fields += static::ownerBaseFieldDefinitions($entity_type); + + $fields['label'] = BaseFieldDefinition::create('string') + ->setLabel(\t('Title')) + ->setRequired(TRUE) + ->setTranslatable(FALSE) + ->setRevisionable(FALSE) + ->setSetting('max_length', 255) + ->setDisplayOptions('view', [ + 'label' => 'hidden', + 'type' => 'string', + 'weight' => -5, + ]) + ->setDisplayOptions('form', [ + 'type' => 'string_textfield', + 'weight' => -5, + ]) + ->setDisplayConfigurable('form', TRUE) + ->setCardinality(1); + $fields['machine_name'] = BaseFieldDefinition::create('string') + ->setLabel(\t('Machine Name')) + ->setRequired(TRUE) + ->setTranslatable(FALSE) + ->setRevisionable(FALSE) + ->setCardinality(1); + $fields['active'] = BaseFieldDefinition::create('boolean') + ->setLabel(\t('Label')) + ->setRequired(TRUE) + ->setCardinality(1) + ->setTranslatable(FALSE) + ->setRevisionable(FALSE); + $fields['sheet_file'] = BaseFieldDefinition::create('entity_reference') + ->setLabel(\t('Spreadsheet file')) + ->setRequired(TRUE) + ->setTranslatable(FALSE) + ->setRevisionable(FALSE) + ->setSetting('target_type', 'file') + ->setDisplayOptions('form', [ + 'type' => 'file_generic', + ]) + ->setCardinality(1); + $fields['sheet_sheet'] = BaseFieldDefinition::create('string') + ->setLabel(\t('Worksheet')) + ->setDescription(\t('The specific worksheet if the file corresponds to an ODS/XLSX which is possible of containing multiple.')) + ->setCardinality(1); + $fields['mappings'] = BaseFieldDefinition::create('map') + ->setLabel(\t('Mappings')) + ->setDescription(\t('Migration mappings')) + ->setCardinality(1); + $fields['original_mapping'] = BaseFieldDefinition::create('string') + ->setLabel(\t('Original mapping')) + ->setDescription(\t('Original migration template')) + ->setCardinality(1); + + return $fields; + } + } diff --git a/src/Form/Admin.php b/src/Form/Admin.php index 2af89d7..2343bc1 100644 --- a/src/Form/Admin.php +++ b/src/Form/Admin.php @@ -50,7 +50,7 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - $form = []; + //$form = []; $config = $this->config('islandora_spreadsheet_ingest.settings'); $current_whitelist = $config->get('binary_directory_whitelist'); $form['schemes'] = [ diff --git a/src/RequestInterface.php b/src/RequestInterface.php index faf44ca..4f3551d 100644 --- a/src/RequestInterface.php +++ b/src/RequestInterface.php @@ -2,45 +2,11 @@ namespace Drupal\islandora_spreadsheet_ingest; -use Drupal\Core\Config\Entity\ConfigEntityInterface; +use Drupal\Core\Entity\ContentEntityInterface; /** * Request config entity interface. */ -interface RequestInterface extends ConfigEntityInterface { - - /** - * Get the sheet to process. - * - * @return array - * An associative array containing: - * - file: An array of file IDs. - * - sheet: A string indicating which sheet of the sheet should be used. May - * be the empty string for things for which it is not relevent, like CSV. - */ - public function getSheet(); - - /** - * Get the migration mappings. - * - * @return array - * An associative array mapping migration names to associative arrays - * containing: - * - original_migration_id: A string indicating the name of the original - * migration. - * - mappings: An associative array mapping destination field names to - * associative arrays containing: - * - pipeline: An array of migration process plugin definitions to be - * executed to produce the given field. - */ - public function getMappings(); - - /** - * Get the status of the given item, whether or not it is active. - * - * @return bool - * TRUE if active; otherwise, FALSE. - */ - public function getActive(); +interface RequestInterface extends BaseRequestInterface, ContentEntityInterface { } diff --git a/src/RequestStorage.php b/src/RequestStorage.php new file mode 100644 index 0000000..4e058bd --- /dev/null +++ b/src/RequestStorage.php @@ -0,0 +1,9 @@ + Date: Tue, 23 Jul 2024 15:25:16 -0300 Subject: [PATCH 03/17] Consistent entity use. --- islandora_spreadsheet_ingest.routing.yml | 16 ++++++ islandora_spreadsheet_ingest.services.yml | 7 +++ src/Entity/Request.php | 10 ++-- src/Form/Ingest/FileUpload.php | 19 ++++---- src/MigrationDeriver.php | 9 ++-- src/Routing/RequestParamConverter.php | 59 +++++++++++++++++++++++ 6 files changed, 103 insertions(+), 17 deletions(-) create mode 100644 src/Routing/RequestParamConverter.php diff --git a/islandora_spreadsheet_ingest.routing.yml b/islandora_spreadsheet_ingest.routing.yml index 4609ac6..dfe8801 100644 --- a/islandora_spreadsheet_ingest.routing.yml +++ b/islandora_spreadsheet_ingest.routing.yml @@ -20,6 +20,10 @@ entity.isi_request.edit_form: _entity_form: 'isi_request.edit' requirements: _entity_access: 'isi_request.update' + options: + parameters: + isi_request: + type: islandora_spreadsheet_ingest_request entity.isi_request.delete_form: path: '/admin/content/islandora_spreadsheet_ingest/{isi_request}/delete' defaults: @@ -27,12 +31,20 @@ entity.isi_request.delete_form: _entity_form: 'isi_request.delete' requirements: _entity_access: 'isi_request.delete' + options: + parameters: + isi_request: + type: islandora_spreadsheet_ingest_request entity.isi_request.canonical: path: '/admin/content/islandora_spreadsheet_ingest/{isi_request}' defaults: _entity_view: 'isi_request.full' requirements: _entity_access: 'isi_request.view' + options: + parameters: + isi_request: + type: islandora_spreadsheet_ingest_request entity.isi_request.process_form: path: '/admin/content/islandora_spreadsheet_ingest/{isi_request}/process' defaults: @@ -40,6 +52,10 @@ entity.isi_request.process_form: _entity_form: 'isi_request.process' requirements: _entity_access: 'isi_request.activate' + options: + parameters: + isi_request: + type: islandora_spreadsheet_ingest_request islandora_spreadsheet_ingest.admin: path: '/admin/config/islandora_spreadsheet_ingest' defaults: diff --git a/islandora_spreadsheet_ingest.services.yml b/islandora_spreadsheet_ingest.services.yml index f8da1b7..0adb6f4 100644 --- a/islandora_spreadsheet_ingest.services.yml +++ b/islandora_spreadsheet_ingest.services.yml @@ -33,3 +33,10 @@ services: arguments: - isi_deferred_ingest - true + islandora_spreadsheet_ingest.param_converter.request: + class: Drupal\islandora_spreadsheet_ingest\Routing\RequestParamConverter + factory: [null, 'create'] + arguments: + - '@service_container' + tags: + - { name: paramconverter } diff --git a/src/Entity/Request.php b/src/Entity/Request.php index df4771d..f18ba80 100644 --- a/src/Entity/Request.php +++ b/src/Entity/Request.php @@ -55,14 +55,14 @@ class Request extends ContentEntityBase implements EntityOwnerInterface, Request * {@inheritdoc} */ public function getOriginalMapping() { - return $this->get('original_mapping')->getValue(); + return $this->get('original_mapping')->getString(); } /** * {@inheritdoc} */ public function getActive() { - return $this->get('active')->getValue(); + return $this->get('active')->first()->getValue()['value']; } /** @@ -70,8 +70,8 @@ public function getActive() { */ public function getSheet() { return [ - 'file' => $this->get('sheet_file')->getValue(), - 'sheet' => $this->get('sheet_sheet')->getValue(), + 'file' => [$this->get('sheet_file')->first()->getString()], + 'sheet' => $this->get('sheet_sheet')->first()->getString(), ]; } @@ -79,7 +79,7 @@ public function getSheet() { * {@inheritdoc} */ public function getMappings() { - return $this->get('mappings')->getValue(); + return $this->get('mappings')->first()->getValue(); } /** diff --git a/src/Form/Ingest/FileUpload.php b/src/Form/Ingest/FileUpload.php index 52d13bb..2128cf4 100644 --- a/src/Form/Ingest/FileUpload.php +++ b/src/Form/Ingest/FileUpload.php @@ -174,9 +174,9 @@ public function form(array $form, FormStateInterface $form_state) { '#description' => $this->t("Label for the Example."), '#required' => TRUE, ]; - $form['id'] = [ + $form['machine_name'] = [ '#type' => 'machine_name', - '#default_value' => $entity->id(), + '#default_value' => $entity->get('machine_name')->getString(), '#disabled' => !$entity->isNew(), '#machine_name' => [ 'exists' => [$this, 'exist'], @@ -261,14 +261,15 @@ protected function builder($entity_type_id, RequestInterface $request, array &$f // Copy/transform the info from the target. [$original, $mapped] = $this->mapMappings($request->getOriginalMapping()); $request->set('mappings', $mapped); - $request->set('originalMapping', $original); - $request->set('sheet', [ - 'file' => ($form_state->getValue(['sheet', 'file', 'fids']) ?? - $form_state->getValue(['sheet', 'file'])), - 'sheet' => $form_state->getValue(['sheet', 'sheet']), - ]); + $request->set('original_mapping', $original); + $request->set( + 'sheet_file', + $form_state->getValue(['sheet', 'file', 'fids']) ?? $form_state->getValue(['sheet', 'file']), + ); + $request->set('sheet_sheet', $form_state->getValue(['sheet', 'sheet'])); $request->set('owner', $this->currentUser()->id()); $request->set('active', TRUE); + $request->set('machine_name', $form_state->getValue('machine_name')); } /** @@ -306,7 +307,7 @@ public function exist($id) { // existence of other requests; however, unsure if we are particularly // concerned. ->accessCheck(FALSE) - ->condition('id', $id) + ->condition('machine_name', $id) ->execute(); return (bool) $entity; } diff --git a/src/MigrationDeriver.php b/src/MigrationDeriver.php index cefdf4b..612fe91 100644 --- a/src/MigrationDeriver.php +++ b/src/MigrationDeriver.php @@ -71,7 +71,7 @@ public function __construct( EntityTypeManagerInterface $entity_type_manager, CacheTagsInvalidatorInterface $invalidator, MigrationGroupDeriverInterface $migration_group_deriver, - MigrationPluginManagerInterface $migration_plugin_manager + MigrationPluginManagerInterface $migration_plugin_manager, ) { $this->logger = $logger; $this->entityTypeManager = $entity_type_manager; @@ -275,7 +275,7 @@ protected function mapPipelineMigrations(array $processes, MigrationInterface $m * {@inheritdoc} */ public function createAll(RequestInterface $request) { - if (!$request->status() || !$request->getActive()) { + if (!$request->getActive()) { $this->logger->info('Call to create on non-active request {id}.', ['id' => $request->id()]); return; } @@ -336,12 +336,15 @@ public function createAll(RequestInterface $request) { */ public function deleteAll(RequestInterface $request) { // Nuke the storage for the given mgiration group. + /** @var \Drupal\migrate_plus\Entity\MigrationInterface[] $migrations */ $migrations = $this->migrationStorage->loadByProperties([ 'migration_group' => $this->migrationGroupDeriver->deriveName($request), ]); // Nuke the message and map tables for the given migrations. - foreach ($migrations as $migration) { + foreach ($migrations as $migration_entity) { + /** @var \Drupal\migrate\Plugin\MigrationInterface $migration */ + $migration = $this->migrationPluginManager->createInstance($migration_entity->id()); $migration->getIdMap()->destroy(); } diff --git a/src/Routing/RequestParamConverter.php b/src/Routing/RequestParamConverter.php new file mode 100644 index 0000000..c440306 --- /dev/null +++ b/src/Routing/RequestParamConverter.php @@ -0,0 +1,59 @@ +requestStorage = $this->entityTypeManager->getStorage('isi_request'); + } + + /** + * {@inheritDoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('entity_type.manager'), + ); + } + + /** + * {@inheritDoc} + */ + public function convert($value, $definition, $name, array $defaults) { + $request_storage = $this->entityTypeManager->getStorage('isi_request'); + if (is_numeric($value) && ($request = $request_storage->load($value))) { + return $request; + } + if ($requests = $request_storage->loadByProperties(['machine_name' => $value])) { + return reset($requests); + } + + return NULL; + } + + /** + * {@inheritDoc} + */ + public function applies($definition, $name, Route $route) { + return isset($definition['type']) && $definition['type'] === 'islandora_spreadsheet_ingest_request'; + } + +} From 413e4fed4ce33c9fe431027f7cb971c8cfd9e660 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Tue, 23 Jul 2024 16:55:09 -0300 Subject: [PATCH 04/17] Some indexes together. --- islandora_spreadsheet_ingest.install | 45 ++++------------------------ src/Entity/Request.php | 8 +++-- src/RequestStorage.php | 9 ------ src/RequestStorageSchema.php | 32 ++++++++++++++++++++ 4 files changed, 43 insertions(+), 51 deletions(-) delete mode 100644 src/RequestStorage.php create mode 100644 src/RequestStorageSchema.php diff --git a/islandora_spreadsheet_ingest.install b/islandora_spreadsheet_ingest.install index 21f24ed..664d47c 100644 --- a/islandora_spreadsheet_ingest.install +++ b/islandora_spreadsheet_ingest.install @@ -47,47 +47,12 @@ function islandora_spreadsheet_ingest_update_9001() { function islandora_spreadsheet_ingest_update_9002() { $etm = \Drupal::entityTypeManager(); $upm = \Drupal::entityDefinitionUpdateManager(); - $config_entity_base_definition = [ - "label" => \t("Islandora Spreadsheet Ingest Request"), - "handlers" => [ - "list_builder" => "Drupal\islandora_spreadsheet_ingest\Controller\RequestListBuilder", - "form" => [ - "process" => "Drupal\islandora_spreadsheet_ingest\Form\Ingest\Review", - "add" => "Drupal\islandora_spreadsheet_ingest\Form\Ingest\FileUpload", - "delete" => "Drupal\islandora_spreadsheet_ingest\Form\RequestDeleteForm", - "edit" => "Drupal\islandora_spreadsheet_ingest\Form\Ingest\FileUpload", - "view" => "Drupal\islandora_spreadsheet_ingest\Form\Ingest\Review", - ], - "access" => "Drupal\islandora_spreadsheet_ingest\RequestAccessControlHandler", - "view_builder" => "Drupal\islandora_spreadsheet_ingest\RequestViewBuilder", - ], - "config_prefix" => "request", - "admin_permission" => "administer islandora_spreadsheet_ingest requests", - "entity_keys" => [ - "id" => "id", - "label" => "label", - ], - "config_export" => [ - "id", - "label", - "sheet", - "originalMapping", - "mappings", - "active", - "owner", - ], - "links" => [ - "canonical" => "/admin/content/islandora_spreadsheet_ingest/{isi_request}", - "process-form" => "/admin/content/islandora_spreadsheet_ingest/{isi_request}/process", - "edit-form" => "/admin/content/islandora_spreadsheet_ingest/{isi_request}/edit", - "map-form" => "/admin/content/islandora_spreadsheet_ingest/{isi_request}/mapping", - "delete-form" => "/admin/content/islandora_spreadsheet_ingest/{isi_request}/delete", - ], - ]; - $upm->uninstallEntityType(new class(['id' => 'isi_request'] + $config_entity_base_definition) extends ConfigEntityType { - // All from the extended class. - }); + $upm->uninstallEntityType($upm->getEntityType('isi_request')); + + // XXX: This should probably be including the definition inline to be + // installed, including field definitions, instead of dynamically lifting the + // definitions from the entity type manager. $definition = $etm->getDefinition('isi_request'); $upm->installFieldableEntityType($definition, Request::baseFieldDefinitions($definition)); } diff --git a/src/Entity/Request.php b/src/Entity/Request.php index f18ba80..2da21bf 100644 --- a/src/Entity/Request.php +++ b/src/Entity/Request.php @@ -16,9 +16,9 @@ * id = "isi_request", * label = @Translation("Islandora Spreadsheet Ingest Request"), * handlers = { + * "storage_schema" = "Drupal\islandora_spreadsheet_ingest\RequestStorageSchema", * "list_builder" = "Drupal\islandora_spreadsheet_ingest\Controller\RequestListBuilder", * "form" = { - * "storage" = "Drupal\islandora_spreadsheet_ingest\RequestStorage", * "process" = "Drupal\islandora_spreadsheet_ingest\Form\Ingest\Review", * "add" = "Drupal\islandora_spreadsheet_ingest\Form\Ingest\FileUpload", * "delete" = "Drupal\islandora_spreadsheet_ingest\Form\RequestDeleteForm", @@ -33,6 +33,7 @@ * data_table = "islandora_spreadsheet_ingest_request_data", * entity_keys = { * "id" = "id", + * "uuid" = "uuid", * "label" = "label", * "owner" = "owner", * }, @@ -166,7 +167,10 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setRequired(TRUE) ->setTranslatable(FALSE) ->setRevisionable(FALSE) - ->setCardinality(1); + ->setCardinality(1) + ->addConstraint('UniqueField', [ + 'message' => 'The machine_name %value is already in use.', + ]); $fields['active'] = BaseFieldDefinition::create('boolean') ->setLabel(\t('Label')) ->setRequired(TRUE) diff --git a/src/RequestStorage.php b/src/RequestStorage.php deleted file mode 100644 index 4e058bd..0000000 --- a/src/RequestStorage.php +++ /dev/null @@ -1,9 +0,0 @@ -getName(); + + if ($table_name === $this->storage->getBaseTable()) { + if ($field_name === 'machine_name') { + $this->addSharedTableFieldUniqueKey($storage_definition, $schema); + } + elseif ($field_name === 'active') { + $this->addSharedTableFieldIndex($storage_definition, $schema); + } + } + + return $schema; + } + +} From 558db2c972e59b03fd50f42ebe1466d821636287 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Wed, 24 Jul 2024 10:05:14 -0300 Subject: [PATCH 05/17] Typehinting and misc cleanup. --- islandora_spreadsheet_ingest.install | 140 ++++++++++++++----- islandora_spreadsheet_ingest.module | 29 ++-- islandora_spreadsheet_ingest.post_update.php | 76 ++++++++++ src/Entity/Request.php | 33 ----- src/Routing/RequestParamConverter.php | 2 +- 5 files changed, 196 insertions(+), 84 deletions(-) create mode 100644 islandora_spreadsheet_ingest.post_update.php diff --git a/islandora_spreadsheet_ingest.install b/islandora_spreadsheet_ingest.install index 664d47c..0658b7d 100644 --- a/islandora_spreadsheet_ingest.install +++ b/islandora_spreadsheet_ingest.install @@ -5,54 +5,122 @@ * Installation hooks. */ -use Drupal\Core\Config\Entity\ConfigEntityType; +use Drupal\Core\Entity\ContentEntityType; +use Drupal\Core\Field\BaseFieldDefinition; +use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\islandora_spreadsheet_ingest\Entity\Request; /** - * Drop old, disused tables. + * Implements hook_update_last_removed(). */ -function islandora_spreadsheet_ingest_update_8201() { - $schema = \Drupal::service('database')->schema(); - - $tables = [ - 'islandora_spreadsheet_ingest_templates', - 'islandora_spreadsheet_ingest_ingests', - ]; - array_map([$schema, 'dropTable'], $tables); - - return t('Dropped tables.'); -} - -/** - * Ensure the Islandora Spreadsheet Request ConfigEntityType is installed. - */ -function islandora_spreadsheet_ingest_update_9001() { - $upm = \Drupal::entityDefinitionUpdateManager(); - $ent = $upm->getEntityType('isi_request'); - if (is_null($ent)) { - $upm->installEntityType(\Drupal::entityTypeManager() - ->getDefinition('isi_request') - ); - - return t('The "isi_request" config entity has been installed.'); - } - else { - return t('The "isi_request" config entity is already installed.'); - } +function islandora_spreadsheet_ingest_update_last_removed() { + return 9001; } /** * Replace config entity with content entity. */ function islandora_spreadsheet_ingest_update_9002() { - $etm = \Drupal::entityTypeManager(); $upm = \Drupal::entityDefinitionUpdateManager(); $upm->uninstallEntityType($upm->getEntityType('isi_request')); - // XXX: This should probably be including the definition inline to be - // installed, including field definitions, instead of dynamically lifting the - // definitions from the entity type manager. - $definition = $etm->getDefinition('isi_request'); - $upm->installFieldableEntityType($definition, Request::baseFieldDefinitions($definition)); + // Much like general schema updates, this needs to include the definition + // inline to be installed, including field definitions, instead of dynamically + // lifting the definitions from the entity type manager in order to be able to + // reliably apply future updates. + $definition = new ContentEntityType([ + "id" => "isi_request", + "label" => \t("Islandora Spreadsheet Ingest Request"), + "handlers" => [ + "storage_schema" => "Drupal\islandora_spreadsheet_ingest\RequestStorageSchema", + "list_builder" => "Drupal\islandora_spreadsheet_ingest\Controller\RequestListBuilder", + "form" => [ + "process" => "Drupal\islandora_spreadsheet_ingest\Form\Ingest\Review", + "add" => "Drupal\islandora_spreadsheet_ingest\Form\Ingest\FileUpload", + "delete" => "Drupal\islandora_spreadsheet_ingest\Form\RequestDeleteForm", + "edit" => "Drupal\islandora_spreadsheet_ingest\Form\Ingest\FileUpload", + "view" => "Drupal\islandora_spreadsheet_ingest\Form\Ingest\Review", + ], + "access" => "Drupal\islandora_spreadsheet_ingest\RequestAccessControlHandler", + "view_builder" => "Drupal\islandora_spreadsheet_ingest\RequestViewBuilder", + ], + "admin_permission" => "administer islandora_spreadsheet_ingest requests", + "base_table" => "islandora_spreadsheet_ingest_request", + "entity_keys" => [ + "id" => "id", + "uuid" => "uuid", + "label" => "label", + "owner" => "uid", + ], + "links" => [ + "canonical" => "/admin/content/islandora_spreadsheet_ingest/{isi_request}", + "process-form" => "/admin/content/islandora_spreadsheet_ingest/{isi_request}/process", + "edit-form" => "/admin/content/islandora_spreadsheet_ingest/{isi_request}/edit", + "map-form" => "/admin/content/islandora_spreadsheet_ingest/{isi_request}/mapping", + "delete-form" => "/admin/content/islandora_spreadsheet_ingest/{isi_request}/delete", + ], + ]); + $fields = []; + $fields['uid'] = BaseFieldDefinition::create('entity_reference') + ->setLabel(\t('User ID')) + ->setSetting('target_type', 'user') + ->setTranslatable(FALSE) + ->setDefaultValueCallback(Request::class . '::getDefaultEntityOwner'); + $fields['label'] = BaseFieldDefinition::create('string') + ->setLabel(\t('Title')) + ->setRequired(TRUE) + ->setTranslatable(FALSE) + ->setRevisionable(FALSE) + ->setSetting('max_length', 255) + ->setDisplayOptions('view', [ + 'label' => 'hidden', + 'type' => 'string', + 'weight' => -5, + ]) + ->setDisplayOptions('form', [ + 'type' => 'string_textfield', + 'weight' => -5, + ]) + ->setDisplayConfigurable('form', TRUE) + ->setCardinality(1); + $fields['machine_name'] = BaseFieldDefinition::create('string') + ->setLabel(\t('Machine Name')) + ->setRequired(TRUE) + ->setTranslatable(FALSE) + ->setRevisionable(FALSE) + ->setCardinality(1) + ->addConstraint('UniqueField', [ + 'message' => 'The machine_name %value is already in use.', + ]); + $fields['active'] = BaseFieldDefinition::create('boolean') + ->setLabel(\t('Label')) + ->setRequired(TRUE) + ->setCardinality(1) + ->setTranslatable(FALSE) + ->setRevisionable(FALSE); + $fields['sheet_file'] = BaseFieldDefinition::create('entity_reference') + ->setLabel(\t('Spreadsheet file')) + ->setRequired(TRUE) + ->setTranslatable(FALSE) + ->setRevisionable(FALSE) + ->setSetting('target_type', 'file') + ->setDisplayOptions('form', [ + 'type' => 'file_generic', + ]) + ->setCardinality(1); + $fields['sheet_sheet'] = BaseFieldDefinition::create('string') + ->setLabel(\t('Worksheet')) + ->setDescription(\t('The specific worksheet if the file corresponds to an ODS/XLSX which is possible of containing multiple.')) + ->setCardinality(1); + $fields['mappings'] = BaseFieldDefinition::create('map') + ->setLabel(\t('Mappings')) + ->setDescription(\t('Migration mappings')) + ->setCardinality(1); + $fields['original_mapping'] = BaseFieldDefinition::create('string') + ->setLabel(\t('Original mapping')) + ->setDescription(\t('Original migration template')) + ->setCardinality(1); + + $upm->installFieldableEntityType($definition, $fields); } diff --git a/islandora_spreadsheet_ingest.module b/islandora_spreadsheet_ingest.module index 1aa0f35..c1026f6 100644 --- a/islandora_spreadsheet_ingest.module +++ b/islandora_spreadsheet_ingest.module @@ -7,10 +7,10 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Core\Access\AccessResult; +use Drupal\Core\Access\AccessResultInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Url; - use Drupal\islandora_spreadsheet_ingest\RequestInterface; /** @@ -19,7 +19,7 @@ use Drupal\islandora_spreadsheet_ingest\RequestInterface; * @param \Drupal\islandora_spreadsheet_ingest\RequestInterface $request * The request of which to add the usage. */ -function _islandora_spreadsheet_ingest_add_file_usage(RequestInterface $request) { +function _islandora_spreadsheet_ingest_add_file_usage(RequestInterface $request) : void { $file_usage_service = \Drupal::service('file.usage'); $file_service = \Drupal::service('entity_type.manager')->getStorage('file'); $fids = $request->getSheet()['file'] ?? NULL; @@ -43,7 +43,7 @@ function _islandora_spreadsheet_ingest_add_file_usage(RequestInterface $request) * @param \Drupal\islandora_spreadsheet_ingest\RequestInterface $request * The request of which to delete the usage. */ -function _islandora_spreadsheet_ingest_delete_file_usage(RequestInterface $request) { +function _islandora_spreadsheet_ingest_delete_file_usage(RequestInterface $request) : void { $file_usage_service = \Drupal::service('file.usage'); $file_service = \Drupal::service('entity_type.manager')->getStorage('file'); $fids = $request->getSheet()['file']; @@ -64,7 +64,7 @@ function _islandora_spreadsheet_ingest_delete_file_usage(RequestInterface $reque /** * Implements hook_ENTITY_TYPE_insert(). */ -function islandora_spreadsheet_ingest_isi_request_insert(RequestInterface $request) { +function islandora_spreadsheet_ingest_isi_request_insert(RequestInterface $request) : void { _islandora_spreadsheet_ingest_add_file_usage($request); // If active, generate the migration group... @@ -80,7 +80,7 @@ function islandora_spreadsheet_ingest_isi_request_insert(RequestInterface $reque /** * Implements hook_ENTITY_TYPE_update(). */ -function islandora_spreadsheet_ingest_isi_request_update(RequestInterface $request) { +function islandora_spreadsheet_ingest_isi_request_update(RequestInterface $request) : void { _islandora_spreadsheet_ingest_delete_file_usage($request->original); _islandora_spreadsheet_ingest_add_file_usage($request); @@ -99,7 +99,7 @@ function islandora_spreadsheet_ingest_isi_request_update(RequestInterface $reque /** * Implements hook_ENTITY_TYPE_delete(). */ -function islandora_spreadsheet_ingest_isi_request_delete(RequestInterface $request) { +function islandora_spreadsheet_ingest_isi_request_delete(RequestInterface $request) : void { _islandora_spreadsheet_ingest_delete_file_usage($request); \Drupal::service('islandora_spreadsheet_ingest.migration_deriver')->deleteAll($request); @@ -109,7 +109,7 @@ function islandora_spreadsheet_ingest_isi_request_delete(RequestInterface $reque /** * Implements hook_entity_operation(). */ -function islandora_spreadsheet_ingest_entity_operation(EntityInterface $entity) { +function islandora_spreadsheet_ingest_entity_operation(EntityInterface $entity) : array { $ops = []; if ($entity->getEntityType()->id() == 'isi_request') { @@ -139,7 +139,7 @@ function islandora_spreadsheet_ingest_entity_operation(EntityInterface $entity) * @see islandora_spreadsheet_ingest_migration_group_entity_access() * @see islandora_spreadsheet_ingest_migration_entity_access() */ -function _islandora_spreadsheet_ingest_migration_entity_helper(EntityInterface $entity, AccountInterface $account, $uid, $tags) { +function _islandora_spreadsheet_ingest_migration_entity_helper(EntityInterface $entity, AccountInterface $account, $uid, $tags) : AccessResultInterface { return AccessResult::allowedIf(in_array('isi_derived_migration', $tags)) ->addCacheableDependency($entity) ->andIf( @@ -151,8 +151,8 @@ function _islandora_spreadsheet_ingest_migration_entity_helper(EntityInterface $ /** * Implements hook_ENTITY_TYPE_entity_access() for migration_group entities. */ -function islandora_spreadsheet_ingest_migration_group_entity_access(EntityInterface $entity, $operation, AccountInterface $account) { - $shared = $entity->shared_configuration ?? []; +function islandora_spreadsheet_ingest_migration_group_entity_access(EntityInterface $entity, $operation, AccountInterface $account) : AccessResultInterface { + $shared = $entity->get('shared_configuration') ?? []; $tags = NestedArray::getValue($shared, ['migration_tags']) ?? []; $uid = NestedArray::getValue($shared, ['source', 'isi', 'uid']) ?? FALSE; return _islandora_spreadsheet_ingest_migration_entity_helper($entity, $account, $uid, $tags); @@ -161,16 +161,17 @@ function islandora_spreadsheet_ingest_migration_group_entity_access(EntityInterf /** * Implements hook_ENTITY_TYPE_entity_access() for migration entities. */ -function islandora_spreadsheet_ingest_migration_entity_access(EntityInterface $entity, $operation, AccountInterface $account) { - $tags = $entity->migration_tags ?? []; - $uid = NestedArray::getValue($entity->source, ['isi', 'uid']) ?? FALSE; +function islandora_spreadsheet_ingest_migration_entity_access(EntityInterface $entity, $operation, AccountInterface $account) : AccessResultInterface { + $tags = $entity->get('migration_tags') ?? []; + $source = $entity->get('source'); + $uid = NestedArray::getValue($source, ['isi', 'uid']) ?? FALSE; return _islandora_spreadsheet_ingest_migration_entity_helper($entity, $account, $uid, $tags); } /** * Implements hook_migration_plugins_alter(). */ -function islandora_spreadsheet_ingest_migration_plugins_alter(&$definitions) { +function islandora_spreadsheet_ingest_migration_plugins_alter(&$definitions) : void { $logger = \Drupal::logger('islandora_spreadsheet_ingest'); $logger->debug('Altering...'); diff --git a/islandora_spreadsheet_ingest.post_update.php b/islandora_spreadsheet_ingest.post_update.php new file mode 100644 index 0000000..96f3ccc --- /dev/null +++ b/islandora_spreadsheet_ingest.post_update.php @@ -0,0 +1,76 @@ +listAll('islandora_spreadsheet_ingest.request'); + $sandbox['count'] = count($sandbox['names']); + if ($sandbox['count'] === 0) { + return "No entities to migrate."; + } + $sandbox['current'] = 0; + } + + if (!($current = array_pop($sandbox['names']))) { + throw new UpdateException("Unexpectedly failed to get item from array."); + } + + $config = $config_factory->get($current); + \Drupal::entityTypeManager()->getStorage('isi_request')->create([ + 'label' => $config->get('label'), + 'machine_name' => $config->get('id'), + 'sheet_file' => $config->get('sheet')['file'], + 'sheet_sheet' => $config->get('sheet')['sheet'], + 'mappings' => $config->get('mappings'), + 'original_mapping' => $config->get('originalMapping'), + 'owner' => $config->get('owner'), + 'active' => $config->get('active'), + ])->save(); + $sandbox['#finished'] = ++$sandbox['current'] / $sandbox['count']; +} + +/** + * Delete disused request config entities. + */ +function islandora_spreadsheet_ingest_post_update_migrate_requests_from_config_to_content_1(array &$sandbox) { + $config_factory = \Drupal::configFactory(); + if (!isset($sandbox['count'])) { + $sandbox['names'] = $config_factory->listAll('islandora_spreadsheet_ingest.request'); + $sandbox['count'] = count($sandbox['names']); + if ($sandbox['count'] === 0) { + return "No entities to delete."; + } + $sandbox['current'] = 0; + } + + if (!($current = array_pop($sandbox['names']))) { + throw new UpdateException("Unexpectedly failed to get item from array."); + } + + $config = $config_factory->getEditable($current); + + $file_usage_service = \Drupal::service('file.usage'); + $file_service = \Drupal::service('entity_type.manager')->getStorage('file'); + $fids = $config->get('sheet')['file']; + if ($fids && ($file = $file_service->load(reset($fids)))) { + $file_usage_service->delete( + $file, + 'islandora_spreadsheet_ingest', + 'isi_request', + $config->get('id'), + ); + } + + $config->delete(); + $sandbox['#finished'] = ++$sandbox['current'] / $sandbox['count']; +} diff --git a/src/Entity/Request.php b/src/Entity/Request.php index 2da21bf..61ce8aa 100644 --- a/src/Entity/Request.php +++ b/src/Entity/Request.php @@ -30,7 +30,6 @@ * }, * admin_permission = "administer islandora_spreadsheet_ingest requests", * base_table = "islandora_spreadsheet_ingest_request", - * data_table = "islandora_spreadsheet_ingest_request_data", * entity_keys = { * "id" = "id", * "uuid" = "uuid", @@ -90,38 +89,6 @@ public function getOwner() { return $this->traitGetOwner()->id(); } - /** - * {@inheritdoc} - */ - public function calculateDependencies() { - parent::calculateDependencies(); - - $storage = $this->entityTypeManager()->getStorage('migration'); - - // XXX: We expect the module to be accounted for in the "migration_group" - // config entity, and so no need deal with it specifically for the - // migration plugin. - foreach (array_column($this->getMappings(), 'original_migration_id') as $original_migration_id) { - if ($storage->load($original_migration_id)) { - $this->addDependency('config', "migrate_plus.migration.{$original_migration_id}"); - } - } - [$type, $id] = explode(':', $this->getOriginalMapping()); - switch ($type) { - case 'migration_group': - $this->addDependency('config', "migrate_plus.migration_group.{$id}"); - break; - - default: - throw new \Exception(strtr('Unknown type of original mapping: "!type"', [ - '!type' => $type, - ])); - - } - - return $this; - } - /** * {@inheritDoc} */ diff --git a/src/Routing/RequestParamConverter.php b/src/Routing/RequestParamConverter.php index c440306..4451035 100644 --- a/src/Routing/RequestParamConverter.php +++ b/src/Routing/RequestParamConverter.php @@ -22,7 +22,7 @@ class RequestParamConverter implements ParamConverterInterface, ContainerInjecti public function __construct( protected EntityTypeManagerInterface $entityTypeManager, ) { - $this->requestStorage = $this->entityTypeManager->getStorage('isi_request'); + // No-op. } /** From 08f4717b9b0b6a7d06540267b227b711b973307c Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Wed, 24 Jul 2024 10:08:43 -0300 Subject: [PATCH 06/17] Misc coding standards. --- islandora_spreadsheet_ingest.install | 5 ++--- src/Form/Admin.php | 1 - src/MigrationGroupDeriver.php | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/islandora_spreadsheet_ingest.install b/islandora_spreadsheet_ingest.install index 0658b7d..039f1f7 100644 --- a/islandora_spreadsheet_ingest.install +++ b/islandora_spreadsheet_ingest.install @@ -7,20 +7,19 @@ use Drupal\Core\Entity\ContentEntityType; use Drupal\Core\Field\BaseFieldDefinition; -use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\islandora_spreadsheet_ingest\Entity\Request; /** * Implements hook_update_last_removed(). */ -function islandora_spreadsheet_ingest_update_last_removed() { +function islandora_spreadsheet_ingest_update_last_removed() : int { return 9001; } /** * Replace config entity with content entity. */ -function islandora_spreadsheet_ingest_update_9002() { +function islandora_spreadsheet_ingest_update_9002() : void { $upm = \Drupal::entityDefinitionUpdateManager(); $upm->uninstallEntityType($upm->getEntityType('isi_request')); diff --git a/src/Form/Admin.php b/src/Form/Admin.php index 2343bc1..01ae837 100644 --- a/src/Form/Admin.php +++ b/src/Form/Admin.php @@ -50,7 +50,6 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { - //$form = []; $config = $this->config('islandora_spreadsheet_ingest.settings'); $current_whitelist = $config->get('binary_directory_whitelist'); $form['schemes'] = [ diff --git a/src/MigrationGroupDeriver.php b/src/MigrationGroupDeriver.php index b72362e..74cf2be 100644 --- a/src/MigrationGroupDeriver.php +++ b/src/MigrationGroupDeriver.php @@ -60,7 +60,7 @@ class MigrationGroupDeriver implements MigrationGroupDeriverInterface { public function __construct( LoggerInterface $logger, EntityTypeManagerInterface $entity_type_manager, - CacheTagsInvalidatorInterface $invalidator + CacheTagsInvalidatorInterface $invalidator, ) { $this->logger = $logger; $this->entityTypeManager = $entity_type_manager; From baf6b29010e34e585e1f4aed80df0bbeb0ba9b48 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Wed, 24 Jul 2024 10:15:39 -0300 Subject: [PATCH 07/17] Skip phpcpd on the .install. Given that .installs often need to repeat chunks of schemas in order to manage them, it is somewhat impossible to avoid copypasta. --- .github/workflows/lint.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 638f94c..6b34baa 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -14,3 +14,5 @@ jobs: uses: actions/checkout@v4 - name: Run CodeSniffer uses: discoverygarden/CodeSniffer@v1 + with: + phpcpd-exclude: islandora_spreadsheet_ingest.install From e33ba70b8a32009b9ff57d1597542d05c0b2d7a1 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Wed, 24 Jul 2024 12:12:54 -0300 Subject: [PATCH 08/17] Copy map and message tables. --- islandora_spreadsheet_ingest.post_update.php | 50 +++++++++++++++++++- src/MigrationDeriver.php | 2 +- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/islandora_spreadsheet_ingest.post_update.php b/islandora_spreadsheet_ingest.post_update.php index 96f3ccc..aa0df2b 100644 --- a/islandora_spreadsheet_ingest.post_update.php +++ b/islandora_spreadsheet_ingest.post_update.php @@ -6,6 +6,7 @@ */ use Drupal\Core\Utility\UpdateException; +use Drupal\migrate\Plugin\migrate\id_map\Sql; /** * Migrate request entities from config to content. @@ -25,8 +26,10 @@ function islandora_spreadsheet_ingest_post_update_migrate_requests_from_config_t throw new UpdateException("Unexpectedly failed to get item from array."); } + // Create copy of request. $config = $config_factory->get($current); - \Drupal::entityTypeManager()->getStorage('isi_request')->create([ + /** @var \Drupal\islandora_spreadsheet_ingest\RequestInterface $request */ + $request = \Drupal::entityTypeManager()->getStorage('isi_request')->create([ 'label' => $config->get('label'), 'machine_name' => $config->get('id'), 'sheet_file' => $config->get('sheet')['file'], @@ -35,7 +38,50 @@ function islandora_spreadsheet_ingest_post_update_migrate_requests_from_config_t 'original_mapping' => $config->get('originalMapping'), 'owner' => $config->get('owner'), 'active' => $config->get('active'), - ])->save(); + ]); + $request->save(); + + // Copy ID map and messages tables to the new entities, as those + // associated with the old should be deleted in the next phase. + $source_mg_name = "isi__{$config->get('id')}"; + $dest_mg_name = \Drupal::service('islandora_spreadsheet_ingest.migration_group_deriver')->deriveName($request); + /** @var \Drupal\migrate\Plugin\MigrationPluginManagerInterface $migration_plugin_manager */ + $migration_plugin_manager = \Drupal::service('plugin.manager.migration'); + foreach (array_keys($request->getMappings()) as $name) { + $source_migration_id = "{$source_mg_name}_{$name}"; + $dest_migration_id = "{$dest_mg_name}_{$name}"; + /** @var \Drupal\migrate\Plugin\MigrationInterface $source_migration */ + $source_migration = $migration_plugin_manager->createInstance($source_migration_id); + /** @var \Drupal\migrate\Plugin\MigrationInterface $dest_migration */ + $dest_migration = $migration_plugin_manager->createInstance($dest_migration_id); + $source_id_map = $source_migration->getIdMap(); + $dest_id_map = $dest_migration->getIdMap(); + if (!($source_id_map instanceof Sql)) { + continue; + } + if (!($dest_id_map instanceof Sql)) { + continue; + } + + // XXX: Calling Sql::getDatabase() presently initializes things, to ensure + // that the relevant tables exist. + $source_id_map->getDatabase(); + $database = $dest_id_map->getDatabase(); + + $database->insert($dest_id_map->mapTableName()) + ->from( + $database->select($source_id_map->mapTableName(), 'm') + ->fields('m') + ) + ->execute(); + $database->insert($dest_id_map->messageTableName()) + ->from( + $database->select($source_id_map->messageTableName(), 'm') + ->fields('m') + ) + ->execute(); + } + $sandbox['#finished'] = ++$sandbox['current'] / $sandbox['count']; } diff --git a/src/MigrationDeriver.php b/src/MigrationDeriver.php index 612fe91..52a0505 100644 --- a/src/MigrationDeriver.php +++ b/src/MigrationDeriver.php @@ -335,7 +335,7 @@ public function createAll(RequestInterface $request) { * {@inheritdoc} */ public function deleteAll(RequestInterface $request) { - // Nuke the storage for the given mgiration group. + // Nuke the storage for the given migration group. /** @var \Drupal\migrate_plus\Entity\MigrationInterface[] $migrations */ $migrations = $this->migrationStorage->loadByProperties([ 'migration_group' => $this->migrationGroupDeriver->deriveName($request), From eaf3df8e281f11a26771c5a8acbe1bf36b96c239 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Wed, 24 Jul 2024 12:23:40 -0300 Subject: [PATCH 09/17] Delete the migrated ID map and messages tables. --- islandora_spreadsheet_ingest.post_update.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/islandora_spreadsheet_ingest.post_update.php b/islandora_spreadsheet_ingest.post_update.php index aa0df2b..fb1ed6a 100644 --- a/islandora_spreadsheet_ingest.post_update.php +++ b/islandora_spreadsheet_ingest.post_update.php @@ -116,6 +116,15 @@ function islandora_spreadsheet_ingest_post_update_migrate_requests_from_config_t $config->get('id'), ); } + $source_mg_name = "isi__{$config->get('id')}"; + /** @var \Drupal\migrate\Plugin\MigrationPluginManagerInterface $migration_plugin_manager */ + $migration_plugin_manager = \Drupal::service('plugin.manager.migration'); + foreach (array_keys($config->get('mappings')) as $name) { + $source_migration_id = "{$source_mg_name}_{$name}"; + /** @var \Drupal\migrate\Plugin\MigrationInterface $source_migration */ + $source_migration = $migration_plugin_manager->createInstance($source_migration_id); + $source_migration->getIdMap()->destroy(); + } $config->delete(); $sandbox['#finished'] = ++$sandbox['current'] / $sandbox['count']; From f908ff8ed77fc3b1a72bc668873e007cc4b09b3f Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Wed, 24 Jul 2024 12:24:28 -0300 Subject: [PATCH 10/17] Delete the obsolete config schema. --- .../islandora_spreadsheet_ingest.schema.yml | 65 ------------------- 1 file changed, 65 deletions(-) diff --git a/config/schema/islandora_spreadsheet_ingest.schema.yml b/config/schema/islandora_spreadsheet_ingest.schema.yml index a00aae7..6ccfb99 100644 --- a/config/schema/islandora_spreadsheet_ingest.schema.yml +++ b/config/schema/islandora_spreadsheet_ingest.schema.yml @@ -7,68 +7,3 @@ islandora_spreadsheet_ingest.settings: label: 'List of allowed source directories.' sequence: type: string - -islandora_spreadsheet_ingest.request.*: - type: config_entity - mapping: - id: - type: string - label: ID - label: - type: label - label: Label - active: - type: boolean - label: Active - description: If this request should have migrations derived for it. - sheet: - type: mapping - mapping: - file: - # XXX: Really... kind of indicative that these should be pulled out - # to content entities instead of being config entities... the whole - # having-to-reference a file thing... because the "entity:file" - # thing does not appear to work... - #type: entity:file - type: ignore - label: The spreadsheet file to process. - sheet: - type: string - label: The worksheet of the file to process. - mappings: - type: sequence - sequence: - type: islandora_spreadsheet_ingest.migration_structure - owner: - # XXX: Further reinforcement that these should be pulled out to content - # entities instead of config, because we are relating to the user here. - #type: entity:user - type: ignore - label: The owner's ID; should be either an int or a string. - originalMapping: - type: string - label: | - Reference to the original mapping from which this request was derived. - -islandora_spreadsheet_ingest.migration_structure: - type: mapping - mapping: - original_migration_id: - type: string - label: ID - mappings: - type: sequence - sequence: - type: mapping - mapping: - weight: - type: integer - pipeline: - type: sequence - sequence: - # XXX: The migrate plugin does not define schemas for its plugins, - # nor any obvious mechanism by which to make reference to them... - # migrate_plus _does_ roll a handful, describing the things from - # migrate; however, it is not complete, nor necessarily desirable. - # ... so let's just ignore, for now at least. - type: ignore From 9734c0ff771575830db867d86560bb9a7b570073 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Wed, 24 Jul 2024 12:27:53 -0300 Subject: [PATCH 11/17] Put the interface back together. Had thought at one point that having it split apart might facilitate the migration between config and content, but it turned out not to be necessary. --- src/BaseRequestInterface.php | 46 ------------------------------------ src/RequestInterface.php | 38 +++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 48 deletions(-) delete mode 100644 src/BaseRequestInterface.php diff --git a/src/BaseRequestInterface.php b/src/BaseRequestInterface.php deleted file mode 100644 index 664ee85..0000000 --- a/src/BaseRequestInterface.php +++ /dev/null @@ -1,46 +0,0 @@ - Date: Wed, 24 Jul 2024 12:52:28 -0300 Subject: [PATCH 12/17] Attempt basic config_ignore integration. Expecting the config IDs might need to be reworked to be fully expanded. --- composer.json | 11 +++++++---- .../islandora_spreadsheet_ingest.settings.yml | 1 + .../islandora_spreadsheet_ingest.schema.yml | 3 +++ islandora_spreadsheet_ingest.module | 17 +++++++++++++++++ islandora_spreadsheet_ingest.post_update.php | 7 +++++++ 5 files changed, 35 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index e5dc746..b998665 100644 --- a/composer.json +++ b/composer.json @@ -3,9 +3,12 @@ "type": "drupal-module", "license": "GPL-3.0-only", "require": { - "openspout/openspout": "^3.4 || ^4", - "discoverygarden/dgi_migrate": "^1 || ^2 || ^3", - "drupal/migrate_plus": "^4.2 || ^5.1 || ^6", - "phpoffice/phpspreadsheet": "^1" + "openspout/openspout": "^3.4 || ^4", + "discoverygarden/dgi_migrate": "^1 || ^2 || ^3", + "drupal/migrate_plus": "^4.2 || ^5.1 || ^6", + "phpoffice/phpspreadsheet": "^1" + }, + "suggest": { + "drupal/config_ignore": "We integrate with it to allow our specific drupal/migrate_plus entities to be ignored by config operations." } } diff --git a/config/install/islandora_spreadsheet_ingest.settings.yml b/config/install/islandora_spreadsheet_ingest.settings.yml index 7d475f4..91b7cc0 100644 --- a/config/install/islandora_spreadsheet_ingest.settings.yml +++ b/config/install/islandora_spreadsheet_ingest.settings.yml @@ -1,2 +1,3 @@ --- binary_directory_whitelist: [] +enable_config_ignore_integration: true diff --git a/config/schema/islandora_spreadsheet_ingest.schema.yml b/config/schema/islandora_spreadsheet_ingest.schema.yml index 6ccfb99..87986e3 100644 --- a/config/schema/islandora_spreadsheet_ingest.schema.yml +++ b/config/schema/islandora_spreadsheet_ingest.schema.yml @@ -7,3 +7,6 @@ islandora_spreadsheet_ingest.settings: label: 'List of allowed source directories.' sequence: type: string + enable_config_ignore_integration: + type: boolean + label: 'If our config_ignore integration should be enabled.' diff --git a/islandora_spreadsheet_ingest.module b/islandora_spreadsheet_ingest.module index c1026f6..03eddee 100644 --- a/islandora_spreadsheet_ingest.module +++ b/islandora_spreadsheet_ingest.module @@ -6,6 +6,7 @@ */ use Drupal\Component\Utility\NestedArray; +use Drupal\config_ignore\ConfigIgnoreConfig; use Drupal\Core\Access\AccessResult; use Drupal\Core\Access\AccessResultInterface; use Drupal\Core\Entity\EntityInterface; @@ -197,3 +198,19 @@ function islandora_spreadsheet_ingest_migration_plugins_alter(&$definitions) : v $logger->debug('Altered.'); } + +/** + * Implements hook_config_ignore_ignored_alter(). + */ +function islandora_spreadsheet_ingest_config_ignore_ignored_alter(ConfigIgnoreConfig $ignored) : void { + if (!\Drupal::config('islandora_spreadsheet_ingest.settings')->get('enable_config_ignore_integration')) { + return; + } + + $list = $ignored->getList('import', 'create'); + + $list[] = "migrate_plus.migration_group.isi__*"; + $list[] = "migrate_plus.migration.isi__*"; + + $ignored->setList('import', 'create', $list); +} diff --git a/islandora_spreadsheet_ingest.post_update.php b/islandora_spreadsheet_ingest.post_update.php index fb1ed6a..fae2c5c 100644 --- a/islandora_spreadsheet_ingest.post_update.php +++ b/islandora_spreadsheet_ingest.post_update.php @@ -129,3 +129,10 @@ function islandora_spreadsheet_ingest_post_update_migrate_requests_from_config_t $config->delete(); $sandbox['#finished'] = ++$sandbox['current'] / $sandbox['count']; } + +/** + * Set the default value for enable_config_ignore_integration. + */ +function islandora_spreadsheet_ingest_post_update_set_default_config_ignore_status() { + \Drupal::configFactory()->getEditable('islandora_spreadsheet_ingest.settings')->set('enable_config_ignore_integration', TRUE); +} From ff95a8504ccca7a71a438a71a26f2d1b47f7870c Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Wed, 24 Jul 2024 13:58:03 -0300 Subject: [PATCH 13/17] Add element for the integration to the form. Bit of refactoring to account for potential of upstream to vary. --- src/Form/Admin.php | 58 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/src/Form/Admin.php b/src/Form/Admin.php index 01ae837..9225989 100644 --- a/src/Form/Admin.php +++ b/src/Form/Admin.php @@ -2,7 +2,7 @@ namespace Drupal\islandora_spreadsheet_ingest\Form; -use Drupal\Core\Config\ConfigFactoryInterface; +use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Form\ConfigFormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\StreamWrapper\StreamWrapperInterface; @@ -15,28 +15,54 @@ class Admin extends ConfigFormBase { /** - * The StreamWrapperManager. + * Drupal's stream wrapper manager service.. * * @var \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface */ - protected $streamWrapperManager; + protected StreamWrapperManagerInterface $streamWrapperManager; /** - * {@inheritdoc} + * Drupal's module handler service. + * + * @var \Drupal\Core\Extension\ModuleHandlerInterface */ - public function __construct(ConfigFactoryInterface $config_factory, StreamWrapperManagerInterface $stream_wrapper_manager) { - parent::__construct($config_factory); - $this->streamWrapperManager = $stream_wrapper_manager; - } + protected ModuleHandlerInterface $moduleHandler; /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { - return new static( - $container->get('config.factory'), - $container->get('stream_wrapper_manager') - ); + return parent::create($container) + ->setStreamWrapperManager($container->get('stream_wrapper_manager')) + ->setModuleHandler($container->get('module_handler')); + } + + /** + * Setter for the stream wrapper manager service. + * + * @param \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface $streamWrapperManager + * The stream wrapper manager service to set. + * + * @return $this + * Fluent interface. + */ + public function setStreamWrapperManager(StreamWrapperManagerInterface $streamWrapperManager) : static { + $this->streamWrapperManager = $streamWrapperManager; + return $this; + } + + /** + * Setter for the module handler service. + * + * @param \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler + * The module handler service to set. + * + * @return $this + * Fluent interface. + */ + public function setModuleHandler(ModuleHandlerInterface $moduleHandler) : static { + $this->moduleHandler = $moduleHandler; + return $this; } /** @@ -65,6 +91,13 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#default_value' => $current_whitelist ? implode(',', $current_whitelist) : '', '#description' => $this->t('A comma separated list of local locations from which spreadsheet ingests can use binaries.'), ]; + $form['config_ignore_integration'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Enable config_ignore integration?'), + '#default_value' => $config->get('enable_config_ignore_integration'), + '#description' => $this->t('This module results in many "migrate_plus" config entities being created; however, these config entities should typically be synchronized between systems. Therefore, we integrate with "config_ignore" to ignore the given entities.'), + '#disabled' => !$this->moduleHandler->moduleExists('config_ignore'), + ]; $form['submit'] = [ '#type' => 'submit', '#value' => $this->t('Save'), @@ -88,6 +121,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $whitelist = array_filter(explode(',', $form_state->getValue('paths'))); $config->set('binary_directory_whitelist', $whitelist); $config->set('schemes', array_filter($form_state->getValue('schemes'))); + $config->set('enable_config_ignore_integration', $form_state->getValue('config_ignore_integration')); $config->save(); parent::submitForm($form, $form_state); } From dac7b40a0e4ec4dcbd2a7cf8a40cedc85efed986 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Wed, 24 Jul 2024 14:44:48 -0300 Subject: [PATCH 14/17] Fix some wording. --- src/Form/Admin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Form/Admin.php b/src/Form/Admin.php index 9225989..db5d313 100644 --- a/src/Form/Admin.php +++ b/src/Form/Admin.php @@ -95,7 +95,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#type' => 'checkbox', '#title' => $this->t('Enable config_ignore integration?'), '#default_value' => $config->get('enable_config_ignore_integration'), - '#description' => $this->t('This module results in many "migrate_plus" config entities being created; however, these config entities should typically be synchronized between systems. Therefore, we integrate with "config_ignore" to ignore the given entities.'), + '#description' => $this->t('This module results in many "migrate_plus" config entities being created; however, these config entities should not typically be synchronized between systems. Therefore, we integrate with "config_ignore" to ignore the given entities.'), '#disabled' => !$this->moduleHandler->moduleExists('config_ignore'), ]; $form['submit'] = [ From c360721bed9256934dcb7dabd9053a4a2cb0cebd Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Wed, 24 Jul 2024 15:21:40 -0300 Subject: [PATCH 15/17] Add default bit for URI schemes. --- .../islandora_spreadsheet_ingest.settings.yml | 1 + .../islandora_spreadsheet_ingest.schema.yml | 5 +++++ islandora_spreadsheet_ingest.post_update.php | 17 ++++++++++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/config/install/islandora_spreadsheet_ingest.settings.yml b/config/install/islandora_spreadsheet_ingest.settings.yml index 91b7cc0..17fe7d2 100644 --- a/config/install/islandora_spreadsheet_ingest.settings.yml +++ b/config/install/islandora_spreadsheet_ingest.settings.yml @@ -1,3 +1,4 @@ --- binary_directory_whitelist: [] enable_config_ignore_integration: true +schemes: [] diff --git a/config/schema/islandora_spreadsheet_ingest.schema.yml b/config/schema/islandora_spreadsheet_ingest.schema.yml index 87986e3..c304778 100644 --- a/config/schema/islandora_spreadsheet_ingest.schema.yml +++ b/config/schema/islandora_spreadsheet_ingest.schema.yml @@ -10,3 +10,8 @@ islandora_spreadsheet_ingest.settings: enable_config_ignore_integration: type: boolean label: 'If our config_ignore integration should be enabled.' + schemes: + type: sequence + label: 'Allowed source URI schemes.' + sequence: + type: string diff --git a/islandora_spreadsheet_ingest.post_update.php b/islandora_spreadsheet_ingest.post_update.php index fae2c5c..529cccd 100644 --- a/islandora_spreadsheet_ingest.post_update.php +++ b/islandora_spreadsheet_ingest.post_update.php @@ -134,5 +134,20 @@ function islandora_spreadsheet_ingest_post_update_migrate_requests_from_config_t * Set the default value for enable_config_ignore_integration. */ function islandora_spreadsheet_ingest_post_update_set_default_config_ignore_status() { - \Drupal::configFactory()->getEditable('islandora_spreadsheet_ingest.settings')->set('enable_config_ignore_integration', TRUE); + \Drupal::configFactory() + ->getEditable('islandora_spreadsheet_ingest.settings') + ->set('enable_config_ignore_integration', TRUE) + ->save(); +} + +/** + * Set a value for islandora_spreadsheet_ingest.settings:schemes, if unset. + */ +function islandora_spreadsheet_ingest_post_update_set_default_schemes(&$sandbox) { + $config = \Drupal::configFactory()->getEditable('islandora_spreadsheet_ingest.settings'); + if ($config->get('schemes') === NULL) { + $config->set('schemes', [])->save(); + return \t('Set default value of an empty array for islandora_spreadsheet_ingest.settings:schemes.'); + } + return \t('A value is already present for islandora_spreadsheet_ingest.settings:schemes.'); } From 5fd76bac56f4992dafe1f9ccb28821816cee4c0c Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Wed, 24 Jul 2024 19:48:06 -0300 Subject: [PATCH 16/17] No-go on `config_ignore`; move to config transform API instead. `config_ignore` only works on import: It would not prevent the export and attempts to import of the exported configs on other systems. Instead, Drupal's config transform API allows the config to be dealt with. --- composer.json | 3 - .../islandora_spreadsheet_ingest.settings.yml | 1 - islandora_spreadsheet_ingest.module | 17 --- islandora_spreadsheet_ingest.post_update.php | 10 -- islandora_spreadsheet_ingest.services.yml | 7 ++ .../ConfigTransformationEventSubscriber.php | 101 ++++++++++++++++++ src/Form/Admin.php | 8 -- 7 files changed, 108 insertions(+), 39 deletions(-) create mode 100644 src/EventSubscriber/ConfigTransformationEventSubscriber.php diff --git a/composer.json b/composer.json index b998665..9fe6c18 100644 --- a/composer.json +++ b/composer.json @@ -7,8 +7,5 @@ "discoverygarden/dgi_migrate": "^1 || ^2 || ^3", "drupal/migrate_plus": "^4.2 || ^5.1 || ^6", "phpoffice/phpspreadsheet": "^1" - }, - "suggest": { - "drupal/config_ignore": "We integrate with it to allow our specific drupal/migrate_plus entities to be ignored by config operations." } } diff --git a/config/install/islandora_spreadsheet_ingest.settings.yml b/config/install/islandora_spreadsheet_ingest.settings.yml index 17fe7d2..fc35882 100644 --- a/config/install/islandora_spreadsheet_ingest.settings.yml +++ b/config/install/islandora_spreadsheet_ingest.settings.yml @@ -1,4 +1,3 @@ --- binary_directory_whitelist: [] -enable_config_ignore_integration: true schemes: [] diff --git a/islandora_spreadsheet_ingest.module b/islandora_spreadsheet_ingest.module index 03eddee..c1026f6 100644 --- a/islandora_spreadsheet_ingest.module +++ b/islandora_spreadsheet_ingest.module @@ -6,7 +6,6 @@ */ use Drupal\Component\Utility\NestedArray; -use Drupal\config_ignore\ConfigIgnoreConfig; use Drupal\Core\Access\AccessResult; use Drupal\Core\Access\AccessResultInterface; use Drupal\Core\Entity\EntityInterface; @@ -198,19 +197,3 @@ function islandora_spreadsheet_ingest_migration_plugins_alter(&$definitions) : v $logger->debug('Altered.'); } - -/** - * Implements hook_config_ignore_ignored_alter(). - */ -function islandora_spreadsheet_ingest_config_ignore_ignored_alter(ConfigIgnoreConfig $ignored) : void { - if (!\Drupal::config('islandora_spreadsheet_ingest.settings')->get('enable_config_ignore_integration')) { - return; - } - - $list = $ignored->getList('import', 'create'); - - $list[] = "migrate_plus.migration_group.isi__*"; - $list[] = "migrate_plus.migration.isi__*"; - - $ignored->setList('import', 'create', $list); -} diff --git a/islandora_spreadsheet_ingest.post_update.php b/islandora_spreadsheet_ingest.post_update.php index 529cccd..c887edf 100644 --- a/islandora_spreadsheet_ingest.post_update.php +++ b/islandora_spreadsheet_ingest.post_update.php @@ -130,16 +130,6 @@ function islandora_spreadsheet_ingest_post_update_migrate_requests_from_config_t $sandbox['#finished'] = ++$sandbox['current'] / $sandbox['count']; } -/** - * Set the default value for enable_config_ignore_integration. - */ -function islandora_spreadsheet_ingest_post_update_set_default_config_ignore_status() { - \Drupal::configFactory() - ->getEditable('islandora_spreadsheet_ingest.settings') - ->set('enable_config_ignore_integration', TRUE) - ->save(); -} - /** * Set a value for islandora_spreadsheet_ingest.settings:schemes, if unset. */ diff --git a/islandora_spreadsheet_ingest.services.yml b/islandora_spreadsheet_ingest.services.yml index 0adb6f4..5063510 100644 --- a/islandora_spreadsheet_ingest.services.yml +++ b/islandora_spreadsheet_ingest.services.yml @@ -40,3 +40,10 @@ services: - '@service_container' tags: - { name: paramconverter } + islandora_spreadsheet_ingest.event_subscriber.config_transform: + class: Drupal\islandora_spreadsheet_ingest\EventSubscriber\ConfigTransformationEventSubscriber + factory: [null, 'create'] + arguments: + - '@service_container' + tags: + - { name: event_subscriber } diff --git a/src/EventSubscriber/ConfigTransformationEventSubscriber.php b/src/EventSubscriber/ConfigTransformationEventSubscriber.php new file mode 100644 index 0000000..ed3a6f4 --- /dev/null +++ b/src/EventSubscriber/ConfigTransformationEventSubscriber.php @@ -0,0 +1,101 @@ +get('config.storage'), + ); + } + + /** + * {@inheritDoc} + */ + public static function getSubscribedEvents() : array { + return [ + ConfigEvents::STORAGE_TRANSFORM_EXPORT => 'onExportTransform', + ConfigEvents::STORAGE_TRANSFORM_IMPORT => 'onImportTransform', + ]; + } + + /** + * Config export event handler. + * + * @param \Drupal\Core\Config\StorageTransformEvent $event + * The event to which to respond. + */ + public function onExportTransform(StorageTransformEvent $event) : void { + $storage = $event->getStorage(); + foreach ($this->toIgnore($storage) as $name) { + $storage->delete($name); + } + } + + /** + * Config import event handler. + * + * @param \Drupal\Core\Config\StorageTransformEvent $event + * The event to which to respond. + */ + public function onImportTransform(StorageTransformEvent $event) : void { + $storage = $event->getStorage(); + + $inbound = iterator_to_array($this->toIgnore($storage), FALSE); + $current = iterator_to_array($this->toIgnore($this->activeStorage), FALSE); + + // In case a config object escaped let's deal with it. + foreach (array_diff($inbound, $current) as $to_delete) { + $storage->delete($to_delete); + } + + // Keep the current config as the current config. + foreach ($current as $to_maintain) { + $storage->write($to_maintain, $this->activeStorage->read($to_maintain)); + } + } + + /** + * Helper; yield all the configs that should not change on imports/exports. + * + * @param \Drupal\Core\Config\StorageInterface $storage + * The storage from which to enumerate configs. + * + * @return \Generator + * The names of the configs that should never be changed on imports/exports. + */ + protected function toIgnore(StorageInterface $storage) { + yield from $storage->listAll(static::MIGRATION_PREFIX); + yield from $storage->listAll(static::MIGRATION_GROUP_PREFIX); + } + +} diff --git a/src/Form/Admin.php b/src/Form/Admin.php index db5d313..9cfaa51 100644 --- a/src/Form/Admin.php +++ b/src/Form/Admin.php @@ -91,13 +91,6 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#default_value' => $current_whitelist ? implode(',', $current_whitelist) : '', '#description' => $this->t('A comma separated list of local locations from which spreadsheet ingests can use binaries.'), ]; - $form['config_ignore_integration'] = [ - '#type' => 'checkbox', - '#title' => $this->t('Enable config_ignore integration?'), - '#default_value' => $config->get('enable_config_ignore_integration'), - '#description' => $this->t('This module results in many "migrate_plus" config entities being created; however, these config entities should not typically be synchronized between systems. Therefore, we integrate with "config_ignore" to ignore the given entities.'), - '#disabled' => !$this->moduleHandler->moduleExists('config_ignore'), - ]; $form['submit'] = [ '#type' => 'submit', '#value' => $this->t('Save'), @@ -121,7 +114,6 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $whitelist = array_filter(explode(',', $form_state->getValue('paths'))); $config->set('binary_directory_whitelist', $whitelist); $config->set('schemes', array_filter($form_state->getValue('schemes'))); - $config->set('enable_config_ignore_integration', $form_state->getValue('config_ignore_integration')); $config->save(); parent::submitForm($form, $form_state); } From fbe14ac3d990bd18a80219161e640274c4269547 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Thu, 25 Jul 2024 11:19:51 -0300 Subject: [PATCH 17/17] Missed reference to the `config_ignore` setting that's no longer relevant. --- config/schema/islandora_spreadsheet_ingest.schema.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/config/schema/islandora_spreadsheet_ingest.schema.yml b/config/schema/islandora_spreadsheet_ingest.schema.yml index c304778..258d7fa 100644 --- a/config/schema/islandora_spreadsheet_ingest.schema.yml +++ b/config/schema/islandora_spreadsheet_ingest.schema.yml @@ -7,9 +7,6 @@ islandora_spreadsheet_ingest.settings: label: 'List of allowed source directories.' sequence: type: string - enable_config_ignore_integration: - type: boolean - label: 'If our config_ignore integration should be enabled.' schemes: type: sequence label: 'Allowed source URI schemes.'