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