From 50d6f37c1224fbc599b93047e93921102ada1092 Mon Sep 17 00:00:00 2001 From: ajstanley <alanjarlathstanley@gmail.com> Date: Wed, 19 Mar 2025 13:59:00 +0000 Subject: [PATCH] batched --- src/Form/CreateMediaFromFileForm.php | 3 +- src/Utils.php | 157 +++++++++++++-------------- 2 files changed, 75 insertions(+), 85 deletions(-) diff --git a/src/Form/CreateMediaFromFileForm.php b/src/Form/CreateMediaFromFileForm.php index 48577e9..af6d221 100644 --- a/src/Form/CreateMediaFromFileForm.php +++ b/src/Form/CreateMediaFromFileForm.php @@ -142,7 +142,8 @@ final class CreateMediaFromFileForm extends FormBase { $destination = "{$file_system}{$directory}"; $media_type = $form_state->getValue('media_type'); $media_use = $form_state->getValue('media_use'); - $results = $this->mediaUtils->buildMedia($source_path, $destination, $media_type, $media_use); + // $results = $this->mediaUtils->buildMedia($source_path, $destination, $media_type, $media_use); + $results = $this->mediaUtils->buildMediaBatch($source_path, $destination, $media_type, $media_use); $this->messenger()->addStatus($this->t('Media files have been processed from %source to %destination.', [ '%source' => $source_path, '%destination' => $destination, diff --git a/src/Utils.php b/src/Utils.php index dc59149..4281d74 100644 --- a/src/Utils.php +++ b/src/Utils.php @@ -4,117 +4,106 @@ declare(strict_types=1); namespace Drupal\islandora_inplace_media; -use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\File\FileSystemInterface; -use Drupal\Core\Logger\LoggerChannelFactoryInterface; -use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\file\Entity\File; use Drupal\media\Entity\Media; -use Drupal\media\Entity\MediaType; /** * Utility class for managing media file operations in Islandora. */ -final class Utils { +class Utils { /** - * Constructs a Utils object. + * Processes individual file. */ - public function __construct( - private readonly EntityTypeManagerInterface $entityTypeManager, - private readonly FileSystemInterface $fileSystem, - private readonly LoggerChannelFactoryInterface $loggerFactory, - private readonly EntityFieldManagerInterface $entityFieldManager, - ) {} + public static function processMediaBatch($file_name, $dir, $dest, $media_type, $media_use_tid, &$context) { + if (!isset($context['results'])) { + $context['results'] = []; + } + + $logger = \Drupal::logger('islandora_inplace_media'); + $fileSystem = \Drupal::service('file_system'); + + $source_path = $dir . '/' . $file_name; + $destination_path = $dest . '/' . $file_name; + + if (!file_exists($source_path)) { + $logger->warning('File does not exist: @file', ['@file' => $source_path]); + return; + } + + $moved_file = $fileSystem->move($source_path, $destination_path, FileSystemInterface::EXISTS_RENAME); + $new_file = File::create([ + 'uri' => $moved_file, + 'status' => 1, + ]); + $new_file->save(); + $context['results'][$new_file->id()] = $moved_file; + + if (preg_match('/^(\d+)_/', $file_name, $matches)) { + $nid = $matches[1] ?? NULL; + } + unlink($source_path); + + if ($nid) { + $media = Media::create([ + "bundle" => $media_type, + "name" => $file_name, + "field_media_file" => [ + "target_id" => $new_file->id(), + ], + 'field_media_use' => [ + "target_id" => $media_use_tid, + ], + "field_media_of" => $nid, + ]); + $media->save(); + } + } /** - * Moves files from staging to a managed folder and creates media entities. - * - * @param string $dir - * The source directory containing files. - * @param string $dest - * The destination directory (e.g., 'public://media' or 'private://media'). - * @param string $media_type - * The media type to be created. - * @param string $media_use_tid - * The terms id for new media. + * Builds batch from input directory. */ - public function buildMedia(string $dir, string $dest, string $media_type, string $media_use_tid): array { - $results = []; + public static function buildMediaBatch(string $dir, string $dest, string $media_type, string $media_use_tid) { if (!is_dir($dir)) { - $this->loggerFactory->get('islandora_inplace_media')->error('Source directory does not exist: @dir', ['@dir' => $dir]); - return $results; + \Drupal::logger('islandora_inplace_media')->error('Source directory does not exist: @dir', ['@dir' => $dir]); + return; } - $default_file_field = $this->getDefaultFileField($media_type); - $this->fileSystem->prepareDirectory($dest, FileSystemInterface::CREATE_DIRECTORY); + + // Use a service within the function, not in the batch context. + $fileSystem = \Drupal::service('file_system'); + $fileSystem->prepareDirectory($dest, FileSystemInterface::CREATE_DIRECTORY); $files = scandir($dir); $files = array_diff($files, ['.', '..']); - foreach ($files as $file_name) { - $source_path = $dir . '/' . $file_name; - $destination_path = $dest . '/' . $file_name; + $batch = [ + 'title' => t('Processing media files...'), + 'operations' => [], + // Static method reference. + 'finished' => [self::class, 'finishMediaBatch'], + ]; - $moved_file = $this->fileSystem->move($source_path, $destination_path, FileSystemInterface::EXISTS_RENAME); - $new_file = File::create([ - 'uri' => $moved_file, - 'status' => 1, - ]); - $new_file->save(); - $results[$new_file->id()] = $moved_file; - if (preg_match('/n(\d+)_/', $file_name, $matches)) { - $nid = $matches[1] ?? NULL; - } - unlink($source_path); - if ($nid) { - $media = Media::create([ - "bundle" => $media_type, - "name" => $file_name, - $default_file_field => [ - "target_id" => $new_file->id(), - ], - 'field_media_use' => [ - "target_id" => $media_use_tid, - ], - "field_media_of" => $nid, - ]); - $media->save(); - } + foreach ($files as $file_name) { + $batch['operations'][] = [ + [self::class, 'processMediaBatch'], + [$file_name, $dir, $dest, $media_type, $media_use_tid], + ]; } - return $results; + + batch_set($batch); } /** - * Get the default file field from a media type. - * - * @param string $media_type_id - * The media type ID. - * - * @return string|null - * The field name of the default file field, or NULL if none is found. + * Display results. */ - public function getDefaultFileField(string $media_type_id): ?string { - // Load the media type. - $media_type = MediaType::load($media_type_id); - if (!$media_type) { - $this->loggerFactory->get('islandora_inplace_media')->error('Media type @type not found.', ['@type' => $media_type_id]); - return NULL; + public static function finishMediaBatch($success, $results, $operations) { + if ($success) { + \Drupal::logger('islandora_inplace_media')->notice('Successfully processed media files.'); } - - // Get all field definitions for the media entity type. - $field_definitions = $this->entityFieldManager->getFieldDefinitions('media', $media_type_id); - - // Look for the first file-based field (file or image). - foreach ($field_definitions as $field_name => $field_definition) { - $storage_type = $field_definition->getType(); - if (in_array($storage_type, ['file', 'image'])) { - if ($field_name != 'thumbnail') { - return $field_name; - } - } + else { + \Drupal::logger('islandora_inplace_media')->error('There were errors processing media files.'); } - - return NULL; } }