Compare commits

...

2 Commits

Author SHA1 Message Date
ajstanley e261fdd0c0 batch processing 3 weeks ago
ajstanley 50d6f37c12 batched 3 weeks ago
  1. 2
      README.md
  2. 7
      islandora_inplace_media.links.menu.yml
  3. 3
      src/Form/CreateMediaFromFileForm.php
  4. 157
      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,

157
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;
}
}

Loading…
Cancel
Save