diff --git a/drush.10-11.services.yml b/drush.10-11.services.yml index 708e827..854b610 100644 --- a/drush.10-11.services.yml +++ b/drush.10-11.services.yml @@ -19,3 +19,15 @@ services: ] tags: - { name: drush.command } + dgi_actions.update_identifier_locations: + class: \Drupal\dgi_actions\Drush\Commands\UpdateIdentifierLocations + arguments: [ + '@http_client', + '@entity_type.manager', + '@dgi_actions.utils', + '@dgi_actions.dgiutils', + '@islandora.utils', + '@logger.channel.dgi_actions' + ] + tags: + - { name: drush.command } diff --git a/src/Drush/Commands/UpdateIdentifierLocations.php b/src/Drush/Commands/UpdateIdentifierLocations.php new file mode 100644 index 0000000..81af0ad --- /dev/null +++ b/src/Drush/Commands/UpdateIdentifierLocations.php @@ -0,0 +1,250 @@ +client = $client; + $this->entityTypeManager = $entity_type_manager; + $this->identifierUtils = $identifier_utils; + $this->utils = $utils; + $this->islandoraUtils = $islandora_utils; + $this->ourLogger = $logger; + } + + /** + * {@inheritDoc} + */ + public static function create(ContainerInterface $container) : self { + return new static( + $container->get('http_client'), + $container->get('entity_type.manager'), + $container->get('dgi_actions.identifier_utils'), + $container->get('dgi_actions.utils'), + $container->get('islandora.utils'), + $container->get('logger.channel.dgi_actions') + ); + } + + /** + * Generates missing identifiers for entities. + * + * Mints missing identifiers of a configured identifier service and updates + * the target entity in the configured field if a missing identifier was + * minted. + * + * @param array $options + * An array containing options passed to the generate command containing: + * -identifier_id: The DGI Actions Identifier being targeted for use in the + * generation process. + * -ids: Comma separated list of IDs to be targeted or all entities if not + * specified. + * + * @command dgi_actions:update_identifier_locations + * + * @option identifier_id + * A string pointing to the DGI Actions Identifier ID to be used for the + * generation. + * @option ids + * A comma separated list of IDs to be targeted or all entities if not + * specified. + * + * @aliases da:update_identifier_locations + * + * @usage dgi_actions:update_identifier_locations --identifier_id=handle + * Generates missing identifiers by searching all entities for the "handle" + * DGI Actions Identifier entity. + * @usage dgi_actions:update_identifier_locations --identifier_id=handle --ids=1,2,3 + * Generates missing identifiers for the entities with IDs of 1, 2, or 3 for + * the "handle" DGI Actions Identifier entity. + */ + public function generate(array $options = [ + 'identifier_id' => self::REQ, + 'ids' => self::OPT, + ]): void { + $identifier = $this->entityTypeManager->getStorage('dgiactions_identifier')->load($options['identifier_id']); + $ids = $options['ids']; + $batch = [ + 'title' => dt('Generating identifiers...'), + 'operations' => [ + [ + [$this, 'generateBatch'], [ + $identifier, + $ids, + ], + ], + ], + ]; + drush_op('batch_set', $batch); + drush_op('drush_backend_batch_process'); + } + + /** + * Validates the generate command. + * + * @hook validate dgi_actions:generate + */ + public function updateValidate(CommandData $data) { + $options = $data->getArgsAndOptions(); + + if (empty($options['options']['identifier_id'])) { + return new CommandError(dt('An "identifier_id" must be specified.')); + } + $identifiers = $this->identifierUtils->getIdentifiers(); + if (!isset($identifiers[$options['options']['identifier_id']])) { + return new CommandError(dt('The DGI Actions identifier entity (!id) does not exist.', ['!id' => $options['options']['identifier_id']])); + } + } + + /** + * Batch for updating NULL field_weight values where siblings are integers. + * + * @param \Drupal\dgi_actions\Entity\IdentifierInterface $identifier + * The DGI Actions Identifier ID to be used for the generation. + * @param string|null $ids + * The IDs to go generate identifiers for or NULL if the entire repository. + * @param array|\DrushBatchContext $context + * Batch context. + */ + public function generateBatch(IdentifierInterface $identifier, ?string $ids, &$context): void { + $sandbox =& $context['sandbox']; + + $entity_type = $identifier->get('entity'); + $entity_id_key = $this->entityTypeManager->getDefinition($entity_type)->getKeys()['id']; + + $entity_storage = $this->entityTypeManager->getStorage($entity_type); + $query = $entity_storage->getQuery() + ->accessCheck(FALSE); + + $query->condition('field_handle', '', '<>'); + + if ($ids) { + $query->condition($entity_id_key, explode(',', $ids), 'IN'); + } + + if (!isset($sandbox['total'])) { + $count_query = clone $query; + $sandbox['total'] = $count_query->count()->execute(); + if ($sandbox['total'] === 0) { + $context['message'] = dt('Batch empty.'); + $context['finished'] = 1; + return; + } + $sandbox['last_id'] = FALSE; + $sandbox['completed'] = 0; + } + + if ($sandbox['last_id']) { + $query->condition($entity_id_key, $sandbox['last_id'], '>'); + } + $query->sort($entity_id_key); + $query->range(0, 10); + + foreach ($query->execute() as $result) { + try { + $sandbox['last_id'] = $result; + + $entity = $this->entityTypeManager->getStorage($entity_type)->load($result); + $this->ourLogger->debug('Attempting to generate/validate location for {entity} {entity_id}.', [ + 'entity' => $entity_type, + 'entity_id' => $result, + ]); + if (!$entity) { + // $identifier = $node->get($identifier_field)->getString(); + // $response = \Drupal::service('http_client')->request('GET', $identifier); + // Parse the response to get the actual location. + // Does the location from the response = what we expect generated with the new change? + } + } + catch (\Exception $e) { + $this->ourLogger->error( + 'Encountered an exception: {exception}', [ + 'exception' => $e, + ] + ); + } + $sandbox['completed']++; + $context['finished'] = $sandbox['completed'] / $sandbox['total']; + } + } + +}