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
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

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}";
$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,

117
src/Utils.php

@ -4,73 +4,52 @@ 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,
) {}
/**
* 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;
public static function processMediaBatch($file_name, $dir, $dest, $media_type, $media_use_tid, &$context) {
if (!isset($context['results'])) {
$context['results'] = [];
}
$default_file_field = $this->getDefaultFileField($media_type);
$this->fileSystem->prepareDirectory($dest, FileSystemInterface::CREATE_DIRECTORY);
$files = scandir($dir);
$files = array_diff($files, ['.', '..']);
$logger = \Drupal::logger('islandora_inplace_media');
$fileSystem = \Drupal::service('file_system');
foreach ($files as $file_name) {
$source_path = $dir . '/' . $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([
'uri' => $moved_file,
'status' => 1,
]);
$new_file->save();
$results[$new_file->id()] = $moved_file;
if (preg_match('/n(\d+)_/', $file_name, $matches)) {
$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,
$default_file_field => [
"field_media_file" => [
"target_id" => $new_file->id(),
],
'field_media_use' => [
@ -81,40 +60,50 @@ final class Utils {
$media->save();
}
}
return $results;
}
/**
* 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.
* Builds batch from input directory.
*/
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 buildMediaBatch(string $dir, string $dest, string $media_type, string $media_use_tid) {
if (!is_dir($dir)) {
\Drupal::logger('islandora_inplace_media')->error('Source directory does not exist: @dir', ['@dir' => $dir]);
return;
}
// Get all field definitions for the media entity type.
$field_definitions = $this->entityFieldManager->getFieldDefinitions('media', $media_type_id);
// Use a service within the function, not in the batch context.
$fileSystem = \Drupal::service('file_system');
$fileSystem->prepareDirectory($dest, FileSystemInterface::CREATE_DIRECTORY);
// 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;
}
$files = scandir($dir);
$files = array_diff($files, ['.', '..']);
$batch = [
'title' => t('Processing media files...'),
'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