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