From 8b838c719fb4bc1ab0ed626c98d3f11748247a78 Mon Sep 17 00:00:00 2001 From: dannylamb Date: Wed, 5 May 2021 15:11:11 +0000 Subject: [PATCH] Letting user select media type instead of guessing --- src/Form/AddChildrenForm.php | 82 ++++------------------------ src/Form/AddMediaForm.php | 100 +++++++++++++++++++++-------------- 2 files changed, 72 insertions(+), 110 deletions(-) diff --git a/src/Form/AddChildrenForm.php b/src/Form/AddChildrenForm.php index 4df05ea5..0ff72496 100644 --- a/src/Form/AddChildrenForm.php +++ b/src/Form/AddChildrenForm.php @@ -3,20 +3,10 @@ namespace Drupal\islandora\Form; use Drupal\Core\Access\AccessResult; -use Drupal\Core\Config\ImmutableConfig; -use Drupal\Core\Database\Connection; use Drupal\Core\Form\FormStateInterface; -use Drupal\Core\Entity\EntityFieldManagerInterface; -use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\Entity\EntityTypeBundleInfoInterface; use Drupal\Core\Routing\RouteMatch; -use Drupal\Core\Routing\RouteMatchInterface; -use Drupal\Core\Session\AccountInterface; use Drupal\Core\Url; -use Drupal\Core\Utility\Token; use Drupal\islandora\IslandoraUtils; -use Drupal\islandora\MediaSource\MediaSourceService; -use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpKernel\Exception\HttpException; @@ -25,58 +15,6 @@ use Symfony\Component\HttpKernel\Exception\HttpException; */ class AddChildrenForm extends AddMediaForm { - /** - * To list the available bundle types. - * - * @var \Drupal\Core\Entity\EntityTypeBundleInfo - */ - protected $entityTypeBundleInfo; - - /** - * Constructs a new IslandoraUploadForm object. - */ - public function __construct( - EntityTypeManagerInterface $entity_type_manager, - EntityFieldManagerInterface $entity_field_manager, - IslandoraUtils $utils, - MediaSourceService $media_source, - ImmutableConfig $config, - Token $token, - AccountInterface $account, - RouteMatchInterface $route_match, - Connection $database, - EntityTypeBundleInfoInterface $entity_type_bundle_info - ) { - $this->entityTypeManager = $entity_type_manager; - $this->entityFieldManager = $entity_field_manager; - $this->utils = $utils; - $this->mediaSource = $media_source; - $this->config = $config; - $this->token = $token; - $this->account = $account; - $this->routeMatch = $route_match; - $this->database = $database; - $this->entityTypeBundleInfo = $entity_type_bundle_info; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container) { - return new static( - $container->get('entity_type.manager'), - $container->get('entity_field.manager'), - $container->get('islandora.utils'), - $container->get('islandora.media_source_service'), - $container->get('config.factory')->get('islandora.settings'), - $container->get('token'), - $container->get('current_user'), - $container->get('current_route_match'), - $container->get('database'), - $container->get('entity_type.bundle.info') - ); - } - /** * {@inheritdoc} */ @@ -111,9 +49,7 @@ class AddChildrenForm extends AddMediaForm { // Drop down to select content type. $options = []; foreach ($this->entityTypeBundleInfo->getBundleInfo('node') as $bundle_id => $bundle) { - if ($this->utils->isIslandoraType('node', $bundle_id)) { - $options[$bundle_id] = $bundle['label']; - } + $options[$bundle_id] = $bundle['label']; }; $form['bundle'] = [ '#type' => 'select', @@ -123,7 +59,7 @@ class AddChildrenForm extends AddMediaForm { '#required' => TRUE, ]; - // Filter out bundles that don't have field_model. + // Find bundles that don't have field_model. $bundles_with_model = []; foreach (array_keys($options) as $bundle) { $fields = $this->entityFieldManager->getFieldDefinitions('node', $bundle); @@ -155,7 +91,7 @@ class AddChildrenForm extends AddMediaForm { } } - $this->addMediaUseTerms($form); + $this->addMediaType($form); $form['submit'] = [ '#type' => 'submit', @@ -177,6 +113,7 @@ class AddChildrenForm extends AddMediaForm { $fids = $form_state->getValue('upload'); $bundle = $form_state->getValue('bundle'); $model_tid = $form_state->getValue('model'); + $media_type = $form_state->getValue('media_type'); $use_tids = $form_state->getValue('use'); // Create an operation for each uploaded file. @@ -184,7 +121,7 @@ class AddChildrenForm extends AddMediaForm { foreach ($fids as $fid) { $operations[] = [ [$this, 'buildNodeForFile'], - [$fid, $parent_id, $bundle, $model_tid, $use_tids], + [$fid, $parent_id, $bundle, $model_tid, $media_type, $use_tids], ]; } @@ -210,6 +147,8 @@ class AddChildrenForm extends AddMediaForm { * Content type to create. * @param int|null $model_tid * Id of the Model term. + * @param string $media_type + * Media type to create. * @param int[] $use_tids * Ids of the Media Use terms. * @param array $context @@ -217,7 +156,7 @@ class AddChildrenForm extends AddMediaForm { * * @throws \Symfony\Component\HttpKernel\Exception\HttpException */ - public function buildNodeForFile($fid, $parent_id, $bundle, $model_tid, array $use_tids, array &$context) { + public function buildNodeForFile($fid, $parent_id, $bundle, $model_tid, $media_type, array $use_tids, array &$context) { // Since we make 3 different entities, do this in a transaction. $transaction = $this->database->startTransaction(); @@ -229,7 +168,6 @@ class AddChildrenForm extends AddMediaForm { // Make the resource node. $parent = $this->entityTypeManager->getStorage('node')->load($parent_id); - $media_type = $this->guessMediaTypeFromMimetype($file->getMimetype()); $source_field = $this->mediaSource->getSourceFieldName($media_type); $node = $this->entityTypeManager->getStorage('node')->create([ @@ -252,9 +190,11 @@ class AddChildrenForm extends AddMediaForm { 'bundle' => $media_type, $source_field => $fid, 'name' => $file->getFileName(), - IslandoraUtils::MEDIA_USAGE_FIELD => $this->entityTypeManager->getStorage('taxonomy_term')->loadMultiple($use_tids), IslandoraUtils::MEDIA_OF_FIELD => $node, ]); + if (!empty($use_tids)) { + $media->set(IslandoraUtils::MEDIA_USAGE_FIELD, $this->entityTypeManager->getStorage('taxonomy_term')->loadMultiple($use_tids)); + } $media->save(); } catch (HttpException $e) { diff --git a/src/Form/AddMediaForm.php b/src/Form/AddMediaForm.php index b816e5a4..281abd9a 100644 --- a/src/Form/AddMediaForm.php +++ b/src/Form/AddMediaForm.php @@ -8,6 +8,7 @@ use Drupal\Core\Database\Connection; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Entity\EntityFieldManagerInterface; +use Drupal\Core\Entity\EntityTypeBundleInfoInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Routing\RouteMatch; use Drupal\Core\Routing\RouteMatchInterface; @@ -95,6 +96,13 @@ class AddMediaForm extends FormBase { */ protected $database; + /** + * To list the available bundle types. + * + * @var \Drupal\Core\Entity\EntityTypeBundleInfo + */ + protected $entityTypeBundleInfo; + /** * Constructs a new IslandoraUploadForm object. */ @@ -107,7 +115,8 @@ class AddMediaForm extends FormBase { Token $token, AccountInterface $account, RouteMatchInterface $route_match, - Connection $database + Connection $database, + EntityTypeBundleInfoInterface $entity_type_bundle_info ) { $this->entityTypeManager = $entity_type_manager; $this->entityFieldManager = $entity_field_manager; @@ -118,6 +127,7 @@ class AddMediaForm extends FormBase { $this->account = $account; $this->routeMatch = $route_match; $this->database = $database; + $this->entityTypeBundleInfo = $entity_type_bundle_info; } /** @@ -133,7 +143,8 @@ class AddMediaForm extends FormBase { $container->get('token'), $container->get('current_user'), $container->get('current_route_match'), - $container->get('database') + $container->get('database'), + $container->get('entity_type.bundle.info') ); } @@ -169,7 +180,7 @@ class AddMediaForm extends FormBase { '#multiple' => TRUE, ]; - $this->addMediaUseTerms($form); + $this->addMediaType($form); $form['submit'] = [ '#type' => 'submit', @@ -185,7 +196,31 @@ class AddMediaForm extends FormBase { * @param array $form * Form array. */ - protected function addMediaUseTerms(array &$form) { + protected function addMediaType(array &$form) { + // Drop down to select media type. + $options = []; + foreach ($this->entityTypeBundleInfo->getBundleInfo('media') as $bundle_id => $bundle) { + $options[$bundle_id] = $bundle['label']; + }; + $form['media_type'] = [ + '#type' => 'select', + '#title' => $this->t('Media type'), + '#description' => $this->t('Each media created will have this type.'), + '#options' => $options, + '#required' => TRUE, + ]; + + // Find bundles that don't have field_media_use. + $bundles_with_media_use = []; + foreach (array_keys($options) as $bundle) { + $fields = $this->entityFieldManager->getFieldDefinitions('media', $bundle); + if (isset($fields[IslandoraUtils::MEDIA_USAGE_FIELD])) { + $bundles_with_media_use[] = $bundle; + } + } + + // Media use drop down. + // Only shows up if the selected bundle has field_media_use. $options = []; $terms = $this->entityTypeManager->getStorage('taxonomy_term')->loadTree('islandora_media_use', 0, NULL, TRUE); foreach ($terms as $term) { @@ -196,8 +231,18 @@ class AddMediaForm extends FormBase { '#title' => $this->t('Usage'), '#description' => $this->t("Defined by Portland Common Data Model: Use Extension https://pcdm.org/2015/05/12/use. ''Original File'' will trigger creation of derivatives."), '#options' => $options, - '#required' => TRUE, + '#states' => [ + 'visible' => [], + 'required' => [], + ], ]; + + if (!empty($bundles_with_media_use)) { + foreach ($bundles_with_media_use as $bundle) { + $form['use']['#states']['visible'][] = [':input[name="media_type"]' => ['value' => $bundle]]; + $form['use']['#states']['required'][] = [':input[name="media_type"]' => ['value' => $bundle]]; + } + } } /** @@ -210,12 +255,16 @@ class AddMediaForm extends FormBase { // Hack values out of the form. $fids = $form_state->getValue('upload'); + $media_type = $form_state->getValue('media_type'); $tids = $form_state->getValue('use'); // Create an operation for each uploaded file. $operations = []; foreach ($fids as $fid) { - $operations[] = [[$this, 'buildMediaForFile'], [$fid, $parent_id, $tids]]; + $operations[] = [ + [$this, 'buildMediaForFile'], + [$fid, $parent_id, $media_type, $tids], + ]; } // Set up and trigger the batch. @@ -236,6 +285,8 @@ class AddMediaForm extends FormBase { * Uploaded file id. * @param int $parent_id * Id of the parent node. + * @param string $media_type + * Meida type for the new media. * @param int[] $tids * Array of Media Use term ids. * @param array $context @@ -243,7 +294,7 @@ class AddMediaForm extends FormBase { * * @throws \Symfony\Component\HttpKernel\Exception\HttpException */ - public function buildMediaForFile($fid, $parent_id, array $tids, array &$context) { + public function buildMediaForFile($fid, $parent_id, $media_type, array $tids, array &$context) { // Since we make 2 different entities, do this in a transaction. $transaction = $this->database->startTransaction(); @@ -256,7 +307,6 @@ class AddMediaForm extends FormBase { // Make the media and assign it to the parent resource node. $parent = $this->entityTypeManager->getStorage('node')->load($parent_id); - $media_type = $this->guessMediaTypeFromMimetype($file->getMimetype()); $source_field = $this->mediaSource->getSourceFieldName($media_type); $terms = $this->entityTypeManager->getStorage('taxonomy_term')->loadMultiple($tids); @@ -265,9 +315,11 @@ class AddMediaForm extends FormBase { 'uid' => $this->account->id(), $source_field => $fid, 'name' => $file->getFileName(), - IslandoraUtils::MEDIA_USAGE_FIELD => $terms, IslandoraUtils::MEDIA_OF_FIELD => $parent, ]); + if ($media->hasField(IslandoraUtils::MEDIA_USAGE_FIELD)) { + $media->set(IslandoraUtils::MEDIA_USAGE_FIELD, $terms); + } $media->save(); } catch (HttpException $e) { @@ -280,36 +332,6 @@ class AddMediaForm extends FormBase { } } - /** - * Sniffs media type from mimetype. - * - * @param string $mimetype - * Mimetype. - * - * @return string - * Id of media type. - */ - protected function guessMediaTypeFromMimetype($mimetype) { - $exploded_mime = explode('/', $mimetype); - if ($exploded_mime[0] == 'image') { - if (in_array($exploded_mime[1], ['tiff', 'jp2'])) { - return 'file'; - } - else { - return 'image'; - } - } - elseif ($exploded_mime[0] == 'audio') { - return 'audio'; - } - elseif ($exploded_mime[0] == 'video') { - return 'video'; - } - else { - return 'file'; - } - } - /** * Batch finished callback. *