Browse Source

initial commit

main
ajstanley 1 month ago
commit
c1cd174af3
  1. 19
      README.md
  2. 13
      css/form-styles.css
  3. 7
      islandora_inplace_media.info.yml
  4. 5
      islandora_inplace_media.libraries.yml
  5. 6
      islandora_inplace_media.module
  6. 7
      islandora_inplace_media.routing.yml
  7. 4
      islandora_inplace_media.services.yml
  8. 154
      src/Form/CreateMediaFromFileForm.php
  9. 120
      src/Utils.php

19
README.md

@ -0,0 +1,19 @@
## INTRODUCTION
The Islandora Inplace Media module allows ussers ti create and attach media from files staged on the server.
## INSTALLATION
Install as you would normally install a contributed Drupal module.
See: https://www.drupal.org/node/895232 for further information.
## USAGE
Navigate to islandora-inplace-media/create-media-from-file and fill in the form.
## MAINTAINERS
Current maintainers for Drupal 10:
- Robertson Library UPEI

13
css/form-styles.css

@ -0,0 +1,13 @@
/* Use Flexbox to align form fields side by side */
.media-fields-wrapper {
display: flex;
gap: 20px; /* Space between elements */
align-items: center;
}
/* Ensure each field takes up equal space */
.media-side-by-side {
flex: 1;
min-width: 200px; /* Prevents elements from getting too small */
}

7
islandora_inplace_media.info.yml

@ -0,0 +1,7 @@
name: 'Islandora Inplace Media'
type: module
description: 'Allows Uploaded files to be attched to exisitng nodes as media'
package: Custom
core_version_requirement: ^10 || ^11
dependencies:
- islandora:islandora

5
islandora_inplace_media.libraries.yml

@ -0,0 +1,5 @@
form_styles:
version: 1.x
css:
theme:
css/form-styles.css: {}

6
islandora_inplace_media.module

@ -0,0 +1,6 @@
<?php
/**
* @file
* Primary module hooks for Islandora Inplace Media module.
*/

7
islandora_inplace_media.routing.yml

@ -0,0 +1,7 @@
islandora_inplace_media.create_media_from_file:
path: '/islandora-inplace-media/create-media-from-file'
defaults:
_title: 'Create Media From File'
_form: 'Drupal\islandora_inplace_media\Form\CreateMediaFromFileForm'
requirements:
_permission: 'access content'

4
islandora_inplace_media.services.yml

@ -0,0 +1,4 @@
services:
islandora_inplace_media.utils:
class: Drupal\islandora_inplace_media\Utils
arguments: ['@entity_type.manager', '@file_system', '@logger.factory', '@entity_field.manager']

154
src/Form/CreateMediaFromFileForm.php

@ -0,0 +1,154 @@
<?php
declare(strict_types=1);
namespace Drupal\islandora_inplace_media\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\islandora_inplace_media\Utils;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides an Islandora Inplace Media form.
*/
final class CreateMediaFromFileForm extends FormBase {
/**
* The Inplace Media Utils service.
*
* @var \Drupal\islandora_inplace_media\Utils
*/
protected Utils $mediaUtils;
/**
* The entity type manager service.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* {@inheritdoc}
*/
public function __construct(Utils $mediaUtils, EntityTypeManagerInterface $entityTypeManager) {
$this->mediaUtils = $mediaUtils;
$this->entityTypeManager = $entityTypeManager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container): self {
return new self(
$container->get('islandora_inplace_media.utils'),
$container->get('entity_type.manager')
);
}
/**
* {@inheritdoc}
*/
public function getFormId(): string {
return 'islandora_inplace_media_create_media_from_file';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state): array {
$vid = 'islandora_media_use';
$terms = $this->entityTypeManager->getStorage('taxonomy_term')->loadTree($vid);
$media_use_options = [];
$term_default = '';
foreach ($terms as $term) {
$media_use_options[$term->tid] = $term->name;
if ($term->name == 'Original File') {
$term_default = $term->tid;
}
}
$media_types = $this->entityTypeManager->getStorage('media_type')->loadMultiple();
$types = array_map(fn($media_type) => $media_type->label(), $media_types);
$form['source'] = [
'#type' => 'textfield',
'#title' => $this->t('Enter full file path to input directory'),
'#required' => TRUE,
];
$form['directory'] = [
'#type' => 'textfield',
'#title' => $this->t('Enter the destination directory'),
'#required' => TRUE,
];
$form['destination'] = [
'#type' => 'radios',
'#options' => [
'public' => $this->t('Public'),
'private' => $this->t('Private'),
],
'#title' => $this->t('Select file system'),
'#required' => TRUE,
'#default_value' => 'public',
];
$form['field_wrapper'] = [
'#type' => 'container',
'#attributes' => ['class' => ['media-fields-wrapper']],
];
$form['field_wrapper']['media_type'] = [
'#title' => $this->t("Media type."),
'#type' => 'select',
'#options' => $types,
'#attributes' => ['class' => ['media-side-by-side']],
];
$form['field_wrapper']['media_use'] = [
'#title' => $this->t("Media use."),
'#type' => 'select',
'#options' => $media_use_options,
'#default_value' => $term_default,
'#attributes' => ['class' => ['media-side-by-side']],
];
$form['actions'] = [
'#type' => 'actions',
'submit' => [
'#type' => 'submit',
'#value' => $this->t('Send'),
],
];
$form['#attached']['library'][] = 'islandora_inplace_media/form_styles';
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state): void {
$source_path = $form_state->getValue('source');
if (!is_dir($source_path)) {
$form_state->setErrorByName('source', $this->t('The specified directory does not exist.'));
}
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state): void {
$source_path = $form_state->getValue('source');
$directory = trim($form_state->getValue('directory'), '/');
$file_system = $form_state->getValue('destination') === 'public' ? 'public://' : 'private://';
$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);
$this->messenger()->addStatus($this->t('Media files have been processed from %source to %destination.', [
'%source' => $source_path,
'%destination' => $destination,
]));
$form_state->setRedirect('<front>');
}
}

120
src/Utils.php

@ -0,0 +1,120 @@
<?php
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 {
/**
* Constructs a Utils object.
*/
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;
}
$default_file_field = $this->getDefaultFileField($media_type);
$this->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;
$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();
}
}
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.
*/
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;
}
// 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;
}
}
}
return NULL;
}
}
Loading…
Cancel
Save