diff --git a/drush.services.yml b/drush.services.yml new file mode 100644 index 0000000..642ed84 --- /dev/null +++ b/drush.services.yml @@ -0,0 +1,6 @@ +services: + pdf_action.commands: + class: Drupal\pdf_action\Commands\PdfDerivativeCommands + arguments: ['@entity_type.manager'] + tags: + - { name: drush.command } diff --git a/pdf_action.services.yml b/pdf_action.services.yml new file mode 100644 index 0000000..642ed84 --- /dev/null +++ b/pdf_action.services.yml @@ -0,0 +1,6 @@ +services: + pdf_action.commands: + class: Drupal\pdf_action\Commands\PdfDerivativeCommands + arguments: ['@entity_type.manager'] + tags: + - { name: drush.command } diff --git a/src/Commands/PdfDerivativeCommands.php b/src/Commands/PdfDerivativeCommands.php new file mode 100644 index 0000000..07bb7d6 --- /dev/null +++ b/src/Commands/PdfDerivativeCommands.php @@ -0,0 +1,137 @@ +entityTypeManager = $entityTypeManager; + } + + public static function create(ContainerInterface $container): self { + return new static( + $container->get('entity_type.manager') + ); + } + + /** + * Generate PDF derivatives using flexible filters. + * + * @command pdf:derive + * + * @option model Filter by field_model taxonomy term ID(s), comma separated + * @option nid-start Minimum NID + * @option nid-end Maximum NID + * @option nids Explicit NID list (comma separated) + * @option limit Max number of nodes to process + * @option chunk Chunk size for processing (default 50) + * @option dry-run Show what would run without executing action + */ + public function derive(array $options = [ + 'model' => NULL, + 'nid-start' => NULL, + 'nid-end' => NULL, + 'nids' => NULL, + 'limit' => NULL, + 'chunk' => 50, + 'dry-run' => FALSE, + ]) { + + $query = $this->entityTypeManager + ->getStorage('node') + ->getQuery() + ->accessCheck(FALSE); + + // --- Model filter --- + if (!empty($options['model'])) { + $models = array_map('intval', explode(',', $options['model'])); + $query->condition('field_model.target_id', $models, 'IN'); + $this->logger()->notice('Filtering by model: ' . implode(',', $models)); + } + + // --- NID range --- + if (!empty($options['nid-start'])) { + $query->condition('nid', (int) $options['nid-start'], '>='); + } + + if (!empty($options['nid-end'])) { + $query->condition('nid', (int) $options['nid-end'], '<='); + } + + // --- Explicit NIDs --- + if (!empty($options['nids'])) { + $nids = array_map('intval', explode(',', $options['nids'])); + $query->condition('nid', $nids, 'IN'); + } + + // --- Limit --- + if (!empty($options['limit'])) { + $query->range(0, (int) $options['limit']); + } + + $nids = $query->execute(); + + if (!$nids) { + $this->logger()->warning('No nodes matched.'); + return; + } + + $total = count($nids); + $this->logger()->notice("Matched $total nodes."); + + // Load action + $action = $this->entityTypeManager + ->getStorage('action') + ->load('create_pdf_derivative'); + + if (!$action) { + $this->logger()->error('Action pdf_action_create_pdf_derivative not found.'); + return; + } + + $node_storage = $this->entityTypeManager->getStorage('node'); + + $processed = 0; + $chunk_size = max(1, (int) $options['chunk']); + $dry_run = !empty($options['dry-run']); + + foreach (array_chunk($nids, $chunk_size) as $chunk) { + + $nodes = $node_storage->loadMultiple($chunk); + + foreach ($nodes as $node) { + + if ($dry_run) { + $this->logger()->notice("DRY RUN: Would process NID {$node->id()}"); + continue; + } + + try { + $action->execute($node); + $processed++; + } + catch (\Throwable $e) { + $this->logger()->error("Failed NID {$node->id()}: {$e->getMessage()}"); + } + } + + if (!$dry_run) { + $this->logger()->notice("Processed $processed / $total"); + } + } + + if ($dry_run) { + $this->logger()->success("Dry run complete. $total nodes matched."); + } + else { + $this->logger()->success("Done. Processed $processed nodes."); + } + } +} diff --git a/src/Plugin/Action/CreatePdfDerivative.php b/src/Plugin/Action/CreatePdfDerivative.php index 22fe965..2226913 100644 --- a/src/Plugin/Action/CreatePdfDerivative.php +++ b/src/Plugin/Action/CreatePdfDerivative.php @@ -116,6 +116,10 @@ final class CreatePdfDerivative extends ConfigurableActionBase implements Contai public function execute(ContentEntityInterface $entity = NULL): void { $identifier = $this->configuration['media_use_identifier']; $pdf_term = $this->islandoraUtils->getTermForUri($identifier); + $media = $this->islandoraUtils->getMediaWithTerm($entity, $pdf_term); + if ($media) { + return; + } $terms = [ $this->islandoraUtils->getTermForUri('http://pcdm.org/use#ServiceFile'), $this->islandoraUtils->getTermForUri('http://pcdm.org/use#OriginalFile'),