Compare commits

...

2 Commits

Author SHA1 Message Date
ajstanley e261fdd0c0 batch processing 9 months ago
ajstanley 50d6f37c12 batched 9 months ago
  1. 2
      README.md
  2. 7
      islandora_inplace_media.links.menu.yml
  3. 3
      src/Form/CreateMediaFromFileForm.php
  4. 117
      src/Utils.php

2
README.md

@ -1,6 +1,6 @@
## INTRODUCTION ## INTRODUCTION
The Islandora Inplace Media module allows users ti create and attach media from files staged on the server. The Islandora Inplace Media module allows users to create and attach media from files staged on the server.
## INSTALLATION ## INSTALLATION

7
islandora_inplace_media.links.menu.yml

@ -0,0 +1,7 @@
islandora_inplace_media.admin_media_settings:
title: 'Add media from directory'
description: 'Create media from file directory'
route_name: islandora_inplace_media.create_media_from_file
parent: system.admin_config_media
menu_name: administration
weight: 10

3
src/Form/CreateMediaFromFileForm.php

@ -142,7 +142,8 @@ final class CreateMediaFromFileForm extends FormBase {
$destination = "{$file_system}{$directory}"; $destination = "{$file_system}{$directory}";
$media_type = $form_state->getValue('media_type'); $media_type = $form_state->getValue('media_type');
$media_use = $form_state->getValue('media_use'); $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.', [ $this->messenger()->addStatus($this->t('Media files have been processed from %source to %destination.', [
'%source' => $source_path, '%source' => $source_path,
'%destination' => $destination, '%destination' => $destination,

117
src/Utils.php

@ -4,73 +4,52 @@ declare(strict_types=1);
namespace Drupal\islandora_inplace_media; namespace Drupal\islandora_inplace_media;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\File\FileSystemInterface; use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\file\Entity\File; use Drupal\file\Entity\File;
use Drupal\media\Entity\Media; use Drupal\media\Entity\Media;
use Drupal\media\Entity\MediaType;
/** /**
* Utility class for managing media file operations in Islandora. * Utility class for managing media file operations in Islandora.
*/ */
final class Utils { class Utils {
/** /**
* Constructs a Utils object. * Processes individual file.
*/ */
public function __construct( public static function processMediaBatch($file_name, $dir, $dest, $media_type, $media_use_tid, &$context) {
private readonly EntityTypeManagerInterface $entityTypeManager, if (!isset($context['results'])) {
private readonly FileSystemInterface $fileSystem, $context['results'] = [];
private readonly LoggerChannelFactoryInterface $loggerFactory,
private readonly EntityFieldManagerInterface $entityFieldManager,
) {}
/**
* 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.
*/
public function buildMedia(string $dir, string $dest, string $media_type, string $media_use_tid): array {
$results = [];
if (!is_dir($dir)) {
$this->loggerFactory->get('islandora_inplace_media')->error('Source directory does not exist: @dir', ['@dir' => $dir]);
return $results;
} }
$default_file_field = $this->getDefaultFileField($media_type);
$this->fileSystem->prepareDirectory($dest, FileSystemInterface::CREATE_DIRECTORY);
$files = scandir($dir); $logger = \Drupal::logger('islandora_inplace_media');
$files = array_diff($files, ['.', '..']); $fileSystem = \Drupal::service('file_system');
foreach ($files as $file_name) {
$source_path = $dir . '/' . $file_name; $source_path = $dir . '/' . $file_name;
$destination_path = $dest . '/' . $file_name; $destination_path = $dest . '/' . $file_name;
$moved_file = $this->fileSystem->move($source_path, $destination_path, FileSystemInterface::EXISTS_RENAME); 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([ $new_file = File::create([
'uri' => $moved_file, 'uri' => $moved_file,
'status' => 1, 'status' => 1,
]); ]);
$new_file->save(); $new_file->save();
$results[$new_file->id()] = $moved_file; $context['results'][$new_file->id()] = $moved_file;
if (preg_match('/n(\d+)_/', $file_name, $matches)) {
if (preg_match('/^(\d+)_/', $file_name, $matches)) {
$nid = $matches[1] ?? NULL; $nid = $matches[1] ?? NULL;
} }
unlink($source_path); unlink($source_path);
if ($nid) { if ($nid) {
$media = Media::create([ $media = Media::create([
"bundle" => $media_type, "bundle" => $media_type,
"name" => $file_name, "name" => $file_name,
$default_file_field => [ "field_media_file" => [
"target_id" => $new_file->id(), "target_id" => $new_file->id(),
], ],
'field_media_use' => [ 'field_media_use' => [
@ -81,40 +60,50 @@ final class Utils {
$media->save(); $media->save();
} }
} }
return $results;
}
/** /**
* Get the default file field from a media type. * Builds batch from input directory.
*
* @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.
*/ */
public function getDefaultFileField(string $media_type_id): ?string { public static function buildMediaBatch(string $dir, string $dest, string $media_type, string $media_use_tid) {
// Load the media type. if (!is_dir($dir)) {
$media_type = MediaType::load($media_type_id); \Drupal::logger('islandora_inplace_media')->error('Source directory does not exist: @dir', ['@dir' => $dir]);
if (!$media_type) { return;
$this->loggerFactory->get('islandora_inplace_media')->error('Media type @type not found.', ['@type' => $media_type_id]);
return NULL;
} }
// Get all field definitions for the media entity type. // Use a service within the function, not in the batch context.
$field_definitions = $this->entityFieldManager->getFieldDefinitions('media', $media_type_id); $fileSystem = \Drupal::service('file_system');
$fileSystem->prepareDirectory($dest, FileSystemInterface::CREATE_DIRECTORY);
// Look for the first file-based field (file or image). $files = scandir($dir);
foreach ($field_definitions as $field_name => $field_definition) { $files = array_diff($files, ['.', '..']);
$storage_type = $field_definition->getType();
if (in_array($storage_type, ['file', 'image'])) { $batch = [
if ($field_name != 'thumbnail') { 'title' => t('Processing media files...'),
return $field_name; 'operations' => [],
} // Static method reference.
'finished' => [self::class, 'finishMediaBatch'],
];
foreach ($files as $file_name) {
$batch['operations'][] = [
[self::class, 'processMediaBatch'],
[$file_name, $dir, $dest, $media_type, $media_use_tid],
];
} }
batch_set($batch);
} }
return NULL; /**
* Display results.
*/
public static function finishMediaBatch($success, $results, $operations) {
if ($success) {
\Drupal::logger('islandora_inplace_media')->notice('Successfully processed media files.');
}
else {
\Drupal::logger('islandora_inplace_media')->error('There were errors processing media files.');
}
} }
} }

Loading…
Cancel
Save