9 changed files with 383 additions and 118 deletions
@ -0,0 +1,80 @@
|
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace Drupal\islandora_batch_action\Batch; |
||||
|
||||
use Drupal\Core\Batch\BatchBuilder; |
||||
|
||||
/** |
||||
* Provides a batch job to perform a Drupal Action on a list of node IDs. |
||||
*/ |
||||
final class ActionBatch { |
||||
|
||||
/** |
||||
* Executes the batch job. |
||||
* |
||||
* @param array $entity_ids |
||||
* An array of entity IDs. |
||||
* @param string $action_id |
||||
* The action plugin ID to perform on each node. |
||||
* @param string $entity_type |
||||
* Must be either node or media |
||||
*/ |
||||
public function run(array $entity_ids, string $action_id, string $entity_type): void { |
||||
$batch_builder = new BatchBuilder(); |
||||
|
||||
$batch_builder->setTitle(t('Performing batch action on entities.')) |
||||
->setInitMessage(t('Starting the batch action.')) |
||||
->setProgressMessage(t('Processing @current out of @total.')) |
||||
->setErrorMessage(t('An error occurred.')); |
||||
|
||||
foreach ($entity_ids as $entity_id) { |
||||
$batch_builder->addOperation([__CLASS__, 'processEntity'], [ |
||||
$entity_id, |
||||
$action_id, |
||||
$entity_type, |
||||
]); |
||||
} |
||||
batch_set($batch_builder->toArray()); |
||||
} |
||||
|
||||
/** |
||||
* Processes an individual entity for the batch operation. |
||||
* |
||||
* @param int $entity_id |
||||
* The entity ID to process. |
||||
* @param string $action_id |
||||
* The action plugin ID. |
||||
* @param array $context |
||||
* The batch context array. |
||||
*/ |
||||
public static function processEntity(int $entity_id, string $action_id, string $entity_type, array &$context): void { |
||||
$entityTypeManager = \Drupal::service('entity_type.manager'); |
||||
$entity = $entityTypeManager->getStorage($entity_type)->load($entity_id); |
||||
if (!$entity) { |
||||
$context['results']['failed'][] = $entity_id; |
||||
return; |
||||
} |
||||
$action_storage = $entityTypeManager->getStorage('action'); |
||||
$configured_action = $action_storage->load($action_id); |
||||
|
||||
if (!$configured_action) { |
||||
$context['results']['failed'][] = $entity_id; |
||||
return; |
||||
} |
||||
try { |
||||
$configured_action->execute([$entity]); |
||||
$context['results']['processed'][] = $entity_id; |
||||
} |
||||
catch (\Exception $e) { |
||||
\Drupal::logger('islandora_batch_action') |
||||
->error('Batch action failed for node @nid: @message', [ |
||||
'@nid' => $entity_id, |
||||
'@message' => $e->getMessage(), |
||||
]); |
||||
$context['results']['failed'][] = $entity_id; |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -1,76 +0,0 @@
|
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace Drupal\islandora_batch_action\Batch; |
||||
|
||||
use Drupal\Core\Batch\BatchBuilder; |
||||
|
||||
/** |
||||
* Provides a batch job to perform a Drupal Action on a list of node IDs. |
||||
*/ |
||||
final class NodeActionBatch { |
||||
|
||||
/** |
||||
* Executes the batch job. |
||||
* |
||||
* @param array $node_ids |
||||
* An array of node IDs. |
||||
* @param string $action_id |
||||
* The action plugin ID to perform on each node. |
||||
*/ |
||||
public function run(array $node_ids, string $action_id): void { |
||||
$batch_builder = new BatchBuilder(); |
||||
|
||||
$batch_builder->setTitle(t('Performing batch action on nodes.')) |
||||
->setInitMessage(t('Starting the batch action.')) |
||||
->setProgressMessage(t('Processing @current out of @total.')) |
||||
->setErrorMessage(t('An error occurred.')); |
||||
|
||||
// Register the operation for each node. |
||||
foreach ($node_ids as $node_id) { |
||||
$batch_builder->addOperation([__CLASS__, 'processNode'], [$node_id, $action_id]); |
||||
} |
||||
|
||||
batch_set($batch_builder->toArray()); |
||||
} |
||||
|
||||
/** |
||||
* Processes an individual node for the batch operation. |
||||
* |
||||
* @param int $node_id |
||||
* The node ID to process. |
||||
* @param string $action_id |
||||
* The action plugin ID. |
||||
* @param array $context |
||||
* The batch context array. |
||||
*/ |
||||
public static function processNode(int $node_id, string $action_id, array &$context): void { |
||||
$entityTypeManager = \Drupal::service('entity_type.manager'); |
||||
$node = $entityTypeManager->getStorage('node')->load($node_id); |
||||
if (!$node) { |
||||
$context['results']['failed'][] = $node_id; |
||||
return; |
||||
} |
||||
$action_storage = $entityTypeManager->getStorage('action'); |
||||
$configured_action = $action_storage->load($action_id); |
||||
|
||||
if (!$configured_action) { |
||||
$context['results']['failed'][] = $node_id; |
||||
return; |
||||
} |
||||
try { |
||||
$configured_action->execute([$node]); |
||||
$context['results']['processed'][] = $node_id; |
||||
} |
||||
catch (\Exception $e) { |
||||
\Drupal::logger('islandora_batch_action')->error('Batch action failed for node @nid: @message', [ |
||||
'@nid' => $node_id, |
||||
'@message' => $e->getMessage(), |
||||
]); |
||||
$context['results']['failed'][] = $node_id; |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,100 @@
|
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace Drupal\islandora_batch_action\Form; |
||||
|
||||
use Drupal\Core\Form\FormBase; |
||||
use Drupal\Core\Form\FormStateInterface; |
||||
use Symfony\Component\DependencyInjection\ContainerInterface; |
||||
use Drupal\islandora_batch_action\IslandoraBatchActionUtils; |
||||
use Drupal\media\Entity\MediaType; |
||||
use Drupal\islandora_batch_action\Batch\ActionBatch; |
||||
|
||||
/** |
||||
* Provides a Islandora Batch Action form. |
||||
*/ |
||||
final class MediaActionsForm extends FormBase { |
||||
|
||||
/** |
||||
* The Batch Action Utils service. |
||||
* |
||||
* @var \Drupal\islandora_batch_action\IslandoraBatchActionUtils |
||||
*/ |
||||
protected IslandoraBatchActionUtils $islandoraBatchActionUtils; |
||||
|
||||
/** |
||||
* The batch job service. |
||||
* |
||||
* @var \Drupal\islandora_batch_action\Batch\ActionBatch |
||||
*/ |
||||
protected ActionBatch $batchJob; |
||||
|
||||
public function __construct(IslandoraBatchActionUtils $islandoraBatchActionUtils, ActionBatch $batchJob,) { |
||||
$this->islandoraBatchActionUtils = $islandoraBatchActionUtils; |
||||
$this->batchJob = $batchJob; |
||||
} |
||||
|
||||
public static function create(ContainerInterface $container) { |
||||
return new static( |
||||
$container->get('islandora_batch_action.utils'), |
||||
$container->get('islandora_batch_action.action_batch'), |
||||
); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
public function getFormId(): string { |
||||
return 'islandora_batch_action_generate_dimensions'; |
||||
} |
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
public function buildForm(array $form, FormStateInterface $form_state): array { |
||||
|
||||
$form['media_type'] = [ |
||||
'#type' => 'select', |
||||
'#title' => $this->t('Media Type'), |
||||
'#options' => $this->islandoraBatchActionUtils->getMediaOptions(), |
||||
'#required' => TRUE, |
||||
]; |
||||
$form['usage'] = [ |
||||
'#type' => 'select', |
||||
'#title' => $this->t('Media Use'), |
||||
'#options' => $this->islandoraBatchActionUtils->getVocabularyOptions('islandora_media_use'), |
||||
'#required' => TRUE, |
||||
]; |
||||
$form['media_action'] = [ |
||||
'#type' => 'select', |
||||
'#title' => $this->t('Action'), |
||||
'#options' => $this->islandoraBatchActionUtils->getMediaActions(), |
||||
'#required' => TRUE, |
||||
]; |
||||
|
||||
$form['actions'] = [ |
||||
'#type' => 'actions', |
||||
'submit' => [ |
||||
'#type' => 'submit', |
||||
'#value' => $this->t('Create batch'), |
||||
], |
||||
]; |
||||
|
||||
return $form; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* {@inheritdoc} |
||||
*/ |
||||
public function submitForm(array &$form, FormStateInterface $form_state): void { |
||||
$media_type = $form_state->getValue('media_type'); |
||||
$tid = $form_state->getValue('usage'); |
||||
$mids = $this->islandoraBatchActionUtils->getMediaList($media_type, $tid); |
||||
$action_id = $form_state->getValue('media_action'); |
||||
$this->batchJob->run($mids, $action_id, 'media'); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,85 @@
|
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace Drupal\islandora_batch_action\Plugin\Action; |
||||
|
||||
use Drupal\Core\Access\AccessResultInterface; |
||||
use Drupal\Core\Action\ActionBase; |
||||
use Drupal\Core\Annotation\Action; |
||||
use Drupal\Core\Entity\ContentEntityInterface; |
||||
use Drupal\Core\Entity\EntityTypeManagerInterface; |
||||
use Drupal\Core\File\FileSystemInterface; |
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface; |
||||
use Drupal\Core\Session\AccountInterface; |
||||
use Symfony\Component\DependencyInjection\ContainerInterface; |
||||
|
||||
|
||||
/** |
||||
* Provides a Generate Image Media Dimensions action. |
||||
* |
||||
* @Action( |
||||
* id = "islandora_batch_action_generate_image_media_dimensions", |
||||
* label = @Translation("Generate Image Media Dimensions"), |
||||
* type = "media", |
||||
* category = @Translation("Custom"), |
||||
* ) |
||||
*/ |
||||
final class GenerateImageMediaDimensions extends ActionBase implements ContainerFactoryPluginInterface { |
||||
|
||||
/** |
||||
* Constructor. |
||||
*/ |
||||
public function __construct( |
||||
array $configuration, |
||||
$plugin_id, |
||||
$plugin_definition, |
||||
private readonly EntityTypeManagerInterface $entityTypeManager, |
||||
private readonly FileSystemInterface $fileSystem |
||||
) { |
||||
parent::__construct($configuration, $plugin_id, $plugin_definition); |
||||
} |
||||
|
||||
/** |
||||
* Dependency injection factory. |
||||
*/ |
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): self { |
||||
return new self( |
||||
$configuration, |
||||
$plugin_id, |
||||
$plugin_definition, |
||||
$container->get('entity_type.manager'), |
||||
$container->get('file_system') |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* Access check. |
||||
*/ |
||||
public function access($entity, AccountInterface $account = NULL, $return_as_object = FALSE): AccessResultInterface|bool { |
||||
$access = $entity->access('update', $account, TRUE) |
||||
->andIf($entity->get('field_height')->access('edit', $account, TRUE)); |
||||
return $return_as_object ? $access : $access->isAllowed(); |
||||
} |
||||
|
||||
/** |
||||
* Action execution. |
||||
*/ |
||||
public function execute(ContentEntityInterface $entity = NULL): void { |
||||
$height = $entity->get('field_height')->getValue()[0]['value']; |
||||
$width = $entity->get('field_width')->getValue()[0]['value']; |
||||
$field = $entity->hasField('field_media_file') ? 'field_media_file' : 'field_media_image'; |
||||
if (!$width || !$height) { |
||||
if ($entity->hasField($field) && !$entity->get($field)->isEmpty()) { |
||||
$file = $entity->get($field)->entity; |
||||
$realpath = $this->fileSystem->realpath($file->getFileUri()); |
||||
$dimensions = getimagesize($realpath); |
||||
if ($dimensions) { |
||||
$entity->set('field_height', $dimensions[1]); |
||||
$entity->set('field_width', $dimensions[0]); |
||||
$entity->save(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
Loading…
Reference in new issue