6 changed files with 168 additions and 5 deletions
@ -0,0 +1,7 @@ |
|||||||
|
services: |
||||||
|
islandora_inplace_media.commands: |
||||||
|
class: Drupal\islandora_inplace_media\Commands\IslandoraInplaceMediaCommands |
||||||
|
arguments: |
||||||
|
- '@islandora_inplace_media.processor' |
||||||
|
tags: |
||||||
|
- { name: drush.command } |
||||||
@ -1,7 +1,7 @@ |
|||||||
name: 'Islandora Inplace Media' |
name: 'Islandora Inplace Media' |
||||||
type: module |
type: module |
||||||
description: 'Allows Uploaded files to be attched to exisitng nodes as media' |
description: 'Allows Uploaded files to be attached to existing nodes as media' |
||||||
package: Custom |
package: Islandora |
||||||
core_version_requirement: ^10 || ^11 |
core_version_requirement: ^10 || ^11 |
||||||
dependencies: |
dependencies: |
||||||
- islandora:islandora |
- islandora:islandora |
||||||
|
|||||||
@ -1,4 +1,13 @@ |
|||||||
services: |
services: |
||||||
islandora_inplace_media.utils: |
|
||||||
class: Drupal\islandora_inplace_media\Utils |
logger.channel.islandora_inplace_media: |
||||||
arguments: ['@entity_type.manager', '@file_system', '@logger.factory', '@entity_field.manager'] |
class: Drupal\Core\Logger\LoggerChannel |
||||||
|
factory: logger.factory:get |
||||||
|
arguments: ['islandora_inplace_media'] |
||||||
|
|
||||||
|
islandora_inplace_media.processor: |
||||||
|
class: Drupal\islandora_inplace_media\Service\InplaceMediaProcessor |
||||||
|
arguments: |
||||||
|
- '@file_system' |
||||||
|
- '@file.repository' |
||||||
|
- '@logger.channel.islandora_inplace_media' |
||||||
|
|||||||
@ -0,0 +1,77 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\islandora_inplace_media\Commands; |
||||||
|
|
||||||
|
use Drush\Commands\DrushCommands; |
||||||
|
use Drupal\islandora_inplace_media\Service\InplaceMediaProcessor; |
||||||
|
use Symfony\Component\Console\Helper\ProgressBar; |
||||||
|
|
||||||
|
class IslandoraInplaceMediaCommands extends DrushCommands { |
||||||
|
|
||||||
|
public function __construct( |
||||||
|
protected InplaceMediaProcessor $processor |
||||||
|
) { |
||||||
|
parent::__construct(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Create Islandora media from files. |
||||||
|
* |
||||||
|
* @command islandora:inplace-media |
||||||
|
* @aliases iim |
||||||
|
* |
||||||
|
* @option source_dir |
||||||
|
* Source directory containing files. |
||||||
|
* @option destination_path |
||||||
|
* Destination directory (public://, private://, or absolute). |
||||||
|
* @option media_type |
||||||
|
* Media bundle machine name. |
||||||
|
* @option media_use |
||||||
|
* Taxonomy term ID for field_media_use. |
||||||
|
* @option file_type |
||||||
|
* Media file field name. |
||||||
|
* @option limit |
||||||
|
* Maximum number of files to process. |
||||||
|
* @option offset |
||||||
|
* Number of files to skip before processing. |
||||||
|
* @option queue |
||||||
|
* Queue files instead of processing immediately. |
||||||
|
*/ |
||||||
|
public function run(array $options = [ |
||||||
|
'source_dir' => NULL, |
||||||
|
'destination_path' => NULL, |
||||||
|
'media_type' => NULL, |
||||||
|
'media_use' => NULL, |
||||||
|
'file_type' => 'field_media_file', |
||||||
|
'limit' => NULL, |
||||||
|
'offset' => 0, |
||||||
|
'queue' => FALSE, |
||||||
|
]) { |
||||||
|
$files = array_values(array_diff(scandir($options['source_dir']), ['.', '..'])); |
||||||
|
|
||||||
|
if ($options['offset']) { |
||||||
|
$files = array_slice($files, (int) $options['offset']); |
||||||
|
} |
||||||
|
if ($options['limit']) { |
||||||
|
$files = array_slice($files, 0, (int) $options['limit']); |
||||||
|
} |
||||||
|
|
||||||
|
$progress = new ProgressBar($this->output(), count($files)); |
||||||
|
$progress->start(); |
||||||
|
|
||||||
|
foreach ($files as $file) { |
||||||
|
if ($options['queue']) { |
||||||
|
\Drupal::queue('islandora_inplace_media') |
||||||
|
->createItem(['file' => $file, 'options' => $options]); |
||||||
|
} |
||||||
|
else { |
||||||
|
$this->processor->processFile($file, $options); |
||||||
|
} |
||||||
|
$progress->advance(); |
||||||
|
} |
||||||
|
|
||||||
|
$progress->finish(); |
||||||
|
$this->output()->writeln(''); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,21 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\islandora_inplace_media\Plugin\QueueWorker; |
||||||
|
|
||||||
|
use Drupal\Core\Queue\QueueWorkerBase; |
||||||
|
|
||||||
|
/** |
||||||
|
* @QueueWorker( |
||||||
|
* id = "islandora_inplace_media", |
||||||
|
* title = @Translation("Islandora Inplace Media"), |
||||||
|
* cron = {"time" = 60} |
||||||
|
* ) |
||||||
|
*/ |
||||||
|
class InplaceMediaQueueWorker extends QueueWorkerBase { |
||||||
|
|
||||||
|
public function processItem($data) { |
||||||
|
\Drupal::service('islandora_inplace_media.processor') |
||||||
|
->processFile($data['file'], $data['options']); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,49 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\islandora_inplace_media\Service; |
||||||
|
|
||||||
|
use Drupal\Core\File\FileSystemInterface; |
||||||
|
use Drupal\file\FileRepositoryInterface; |
||||||
|
use Drupal\Core\File\FileExists; |
||||||
|
use Drupal\file\Entity\File; |
||||||
|
use Drupal\media\Entity\Media; |
||||||
|
use Psr\Log\LoggerInterface; |
||||||
|
|
||||||
|
class InplaceMediaProcessor { |
||||||
|
|
||||||
|
public function __construct( |
||||||
|
protected FileSystemInterface $fileSystem, |
||||||
|
protected FileRepositoryInterface $fileRepository, |
||||||
|
protected LoggerInterface $logger, |
||||||
|
) {} |
||||||
|
|
||||||
|
public function processFile(string $file, array $opts): void { |
||||||
|
$source = "{$opts['source_dir']}/{$file}"; |
||||||
|
$dest = "{$opts['destination_path']}/{$file}"; |
||||||
|
|
||||||
|
if (!file_exists($source)) { |
||||||
|
$this->logger->warning('Missing file @file', ['@file' => $source]); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$uri = ($source === $dest) |
||||||
|
? $dest |
||||||
|
: $this->fileSystem->copy($source, $dest, FileExists::Rename); |
||||||
|
|
||||||
|
$fileEntity = $this->fileRepository->loadByUri($uri) |
||||||
|
?? File::create(['uri' => $uri, 'status' => 1, 'uid' => 1]); |
||||||
|
$fileEntity->save(); |
||||||
|
preg_match('/^(\d+)_/', $file, $m); |
||||||
|
$nid = $m[1] ?? NULL; |
||||||
|
|
||||||
|
Media::create([ |
||||||
|
'bundle' => $opts['media_type'], |
||||||
|
'name' => $file, |
||||||
|
'uid' => 1, |
||||||
|
$opts['file_type'] => ['target_id' => $fileEntity->id()], |
||||||
|
'field_media_use' => ['target_id' => $opts['media_use']], |
||||||
|
'field_media_of' => $nid, |
||||||
|
])->save(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
Loading…
Reference in new issue