You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

303 lines
9.4 KiB

<?php
declare(strict_types=1);
namespace Drupal\islandora_inplace_media\Form;
use Drupal\Core\StreamWrapper\StreamWrapperInterface;
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;
use Drupal\Core\Url;
use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
use Drupal\field\Entity\FieldConfig;
/**
* 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;
/**
* The stream wrapper service.
*
* @var \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface
*/
protected $streamWrapperManager;
/**
* Media field mapping.
*
* @var array
*/
protected $fileTypes = [
'audio' => 'field_media_audio_file',
'document' => 'field_media_document',
'file' => 'field_media_file',
'image' => 'field_media_image',
'video' => 'field_media_video_file',
];
/**
* {@inheritdoc}
*/
public function __construct(Utils $mediaUtils, EntityTypeManagerInterface $entityTypeManager, StreamWrapperManagerInterface $streamWrapperManager) {
$this->mediaUtils = $mediaUtils;
$this->entityTypeManager = $entityTypeManager;
$this->streamWrapperManager = $streamWrapperManager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container): self {
return new self(
$container->get('islandora_inplace_media.utils'),
$container->get('entity_type.manager'),
$container->get('stream_wrapper_manager')
);
}
/**
* {@inheritdoc}
*/
public function getFormId(): string {
return 'islandora_inplace_media_create_media_from_file';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state): array {
$server_software = $_SERVER['SERVER_SOFTWARE'] ?? '';
$default_ownership = match (TRUE) {
str_contains($server_software, 'apache') => 'www-data:www-data',
str_contains($server_software, 'nginx') => 'nginx:nginx',
default => 'unknown:unknown',
};
$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;
}
}
$wrappers = $this->streamWrapperManager->getWrappers();
$file_system_options = [];
$file_system_options['default'] = $this->t("File system defined in media type");
$unwanted = ['temporary', 'assets', 'temporary', 'library-definitions', 'asset', 'php-file'];
foreach ($wrappers as $scheme => $wrapper_info) {
if (in_array($scheme, $unwanted)) {
continue;
}
try {
$instance = $this->streamWrapperManager->getViaScheme($scheme);
$file_system_options[$scheme] = $instance->getName() ?: $scheme;
}
catch (\Exception $e) {
// Log or ignore missing/broken stream wrapper
}
}
$media_types = $this->entityTypeManager->getStorage('media_type')->loadMultiple();
$types = array_map(fn($media_type) => $media_type->label(), $media_types);
$form['instructions'] = [
'#type' => 'link',
'#title' => $this->t('View Instructions'),
'#url' => Url::fromRoute('islandora_inplace_media.instructions_modal'),
'#attributes' => [
'class' => ['use-ajax', 'button', 'button--small'],
'data-dialog-type' => 'modal',
'data-dialog-options' => json_encode([
'width' => 700,
]),
],
'#attached' => [
'library' => [
'core/drupal.dialog.ajax',
],
],
];
$form['in_place'] = [
'#type' => 'checkbox',
'#title' => $this->t('Already in place?'),
'#description' => $this->t("Check this box if files are already in the file system directory."),
];
$form['source'] = [
'#type' => 'textfield',
'#title' => $this->t('Enter the full file path to the input directory'),
'#states' => [
'visible' => [
':input[name="in_place"]' => ['checked' => FALSE],
],
'required' => [
':input[name="in_place"]' => ['checked' => FALSE],
],
],
];
$form['destination'] = [
'#type' => 'textfield',
'#title' => $this->t('Enter the directory on the file system'),
'#required' => TRUE,
];
$form['file_system'] = [
'#type' => 'radios',
'#options' => $file_system_options,
'#title' => $this->t('Select file system'),
'#required' => TRUE,
'#default_value' => 'default',
];
if (count($file_system_options) <= 1) {
$form['file_system']['#attributes']['style'] = 'display: none;';
}
$form['field_wrapper'] = [
'#type' => 'container',
'#attributes' => ['class' => ['media-fields-wrapper']],
];
$form['field_wrapper']['media_type_wrapper'] = [
'#type' => 'container',
'#attributes' => ['class' => ['media-field-container']],
];
$form['field_wrapper']['media_type_wrapper']['media_type'] = [
'#title' => $this->t("Media type."),
'#type' => 'select',
'#options' => $types,
'#attributes' => ['class' => ['media-side-by-side']],
];
$form['field_wrapper']['media_use_wrapper'] = [
'#type' => 'container',
'#attributes' => ['class' => ['media-field-container']],
];
$form['field_wrapper']['media_use_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['field_wrapper']['ownership_wrapper'] = [
'#type' => 'container',
'#attributes' => ['class' => ['media-field-container']],
];
$form['field_wrapper']['ownership_wrapper']['ownership'] = [
'#type' => 'textfield',
'#title' => $this->t('File ownership'),
'#default_value' => $default_ownership,
'#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 {
$file_system = $this->getFilesystem($form_state);
$source_directory = rtrim($form_state->getValue('in_place') ? $file_system . $form_state->getValue('destination') : $form_state->getValue('source'), '/');
if (!is_dir($source_directory)) {
if (str_starts_with($file_system, 'fedora')) {
$form_state->setErrorByName('source', $this->t('The fedora file system is not suitable for preloading files.'));
}
else {
$form_state->setErrorByName('source', $this->t('The specified directory does not exist.'));
}
return;
}
if (empty(array_diff(scandir($source_directory), ['.', '..']))) {
$form_state->setErrorByName('source', $this->t('The specified directory is empty.'));
}
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state): void {
$file_system = $this->getFilesystem($form_state);
$media_type = $form_state->getValue('media_type');
$destination = trim($form_state->getValue('destination'), '/');
$build_data = [
'source_dir' => $form_state->getValue('in_place') ? $file_system . $destination : $form_state->getValue('source'),
'destination_path' => "{$file_system}{$destination}",
'media_type' => $form_state->getValue('media_type'),
'file_type' => $this->fileTypes[$media_type],
'media_use' => $form_state->getValue('media_use'),
'ownership' => $form_state->getValue('ownership'),
];
$this->mediaUtils->buildMediaBatch($build_data);
if ($form_state->getValue('in_place')) {
$status = $this->t('Media files in %destination have been processed', [
'%destination' => $destination,
]);
}
else {
$status = $this->t('Media files have been processed from %source to %destination.', [
'%source' => $build_data['source_dir'],
'%destination' => $build_data['destination_path'],
]);
}
$this->messenger()->addStatus($status);
$form_state->setRedirect('<front>');
}
/**
* Gets default filesystem for media type.
*/
protected function getFilesystem($form_state) {
$media_type = $form_state->getValue('media_type');
$file_type = $this->fileTypes[$media_type];
if ($form_state->getValue('file_system') == 'default') {
$field_config = FieldConfig::loadByName('media', $media_type, $file_type);
if ($field_config) {
$settings = $field_config->getSettings();
$scheme = $settings['uri_scheme'] ?? 'public';
$file_system = $scheme . "://";
}
}
else {
$file_system = $form_state->getValue('file_system') . "://";
}
return $file_system;
}
}