4 changed files with 153 additions and 0 deletions
@ -0,0 +1,6 @@
|
||||
services: |
||||
pdf_action.commands: |
||||
class: Drupal\pdf_action\Commands\PdfDerivativeCommands |
||||
arguments: ['@entity_type.manager'] |
||||
tags: |
||||
- { name: drush.command } |
||||
@ -0,0 +1,6 @@
|
||||
services: |
||||
pdf_action.commands: |
||||
class: Drupal\pdf_action\Commands\PdfDerivativeCommands |
||||
arguments: ['@entity_type.manager'] |
||||
tags: |
||||
- { name: drush.command } |
||||
@ -0,0 +1,137 @@
|
||||
<?php |
||||
|
||||
namespace Drupal\pdf_action\Commands; |
||||
|
||||
use Drush\Commands\DrushCommands; |
||||
use Drupal\Core\Entity\EntityTypeManagerInterface; |
||||
use Symfony\Component\DependencyInjection\ContainerInterface; |
||||
|
||||
class PdfDerivativeCommands extends DrushCommands { |
||||
|
||||
protected EntityTypeManagerInterface $entityTypeManager; |
||||
|
||||
public function __construct(EntityTypeManagerInterface $entityTypeManager) { |
||||
parent::__construct(); |
||||
$this->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."); |
||||
} |
||||
} |
||||
} |
||||
Loading…
Reference in new issue