From b7337136105cea011a230398bc87494c1e04d245 Mon Sep 17 00:00:00 2001 From: ajstanley Date: Wed, 1 Dec 2021 16:40:34 -0400 Subject: [PATCH 001/252] added additional exception --- modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php b/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php index aecb77064..dc750a5a9 100644 --- a/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php +++ b/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php @@ -8,6 +8,7 @@ use Drupal\Component\Utility\UrlHelper; use GuzzleHttp\ClientInterface; use GuzzleHttp\Exception\ClientException; +use GuzzleHttp\Exception\ConnectException; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -118,6 +119,9 @@ private function validateIiifUrl($server_uri) { catch (ClientException $e) { return FALSE; } + catch (ConnectException $e) { + return FALSE; + } } From 0bea8da572110f8910bd1e14542edf7bfcccf018 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Tue, 12 Jul 2022 16:23:33 -0300 Subject: [PATCH 002/252] WIP Modify GenerateOCRDerivativeFile to support hOCR --- .../Action/GenerateOCRDerivativeFile.php | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivativeFile.php b/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivativeFile.php index f6b8034a9..73318e35d 100644 --- a/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivativeFile.php +++ b/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivativeFile.php @@ -8,7 +8,7 @@ use Drupal\islandora\Plugin\Action\AbstractGenerateDerivativeMediaFile; /** - * Emits a Node for generating fits derivatives event. + * Generates OCR derivatives event. * * @Action( * id = "generate_extracted_text_file", @@ -29,6 +29,7 @@ public function defaultConfiguration() { $config['destination_media_type'] = 'file'; $config['scheme'] = $this->config->get('default_scheme'); $config['destination_text_field_name'] = ''; + $config['text_format'] = 'plain_text'; return $config; } @@ -38,7 +39,7 @@ public function defaultConfiguration() { public function buildConfigurationForm(array $form, FormStateInterface $form_state) { $map = $this->entityFieldManager->getFieldMapByFieldType('text_long'); $file_fields = $map['media']; - $field_options = array_combine(array_keys($file_fields), array_keys($file_fields)); + $field_options = ['none' => $this->t('None')] + array_combine(array_keys($file_fields), array_keys($file_fields)); $form = parent::buildConfigurationForm($form, $form_state); $form['mimetype']['#description'] = $this->t('Mimetype to convert to (e.g. application/xml, etc...)'); $form['mimetype']['#value'] = 'text/plain'; @@ -48,13 +49,23 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta $last = array_slice($form, count($form) - $position + 1); $middle['destination_text_field_name'] = [ - '#required' => TRUE, + '#required' => FALSE, '#type' => 'select', '#options' => $field_options, '#title' => $this->t('Destination Text field Name'), '#default_value' => $this->configuration['destination_text_field_name'], '#description' => $this->t('Text field on Media Type to hold extracted text.'), ]; + $middle['text_format'] = [ + '#type' => 'select', + '#title' => $this->t('Format'), + '#options' => [ + 'plain_text' => $this->t('Plain text'), + 'hocr' => $this->t('hOCR text with positional data'), + ], + '#default_value' => $this->configuration['text_format'], + '#description' => $this->t("The type of text to be returned."), + ]; $form = array_merge($first, $middle, $last); unset($form['args']); @@ -81,17 +92,28 @@ public function validateConfigurationForm(array &$form, FormStateInterface $form public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { parent::submitConfigurationForm($form, $form_state); $this->configuration['destination_text_field_name'] = $form_state->getValue('destination_text_field_name'); + $this->configuration['text_format'] = $form_state->getValue('text_format'); + switch ($form_state->getValue('text_format')) { + case 'hocr': + $this->configuration['args'] = '-c tessedit_create_hocr=1 -c hocr_font_info=0'; + break; + case 'plain_text': + $his->configuration['args'] = ''; + break; + } } /** * Override this to return arbitrary data as an array to be json encoded. */ protected function generateData(EntityInterface $entity) { + $data = parent::generateData($entity); $route_params = [ 'media' => $entity->id(), 'destination_field' => $this->configuration['destination_field_name'], 'destination_text_field' => $this->configuration['destination_text_field_name'], + 'text_format' => $this->configuration['text_format'], ]; $data['destination_uri'] = Url::fromRoute('islandora_text_extraction.attach_file_to_media', $route_params) ->setAbsolute() From bd17a381ead0ee6eef852511e8da589c2aa9b8ae Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Wed, 27 Jul 2022 19:24:32 +0000 Subject: [PATCH 003/252] Add Structured OCR field to IIIF Manifest view. --- .../src/Plugin/views/style/IIIFManifest.php | 10 ++++++++++ .../Action/AbstractGenerateDerivativeMediaFile.php | 5 ++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 194670016..446358d05 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -313,6 +313,7 @@ protected function defineOptions() { $options = parent::defineOptions(); $options['iiif_tile_field'] = ['default' => '']; + $options['iiif_ocr_file_field'] = ['default' => '']; return $options; } @@ -368,6 +369,15 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { // otherwise could lock up the form when setting up a View. '#required' => count($field_options) > 0, ]; + + $form['iiif_ocr_file_field'] = [ + '#title' => $this->t('Structured OCR data file field'), + '#type' => 'checkboxes', + '#default_value' => $this->options['iiif_ocr_file_field'], + '#description' => $this->t('The source of structured OCR text for each entity.'), + '#options' => $field_options, + '#required' => FALSE, + ]; } /** diff --git a/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php b/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php index be9eca80b..2c4e92240 100644 --- a/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php +++ b/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php @@ -5,7 +5,6 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Url; - /** * Emits a Node for generating derivatives event. * @@ -39,8 +38,8 @@ public function defaultConfiguration() { */ protected function generateData(EntityInterface $entity) { $data = parent::generateData($entity); - if (get_class($entity) != 'Drupal\media\Entity\Media') { - throw new \RuntimeException("Entity {$entity->getEntityTypeId()} {$entity->id()} is not a media", 500); + if (get_class($entity) != 'Drupal\media\Entity\Media') { + throw new \RuntimeException("Entity {$entity->getEntityTypeId()} {$entity->id()} is not a media", 500); } $source_file = $this->mediaSource->getSourceFile($entity); if (!$source_file) { From 0644795c54b7bbfe94f4163aaf53e90408feca69 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Wed, 24 Aug 2022 19:13:29 +0000 Subject: [PATCH 004/252] Skip empty image fields when constructing IIIF manifest. --- modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 446358d05..ba971b474 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -189,7 +189,7 @@ public function render() { */ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_base_id) { $canvases = []; - foreach ($this->options['iiif_tile_field'] as $iiif_tile_field) { + foreach (array_filter(array_values($this->options['iiif_tile_field'])) as $iiif_tile_field) { $viewsField = $this->view->field[$iiif_tile_field]; $entity = $viewsField->getEntity($row); From 4179f5cee7e33f8e9eb8e3e6778272143ddd6bf8 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Thu, 25 Aug 2022 19:45:23 +0000 Subject: [PATCH 005/252] WIP get hocr field in iiif view. --- modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index ba971b474..b06b0f5d9 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -191,6 +191,7 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas $canvases = []; foreach (array_filter(array_values($this->options['iiif_tile_field'])) as $iiif_tile_field) { $viewsField = $this->view->field[$iiif_tile_field]; + $ocrField = array_pop(array_filter(array_values($this->options['iiif_ocr_file_field']))); $entity = $viewsField->getEntity($row); if (isset($entity->{$viewsField->definition['field_name']})) { From 49c48a1493e1df1a55d36ed5d54db35d7331f24f Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Fri, 26 Aug 2022 17:52:20 +0000 Subject: [PATCH 006/252] WIP: Add hOCR file stream to IIIF Manifest. --- .../src/Plugin/views/style/IIIFManifest.php | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index b06b0f5d9..ad5ea178c 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -191,20 +191,25 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas $canvases = []; foreach (array_filter(array_values($this->options['iiif_tile_field'])) as $iiif_tile_field) { $viewsField = $this->view->field[$iiif_tile_field]; - $ocrField = array_pop(array_filter(array_values($this->options['iiif_ocr_file_field']))); + $iiif_ocr_file_field = array_filter(array_values($this->options['iiif_ocr_file_field'])); + $ocrField = count($iiif_ocr_file_field) > 0 ? $this->view->field[$iiif_ocr_file_field[0]] : NULL; $entity = $viewsField->getEntity($row); if (isset($entity->{$viewsField->definition['field_name']})) { /** @var \Drupal\Core\Field\FieldItemListInterface $images */ - $images = $entity->{$viewsField->definition['field_name']}; + $images = $entity->{$viewsField->definition['field_name']}; foreach ($images as $image) { if (!$image->entity->access('view')) { // If the user does not have permission to view the file, skip it. continue; } + + $ocrs = $entity->{$ocrField->definition['field_name']}; + // Create the IIIF URL for this file // Visiting $iiif_url will resolve to the info.json for the image. + $ocr = isset($ocrs[$i]) ? $ocrs[$i] : NULL; $file_url = $image->entity->createFileUrl(FALSE); $mime_type = $image->entity->getMimeType(); $iiif_url = rtrim($iiif_address, '/') . '/' . urlencode($file_url); @@ -242,8 +247,7 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas } } } - - $canvases[] = [ + $tmp_canvas = [ // @see https://iiif.io/api/presentation/2.1/#canvas '@id' => $canvas_id, '@type' => 'sc:Canvas', @@ -272,6 +276,17 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas ], ], ]; + + if (isset($ocr)) { + $tmp_canvas['seeAlso'] = [ + '@id' => $ocr->entity->createFileUrl(FALSE), + 'format' => 'text/vnd.hocr+html', + 'profile' => 'http://kba.cloud/hocr-spec', + 'label' => 'hOCR embedded text', + ]; + } + + $canvases[] = $tmp_canvas; } } } From 5e1d53d377ae35bb19a8d2415773a9715e4c0cb6 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Wed, 7 Sep 2022 16:16:31 +0000 Subject: [PATCH 007/252] Add empty check when adding hOCR to IIIF manifest. --- .../islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index ad5ea178c..561b216dd 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -191,13 +191,13 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas $canvases = []; foreach (array_filter(array_values($this->options['iiif_tile_field'])) as $iiif_tile_field) { $viewsField = $this->view->field[$iiif_tile_field]; - $iiif_ocr_file_field = array_filter(array_values($this->options['iiif_ocr_file_field'])); + $iiif_ocr_file_field = !empty($this->options['iiif_ocr_file_field']) ? array_filter(array_values($this->options['iiif_ocr_file_field'])): array(); $ocrField = count($iiif_ocr_file_field) > 0 ? $this->view->field[$iiif_ocr_file_field[0]] : NULL; $entity = $viewsField->getEntity($row); if (isset($entity->{$viewsField->definition['field_name']})) { - /** @var \Drupal\Core\Field\FieldItemListInterface $images */ + /** @var \Drupal\Core\Field\FieldItemListInterface $images */ $images = $entity->{$viewsField->definition['field_name']}; foreach ($images as $image) { if (!$image->entity->access('view')) { @@ -209,7 +209,7 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas // Create the IIIF URL for this file // Visiting $iiif_url will resolve to the info.json for the image. - $ocr = isset($ocrs[$i]) ? $ocrs[$i] : NULL; + $ocr = isset($ocrs[$i]) ? $ocrs[$i] : FALSE; $file_url = $image->entity->createFileUrl(FALSE); $mime_type = $image->entity->getMimeType(); $iiif_url = rtrim($iiif_address, '/') . '/' . urlencode($file_url); From bf25e2447ac50b75411c10f7f0f014bf4edf0d8c Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Wed, 7 Sep 2022 18:43:03 +0000 Subject: [PATCH 008/252] Fix error caused by rebase. --- .../src/Plugin/views/style/IIIFManifest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 561b216dd..594e75d8f 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -197,15 +197,15 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas if (isset($entity->{$viewsField->definition['field_name']})) { - /** @var \Drupal\Core\Field\FieldItemListInterface $images */ - $images = $entity->{$viewsField->definition['field_name']}; - foreach ($images as $image) { + /** @var \Drupal\Core\Field\FieldItemListInterface $images */ + $images = $entity->{$viewsField->definition['field_name']}; + foreach ($images as $i => $image) { if (!$image->entity->access('view')) { // If the user does not have permission to view the file, skip it. continue; } - $ocrs = $entity->{$ocrField->definition['field_name']}; + $ocrs = $entity->{$ocrField->definition['field_name']}; // Create the IIIF URL for this file // Visiting $iiif_url will resolve to the info.json for the image. From 78cee0a35a2310273e125f948fc76009870d0e3c Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Thu, 8 Sep 2022 12:46:23 +0000 Subject: [PATCH 009/252] Fix PHPCS errors. --- .../islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 594e75d8f..a09152423 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -191,7 +191,7 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas $canvases = []; foreach (array_filter(array_values($this->options['iiif_tile_field'])) as $iiif_tile_field) { $viewsField = $this->view->field[$iiif_tile_field]; - $iiif_ocr_file_field = !empty($this->options['iiif_ocr_file_field']) ? array_filter(array_values($this->options['iiif_ocr_file_field'])): array(); + $iiif_ocr_file_field = !empty($this->options['iiif_ocr_file_field']) ? array_filter(array_values($this->options['iiif_ocr_file_field'])) : []; $ocrField = count($iiif_ocr_file_field) > 0 ? $this->view->field[$iiif_ocr_file_field[0]] : NULL; $entity = $viewsField->getEntity($row); @@ -205,7 +205,7 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas continue; } - $ocrs = $entity->{$ocrField->definition['field_name']}; + $ocrs = $entity->{$ocrField->definition['field_name']}; // Create the IIIF URL for this file // Visiting $iiif_url will resolve to the info.json for the image. From a41ecaa754a071904bb4a397996a2f0a127d30ad Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Thu, 8 Sep 2022 12:55:15 +0000 Subject: [PATCH 010/252] Fix PHPCS errors. --- src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php b/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php index 2c4e92240..be9eca80b 100644 --- a/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php +++ b/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php @@ -5,6 +5,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Url; + /** * Emits a Node for generating derivatives event. * @@ -38,8 +39,8 @@ public function defaultConfiguration() { */ protected function generateData(EntityInterface $entity) { $data = parent::generateData($entity); - if (get_class($entity) != 'Drupal\media\Entity\Media') { - throw new \RuntimeException("Entity {$entity->getEntityTypeId()} {$entity->id()} is not a media", 500); + if (get_class($entity) != 'Drupal\media\Entity\Media') { + throw new \RuntimeException("Entity {$entity->getEntityTypeId()} {$entity->id()} is not a media", 500); } $source_file = $this->mediaSource->getSourceFile($entity); if (!$source_file) { From c07d1f65401a0e96fae994953945be79b83779ba Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Thu, 8 Sep 2022 13:03:45 +0000 Subject: [PATCH 011/252] Fix PHPCS Errors. --- .../src/Plugin/Action/GenerateOCRDerivativeFile.php | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivativeFile.php b/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivativeFile.php index 73318e35d..4ff0d93fc 100644 --- a/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivativeFile.php +++ b/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivativeFile.php @@ -97,6 +97,7 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s case 'hocr': $this->configuration['args'] = '-c tessedit_create_hocr=1 -c hocr_font_info=0'; break; + case 'plain_text': $his->configuration['args'] = ''; break; From aa3c71893e7aea98dff67e660df5f3b7832fafb0 Mon Sep 17 00:00:00 2001 From: shriram Date: Tue, 18 Oct 2022 16:10:19 -0300 Subject: [PATCH 012/252] delete media associated with an islandora object --- islandora.module | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/islandora.module b/islandora.module index 5b5446d13..708f8ec19 100644 --- a/islandora.module +++ b/islandora.module @@ -320,9 +320,10 @@ function islandora_form_alter(&$form, FormStateInterface $form_state, $form_id) 'media_extracted_text_add_form', 'media_file_add_form', 'media_image_add_form', 'media_fits_technical_metadata_add_form', 'media_video_add_form', ]; - + //kint($form); if (in_array($form['#form_id'], $media_add_forms)) { $params = \Drupal::request()->query->all(); + if (isset($params['edit'])) { $media_of_nid = $params['edit']['field_media_of']['widget'][0]['target_id']; $node = \Drupal::entityTypeManager()->getStorage('node')->load($media_of_nid); @@ -346,6 +347,7 @@ function islandora_field_widget_image_image_form_alter(&$element, $form_state, $ function islandora_add_default_image_alt_text($element, $form_state, $form) { if ($element['alt']['#access']) { $params = \Drupal::request()->query->all(); + if (isset($params['edit'])) { $media_of_nid = $params['edit']['field_media_of']['widget'][0]['target_id']; $node = \Drupal::entityTypeManager()->getStorage('node')->load($media_of_nid); @@ -423,7 +425,7 @@ function islandora_entity_extra_field_info() { if (!empty($pseudo_bundles)) { foreach ($pseudo_bundles as $key) { [$bundle, $content_entity] = explode(":", $key); - $extra_field[$content_entity][$bundle]['display'][IslandoraSettingsForm::GEMINI_PSEUDO_FIELD] = [ + $extra_field[$content_entity][$bundle]['display']['field_gemini_uri'] = [ 'label' => t('Fedora URI'), 'description' => t('The URI to the persistent'), 'weight' => 100, @@ -548,3 +550,27 @@ function islandora_preprocess_views_view_table(&$variables) { } } } + +function islandora_form_node_islandora_object_delete_form_alter(&$form, &$form_state){ + $form['delete_associated_content'] = array( + '#type' => 'checkbox', + '#title' => t('Delete all associated medias and nodes'), + ); + + $form['actions']['submit']['#submit'][] = 'islandora_form_node_islandora_object_delete_form_submit'; + return $form; +} + +function islandora_form_node_islandora_object_delete_form_submit($form, &$form_state){ + + $result = $form_state->getValues('delete_associated_content'); + + if($result['delete_associated_content'] == 1) { + $utils = \Drupal::service('islandora.utils'); + $medias = $utils->getMedia($form_state->getFormObject()->getEntity()); + foreach ($medias as $media) { + $media->delete(); + } + } +} + From 2e4780163e50fb2312e1463dd41832c50f21c24a Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Thu, 20 Oct 2022 02:39:22 +0000 Subject: [PATCH 013/252] Add check for falsity in IIIF Manifest along with 'isset()' --- modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index a09152423..cc4b5e94e 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -277,7 +277,7 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas ], ]; - if (isset($ocr)) { + if (isset($ocr) && $ocr != FALSE) { $tmp_canvas['seeAlso'] = [ '@id' => $ocr->entity->createFileUrl(FALSE), 'format' => 'text/vnd.hocr+html', From 33ce9e4e135dacc342819b0b8bea2824cd023c72 Mon Sep 17 00:00:00 2001 From: shriram Date: Thu, 27 Oct 2022 14:31:18 -0300 Subject: [PATCH 014/252] list media associated with a Islandora object --- islandora.module | 69 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 22 deletions(-) diff --git a/islandora.module b/islandora.module index 708f8ec19..ab9eab18a 100644 --- a/islandora.module +++ b/islandora.module @@ -27,6 +27,7 @@ use Drupal\file\FileInterface; use Drupal\taxonomy\TermInterface; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\serialization\Normalizer\CacheableNormalizerInterface; +use Drupal\Core\Entity\EntityForm; /** * Implements hook_help(). @@ -320,7 +321,7 @@ function islandora_form_alter(&$form, FormStateInterface $form_state, $form_id) 'media_extracted_text_add_form', 'media_file_add_form', 'media_image_add_form', 'media_fits_technical_metadata_add_form', 'media_video_add_form', ]; - //kint($form); + if (in_array($form['#form_id'], $media_add_forms)) { $params = \Drupal::request()->query->all(); @@ -332,6 +333,51 @@ function islandora_form_alter(&$form, FormStateInterface $form_state, $form_id) } } } + + $form_object = $form_state->getFormObject(); + + $utils = \Drupal::service('islandora.utils'); + +// kint($form,$form_state); + + if($form_object instanceof EntityForm) { + $entity = $form_object->getEntity(); + if ($utils->isIslandoraType($entity->getEntityTypeId(), $entity->bundle()) && strpos($form['#form_id'], 'delete_form') !== FALSE) { + $form['delete_associated_content'] = array( + '#type' => 'checkbox', + '#title' => t('Delete all associated medias and nodes'), + ); + + $medias = $utils->getMedia($form_state->getFormObject()->getEntity()); + $media_list = ""; + + foreach($medias as $media){ + $media_list.= "
  • {$media->getName()}
  • "; + } + + $form['media_items'] = array( + '#suffix' => "
      {$media_list}
    ", // Add markup after form item + ); + + $form['actions']['submit']['#submit'][] = 'islandora_object_delete_form_submit'; + return $form; + } + } + return $form; +} + +function islandora_object_delete_form_submit($form, &$form_state){ + + $result = $form_state->getValues('delete_associated_content'); + $utils = \Drupal::service('islandora.utils'); + + if($result['delete_associated_content'] == 1) { + + $medias = $utils->getMedia($form_state->getFormObject()->getEntity()); + foreach ($medias as $media) { + $media->delete(); + } + } } /** @@ -551,26 +597,5 @@ function islandora_preprocess_views_view_table(&$variables) { } } -function islandora_form_node_islandora_object_delete_form_alter(&$form, &$form_state){ - $form['delete_associated_content'] = array( - '#type' => 'checkbox', - '#title' => t('Delete all associated medias and nodes'), - ); - - $form['actions']['submit']['#submit'][] = 'islandora_form_node_islandora_object_delete_form_submit'; - return $form; -} -function islandora_form_node_islandora_object_delete_form_submit($form, &$form_state){ - - $result = $form_state->getValues('delete_associated_content'); - - if($result['delete_associated_content'] == 1) { - $utils = \Drupal::service('islandora.utils'); - $medias = $utils->getMedia($form_state->getFormObject()->getEntity()); - foreach ($medias as $media) { - $media->delete(); - } - } -} From 3602bb441b991dce7a08cffb98b93300b05ea907 Mon Sep 17 00:00:00 2001 From: shriram Date: Tue, 1 Nov 2022 12:16:29 -0300 Subject: [PATCH 015/252] fixed failing coding standard checks --- islandora.module | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/islandora.module b/islandora.module index ab9eab18a..63018266e 100644 --- a/islandora.module +++ b/islandora.module @@ -324,7 +324,6 @@ function islandora_form_alter(&$form, FormStateInterface $form_state, $form_id) if (in_array($form['#form_id'], $media_add_forms)) { $params = \Drupal::request()->query->all(); - if (isset($params['edit'])) { $media_of_nid = $params['edit']['field_media_of']['widget'][0]['target_id']; $node = \Drupal::entityTypeManager()->getStorage('node')->load($media_of_nid); @@ -333,31 +332,28 @@ function islandora_form_alter(&$form, FormStateInterface $form_state, $form_id) } } } - $form_object = $form_state->getFormObject(); $utils = \Drupal::service('islandora.utils'); -// kint($form,$form_state); - - if($form_object instanceof EntityForm) { + if ($form_object instanceof EntityForm) { $entity = $form_object->getEntity(); if ($utils->isIslandoraType($entity->getEntityTypeId(), $entity->bundle()) && strpos($form['#form_id'], 'delete_form') !== FALSE) { - $form['delete_associated_content'] = array( + $form['delete_associated_content'] = [ '#type' => 'checkbox', '#title' => t('Delete all associated medias and nodes'), - ); + ]; $medias = $utils->getMedia($form_state->getFormObject()->getEntity()); $media_list = ""; - foreach($medias as $media){ - $media_list.= "
  • {$media->getName()}
  • "; + foreach ($medias as $media) { + $media_list .= "
  • {$media->getName()}
  • "; } - $form['media_items'] = array( - '#suffix' => "
      {$media_list}
    ", // Add markup after form item - ); + $form['media_items'] = [ + '#suffix' => "
      {$media_list}
    ", + ]; $form['actions']['submit']['#submit'][] = 'islandora_object_delete_form_submit'; return $form; @@ -366,12 +362,15 @@ function islandora_form_alter(&$form, FormStateInterface $form_state, $form_id) return $form; } -function islandora_object_delete_form_submit($form, &$form_state){ +/** + * Implements a submit handler for the delete form. + */ +function islandora_object_delete_form_submit($form, &$form_state) { $result = $form_state->getValues('delete_associated_content'); $utils = \Drupal::service('islandora.utils'); - if($result['delete_associated_content'] == 1) { + if ($result['delete_associated_content'] == 1) { $medias = $utils->getMedia($form_state->getFormObject()->getEntity()); foreach ($medias as $media) { @@ -393,7 +392,6 @@ function islandora_field_widget_image_image_form_alter(&$element, $form_state, $ function islandora_add_default_image_alt_text($element, $form_state, $form) { if ($element['alt']['#access']) { $params = \Drupal::request()->query->all(); - if (isset($params['edit'])) { $media_of_nid = $params['edit']['field_media_of']['widget'][0]['target_id']; $node = \Drupal::entityTypeManager()->getStorage('node')->load($media_of_nid); @@ -471,7 +469,7 @@ function islandora_entity_extra_field_info() { if (!empty($pseudo_bundles)) { foreach ($pseudo_bundles as $key) { [$bundle, $content_entity] = explode(":", $key); - $extra_field[$content_entity][$bundle]['display']['field_gemini_uri'] = [ + $extra_field[$content_entity][$bundle]['display'][IslandoraSettingsForm::GEMINI_PSEUDO_FIELD] = [ 'label' => t('Fedora URI'), 'description' => t('The URI to the persistent'), 'weight' => 100, @@ -596,6 +594,3 @@ function islandora_preprocess_views_view_table(&$variables) { } } } - - - From 5bd2cdd85177397c23f4f7e3b639469597b5c9cb Mon Sep 17 00:00:00 2001 From: shriram Date: Tue, 1 Nov 2022 13:08:36 -0300 Subject: [PATCH 016/252] check if the entity is a node --- islandora.module | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/islandora.module b/islandora.module index 63018266e..e8aeb2322 100644 --- a/islandora.module +++ b/islandora.module @@ -333,12 +333,11 @@ function islandora_form_alter(&$form, FormStateInterface $form_state, $form_id) } } $form_object = $form_state->getFormObject(); - $utils = \Drupal::service('islandora.utils'); if ($form_object instanceof EntityForm) { $entity = $form_object->getEntity(); - if ($utils->isIslandoraType($entity->getEntityTypeId(), $entity->bundle()) && strpos($form['#form_id'], 'delete_form') !== FALSE) { + if ($entity->getEntityTypeId() == "node" && $utils->isIslandoraType($entity->getEntityTypeId(), $entity->bundle()) && strpos($form['#form_id'], 'delete_form') !== FALSE) { $form['delete_associated_content'] = [ '#type' => 'checkbox', '#title' => t('Delete all associated medias and nodes'), From fd5c38a10734efc26de0b3634c8c08a5791f8e36 Mon Sep 17 00:00:00 2001 From: shriram Date: Tue, 1 Nov 2022 16:00:22 -0300 Subject: [PATCH 017/252] added test cases for deleting node with media --- tests/src/Functional/DeleteNodeWithMedia.php | 94 ++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 tests/src/Functional/DeleteNodeWithMedia.php diff --git a/tests/src/Functional/DeleteNodeWithMedia.php b/tests/src/Functional/DeleteNodeWithMedia.php new file mode 100644 index 000000000..b9cc8f99a --- /dev/null +++ b/tests/src/Functional/DeleteNodeWithMedia.php @@ -0,0 +1,94 @@ +drupalCreateUser([ + 'delete any media', + 'create media', + 'view media', + 'bypass node access', + ]); + $this->drupalLogin($account); + + $assert_session = $this->assertSession(); + + $testImageMediaType = $this->createMediaType('image', ['id' => 'test_image_media_type']); + $testImageMediaType->save(); + + $this->createEntityReferenceField('media', $testImageMediaType->id(), 'field_media_of', 'Media Of', 'node', 'default', [], 2); + + $node = $this->container->get('entity_type.manager')->getStorage('node')->create([ + 'type' => 'test_type', + 'title' => 'node', + ]); + $node->save(); + + // Make an image for the Media. + $file = $this->container->get('entity_type.manager')->getStorage('file')->create([ + 'uid' => $account->id(), + 'uri' => "public://test.jpeg", + 'filename' => "test.jpeg", + 'filemime' => "image/jpeg", + 'status' => FILE_STATUS_PERMANENT, + ]); + $file->save(); + + $this->drupalGet("node/1/delete"); + $assert_session->pageTextNotContains('Delete all associated medias and nodes'); + + // Make the media, and associate it with the image and node. + $media1 = $this->container->get('entity_type.manager')->getStorage('media')->create([ + 'bundle' => $testImageMediaType->id(), + 'name' => 'Media1', + 'field_media_image' => + [ + 'target_id' => $file->id(), + 'alt' => 'Some Alt', + 'title' => 'Some Title', + ], + 'field_media_of' => ['target_id' => $node->id()], + ]); + $media1->save(); + + $media2 = $this->container->get('entity_type.manager')->getStorage('media')->create([ + 'bundle' => $testImageMediaType->id(), + 'name' => 'Media2', + 'field_media_image' => + [ + 'target_id' => $file->id(), + 'alt' => 'Some Alt', + 'title' => 'Some Title', + ], + 'field_media_of' => ['target_id' => $node->id()], + ]); + $media2->save(); + + $delete = ['delete_associated_content' => TRUE]; + + $this->drupalGet("node/1/delete"); + $assert_session->pageTextContains('Media1'); + $assert_session->pageTextContains('Media2'); + $this->submitForm($delete, 'Delete'); + + $assert_session->pageTextContains('Media1'); + $assert_session->pageTextContains('Media2'); + + $this->drupalGet("media/1/delete"); + $assert_session->pageTextContains('Page not found'); + + $this->drupalGet("media/2/delete"); + $assert_session->pageTextContains('Page not found'); + } + +} From 3f7ca2ca10bf5e01a9211819550321c4aad22e12 Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 7 Nov 2022 09:43:38 -0400 Subject: [PATCH 018/252] Fix/batch upload children, with validation according to default widget (#896) * Add ctools, prior to using it. * Fix up all the dependency references. ... before the colon is the project name, so should only be "drupal" for modules shipped in core. * Some more together. * Decent progress... getting things actually rendering... ... bit of refactoring stuff making a mess. * More worky. ... as in, basically functional. Still needs coding standards pass, and testing with more/all types of content. * Coding standards, and warning of validation issues. * Pull the batch out to a separate service. * Something of namespacing the child-specific batch... ... 'cause need to slap together a media-specific batch similarly? * All together, I think... Both the child-uploading, and media-uploading forms. * It is not necessary to explicitly mark the files as permanent. * Further generalizing... ... no longer necessarily trying to load files, where files might not be present (for non-file media... oEmbed things?). * Adjust class comment. * Get rid of the deprecation flags. * Remove unused constant. ... is defined instead at the "FileSelectionForm" level, accidentally left it here from intermediate implementation state. * Pass the renderer along, with the version constraint. * Add update hook to enable ctools in sites where it may not be. ... as it's now required. * Cover ALL the exits. * Refine message. * Excessively long line in comment... ... whoops. * Bump spec up to allow ctools 4. Gave it a run through here, and seemed to work fine; however, ctools' project page still seems to suggest the 3 major version should be preferred... but let's allow 4, if people are using or want to test it out? * Fix undefined "count" index. --- composer.json | 5 +- islandora.info.yml | 25 +- islandora.install | 38 +++ islandora.routing.yml | 14 +- islandora.services.yml | 16 ++ src/Form/AddChildrenForm.php | 2 +- .../AbstractBatchProcessor.php | 258 ++++++++++++++++++ .../AbstractFileSelectionForm.php | 157 +++++++++++ src/Form/AddChildrenWizard/AbstractForm.php | 125 +++++++++ src/Form/AddChildrenWizard/Access.php | 71 +++++ .../AddChildrenWizard/ChildBatchProcessor.php | 57 ++++ .../ChildFileSelectionForm.php | 32 +++ src/Form/AddChildrenWizard/ChildForm.php | 24 ++ .../ChildTypeSelectionForm.php | 157 +++++++++++ src/Form/AddChildrenWizard/FieldTrait.php | 66 +++++ .../AddChildrenWizard/MediaBatchProcessor.php | 34 +++ .../MediaFileSelectionForm.php | 32 +++ src/Form/AddChildrenWizard/MediaForm.php | 24 ++ .../MediaTypeSelectionForm.php | 227 +++++++++++++++ src/Form/AddChildrenWizard/MediaTypeTrait.php | 58 ++++ src/Form/AddChildrenWizard/WizardTrait.php | 40 +++ 21 files changed, 1441 insertions(+), 21 deletions(-) create mode 100644 src/Form/AddChildrenWizard/AbstractBatchProcessor.php create mode 100644 src/Form/AddChildrenWizard/AbstractFileSelectionForm.php create mode 100644 src/Form/AddChildrenWizard/AbstractForm.php create mode 100644 src/Form/AddChildrenWizard/Access.php create mode 100644 src/Form/AddChildrenWizard/ChildBatchProcessor.php create mode 100644 src/Form/AddChildrenWizard/ChildFileSelectionForm.php create mode 100644 src/Form/AddChildrenWizard/ChildForm.php create mode 100644 src/Form/AddChildrenWizard/ChildTypeSelectionForm.php create mode 100644 src/Form/AddChildrenWizard/FieldTrait.php create mode 100644 src/Form/AddChildrenWizard/MediaBatchProcessor.php create mode 100644 src/Form/AddChildrenWizard/MediaFileSelectionForm.php create mode 100644 src/Form/AddChildrenWizard/MediaForm.php create mode 100644 src/Form/AddChildrenWizard/MediaTypeSelectionForm.php create mode 100644 src/Form/AddChildrenWizard/MediaTypeTrait.php create mode 100644 src/Form/AddChildrenWizard/WizardTrait.php diff --git a/composer.json b/composer.json index 24eb9e5ba..c02d7c168 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,8 @@ "drupal/token" : "^1.3", "drupal/flysystem" : "^2.0@alpha", "islandora/crayfish-commons": "^2", - "drupal/file_replace": "^1.1" + "drupal/file_replace": "^1.1", + "drupal/ctools": "^3.8 || ^4" }, "require-dev": { "phpunit/phpunit": "^6", @@ -37,7 +38,7 @@ "sebastian/phpcpd": "*" }, "suggest": { - "drupal/transliterate_filenames": "Sanitizes filenames when they are uploaded so they don't break your repository." + "drupal/transliterate_filenames": "Sanitizes filenames when they are uploaded so they don't break your repository." }, "license": "GPL-2.0-or-later", "authors": [ diff --git a/islandora.info.yml b/islandora.info.yml index 9cd89cddc..0336d89d3 100644 --- a/islandora.info.yml +++ b/islandora.info.yml @@ -13,22 +13,23 @@ dependencies: - drupal:text - drupal:options - drupal:link - - drupal:jsonld - - drupal:search_api - - drupal:jwt + - jsonld:jsonld + - search_api:search_api + - jwt:jwt - drupal:rest - - drupal:filehash + - filehash:filehash - drupal:basic_auth - - drupal:context_ui + - context:context_ui - drupal:action - - drupal:eva + - eva:eva - drupal:taxonomy - drupal:views_ui - drupal:media - - drupal:prepopulate - - drupal:features_ui - - drupal:migrate_source_csv + - prepopulate:prepopulate + - features:features_ui + - migrate_source_csv:migrate_source_csv - drupal:content_translation - - drupal:flysystem - - drupal:token - - drupal:file_replace + - flysystem:flysystem + - token:token + - file_replace:file_replace + - ctools:ctools diff --git a/islandora.install b/islandora.install index f9eb1225f..ad2eb8e1c 100644 --- a/islandora.install +++ b/islandora.install @@ -5,6 +5,10 @@ * Install/update hook implementations. */ +use Drupal\Core\Extension\ExtensionNameLengthException; +use Drupal\Core\Extension\MissingDependencyException; +use Drupal\Core\Utility\UpdateException; + /** * Adds common namespaces to jsonld.settings. */ @@ -174,3 +178,37 @@ function update_jsonld_included_namespaces() { ->warning("Could not find required jsonld.settings to add default RDF namespaces."); } } + +/** + * Ensure that ctools is enabled. + */ +function islandora_update_8007() { + $module_handler = \Drupal::moduleHandler(); + if ($module_handler->moduleExists('ctools')) { + return t('The "@module_name" module is already enabled, no action necessary.', [ + '@module_name' => 'ctools', + ]); + } + + /** @var \Drupal\Core\Extension\ModuleInstallerInterface $installer */ + $installer = \Drupal::service('module_installer'); + + try { + if ($installer->install(['ctools'], TRUE)) { + return t('The "@module_name" module was enabled successfully.', [ + '@module_name' => 'ctools', + ]); + } + } + catch (ExtensionNameLengthException | MissingDependencyException $e) { + throw new UpdateException('Failed; ensure that the ctools module is available in the Drupal installation.', 0, $e); + } + catch (\Exception $e) { + throw new UpdateException('Failed; encountered an exception while trying to enable ctools.', 0, $e); + } + + // Theoretically impossible to hit, as ModuleInstaller::install() only returns + // TRUE (or throws/propagates an exception), but... probably a good idea to + // have the here, just in case? + throw new UpdateException('Failed; hit the end of the update hook implementation, which is not expected.'); +} diff --git a/islandora.routing.yml b/islandora.routing.yml index 5387e9a47..86d134828 100644 --- a/islandora.routing.yml +++ b/islandora.routing.yml @@ -37,14 +37,15 @@ islandora.add_member_to_node_page: _entity_create_any_access: 'node' islandora.upload_children: - path: '/node/{node}/members/upload' + path: '/node/{node}/members/upload/{step}' defaults: - _form: '\Drupal\islandora\Form\AddChildrenForm' + _wizard: '\Drupal\islandora\Form\AddChildrenWizard\ChildForm' _title: 'Upload Children' + step: 'type_selection' options: _admin_route: 'TRUE' requirements: - _custom_access: '\Drupal\islandora\Form\AddChildrenForm::access' + _custom_access: '\Drupal\islandora\Form\AddChildrenWizard\Access::childAccess' islandora.add_media_to_node_page: path: '/node/{node}/media/add' @@ -58,14 +59,15 @@ islandora.add_media_to_node_page: _entity_create_any_access: 'media' islandora.upload_media: - path: '/node/{node}/media/upload' + path: '/node/{node}/media/upload/{step}' defaults: - _form: '\Drupal\islandora\Form\AddMediaForm' + _wizard: '\Drupal\islandora\Form\AddChildrenWizard\MediaForm' _title: 'Add media' + step: 'type_selection' options: _admin_route: 'TRUE' requirements: - _custom_access: '\Drupal\islandora\Form\AddMediaForm::access' + _custom_access: '\Drupal\islandora\Form\AddChildrenWizard\Access::mediaAccess' islandora.media_source_update: path: '/media/{media}/source' diff --git a/islandora.services.yml b/islandora.services.yml index 4b3a9d16e..4108e2446 100644 --- a/islandora.services.yml +++ b/islandora.services.yml @@ -59,3 +59,19 @@ services: arguments: ['@jwt.authentication.jwt'] tags: - { name: event_subscriber } + islandora.upload_children.batch_processor: + class: Drupal\islandora\Form\AddChildrenWizard\ChildBatchProcessor + arguments: + - '@entity_type.manager' + - '@database' + - '@current_user' + - '@messenger' + - '@date.formatter' + islandora.upload_media.batch_processor: + class: Drupal\islandora\Form\AddChildrenWizard\MediaBatchProcessor + arguments: + - '@entity_type.manager' + - '@database' + - '@current_user' + - '@messenger' + - '@date.formatter' diff --git a/src/Form/AddChildrenForm.php b/src/Form/AddChildrenForm.php index 0ff724962..528b42832 100644 --- a/src/Form/AddChildrenForm.php +++ b/src/Form/AddChildrenForm.php @@ -229,7 +229,7 @@ public function buildNodeFinished($success, $results, $operations) { * @param \Drupal\Core\Routing\RouteMatch $route_match * The current routing match. * - * @return \Drupal\Core\Access\AccessResultAllowed|\Drupal\Core\Access\AccessResultForbidden + * @return \Drupal\Core\Access\AccessResultInterface * Whether we can or can't show the "thing". */ public function access(RouteMatch $route_match) { diff --git a/src/Form/AddChildrenWizard/AbstractBatchProcessor.php b/src/Form/AddChildrenWizard/AbstractBatchProcessor.php new file mode 100644 index 000000000..6193c0c30 --- /dev/null +++ b/src/Form/AddChildrenWizard/AbstractBatchProcessor.php @@ -0,0 +1,258 @@ +entityTypeManager = $entity_type_manager; + $this->database = $database; + $this->currentUser = $current_user; + $this->messenger = $messenger; + $this->dateFormatter = $date_formatter; + } + + /** + * Implements callback_batch_operation() for our child addition batch. + */ + public function batchOperation($delta, $info, array $values, &$context) { + $transaction = $this->database->startTransaction(); + + try { + $entities[] = $node = $this->getNode($info, $values); + $entities[] = $this->createMedia($node, $info, $values); + + $context['results'] = array_merge_recursive($context['results'], [ + 'validation_violations' => $this->validationClassification($entities), + ]); + $context['results']['count'] = ($context['results']['count'] ?? 0) + 1; + } + catch (HttpExceptionInterface $e) { + $transaction->rollBack(); + throw $e; + } + catch (\Exception $e) { + $transaction->rollBack(); + throw new HttpException(500, $e->getMessage(), $e); + } + } + + /** + * Loads the file indicated. + * + * @param mixed $info + * Widget values. + * + * @return \Drupal\file\FileInterface|null + * The loaded file. + * + * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException + * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException + */ + protected function getFile($info) : ?FileInterface { + return (is_array($info) && isset($info['target_id'])) ? + $this->entityTypeManager->getStorage('file')->load($info['target_id']) : + NULL; + } + + /** + * Get the node to which to attach our media. + * + * @param mixed $info + * Info from the widget used to create the request. + * @param array $values + * Additional form inputs. + * + * @return \Drupal\node\NodeInterface + * The node to which to attach the created media. + */ + abstract protected function getNode($info, array $values) : NodeInterface; + + /** + * Get a name to use for bulk-created assets. + * + * @param mixed $info + * Widget values. + * @param array $values + * Form values. + * + * @return string + * An applicable name. + * + * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException + * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException + */ + protected function getName($info, array $values) : string { + $file = $this->getFile($info); + return $file ? $file->getFilename() : strtr('Bulk ingest, {date}', [ + '{date}' => $this->dateFormatter->format(time(), 'long'), + ]); + } + + /** + * Create a media referencing the given file, associated with the given node. + * + * @param \Drupal\node\NodeInterface $node + * The node to which the media should be associated. + * @param mixed $info + * The widget info for the media source field. + * @param array $values + * Values from the wizard, which should contain at least: + * - media_type: The machine name/ID of the media type as which to create + * the media + * - use: An array of the selected "media use" terms. + * + * @return \Drupal\media\MediaInterface + * The created media entity. + * + * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException + * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException + * @throws \Drupal\Core\Entity\EntityStorageException + */ + protected function createMedia(NodeInterface $node, $info, array $values) : MediaInterface { + $taxonomy_term_storage = $this->entityTypeManager->getStorage('taxonomy_term'); + + // Create a media with the file attached and also pointing at the node. + $field = $this->getField($values); + + $media_values = array_merge( + [ + 'bundle' => $values['media_type'], + 'name' => $this->getName($info, $values), + IslandoraUtils::MEDIA_OF_FIELD => $node, + IslandoraUtils::MEDIA_USAGE_FIELD => ($values['use'] ? + $taxonomy_term_storage->loadMultiple($values['use']) : + NULL), + 'uid' => $this->currentUser->id(), + // XXX: Published... no constant? + 'status' => 1, + ], + [ + $field->getName() => [ + $info, + ], + ] + ); + $media = $this->entityTypeManager->getStorage('media')->create($media_values); + if ($media->save() !== SAVED_NEW) { + throw new \Exception("Failed to create media."); + } + + return $media; + } + + /** + * Helper to bulk process validatable entities. + * + * @param array $entities + * An array of entities to scan for validation violations. + * + * @return array + * An associative array mapping entity type IDs to entity IDs to a count + * of validation violations found on then given entity. + */ + protected function validationClassification(array $entities) { + $violations = []; + + foreach ($entities as $entity) { + $entity_violations = $entity->validate(); + if ($entity_violations->count() > 0) { + $violations[$entity->getEntityTypeId()][$entity->id()] = $entity_violations->count(); + } + } + + return $violations; + } + + /** + * Implements callback_batch_finished() for our child addition batch. + */ + public function batchProcessFinished($success, $results, $operations): void { + if ($success) { + foreach ($results['validation_violations'] ?? [] as $entity_type => $info) { + foreach ($info as $id => $count) { + $this->messenger->addWarning($this->formatPlural( + $count, + '1 validation error present in bulk created entity of type %type, with ID %id.', + '@count validation errors present in bulk created entity of type %type, with ID %id.', + [ + '%type' => $entity_type, + ':uri' => Url::fromRoute("entity.{$entity_type}.canonical", [$entity_type => $id])->toString(), + '%id' => $id, + ] + )); + } + } + } + else { + $this->messenger->addError($this->t('Encountered an error when processing.')); + } + } + +} diff --git a/src/Form/AddChildrenWizard/AbstractFileSelectionForm.php b/src/Form/AddChildrenWizard/AbstractFileSelectionForm.php new file mode 100644 index 000000000..6aeed8795 --- /dev/null +++ b/src/Form/AddChildrenWizard/AbstractFileSelectionForm.php @@ -0,0 +1,157 @@ +entityTypeManager = $container->get('entity_type.manager'); + $instance->widgetPluginManager = $container->get('plugin.manager.field.widget'); + $instance->entityFieldManager = $container->get('entity_field.manager'); + $instance->currentUser = $container->get('current_user'); + + $instance->batchProcessor = $container->get(static::BATCH_PROCESSOR); + + return $instance; + } + + /** + * Helper; get the media type, based off discovering from form state. + * + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The form state. + * + * @return \Drupal\media\MediaTypeInterface + * The target media type. + * + * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException + * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException + */ + protected function getMediaTypeFromFormState(FormStateInterface $form_state): MediaTypeInterface { + return $this->getMediaType($form_state->getTemporaryValue('wizard')); + } + + /** + * Helper; get field instance, based off discovering from form state. + * + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The form state. + * + * @return \Drupal\Core\Field\FieldDefinitionInterface + * The field definition. + */ + protected function getFieldFromFormState(FormStateInterface $form_state): FieldDefinitionInterface { + $cached_values = $form_state->getTemporaryValue('wizard'); + + $field = $this->getField($cached_values); + $def = $field->getFieldStorageDefinition(); + if ($def instanceof FieldStorageConfigInterface) { + $def->set('cardinality', FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); + } + elseif ($def instanceof BaseFieldDefinition) { + $def->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); + } + else { + throw new \Exception('Unable to remove cardinality limit.'); + } + + return $field; + } + + /** + * Helper; get widget for the field, based on discovering from form state. + * + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The form state. + * + * @return \Drupal\Core\Field\WidgetInterface + * The widget. + */ + protected function getWidgetFromFormState(FormStateInterface $form_state): WidgetInterface { + return $this->getWidget($this->getFieldFromFormState($form_state)); + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state): array { + // Using the media type selected in the previous step, grab the + // media bundle's "source" field, and create a multi-file upload widget + // for it, with the same kind of constraints. + $field = $this->getFieldFromFormState($form_state); + $items = FieldItemList::createInstance($field, $field->getName(), $this->getMediaTypeFromFormState($form_state)->getTypedData()); + + $form['#tree'] = TRUE; + $form['#parents'] = []; + $widget = $this->getWidgetFromFormState($form_state); + $form['files'] = $widget->form( + $items, + $form, + $form_state + ); + + return $form; + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + $cached_values = $form_state->getTemporaryValue('wizard'); + + $widget = $this->getWidgetFromFormState($form_state); + $builder = (new BatchBuilder()) + ->setTitle($this->t('Bulk creating...')) + ->setInitMessage($this->t('Initializing...')) + ->setFinishCallback([$this->batchProcessor, 'batchProcessFinished']); + $values = $form_state->getValue($this->getField($cached_values)->getName()); + $massaged_values = $widget->massageFormValues($values, $form, $form_state); + foreach ($massaged_values as $delta => $info) { + $builder->addOperation( + [$this->batchProcessor, 'batchOperation'], + [$delta, $info, $cached_values] + ); + } + batch_set($builder->toArray()); + } + +} diff --git a/src/Form/AddChildrenWizard/AbstractForm.php b/src/Form/AddChildrenWizard/AbstractForm.php new file mode 100644 index 000000000..e9fac3875 --- /dev/null +++ b/src/Form/AddChildrenWizard/AbstractForm.php @@ -0,0 +1,125 @@ +nodeId = $this->routeMatch->getParameter('node'); + $this->currentUser = $current_user; + } + + /** + * {@inheritdoc} + */ + public static function getParameters() : array { + return array_merge( + parent::getParameters(), + [ + 'tempstore_id' => static::TEMPSTORE_ID, + 'current_user' => \Drupal::service('current_user'), + ] + ); + } + + /** + * {@inheritdoc} + */ + public function getOperations($cached_values) { + $ops = []; + + $ops['type_selection'] = [ + 'title' => $this->t('Type Selection'), + 'form' => static::TYPE_SELECTION_FORM, + 'values' => [ + 'node' => $this->nodeId, + ], + ]; + $ops['file_selection'] = [ + 'title' => $this->t('Widget Input for Selected Type'), + 'form' => static::FILE_SELECTION_FORM, + 'values' => [ + 'node' => $this->nodeId, + ], + ]; + + return $ops; + } + + /** + * {@inheritdoc} + */ + public function getNextParameters($cached_values) { + return parent::getNextParameters($cached_values) + ['node' => $this->nodeId]; + } + + /** + * {@inheritdoc} + */ + public function getPreviousParameters($cached_values) { + return parent::getPreviousParameters($cached_values) + ['node' => $this->nodeId]; + } + +} diff --git a/src/Form/AddChildrenWizard/Access.php b/src/Form/AddChildrenWizard/Access.php new file mode 100644 index 000000000..0adafde51 --- /dev/null +++ b/src/Form/AddChildrenWizard/Access.php @@ -0,0 +1,71 @@ +utils = $utils; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) : self { + return new static( + $container->get('islandora.utils') + ); + } + + /** + * Check if the user can create any "Islandora" nodes and media. + * + * @param \Drupal\Core\Routing\RouteMatch $route_match + * The current routing match. + * + * @return \Drupal\Core\Access\AccessResultInterface + * Whether we can or cannot show the "thing". + */ + public function childAccess(RouteMatch $route_match) : AccessResultInterface { + return AccessResult::allowedIf($this->utils->canCreateIslandoraEntity('node', 'node_type')) + ->andIf($this->mediaAccess($route_match)); + + } + + /** + * Check if the user can create any "Islandora" media. + * + * @param \Drupal\Core\Routing\RouteMatch $route_match + * The current routing match. + * + * @return \Drupal\Core\Access\AccessResultInterface + * Whether we can or cannot show the "thing". + */ + public function mediaAccess(RouteMatch $route_match) : AccessResultInterface { + return AccessResult::allowedIf($this->utils->canCreateIslandoraEntity('media', 'media_type')); + } + +} diff --git a/src/Form/AddChildrenWizard/ChildBatchProcessor.php b/src/Form/AddChildrenWizard/ChildBatchProcessor.php new file mode 100644 index 000000000..084e7816e --- /dev/null +++ b/src/Form/AddChildrenWizard/ChildBatchProcessor.php @@ -0,0 +1,57 @@ +entityTypeManager->getStorage('taxonomy_term'); + $node_storage = $this->entityTypeManager->getStorage('node'); + $parent = $node_storage->load($values['node']); + + // Create a node (with the filename?) (and also belonging to the target + // node). + /** @var \Drupal\node\NodeInterface $node */ + $node = $node_storage->create([ + 'type' => $values['bundle'], + 'title' => $this->getName($info, $values), + IslandoraUtils::MEMBER_OF_FIELD => $parent, + 'uid' => $this->currentUser->id(), + 'status' => NodeInterface::PUBLISHED, + IslandoraUtils::MODEL_FIELD => ($values['model'] ? + $taxonomy_term_storage->load($values['model']) : + NULL), + ]); + + if ($node->save() !== SAVED_NEW) { + throw new \Exception("Failed to create node."); + } + + return $node; + } + + /** + * {@inheritdoc} + */ + public function batchProcessFinished($success, $results, $operations): void { + if ($success) { + $this->messenger->addMessage($this->formatPlural( + $results['count'], + 'Added 1 child node.', + 'Added @count child nodes.' + )); + } + + parent::batchProcessFinished($success, $results, $operations); + } + +} diff --git a/src/Form/AddChildrenWizard/ChildFileSelectionForm.php b/src/Form/AddChildrenWizard/ChildFileSelectionForm.php new file mode 100644 index 000000000..9783d0823 --- /dev/null +++ b/src/Form/AddChildrenWizard/ChildFileSelectionForm.php @@ -0,0 +1,32 @@ +getTemporaryValue('wizard'); + $form_state->setRedirectUrl(Url::fromUri("internal:/node/{$cached_values['node']}/members")); + } + +} diff --git a/src/Form/AddChildrenWizard/ChildForm.php b/src/Form/AddChildrenWizard/ChildForm.php new file mode 100644 index 000000000..0b9a197f4 --- /dev/null +++ b/src/Form/AddChildrenWizard/ChildForm.php @@ -0,0 +1,24 @@ + $this->currentUser->id(), + '{nodeid}' => $this->nodeId, + ]); + } + +} diff --git a/src/Form/AddChildrenWizard/ChildTypeSelectionForm.php b/src/Form/AddChildrenWizard/ChildTypeSelectionForm.php new file mode 100644 index 000000000..f57959971 --- /dev/null +++ b/src/Form/AddChildrenWizard/ChildTypeSelectionForm.php @@ -0,0 +1,157 @@ +nodeBundleOptions === NULL) { + $this->nodeBundleOptions = []; + $this->nodeBundleHasModelField = []; + + $access_handler = $this->entityTypeManager->getAccessControlHandler('node'); + foreach ($this->entityTypeBundleInfo->getBundleInfo('node') as $bundle => $info) { + $access = $access_handler->createAccess( + $bundle, + NULL, + [], + TRUE + ); + $this->cacheableMetadata->addCacheableDependency($access); + if (!$access->isAllowed()) { + continue; + } + $this->nodeBundleOptions[$bundle] = $info['label']; + $fields = $this->entityFieldManager->getFieldDefinitions('node', $bundle); + $this->nodeBundleHasModelField[$bundle] = array_key_exists(IslandoraUtils::MODEL_FIELD, $fields); + } + } + + return $this->nodeBundleOptions; + } + + /** + * Generates a mapping of taxonomy term IDs to their names. + * + * @return \Generator + * The mapping of taxonomy term IDs to their names. + * + * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException + * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException + */ + protected function getModelOptions() : \Generator { + $terms = $this->entityTypeManager->getStorage('taxonomy_term') + ->loadTree('islandora_models', 0, NULL, TRUE); + foreach ($terms as $term) { + yield $term->id() => $term->getName(); + } + } + + /** + * Helper; map node bundles supporting the "has model" field, for #states. + * + * @return \Generator + * Yields associative array mapping the string 'value' to the bundles which + * have the given field. + */ + protected function mapModelStates() : \Generator { + $this->getNodeBundleOptions(); + foreach (array_keys(array_filter($this->nodeBundleHasModelField)) as $bundle) { + yield ['value' => $bundle]; + } + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state) { + $this->cacheableMetadata = CacheableMetadata::createFromRenderArray($form) + ->addCacheContexts([ + 'url', + 'url.query_args', + ]); + $cached_values = $form_state->getTemporaryValue('wizard'); + + $form['bundle'] = [ + '#type' => 'select', + '#title' => $this->t('Content Type'), + '#description' => $this->t('Each child created will have this content type.'), + '#empty_value' => '', + '#default_value' => $cached_values['bundle'] ?? '', + '#options' => $this->getNodeBundleOptions(), + '#required' => TRUE, + ]; + + $model_states = iterator_to_array($this->mapModelStates()); + $form['model'] = [ + '#type' => 'select', + '#title' => $this->t('Model'), + '#description' => $this->t('Each child will be tagged with this model.'), + '#options' => iterator_to_array($this->getModelOptions()), + '#empty_value' => '', + '#default_value' => $cached_values['model'] ?? '', + '#states' => [ + 'visible' => [ + ':input[name="bundle"]' => $model_states, + ], + 'required' => [ + ':input[name="bundle"]' => $model_states, + ], + ], + ]; + + $this->cacheableMetadata->applyTo($form); + return parent::buildForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + protected static function keysToSave() : array { + return array_merge( + parent::keysToSave(), + [ + 'bundle', + 'model', + ] + ); + } + +} diff --git a/src/Form/AddChildrenWizard/FieldTrait.php b/src/Form/AddChildrenWizard/FieldTrait.php new file mode 100644 index 000000000..830f95cda --- /dev/null +++ b/src/Form/AddChildrenWizard/FieldTrait.php @@ -0,0 +1,66 @@ +getMediaType($values); + $media_source = $media_type->getSource(); + $source_field = $media_source->getSourceFieldDefinition($media_type); + + $fields = $this->entityFieldManager()->getFieldDefinitions('media', $media_type->id()); + + return $fields[$source_field->getFieldStorageDefinition()->getName()] ?? + $media_source->createSourceField($media_type); + } + + /** + * Lazy-initialization of the entity field manager service. + * + * @return \Drupal\Core\Entity\EntityFieldManagerInterface + * The entity field manager service. + */ + protected function entityFieldManager() : EntityFieldManagerInterface { + if ($this->entityFieldManager === NULL) { + $this->setEntityFieldManager(\Drupal::service('entity_field.manager')); + } + return $this->entityFieldManager; + } + + /** + * Setter for entity field manager. + */ + public function setEntityFieldManager(EntityFieldManagerInterface $entity_field_manager) : self { + $this->entityFieldManager = $entity_field_manager; + return $this; + } + +} diff --git a/src/Form/AddChildrenWizard/MediaBatchProcessor.php b/src/Form/AddChildrenWizard/MediaBatchProcessor.php new file mode 100644 index 000000000..9a54f03b6 --- /dev/null +++ b/src/Form/AddChildrenWizard/MediaBatchProcessor.php @@ -0,0 +1,34 @@ +entityTypeManager->getStorage('node')->load($values['node']); + } + + /** + * {@inheritdoc} + */ + public function batchProcessFinished($success, $results, $operations): void { + if ($success) { + $this->messenger->addMessage($this->formatPlural( + $results['count'], + 'Added 1 media.', + 'Added @count media.' + )); + } + + parent::batchProcessFinished($success, $results, $operations); + } + +} diff --git a/src/Form/AddChildrenWizard/MediaFileSelectionForm.php b/src/Form/AddChildrenWizard/MediaFileSelectionForm.php new file mode 100644 index 000000000..534c73093 --- /dev/null +++ b/src/Form/AddChildrenWizard/MediaFileSelectionForm.php @@ -0,0 +1,32 @@ +getTemporaryValue('wizard'); + $form_state->setRedirectUrl(Url::fromUri("internal:/node/{$cached_values['node']}/media")); + } + +} diff --git a/src/Form/AddChildrenWizard/MediaForm.php b/src/Form/AddChildrenWizard/MediaForm.php new file mode 100644 index 000000000..2e6fa2177 --- /dev/null +++ b/src/Form/AddChildrenWizard/MediaForm.php @@ -0,0 +1,24 @@ + $this->currentUser->id(), + '{nodeid}' => $this->nodeId, + ]); + } + +} diff --git a/src/Form/AddChildrenWizard/MediaTypeSelectionForm.php b/src/Form/AddChildrenWizard/MediaTypeSelectionForm.php new file mode 100644 index 000000000..b06d004dc --- /dev/null +++ b/src/Form/AddChildrenWizard/MediaTypeSelectionForm.php @@ -0,0 +1,227 @@ +entityTypeBundleInfo = $container->get('entity_type.bundle.info'); + $instance->entityTypeManager = $container->get('entity_type.manager'); + $instance->entityFieldManager = $container->get('entity_field.manager'); + $instance->utils = $container->get('islandora.utils'); + + return $instance; + } + + /** + * {@inheritdoc} + */ + public function getFormId() : string { + return 'islandora_add_media_type_selection'; + } + + /** + * Memoization for ::getMediaBundleOptions(). + * + * @var array|null + */ + protected ?array $mediaBundleOptions = NULL; + + /** + * Indicate presence of usage field on media bundles. + * + * Populated as a side effect in ::getMediaBundleOptions(). + * + * @var array|null + */ + protected ?array $mediaBundleUsageField = NULL; + + /** + * Helper; get options for media types. + * + * @return array + * An associative array mapping the machine name of the media type to its + * human-readable label. + */ + protected function getMediaBundleOptions() : array { + if ($this->mediaBundleOptions === NULL) { + $this->mediaBundleOptions = []; + $this->mediaBundleUsageField = []; + + $access_handler = $this->entityTypeManager->getAccessControlHandler('media'); + foreach ($this->entityTypeBundleInfo->getBundleInfo('media') as $bundle => $info) { + if (!$this->utils->isIslandoraType('media', $bundle)) { + continue; + } + $access = $access_handler->createAccess( + $bundle, + NULL, + [], + TRUE + ); + $this->cacheableMetadata->addCacheableDependency($access); + if (!$access->isAllowed()) { + continue; + } + $this->mediaBundleOptions[$bundle] = $info['label']; + $fields = $this->entityFieldManager->getFieldDefinitions('media', $bundle); + $this->mediaBundleUsageField[$bundle] = array_key_exists(IslandoraUtils::MEDIA_USAGE_FIELD, $fields); + } + } + + return $this->mediaBundleOptions; + } + + /** + * Helper; list the terms of the "islandora_media_use" vocabulary. + * + * @return \Generator + * Generates term IDs as keys mapping to term names. + * + * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException + * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException + */ + protected function getMediaUseOptions() : \Generator { + /** @var \Drupal\taxonomy\TermInterface[] $terms */ + $terms = $this->entityTypeManager->getStorage('taxonomy_term') + ->loadTree('islandora_media_use', 0, NULL, TRUE); + + foreach ($terms as $term) { + yield $term->id() => $term->getName(); + } + } + + /** + * Helper; map media types supporting the usage field for use with #states. + * + * @return \Generator + * Yields associative array mapping the string 'value' to the bundles which + * have the given field. + */ + protected function mapUseStates(): \Generator { + $this->getMediaBundleOptions(); + foreach (array_keys(array_filter($this->mediaBundleUsageField)) as $bundle) { + yield ['value' => $bundle]; + } + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state) { + $this->cacheableMetadata = CacheableMetadata::createFromRenderArray($form) + ->addCacheContexts([ + 'url', + 'url.query_args', + ]); + $cached_values = $form_state->getTemporaryValue('wizard'); + + $form['media_type'] = [ + '#type' => 'select', + '#title' => $this->t('Media Type'), + '#description' => $this->t('Each media created will have this type.'), + '#empty_value' => '', + '#default_value' => $cached_values['media_type'] ?? '', + '#options' => $this->getMediaBundleOptions(), + '#required' => TRUE, + ]; + $use_states = iterator_to_array($this->mapUseStates()); + $form['use'] = [ + '#type' => 'checkboxes', + '#title' => $this->t('Usage'), + '#description' => $this->t('Defined by Portland Common Data Model: Use Extension. "Original File" will trigger creation of derivatives.', [ + ':url' => 'https://pcdm.org/2015/05/12/use', + ]), + '#options' => iterator_to_array($this->getMediaUseOptions()), + '#default_value' => $cached_values['use'] ?? [], + '#states' => [ + 'visible' => [ + ':input[name="media_type"]' => $use_states, + ], + 'required' => [ + ':input[name="media_type"]' => $use_states, + ], + ], + ]; + + $this->cacheableMetadata->applyTo($form); + return $form; + } + + /** + * Helper; enumerate keys to persist in form state. + * + * @return string[] + * The keys to be persisted in our temp value in form state. + */ + protected static function keysToSave() : array { + return [ + 'media_type', + 'use', + ]; + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + $cached_values = $form_state->getTemporaryValue('wizard'); + foreach (static::keysToSave() as $key) { + $cached_values[$key] = $form_state->getValue($key); + } + $form_state->setTemporaryValue('wizard', $cached_values); + } + +} diff --git a/src/Form/AddChildrenWizard/MediaTypeTrait.php b/src/Form/AddChildrenWizard/MediaTypeTrait.php new file mode 100644 index 000000000..36cf6ff2a --- /dev/null +++ b/src/Form/AddChildrenWizard/MediaTypeTrait.php @@ -0,0 +1,58 @@ +entityTypeManager()->getStorage('media_type')->load($values['media_type']); + } + + /** + * Lazy-initialization of the entity type manager service. + * + * @return \Drupal\Core\Entity\EntityTypeManagerInterface + * The entity type manager service. + */ + protected function entityTypeManager() : EntityTypeManagerInterface { + if ($this->entityTypeManager === NULL) { + $this->setEntityTypeManager(\Drupal::service('entity_type.manager')); + } + return $this->entityTypeManager; + } + + /** + * Setter for the entity type manager service. + */ + public function setEntityTypeManager(EntityTypeManagerInterface $entity_type_manager) : self { + $this->entityTypeManager = $entity_type_manager; + return $this; + } + +} diff --git a/src/Form/AddChildrenWizard/WizardTrait.php b/src/Form/AddChildrenWizard/WizardTrait.php new file mode 100644 index 000000000..dd56450fa --- /dev/null +++ b/src/Form/AddChildrenWizard/WizardTrait.php @@ -0,0 +1,40 @@ +widgetPluginManager->getInstance([ + 'field_definition' => $field, + 'form_mode' => 'default', + 'prepare' => TRUE, + ]); + } + +} From e3c7e6eddac3f81614f923c96463f8d24e250412 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Sat, 23 Jul 2022 14:43:48 -0300 Subject: [PATCH 019/252] Document the add members and add media pages. --- src/Controller/ManageMediaController.php | 9 ++++++++- src/Controller/ManageMembersController.php | 10 +++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/Controller/ManageMediaController.php b/src/Controller/ManageMediaController.php index bd670561a..a58d98607 100644 --- a/src/Controller/ManageMediaController.php +++ b/src/Controller/ManageMediaController.php @@ -25,7 +25,7 @@ class ManageMediaController extends ManageMembersController { public function addToNodePage(NodeInterface $node) { $field = IslandoraUtils::MEDIA_OF_FIELD; - return $this->generateTypeList( + $add_media_list = $this->generateTypeList( 'media', 'media_type', 'entity.media.add_form', @@ -33,6 +33,13 @@ public function addToNodePage(NodeInterface $node) { $field, ['query' => ["edit[$field][widget][0][target_id]" => $node->id()]] ); + + return [ + '#type' => 'markup', + '#markup' => $this->t("These available media types below have @field and it is configured to allow this content type.", + ['@field' => $field]), + 'add_media' => $add_media_list, + ]; } /** diff --git a/src/Controller/ManageMembersController.php b/src/Controller/ManageMembersController.php index 7f480fb3d..e07ec5dfb 100644 --- a/src/Controller/ManageMembersController.php +++ b/src/Controller/ManageMembersController.php @@ -88,7 +88,8 @@ public static function create(ContainerInterface $container) { */ public function addToNodePage(NodeInterface $node) { $field = IslandoraUtils::MEMBER_OF_FIELD; - return $this->generateTypeList( + + $add_node_list = $this->generateTypeList( 'node', 'node_type', 'node.add', @@ -96,6 +97,13 @@ public function addToNodePage(NodeInterface $node) { $field, ['query' => ["edit[$field][widget][0][target_id]" => $node->id()]] ); + + return [ + '#type' => 'markup', + '#markup' => $this->t("These available content types below have @field and it is configured to allow this content type.", + ['@field' => $field]), + 'add_node' => $add_node_list, + ]; } /** From 7eebb65c2b7c1f79fdfa563302836c97520176e4 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Mon, 7 Nov 2022 17:10:30 -0400 Subject: [PATCH 020/252] Clarify wording and add manage link. --- src/Controller/ManageMediaController.php | 7 +++++-- src/Controller/ManageMembersController.php | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Controller/ManageMediaController.php b/src/Controller/ManageMediaController.php index a58d98607..d15175f96 100644 --- a/src/Controller/ManageMediaController.php +++ b/src/Controller/ManageMediaController.php @@ -36,8 +36,11 @@ public function addToNodePage(NodeInterface $node) { return [ '#type' => 'markup', - '#markup' => $this->t("These available media types below have @field and it is configured to allow this content type.", - ['@field' => $field]), + '#markup' => $this->t("The following media types can be added because they have the @field field. Manage media types.", + [ + '@field' => $field, + '@manage_media_page' => '/admin/structure/media', + ]), 'add_media' => $add_media_list, ]; } diff --git a/src/Controller/ManageMembersController.php b/src/Controller/ManageMembersController.php index e07ec5dfb..bfd2cf74f 100644 --- a/src/Controller/ManageMembersController.php +++ b/src/Controller/ManageMembersController.php @@ -100,8 +100,11 @@ public function addToNodePage(NodeInterface $node) { return [ '#type' => 'markup', - '#markup' => $this->t("These available content types below have @field and it is configured to allow this content type.", - ['@field' => $field]), + '#markup' => $this->t("The following content types can be added because they have the @field field. Manage content types.", + [ + '@field' => $field, + '@manage_content_types' => '/admin/structure/types', + ]), 'add_node' => $add_node_list, ]; } From 386ba0ceb19e71119cb9e035381f4c93857560e1 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Mon, 7 Nov 2022 18:36:10 -0400 Subject: [PATCH 021/252] Detect access before showing manage links. --- src/Controller/ManageMediaController.php | 16 +++++++++++----- src/Controller/ManageMembersController.php | 16 +++++++++++----- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/Controller/ManageMediaController.php b/src/Controller/ManageMediaController.php index d15175f96..025d1d9dc 100644 --- a/src/Controller/ManageMediaController.php +++ b/src/Controller/ManageMediaController.php @@ -6,6 +6,7 @@ use Drupal\Core\Access\AccessResult; use Drupal\Core\Routing\RouteMatch; use Drupal\node\Entity\Node; +use Drupal\Core\Url; use Drupal\node\NodeInterface; /** @@ -34,13 +35,18 @@ public function addToNodePage(NodeInterface $node) { ['query' => ["edit[$field][widget][0][target_id]" => $node->id()]] ); + $manage_link = Url::fromRoute('entity.media_type.collection')->toRenderArray(); + $manage_link['#title'] = $this->t('Manage media types'); + $manage_link['#type'] = 'link'; + $manage_link['#prefix'] = ' '; + $manage_link['#suffix'] = '.'; + return [ '#type' => 'markup', - '#markup' => $this->t("The following media types can be added because they have the @field field. Manage media types.", - [ - '@field' => $field, - '@manage_media_page' => '/admin/structure/media', - ]), + '#markup' => $this->t("The following media types can be added because they have the @field field.", [ + '@field' => $field, + ]), + 'manage_link' => $manage_link, 'add_media' => $add_media_list, ]; } diff --git a/src/Controller/ManageMembersController.php b/src/Controller/ManageMembersController.php index bfd2cf74f..9827ff350 100644 --- a/src/Controller/ManageMembersController.php +++ b/src/Controller/ManageMembersController.php @@ -7,6 +7,7 @@ use Drupal\Core\Entity\Controller\EntityController; use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\Core\Link; +use Drupal\Core\Url; use Drupal\islandora\IslandoraUtils; use Drupal\node\NodeInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -98,13 +99,18 @@ public function addToNodePage(NodeInterface $node) { ['query' => ["edit[$field][widget][0][target_id]" => $node->id()]] ); + $manage_link = Url::fromRoute('entity.node_type.collection')->toRenderArray(); + $manage_link['#title'] = $this->t('Manage content types'); + $manage_link['#type'] = 'link'; + $manage_link['#prefix'] = ' '; + $manage_link['#suffix'] = '.'; + return [ '#type' => 'markup', - '#markup' => $this->t("The following content types can be added because they have the @field field. Manage content types.", - [ - '@field' => $field, - '@manage_content_types' => '/admin/structure/types', - ]), + '#markup' => $this->t("The following content types can be added because they have the @field field.", [ + '@field' => $field, + ]), + 'manage_link' => $manage_link, 'add_node' => $add_node_list, ]; } From 7ef1afffa2c814b83decb86e13677ecde764d68f Mon Sep 17 00:00:00 2001 From: shriram Date: Tue, 8 Nov 2022 13:44:38 -0400 Subject: [PATCH 022/252] delete media with files and translations --- islandora.module | 159 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 141 insertions(+), 18 deletions(-) diff --git a/islandora.module b/islandora.module index e8aeb2322..9130caebe 100644 --- a/islandora.module +++ b/islandora.module @@ -28,6 +28,7 @@ use Drupal\taxonomy\TermInterface; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\serialization\Normalizer\CacheableNormalizerInterface; use Drupal\Core\Entity\EntityForm; +use Drupal\file\Entity\File; /** * Implements hook_help(). @@ -337,25 +338,34 @@ function islandora_form_alter(&$form, FormStateInterface $form_state, $form_id) if ($form_object instanceof EntityForm) { $entity = $form_object->getEntity(); - if ($entity->getEntityTypeId() == "node" && $utils->isIslandoraType($entity->getEntityTypeId(), $entity->bundle()) && strpos($form['#form_id'], 'delete_form') !== FALSE) { - $form['delete_associated_content'] = [ - '#type' => 'checkbox', - '#title' => t('Delete all associated medias and nodes'), - ]; + if ($entity->getEntityTypeId() == "node" && $utils->isIslandoraType($entity->getEntityTypeId(), $entity->bundle()) && strpos($form['#form_id'], 'delete_form') !== FALSE) { $medias = $utils->getMedia($form_state->getFormObject()->getEntity()); - $media_list = ""; + if (count($medias) != 0) { + $form['delete_associated_content'] = [ + '#type' => 'checkbox', + '#title' => t('Delete all associated medias and nodes'), + ]; + + foreach ($medias as $media) { + $media_list[] = $media->getName(); + } + $form['media_items'] = [ + '#theme' => 'item_list', + '#type' => 'ul', + '#items' => $media_list, + '#attributes' => ['class' => 'mylist'], + '#wrapper_attributes' => ['class' => 'container'], + '#attached' => [ + 'library' => [ + 'islandora/drupal.islandora.theme_css', + ], + ], + ]; - foreach ($medias as $media) { - $media_list .= "
  • {$media->getName()}
  • "; + $form['actions']['submit']['#submit'][] = 'islandora_object_delete_form_submit'; + return $form; } - - $form['media_items'] = [ - '#suffix' => "
      {$media_list}
    ", - ]; - - $form['actions']['submit']['#submit'][] = 'islandora_object_delete_form_submit'; - return $form; } } return $form; @@ -371,10 +381,123 @@ function islandora_object_delete_form_submit($form, &$form_state) { if ($result['delete_associated_content'] == 1) { - $medias = $utils->getMedia($form_state->getFormObject()->getEntity()); - foreach ($medias as $media) { - $media->delete(); + $node = $form_state->getFormObject()->getEntity(); + $medias = $utils->getMedia($node); + $media_list = ""; + + $entity_type_manager = \Drupal::entityTypeManager(); + $entity_field_manager = \Drupal::service('entity_field.manager'); + $current_user = \Drupal::currentUser(); + $logger = \Drupal::logger('logger.channel.islandora'); + $messenger = \Drupal::messenger(); + + $total_count = 0; + $delete_media = []; + $delete_media_translations = []; + $delete_files = []; + $inaccessible_entities = []; + $media_storage = $entity_type_manager->getStorage('media'); + $file_storage = $entity_type_manager->getStorage('file'); + + foreach ($medias as $id => $media) { + $media_list .= $id . ", "; + $lang = $media->language()->getId(); + $selected_langcodes[$lang] = $lang; + + if (!$media->access('delete', $current_user)) { + $inaccessible_entities[] = $media; + continue; + } + // Check for files. + $fields = $entity_field_manager->getFieldDefinitions('media', $media->bundle()); + foreach ($fields as $field) { + $type = $field->getType(); + if ($type == 'file' || $type == 'image') { + $target_id = $media->get($field->getName())->target_id; + $file = File::load($target_id); + if ($file) { + if (!$file->access('delete', $current_user)) { + $inaccessible_entities[] = $file; + continue; + } + $delete_files[$file->id()] = $file; + $total_count++; + } + } + } + + foreach ($selected_langcodes as $langcode) { + // We're only working with media, which are translatable. + $entity = $media->getTranslation($langcode); + if ($entity->isDefaultTranslation()) { + $delete_media[$id] = $entity; + unset($delete_media_translations[$id]); + $total_count += count($entity->getTranslationLanguages()); + } + elseif (!isset($delete_media[$id])) { + $delete_media_translations[$id][] = $entity; + } + } } + + if ($delete_media) { + $media_storage->delete($delete_media); + foreach ($delete_media as $media) { + $logger->notice('The media %label has been deleted.', [ + '%label' => $media->label(), + ]); + } + } + + if ($delete_files) { + $file_storage->delete($delete_files); + foreach ($delete_files as $media) { + $logger->notice('The file %label has been deleted.', [ + '%label' => $media->label(), + ]); + } + } + + if ($delete_media_translations) { + foreach ($delete_media_translations as $id => $translations) { + $media = $medias[$id]; + foreach ($translations as $translation) { + $media->removeTranslation($translation->language()->getId()); + } + $media->save(); + foreach ($translations as $translation) { + $logger->notice('The media %label @language translation has been deleted', [ + '%label' => $media->label(), + '@language' => $translation->language()->getName(), + ]); + } + $total_count += count($translations); + } + } + + if ($inaccessible_entities) { + $messenger->addWarning("@count items has not been deleted because you do not have the necessary permissions.", [ + '@count' => count($inaccessible_entities), + ]); + } + + $build = [ + 'heading' => [ + '#type' => 'html_tag', + '#tag' => 'div', + '#value' => t("The repository item @node and @media", [ + '@node' => $node->getTitle(), + '@media' => \Drupal::translation()->formatPlural( + substr_count($media_list, ",") + 1, 'the media with the id @media has been deleted.', + 'the medias with the id @media have been deleted.', + ['@media' => mb_substr($media_list, 0, strlen($media_list) - 2)]), + ]), + ], + ]; + + $message = \Drupal::service('renderer')->renderPlain($build); + $messenger->deleteByType('status'); + $messenger->addStatus($message); } } From ef1f36f2836bcdc82a8b2ca1526924b99a54f70c Mon Sep 17 00:00:00 2001 From: shriram Date: Tue, 8 Nov 2022 16:07:27 -0400 Subject: [PATCH 023/252] Updated test cases to include file deletion --- islandora.module | 9 ++++++--- ...WithMedia.php => DeleteNodeWithMediaAndFile.php} | 13 +++++++++---- 2 files changed, 15 insertions(+), 7 deletions(-) rename tests/src/Functional/{DeleteNodeWithMedia.php => DeleteNodeWithMediaAndFile.php} (87%) diff --git a/islandora.module b/islandora.module index 9130caebe..44dc35a7d 100644 --- a/islandora.module +++ b/islandora.module @@ -347,9 +347,12 @@ function islandora_form_alter(&$form, FormStateInterface $form_state, $form_id) '#title' => t('Delete all associated medias and nodes'), ]; - foreach ($medias as $media) { + $media_list = []; + + foreach ($medias as $media) { $media_list[] = $media->getName(); } + $form['media_items'] = [ '#theme' => 'item_list', '#type' => 'ul', @@ -451,9 +454,9 @@ function islandora_object_delete_form_submit($form, &$form_state) { if ($delete_files) { $file_storage->delete($delete_files); - foreach ($delete_files as $media) { + foreach ($delete_files as $file) { $logger->notice('The file %label has been deleted.', [ - '%label' => $media->label(), + '%label' => $file->label(), ]); } } diff --git a/tests/src/Functional/DeleteNodeWithMedia.php b/tests/src/Functional/DeleteNodeWithMediaAndFile.php similarity index 87% rename from tests/src/Functional/DeleteNodeWithMedia.php rename to tests/src/Functional/DeleteNodeWithMediaAndFile.php index b9cc8f99a..ff793f0da 100644 --- a/tests/src/Functional/DeleteNodeWithMedia.php +++ b/tests/src/Functional/DeleteNodeWithMediaAndFile.php @@ -7,17 +7,18 @@ * * @group islandora */ -class DeleteNodeWithMedia extends IslandoraFunctionalTestBase { +class DeleteNodeWithMediaAndFile extends IslandoraFunctionalTestBase { /** * Tests delete Node and its assoicated media. */ - public function testDeleteNodeWithMedia() { + public function testDeleteNodeWithMediaAndFile() { $account = $this->drupalCreateUser([ 'delete any media', 'create media', 'view media', 'bypass node access', + 'access files overview', ]); $this->drupalLogin($account); @@ -81,14 +82,18 @@ public function testDeleteNodeWithMedia() { $assert_session->pageTextContains('Media2'); $this->submitForm($delete, 'Delete'); - $assert_session->pageTextContains('Media1'); - $assert_session->pageTextContains('Media2'); + $assert_session->pageTextContains($media1->id()); + $assert_session->pageTextContains($media2->id()); $this->drupalGet("media/1/delete"); $assert_session->pageTextContains('Page not found'); $this->drupalGet("media/2/delete"); $assert_session->pageTextContains('Page not found'); + + $this->drupalGet("/admin/content/files"); + $assert_session->pageTextNotContains('test.jpeg'); + } } From 9b58fc9ecbd2e79cfa04be6ff12e5551931ff9bb Mon Sep 17 00:00:00 2001 From: shriram Date: Thu, 10 Nov 2022 14:56:58 -0400 Subject: [PATCH 024/252] added islandora.libraries.yml --- css/islandora.theme.css | 3 +++ islandora.libraries.yml | 5 +++++ islandora.module | 4 ++-- 3 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 css/islandora.theme.css create mode 100644 islandora.libraries.yml diff --git a/css/islandora.theme.css b/css/islandora.theme.css new file mode 100644 index 000000000..696587ac1 --- /dev/null +++ b/css/islandora.theme.css @@ -0,0 +1,3 @@ +.container .islandora-media-items { + margin: 0; +} diff --git a/islandora.libraries.yml b/islandora.libraries.yml new file mode 100644 index 000000000..047006bfe --- /dev/null +++ b/islandora.libraries.yml @@ -0,0 +1,5 @@ +drupal.islandora.theme_css: + version: VERSION + css: + theme: + css/islandora.theme.css: {} diff --git a/islandora.module b/islandora.module index 44dc35a7d..66c74ad54 100644 --- a/islandora.module +++ b/islandora.module @@ -357,8 +357,8 @@ function islandora_form_alter(&$form, FormStateInterface $form_state, $form_id) '#theme' => 'item_list', '#type' => 'ul', '#items' => $media_list, - '#attributes' => ['class' => 'mylist'], - '#wrapper_attributes' => ['class' => 'container'], + '#attributes' => ['class' => ['islandora-media-items']], + '#wrapper_attributes' => ['class' => ['container']], '#attached' => [ 'library' => [ 'islandora/drupal.islandora.theme_css', From 5c24c190184b680914f10bae7fbff23fa33663bb Mon Sep 17 00:00:00 2001 From: shriram Date: Tue, 15 Nov 2022 14:35:01 -0400 Subject: [PATCH 025/252] added feature toggle for the behavior --- islandora.module | 4 +++- src/Form/IslandoraSettingsForm.php | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/islandora.module b/islandora.module index 66c74ad54..5cab2ccee 100644 --- a/islandora.module +++ b/islandora.module @@ -333,10 +333,12 @@ function islandora_form_alter(&$form, FormStateInterface $form_state, $form_id) } } } + $form_object = $form_state->getFormObject(); $utils = \Drupal::service('islandora.utils'); + $config = \Drupal::config('islandora.settings')->get('delete_media_and_files'); - if ($form_object instanceof EntityForm) { + if ($config == 1 && $form_object instanceof EntityForm) { $entity = $form_object->getEntity(); if ($entity->getEntityTypeId() == "node" && $utils->isIslandoraType($entity->getEntityTypeId(), $entity->bundle()) && strpos($form['#form_id'], 'delete_form') !== FALSE) { diff --git a/src/Form/IslandoraSettingsForm.php b/src/Form/IslandoraSettingsForm.php index 5049ef161..a65ab82f0 100644 --- a/src/Form/IslandoraSettingsForm.php +++ b/src/Form/IslandoraSettingsForm.php @@ -42,6 +42,7 @@ class IslandoraSettingsForm extends ConfigFormBase { 'year', ]; const GEMINI_PSEUDO_FIELD = 'field_gemini_uri'; + const NODE_DELETE_MEDIA_AND_FILES = 'delete_media_and_files'; /** * To list the available bundle types. @@ -201,6 +202,14 @@ public function buildForm(array $form, FormStateInterface $form_state) { $fedora_url = NULL; } + $form[self::NODE_DELETE_MEDIA_AND_FILES] = [ + '#type' => 'checkbox', + '#title' => $this->t('Node Delete with Media and Files'), + '#description' => $this->t('adds a checkbox in the "Delete" tab of islandora objects to delete media and files associated with the object.' + ), + '#default_value' => (bool) $config->get(self::NODE_DELETE_MEDIA_AND_FILES), + ]; + $form[self::FEDORA_URL] = [ '#type' => 'textfield', '#title' => $this->t('Fedora URL'), @@ -351,6 +360,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { ->set(self::UPLOAD_FORM_LOCATION, $form_state->getValue(self::UPLOAD_FORM_LOCATION)) ->set(self::UPLOAD_FORM_ALLOWED_MIMETYPES, $form_state->getValue(self::UPLOAD_FORM_ALLOWED_MIMETYPES)) ->set(self::GEMINI_PSEUDO, $new_pseudo_types) + ->set(self::NODE_DELETE_MEDIA_AND_FILES, $form_state->getValue(self::NODE_DELETE_MEDIA_AND_FILES)) ->save(); parent::submitForm($form, $form_state); From b0c43accb83d54402cf8989232f839fb66addc0f Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Mon, 21 Nov 2022 12:20:20 -0400 Subject: [PATCH 026/252] Upgrade the EVA to 3.0. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index c02d7c168..eebdd9ab7 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "drupal/jwt": "^1.0.0-beta5", "drupal/filehash": "^1.1 || ^2", "drupal/prepopulate" : "^2.2", - "drupal/eva" : "^2.0", + "drupal/eva" : "^3.0", "drupal/features" : "^3.7", "drupal/migrate_plus" : "^5.1", "drupal/migrate_source_csv" : "^3.4", From 4bed36dedeac2d7c05566ef0dde1a579987addd2 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Mon, 25 Jul 2022 13:43:30 -0300 Subject: [PATCH 027/252] Revert "Allowing Image fields for multi-file media (#860)" This reverts commit a297796f47b23b9f5a778d65fe6bee110a70d6ef. --- src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php b/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php index be9eca80b..54e7bde0c 100644 --- a/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php +++ b/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php @@ -88,16 +88,10 @@ protected function generateData(EntityInterface $entity) { */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { $form = parent::buildConfigurationForm($form, $form_state); - $map = $this->entityFieldManager->getFieldMapByFieldType('file'); $file_fields = $map['media']; $file_options = array_combine(array_keys($file_fields), array_keys($file_fields)); - - $map = $this->entityFieldManager->getFieldMapByFieldType('image'); - $image_fields = $map['media']; - $image_options = array_combine(array_keys($image_fields), array_keys($image_fields)); - - $file_options = array_merge(['' => ''], $file_options, $image_options); + $file_options = array_merge(['' => ''], $file_options); $form['event']['#disabled'] = 'disabled'; $form['destination_field_name'] = [ From 72eaaf659adf8e0a8a27a1c18f0a6b9729db34e0 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Tue, 26 Jul 2022 13:31:22 -0300 Subject: [PATCH 028/252] Add Image fields only to Image derivative code. Co-authored-by: @ajstanley --- .../Action/GenerateImageDerivativeFile.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/modules/islandora_image/src/Plugin/Action/GenerateImageDerivativeFile.php b/modules/islandora_image/src/Plugin/Action/GenerateImageDerivativeFile.php index d6f99b584..54b215f38 100644 --- a/modules/islandora_image/src/Plugin/Action/GenerateImageDerivativeFile.php +++ b/modules/islandora_image/src/Plugin/Action/GenerateImageDerivativeFile.php @@ -34,7 +34,23 @@ public function defaultConfiguration() { */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { $form = parent::buildConfigurationForm($form, $form_state); - $form['mimetype']['#description'] = $this->t('Mimetype to convert to (e.g. application/xml, etc...)'); + $map = $this->entityFieldManager->getFieldMapByFieldType('image'); + $file_fields = $map['media']; + $file_options = array_combine(array_keys($file_fields), array_keys($file_fields)); + $file_options = array_merge(['' => ''], $file_options); + // @todo figure out how to write to thumbnail, which is not a real field. + // see https://github.com/Islandora/islandora/issues/891. + unset($file_options['thumbnail']); + + $form['destination_field_name'] = [ + '#required' => TRUE, + '#type' => 'select', + '#options' => $file_options, + '#title' => $this->t('Destination Image field Name'), + '#default_value' => $this->configuration['destination_field_name'], + '#description' => $this->t('Image field on Media to hold derivative. Cannot be the same as source'), + ]; + $form['mimetype']['#value'] = 'image/jpeg'; $form['mimetype']['#type'] = 'hidden'; return $form; From 74dcfd0fa4a321f7007f8f464c37eee4d9f5c85d Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 24 Nov 2022 19:50:10 -0400 Subject: [PATCH 029/252] Improve wording on multi-file derivative Action forms. --- .../Action/GenerateImageDerivativeFile.php | 17 +++++++++---- src/Controller/MediaSourceController.php | 3 +-- src/MediaSource/MediaSourceService.php | 4 +-- .../AbstractGenerateDerivativeMediaFile.php | 25 ++++++++++++++++--- 4 files changed, 36 insertions(+), 13 deletions(-) diff --git a/modules/islandora_image/src/Plugin/Action/GenerateImageDerivativeFile.php b/modules/islandora_image/src/Plugin/Action/GenerateImageDerivativeFile.php index 54b215f38..e0420fe8f 100644 --- a/modules/islandora_image/src/Plugin/Action/GenerateImageDerivativeFile.php +++ b/modules/islandora_image/src/Plugin/Action/GenerateImageDerivativeFile.php @@ -6,7 +6,10 @@ use Drupal\islandora\Plugin\Action\AbstractGenerateDerivativeMediaFile; /** - * Emits a Node for generating derivatives event. + * Emits a Media for generating derivatives event. + * + * Attaches the result as a file in an image field on the emitting + * Media ("multi-file media"). * * @Action( * id = "generate_image_derivative_file", @@ -24,7 +27,6 @@ public function defaultConfiguration() { $config['path'] = '[date:custom:Y]-[date:custom:m]/[media:mid]-ImageService.jpg'; $config['mimetype'] = 'application/xml'; $config['queue'] = 'islandora-connector-houdini'; - $config['destination_media_type'] = 'file'; $config['scheme'] = $this->config->get('default_scheme'); return $config; } @@ -46,13 +48,18 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta '#required' => TRUE, '#type' => 'select', '#options' => $file_options, - '#title' => $this->t('Destination Image field Name'), + '#title' => $this->t('Destination Image field'), '#default_value' => $this->configuration['destination_field_name'], - '#description' => $this->t('Image field on Media to hold derivative. Cannot be the same as source'), + '#description' => $this->t('This Action stores the derivative in an + Image field. If you need to store the result in a File field, use + "Generate a Derivative File for Media Attachment". Selected target field + must be an additional field, not the media\'s main storage field. + Selected target field must be present on the media.'), ]; $form['mimetype']['#value'] = 'image/jpeg'; - $form['mimetype']['#type'] = 'hidden'; + $form['mimetype']['#description'] = 'Mimetype to convert to. Must be + compatible with the destination image field.'; return $form; } diff --git a/src/Controller/MediaSourceController.php b/src/Controller/MediaSourceController.php index bab43fcfc..3d0e79092 100644 --- a/src/Controller/MediaSourceController.php +++ b/src/Controller/MediaSourceController.php @@ -280,8 +280,7 @@ public function attachToMedia( */ public function attachToMediaAccess(AccountInterface $account, RouteMatch $route_match) { $media = $route_match->getParameter('media'); - $node = $this->utils->getParentNode($media); - return AccessResult::allowedIf($node->access('update', $account) && $account->hasPermission('create media')); + return AccessResult::allowedIf($media->access('update', $account)); } } diff --git a/src/MediaSource/MediaSourceService.php b/src/MediaSource/MediaSourceService.php index 9399e3343..60e41672c 100644 --- a/src/MediaSource/MediaSourceService.php +++ b/src/MediaSource/MediaSourceService.php @@ -268,8 +268,8 @@ public function putToNode( 'uri' => $content_location, 'filename' => $this->fileSystem->basename($content_location), 'filemime' => $mimetype, - 'status' => FILE_STATUS_PERMANENT, ]); + $file->setPermanent(); // Validate file extension. $source_field_config = $this->entityTypeManager->getStorage('field_config')->load("media.$bundle.$source_field"); @@ -349,8 +349,8 @@ public function putToMedia( 'uri' => $content_location, 'filename' => $this->fileSystem->basename($content_location), 'filemime' => $mimetype, - 'status' => FILE_STATUS_PERMANENT, ]); + $file->setPermanent(); // Validate file extension. $bundle = $media->bundle(); diff --git a/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php b/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php index 54e7bde0c..f0974b0c0 100644 --- a/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php +++ b/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php @@ -7,7 +7,10 @@ use Drupal\Core\Url; /** - * Emits a Node for generating derivatives event. + * Emits a Media for generating derivatives event. + * + * Attaches the result as a file in a file field on the emitting + * Media ("multi-file media"). * * @Action( * id = "generate_derivative_file", @@ -88,19 +91,33 @@ protected function generateData(EntityInterface $entity) { */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { $form = parent::buildConfigurationForm($form, $form_state); + $map = $this->entityFieldManager->getFieldMapByFieldType('file'); $file_fields = $map['media']; $file_options = array_combine(array_keys($file_fields), array_keys($file_fields)); - $file_options = array_merge(['' => ''], $file_options); + + $map = $this->entityFieldManager->getFieldMapByFieldType('image'); + $image_fields = $map['media']; + $image_options = array_combine(array_keys($image_fields), array_keys($image_fields)); + + $file_options = array_merge(['' => ''], $file_options, $image_options); + + // @todo figure out how to write to thumbnail, which is not a real field. + // see https://github.com/Islandora/islandora/issues/891. + unset($file_options['thumbnail']); + $form['event']['#disabled'] = 'disabled'; $form['destination_field_name'] = [ '#required' => TRUE, '#type' => 'select', '#options' => $file_options, - '#title' => $this->t('Destination File field Name'), + '#title' => $this->t('Destination File field'), '#default_value' => $this->configuration['destination_field_name'], - '#description' => $this->t('File field on Media Type to hold derivative. Cannot be the same as source'), + '#description' => $this->t('This Action stores a derivative file + in a File or Image field on a media. The destination field + must be an additional field, not the media\'s main storage field. + Selected destination field must be present on the media.'), ]; $form['args'] = [ From 48b5333b2d8d84c5bdf3ed494aaa89085cc3c82f Mon Sep 17 00:00:00 2001 From: shriram1056 Date: Fri, 25 Nov 2022 11:36:09 -0400 Subject: [PATCH 030/252] skip entity types protected by entity integrity reference and updated test cases for toggle feature --- config/install/islandora.settings.yml | 1 + config/schema/islandora.schema.yml | 5 +- islandora.module | 50 ++++++++++++------- .../Functional/DeleteNodeWithMediaAndFile.php | 5 ++ 4 files changed, 42 insertions(+), 19 deletions(-) diff --git a/config/install/islandora.settings.yml b/config/install/islandora.settings.yml index 8fb25fb8c..179d42132 100644 --- a/config/install/islandora.settings.yml +++ b/config/install/islandora.settings.yml @@ -1,4 +1,5 @@ broker_url: 'tcp://localhost:61613' jwt_expiry: '+2 hour' gemini_url: '' +delete_media_and_files: TRUE gemini_pseudo_bundles: [] diff --git a/config/schema/islandora.schema.yml b/config/schema/islandora.schema.yml index e85d57396..86b65fd0c 100644 --- a/config/schema/islandora.schema.yml +++ b/config/schema/islandora.schema.yml @@ -14,6 +14,9 @@ islandora.settings: jwt_expiry: type: string label: 'How long JWTs should last before expiring.' + delete_media_and_files: + type: boolean + label: 'Node Delete with Media and Files' upload_form_location: type: string label: 'Upload Form Location' @@ -166,7 +169,7 @@ condition.plugin.node_had_namespace: pid_field: type: ignore label: 'PID field' - + field.formatter.settings.islandora_image: type: field.formatter.settings.image label: 'Islandora image field display format settings' diff --git a/islandora.module b/islandora.module index 5cab2ccee..b651f2915 100644 --- a/islandora.module +++ b/islandora.module @@ -373,6 +373,7 @@ function islandora_form_alter(&$form, FormStateInterface $form_state, $form_id) } } } + return $form; } @@ -390,7 +391,6 @@ function islandora_object_delete_form_submit($form, &$form_state) { $medias = $utils->getMedia($node); $media_list = ""; - $entity_type_manager = \Drupal::entityTypeManager(); $entity_field_manager = \Drupal::service('entity_field.manager'); $current_user = \Drupal::currentUser(); $logger = \Drupal::logger('logger.channel.islandora'); @@ -398,14 +398,12 @@ function islandora_object_delete_form_submit($form, &$form_state) { $total_count = 0; $delete_media = []; - $delete_media_translations = []; - $delete_files = []; + $media_translations = []; + $media_files = []; + $entity_protected_medias = []; $inaccessible_entities = []; - $media_storage = $entity_type_manager->getStorage('media'); - $file_storage = $entity_type_manager->getStorage('file'); foreach ($medias as $id => $media) { - $media_list .= $id . ", "; $lang = $media->language()->getId(); $selected_langcodes[$lang] = $lang; @@ -425,7 +423,7 @@ function islandora_object_delete_form_submit($form, &$form_state) { $inaccessible_entities[] = $file; continue; } - $delete_files[$file->id()] = $file; + $media_files[$id][$file->id()] = $file; $total_count++; } } @@ -436,33 +434,49 @@ function islandora_object_delete_form_submit($form, &$form_state) { $entity = $media->getTranslation($langcode); if ($entity->isDefaultTranslation()) { $delete_media[$id] = $entity; - unset($delete_media_translations[$id]); + unset($media_translations[$id]); $total_count += count($entity->getTranslationLanguages()); } elseif (!isset($delete_media[$id])) { - $delete_media_translations[$id][] = $entity; + $media_translations[$id][] = $entity; } } } if ($delete_media) { - $media_storage->delete($delete_media); foreach ($delete_media as $media) { - $logger->notice('The media %label has been deleted.', [ - '%label' => $media->label(), - ]); + try { + $media->delete(); + $logger->notice('The media %label has been deleted.', [ + '%label' => $media->label(), + ]); + $media_list .= $id . ", "; + } + catch (Exception $e) { + $entity_protected_medias[] = $id; + } } } + $delete_files = array_filter($media_files, function ($media) use ($entity_protected_medias) { + return !in_array($media, $entity_protected_medias); + }, ARRAY_FILTER_USE_KEY); + if ($delete_files) { - $file_storage->delete($delete_files); - foreach ($delete_files as $file) { - $logger->notice('The file %label has been deleted.', [ - '%label' => $file->label(), - ]); + foreach ($delete_files as $files_array) { + foreach ($files_array as $file) { + $file->delete(); + $logger->notice('The file %label has been deleted.', [ + '%label' => $file->label(), + ]); + } } } + $delete_media_translations = array_filter($media_translations, function ($media) use ($entity_protected_medias) { + return !in_array($media, $entity_protected_medias); + }, ARRAY_FILTER_USE_KEY); + if ($delete_media_translations) { foreach ($delete_media_translations as $id => $translations) { $media = $medias[$id]; diff --git a/tests/src/Functional/DeleteNodeWithMediaAndFile.php b/tests/src/Functional/DeleteNodeWithMediaAndFile.php index ff793f0da..40e469c5c 100644 --- a/tests/src/Functional/DeleteNodeWithMediaAndFile.php +++ b/tests/src/Functional/DeleteNodeWithMediaAndFile.php @@ -19,6 +19,7 @@ public function testDeleteNodeWithMediaAndFile() { 'view media', 'bypass node access', 'access files overview', + 'administer site configuration', ]); $this->drupalLogin($account); @@ -75,6 +76,10 @@ public function testDeleteNodeWithMediaAndFile() { ]); $media2->save(); + $this->drupalGet("admin/config/islandora/core"); + $assert_session->pageTextContains('Node Delete with Media and Files'); + \Drupal::configFactory()->getEditable('islandora.settings')->set('delete_media_and_files', TRUE)->save(); + $delete = ['delete_associated_content' => TRUE]; $this->drupalGet("node/1/delete"); From e15b6322ff98df666a0df16200904a33cd8a2de0 Mon Sep 17 00:00:00 2001 From: shriram1056 Date: Fri, 25 Nov 2022 13:28:24 -0400 Subject: [PATCH 031/252] fixed log message --- islandora.module | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/islandora.module b/islandora.module index b651f2915..05e18c4ac 100644 --- a/islandora.module +++ b/islandora.module @@ -444,13 +444,13 @@ function islandora_object_delete_form_submit($form, &$form_state) { } if ($delete_media) { - foreach ($delete_media as $media) { + foreach ($delete_media as $id => $media) { try { $media->delete(); + $media_list .= $id . ", "; $logger->notice('The media %label has been deleted.', [ '%label' => $media->label(), ]); - $media_list .= $id . ", "; } catch (Exception $e) { $entity_protected_medias[] = $id; From 541620493b197052dd42b9584eb1cb6e36b6699c Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 30 Nov 2022 10:07:19 -0400 Subject: [PATCH 032/252] Updates settings and view for filehash^2. --- composer.json | 2 +- .../config/install/filehash.settings.yml | 21 ++- .../install/views.view.file_checksum.yml | 159 ++++++++++-------- 3 files changed, 109 insertions(+), 73 deletions(-) diff --git a/composer.json b/composer.json index c02d7c168..8fe708edb 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ "islandora/jsonld": "^2", "stomp-php/stomp-php": "4.* || ^5", "drupal/jwt": "^1.0.0-beta5", - "drupal/filehash": "^1.1 || ^2", + "drupal/filehash": "^2", "drupal/prepopulate" : "^2.2", "drupal/eva" : "^2.0", "drupal/features" : "^3.7", diff --git a/modules/islandora_core_feature/config/install/filehash.settings.yml b/modules/islandora_core_feature/config/install/filehash.settings.yml index 7deecc696..1ac77eec5 100644 --- a/modules/islandora_core_feature/config/install/filehash.settings.yml +++ b/modules/islandora_core_feature/config/install/filehash.settings.yml @@ -1,5 +1,24 @@ algos: - sha1: sha1 + blake2b_128: '0' + blake2b_160: '0' + blake2b_224: '0' + blake2b_256: '0' + blake2b_384: '0' + blake2b_512: '0' md5: '0' + sha1: sha1 + sha224: '0' sha256: '0' + sha384: '0' + sha512_224: '0' + sha512_256: '0' + sha512: '0' + sha3_224: '0' + sha3_256: '0' + sha3_384: '0' + sha3_512: '0' dedupe: 0 +rehash: false +original: false +dedupe_original: false +mime_types: { } diff --git a/modules/islandora_core_feature/config/install/views.view.file_checksum.yml b/modules/islandora_core_feature/config/install/views.view.file_checksum.yml index b498ba666..a9fd45840 100644 --- a/modules/islandora_core_feature/config/install/views.view.file_checksum.yml +++ b/modules/islandora_core_feature/config/install/views.view.file_checksum.yml @@ -1,14 +1,14 @@ langcode: en status: true dependencies: - enforced: - module: - - islandora_core_feature module: - file - filehash - rest - serialization + enforced: + module: + - islandora_core_feature id: file_checksum label: 'File Checksum' module: views @@ -16,71 +16,24 @@ description: 'Exposes a REST endpoint for getting the checksum of a File' tag: '' base_table: file_managed base_field: fid -core: 8.x display: default: - display_plugin: default id: default display_title: Master + display_plugin: default position: 0 display_options: - access: - type: none - options: { } - cache: - type: tag - options: { } - query: - type: views_query - options: - disable_sql_rewrite: false - distinct: false - replica: false - query_comment: '' - query_tags: { } - exposed_form: - type: basic - options: - submit_button: Apply - reset_button: false - reset_button_label: Reset - exposed_sorts_label: 'Sort by' - expose_sort_order: true - sort_asc_label: Asc - sort_desc_label: Desc - pager: - type: mini - options: - items_per_page: 10 - offset: 0 - id: 0 - total_pages: null - expose: - items_per_page: false - items_per_page_label: 'Items per page' - items_per_page_options: '5, 10, 25, 50' - items_per_page_options_all: false - items_per_page_options_all_label: '- All -' - offset: false - offset_label: Offset - tags: - previous: ‹‹ - next: ›› - style: - type: serializer - row: - type: 'entity:file' - options: - relationship: none - view_mode: default fields: sha1: id: sha1 - table: filehash + table: file_managed field: sha1 relationship: none group_type: group admin_label: '' + entity_type: file + entity_field: sha1 + plugin_id: field label: '' exclude: false alter: @@ -92,7 +45,7 @@ display: external: false replace_spaces: false path_case: none - trim_whitespace: false + trim_whitespace: true alt: '' rel: '' link_class: '' @@ -106,7 +59,7 @@ display: more_link: false more_link_text: '' more_link_path: '' - strip_tags: false + strip_tags: true trim: false preserve_tags: '' html: false @@ -122,13 +75,55 @@ display: hide_empty: false empty_zero: false hide_alter_empty: true - plugin_id: standard - filters: { } - sorts: { } - header: { } - footer: { } + click_sort_column: value + type: filehash + settings: { } + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + pager: + type: mini + options: + offset: 0 + items_per_page: 10 + total_pages: null + id: 0 + tags: + next: ›› + previous: ‹‹ + expose: + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 25, 50' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + access: + type: none + options: { } + cache: + type: tag + options: { } empty: { } - relationships: { } + sorts: { } arguments: fid: id: fid @@ -137,6 +132,9 @@ display: relationship: none group_type: group admin_label: '' + entity_type: file + entity_field: fid + plugin_id: file_fid default_action: 'not found' exception: value: all @@ -151,8 +149,8 @@ display: summary_options: base_path: '' count: true - items_per_page: 25 override: false + items_per_page: 25 summary: sort_order: asc number_of_records: 0 @@ -164,31 +162,46 @@ display: validate_options: { } break_phrase: false not: false - entity_type: file - entity_field: fid - plugin_id: file_fid + filters: { } + style: + type: serializer + row: + type: 'entity:file' + options: + relationship: none + view_mode: default + query: + type: views_query + options: + query_comment: '' + disable_sql_rewrite: false + distinct: false + replica: false + query_tags: { } + relationships: { } + header: { } + footer: { } display_extenders: { } cache_metadata: max-age: -1 contexts: + - 'languages:language_content' - 'languages:language_interface' - request_format - url - url.query_args tags: { } rest_export_1: - display_plugin: rest_export id: rest_export_1 display_title: 'REST export' + display_plugin: rest_export position: 1 display_options: - display_extenders: { } - path: checksum/%file pager: type: some options: - items_per_page: 10 offset: 0 + items_per_page: 10 style: type: serializer options: @@ -198,6 +211,8 @@ display: type: data_field options: field_options: { } + display_extenders: { } + path: checksum/%file auth: - basic_auth - jwt_auth @@ -205,7 +220,9 @@ display: cache_metadata: max-age: -1 contexts: + - 'languages:language_content' - 'languages:language_interface' - request_format - url tags: { } + From def4fda5b6021f6d14288a6880762150648a677f Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 30 Nov 2022 10:51:05 -0400 Subject: [PATCH 033/252] Include original hash, and re-hash. --- .../config/install/filehash.settings.yml | 4 +- .../install/views.view.file_checksum.yml | 85 ++++++++++++++++++- 2 files changed, 84 insertions(+), 5 deletions(-) diff --git a/modules/islandora_core_feature/config/install/filehash.settings.yml b/modules/islandora_core_feature/config/install/filehash.settings.yml index 1ac77eec5..3dcae2973 100644 --- a/modules/islandora_core_feature/config/install/filehash.settings.yml +++ b/modules/islandora_core_feature/config/install/filehash.settings.yml @@ -18,7 +18,7 @@ algos: sha3_384: '0' sha3_512: '0' dedupe: 0 -rehash: false -original: false +rehash: true +original: true dedupe_original: false mime_types: { } diff --git a/modules/islandora_core_feature/config/install/views.view.file_checksum.yml b/modules/islandora_core_feature/config/install/views.view.file_checksum.yml index a9fd45840..2c8191013 100644 --- a/modules/islandora_core_feature/config/install/views.view.file_checksum.yml +++ b/modules/islandora_core_feature/config/install/views.view.file_checksum.yml @@ -6,6 +6,7 @@ dependencies: - filehash - rest - serialization + - user enforced: module: - islandora_core_feature @@ -88,6 +89,70 @@ display: multi_type: separator separator: ', ' field_api_classes: false + original_sha1: + id: original_sha1 + table: file_managed + field: original_sha1 + relationship: none + group_type: group + admin_label: '' + entity_type: file + entity_field: original_sha1 + plugin_id: field + label: '' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: true + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: true + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: false + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: false + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: filehash + settings: { } + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false pager: type: mini options: @@ -117,8 +182,9 @@ display: sort_asc_label: Asc sort_desc_label: Desc access: - type: none - options: { } + type: perm + options: + perm: 'view checksums' cache: type: tag options: { } @@ -190,6 +256,7 @@ display: - request_format - url - url.query_args + - user.permissions tags: { } rest_export_1: id: rest_export_1 @@ -211,7 +278,18 @@ display: type: data_field options: field_options: { } - display_extenders: { } + display_extenders: + matomo: + enabled: false + keyword_gets: '' + keyword_behavior: first + keyword_concat_separator: ' ' + category_behavior: none + category_gets: '' + category_concat_separator: ' ' + category_fallback: '' + category_facets: { } + category_facets_concat_separator: ', ' path: checksum/%file auth: - basic_auth @@ -224,5 +302,6 @@ display: - 'languages:language_interface' - request_format - url + - user.permissions tags: { } From 5f4a6ab3ae474f8c4e11bddb85feb36e386a2b54 Mon Sep 17 00:00:00 2001 From: Jason Hildebrand Date: Thu, 1 Dec 2022 14:24:35 -0600 Subject: [PATCH 034/252] Eliminate warnings when using NodeHasMediaUse views filter. (#914) --- src/Plugin/views/filter/NodeHasMediaUse.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Plugin/views/filter/NodeHasMediaUse.php b/src/Plugin/views/filter/NodeHasMediaUse.php index 0209505d6..3c69bddd5 100644 --- a/src/Plugin/views/filter/NodeHasMediaUse.php +++ b/src/Plugin/views/filter/NodeHasMediaUse.php @@ -18,10 +18,10 @@ class NodeHasMediaUse extends FilterPluginBase { * {@inheritdoc} */ protected function defineOptions() { - return [ - 'use_uri' => ['default' => NULL], - 'negated' => ['default' => FALSE], - ]; + $options = parent::defineOptions(); + $options['use_uri'] = ['default' => NULL]; + $options['negated'] = ['default' => FALSE]; + return $options; } /** From f71f6dc2e874e85855038a107fdc163cff183038 Mon Sep 17 00:00:00 2001 From: Jason Hildebrand Date: Thu, 1 Dec 2022 16:13:40 -0600 Subject: [PATCH 035/252] Fix warning by checking whether key is set. (#909) * Fix warning by checking whether key is set. * Adjust plugin check in integer-weight views hook. --- islandora.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/islandora.module b/islandora.module index 5b5446d13..9814820e2 100644 --- a/islandora.module +++ b/islandora.module @@ -515,7 +515,7 @@ function islandora_preprocess_views_view_table(&$variables) { // Check for a weight selector field. foreach ($variables['view']->field as $field_key => $field) { - if ($field->options['plugin_id'] == 'integer_weight_selector') { + if ($field->getPluginId() == 'integer_weight_selector') { // Check if the weight selector is on the first column. $is_first_column = array_search($field_key, array_keys($variables['view']->field)) > 0 ? FALSE : TRUE; From 6c582a870227ac39022b2a20df4a554a1e2c54e3 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 1 Dec 2022 19:05:49 -0400 Subject: [PATCH 036/252] Permit newer version of migrate_plus. This version has PHP 8.1 support. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index eebdd9ab7..29b408948 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ "drupal/prepopulate" : "^2.2", "drupal/eva" : "^3.0", "drupal/features" : "^3.7", - "drupal/migrate_plus" : "^5.1", + "drupal/migrate_plus" : "^5.1 || ^6", "drupal/migrate_source_csv" : "^3.4", "drupal/token" : "^1.3", "drupal/flysystem" : "^2.0@alpha", From ee85472dc8b0d2e0517f7cc787da7f73271cf63b Mon Sep 17 00:00:00 2001 From: shriram1056 Date: Fri, 2 Dec 2022 16:36:04 -0400 Subject: [PATCH 037/252] minor changes and post_update for delete_media_and_files --- css/{islandora.theme.css => islandora.css} | 0 islandora.libraries.yml | 4 +-- islandora.module | 32 +++++++++++++--------- islandora.post_update.php | 16 +++++++++++ src/Form/IslandoraSettingsForm.php | 2 +- 5 files changed, 38 insertions(+), 16 deletions(-) rename css/{islandora.theme.css => islandora.css} (100%) create mode 100644 islandora.post_update.php diff --git a/css/islandora.theme.css b/css/islandora.css similarity index 100% rename from css/islandora.theme.css rename to css/islandora.css diff --git a/islandora.libraries.yml b/islandora.libraries.yml index 047006bfe..840dc294b 100644 --- a/islandora.libraries.yml +++ b/islandora.libraries.yml @@ -1,5 +1,5 @@ -drupal.islandora.theme_css: +islandora: version: VERSION css: theme: - css/islandora.theme.css: {} + css/islandora.css: {} diff --git a/islandora.module b/islandora.module index 05e18c4ac..64b65ca84 100644 --- a/islandora.module +++ b/islandora.module @@ -355,7 +355,16 @@ function islandora_form_alter(&$form, FormStateInterface $form_state, $form_id) $media_list[] = $media->getName(); } - $form['media_items'] = [ + $form['container'] = [ + '#type' => 'container', + '#states' => [ + 'visible' => [ + ':input[name="delete_associated_content"]' => ['checked' => TRUE], + ], + ], + ]; + + $form['container']['media_items'] = [ '#theme' => 'item_list', '#type' => 'ul', '#items' => $media_list, @@ -363,7 +372,7 @@ function islandora_form_alter(&$form, FormStateInterface $form_state, $form_id) '#wrapper_attributes' => ['class' => ['container']], '#attached' => [ 'library' => [ - 'islandora/drupal.islandora.theme_css', + 'islandora/islandora', ], ], ]; @@ -380,7 +389,7 @@ function islandora_form_alter(&$form, FormStateInterface $form_state, $form_id) /** * Implements a submit handler for the delete form. */ -function islandora_object_delete_form_submit($form, &$form_state) { +function islandora_object_delete_form_submit($form, FormStateInterface $form_state) { $result = $form_state->getValues('delete_associated_content'); $utils = \Drupal::service('islandora.utils'); @@ -389,14 +398,13 @@ function islandora_object_delete_form_submit($form, &$form_state) { $node = $form_state->getFormObject()->getEntity(); $medias = $utils->getMedia($node); - $media_list = ""; + $media_list = []; $entity_field_manager = \Drupal::service('entity_field.manager'); $current_user = \Drupal::currentUser(); $logger = \Drupal::logger('logger.channel.islandora'); $messenger = \Drupal::messenger(); - $total_count = 0; $delete_media = []; $media_translations = []; $media_files = []; @@ -424,7 +432,6 @@ function islandora_object_delete_form_submit($form, &$form_state) { continue; } $media_files[$id][$file->id()] = $file; - $total_count++; } } } @@ -435,7 +442,6 @@ function islandora_object_delete_form_submit($form, &$form_state) { if ($entity->isDefaultTranslation()) { $delete_media[$id] = $entity; unset($media_translations[$id]); - $total_count += count($entity->getTranslationLanguages()); } elseif (!isset($delete_media[$id])) { $media_translations[$id][] = $entity; @@ -447,7 +453,7 @@ function islandora_object_delete_form_submit($form, &$form_state) { foreach ($delete_media as $id => $media) { try { $media->delete(); - $media_list .= $id . ", "; + $media_list[] = $id; $logger->notice('The media %label has been deleted.', [ '%label' => $media->label(), ]); @@ -490,12 +496,11 @@ function islandora_object_delete_form_submit($form, &$form_state) { '@language' => $translation->language()->getName(), ]); } - $total_count += count($translations); } } if ($inaccessible_entities) { - $messenger->addWarning("@count items has not been deleted because you do not have the necessary permissions.", [ + $messenger->addWarning("@count items have not been deleted because you do not have the necessary permissions.", [ '@count' => count($inaccessible_entities), ]); } @@ -507,9 +512,10 @@ function islandora_object_delete_form_submit($form, &$form_state) { '#value' => t("The repository item @node and @media", [ '@node' => $node->getTitle(), '@media' => \Drupal::translation()->formatPlural( - substr_count($media_list, ",") + 1, 'the media with the id @media has been deleted.', - 'the medias with the id @media have been deleted.', - ['@media' => mb_substr($media_list, 0, strlen($media_list) - 2)]), + count($media_list), 'the media with the id @media has been deleted.', + 'the medias with the ids @media have been deleted.', + ['@media' => implode(", ", $media_list)], + ), ]), ], ]; diff --git a/islandora.post_update.php b/islandora.post_update.php new file mode 100644 index 000000000..0a29e56ed --- /dev/null +++ b/islandora.post_update.php @@ -0,0 +1,16 @@ +getEditable('islandora.settings'); + $config->set('delete_media_and_files', TRUE); + $config->save(TRUE); +} diff --git a/src/Form/IslandoraSettingsForm.php b/src/Form/IslandoraSettingsForm.php index a65ab82f0..90e0b4204 100644 --- a/src/Form/IslandoraSettingsForm.php +++ b/src/Form/IslandoraSettingsForm.php @@ -205,7 +205,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { $form[self::NODE_DELETE_MEDIA_AND_FILES] = [ '#type' => 'checkbox', '#title' => $this->t('Node Delete with Media and Files'), - '#description' => $this->t('adds a checkbox in the "Delete" tab of islandora objects to delete media and files associated with the object.' + '#description' => $this->t('Adds a checkbox in the "Delete" tab of islandora objects to delete media and files associated with the object.' ), '#default_value' => (bool) $config->get(self::NODE_DELETE_MEDIA_AND_FILES), ]; From b47d37b1b69c97540a7ea7a772d7785040fbace7 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Tue, 6 Dec 2022 19:48:55 -0400 Subject: [PATCH 038/252] Fix errors when OCR field not set. --- .../islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index cc4b5e94e..c2a2fbc3c 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -205,11 +205,13 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas continue; } - $ocrs = $entity->{$ocrField->definition['field_name']}; + if (!is_null($ocrField)) { + $ocrs = $entity->{$ocrField->definition['field_name']}; + $ocr = isset($ocrs[$i]) ? $ocrs[$i] : FALSE; + } // Create the IIIF URL for this file // Visiting $iiif_url will resolve to the info.json for the image. - $ocr = isset($ocrs[$i]) ? $ocrs[$i] : FALSE; $file_url = $image->entity->createFileUrl(FALSE); $mime_type = $image->entity->getMimeType(); $iiif_url = rtrim($iiif_address, '/') . '/' . urlencode($file_url); From 0b7f12d3baeefc230fcc6f426e668a3d5ab27247 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Fri, 9 Dec 2022 11:41:36 -0400 Subject: [PATCH 039/252] No infinite derivatives. --- src/EventGenerator/EmitEvent.php | 4 ++++ src/Plugin/Action/AbstractGenerateDerivative.php | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/src/EventGenerator/EmitEvent.php b/src/EventGenerator/EmitEvent.php index 683f3e8b6..2e0d226e4 100644 --- a/src/EventGenerator/EmitEvent.php +++ b/src/EventGenerator/EmitEvent.php @@ -157,6 +157,10 @@ public function execute($entity = NULL) { $user = $this->entityTypeManager->getStorage('user')->load($this->account->id()); $data = $this->generateData($entity); + // If $data is the bool false, then abort. No error, but don't emit event. + if ($data === FALSE) { + return; + } $event = $this->eventDispatcher->dispatch( StompHeaderEvent::EVENT_NAME, diff --git a/src/Plugin/Action/AbstractGenerateDerivative.php b/src/Plugin/Action/AbstractGenerateDerivative.php index b22201e11..129af9944 100644 --- a/src/Plugin/Action/AbstractGenerateDerivative.php +++ b/src/Plugin/Action/AbstractGenerateDerivative.php @@ -60,6 +60,13 @@ protected function generateData(EntityInterface $entity) { throw new \RuntimeException("Could not locate taxonomy term with uri: " . $this->configuration['derivative_term_uri'], 500); } + // See if there is a destination media already set, and abort if it's the + // same as the source media. Dont cause an error, just don't continue. + $derivative_media = $this->utils->getMediaWithTerm($entity, $derivative_term); + if (!is_null($derivative_media) && $derivative_media->id() == $source_media->id()) { + return FALSE; + } + $route_params = [ 'node' => $entity->id(), 'media_type' => $this->configuration['destination_media_type'], From f86f2bedb17e40b8989ddbb4f388fede0bf68ba7 Mon Sep 17 00:00:00 2001 From: dannylamb Date: Mon, 12 Dec 2022 10:22:30 -0400 Subject: [PATCH 040/252] Updating default config for GenerateOCRDerivative.php --- .../src/Plugin/Action/GenerateOCRDerivative.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php b/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php index 745c57727..63a714a80 100644 --- a/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php +++ b/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php @@ -22,9 +22,13 @@ class GenerateOCRDerivative extends AbstractGenerateDerivative { public function defaultConfiguration() { $config = parent::defaultConfiguration(); $config['path'] = '[date:custom:Y]-[date:custom:m]/[node:nid]-[term:name].txt'; - $config['mimetype'] = 'application/xml'; + $config['event'] = 'Generate Derivative'; + $config['source_term_uri'] = 'http://pcdm.org/use#OriginalFile'; + $config['derivative_term_uri'] = 'http://pcdm.org/use#ExtractedText'; + $config['mimetype'] = 'text/plain'; $config['queue'] = 'islandora-connector-ocr'; - $config['destination_media_type'] = 'file'; + $config['destination_media_type'] = 'extracted_text'; + $config['scheme'] = 'fedora'; return $config; } From 41f87101226ec466ba369dcd3b98b42255dd48da Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Tue, 13 Dec 2022 16:43:06 -0400 Subject: [PATCH 041/252] Use a proper exception. --- src/EventGenerator/EmitEvent.php | 9 +++++---- src/Exception/IslandoraDerivativeException.php | 12 ++++++++++++ src/Plugin/Action/AbstractGenerateDerivative.php | 3 ++- 3 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 src/Exception/IslandoraDerivativeException.php diff --git a/src/EventGenerator/EmitEvent.php b/src/EventGenerator/EmitEvent.php index 2e0d226e4..fd33fd99c 100644 --- a/src/EventGenerator/EmitEvent.php +++ b/src/EventGenerator/EmitEvent.php @@ -14,6 +14,7 @@ use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\islandora\Event\StompHeaderEvent; use Drupal\islandora\Event\StompHeaderEventException; +use Drupal\islandora\Exception\IslandoraDerivativeException; use Stomp\Exception\StompException; use Stomp\StatefulStomp; use Stomp\Transport\Message; @@ -157,10 +158,6 @@ public function execute($entity = NULL) { $user = $this->entityTypeManager->getStorage('user')->load($this->account->id()); $data = $this->generateData($entity); - // If $data is the bool false, then abort. No error, but don't emit event. - if ($data === FALSE) { - return; - } $event = $this->eventDispatcher->dispatch( StompHeaderEvent::EVENT_NAME, @@ -172,6 +169,10 @@ public function execute($entity = NULL) { $event->getHeaders()->all() ); } + catch (IslandoraDerivativeException $e) { + $this->logger->info($e->getMessage()); + return; + } catch (StompHeaderEventException $e) { $this->logger->error($e->getMessage()); $this->messenger->addError($e->getMessage()); diff --git a/src/Exception/IslandoraDerivativeException.php b/src/Exception/IslandoraDerivativeException.php new file mode 100644 index 000000000..66f636065 --- /dev/null +++ b/src/Exception/IslandoraDerivativeException.php @@ -0,0 +1,12 @@ +utils->getMediaWithTerm($entity, $derivative_term); if (!is_null($derivative_media) && $derivative_media->id() == $source_media->id()) { - return FALSE; + throw new IslandoraDerivativeException("Halting derivative, as source and target media are the same. Derivative term: [" . $this->configuration['derivative_term_uri'] . "] Source term: [" . $this->configuration['source_term_uri'] . "] Node id: [". $entity->id() . "].", 500); } $route_params = [ From 665abfbd6c48418c30eb30a57fb394fe07a2b715 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Tue, 13 Dec 2022 17:12:44 -0400 Subject: [PATCH 042/252] phpcs. --- src/Exception/IslandoraDerivativeException.php | 3 +-- src/Plugin/Action/AbstractGenerateDerivative.php | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Exception/IslandoraDerivativeException.php b/src/Exception/IslandoraDerivativeException.php index 66f636065..7efe47736 100644 --- a/src/Exception/IslandoraDerivativeException.php +++ b/src/Exception/IslandoraDerivativeException.php @@ -7,6 +7,5 @@ * * @package islandora */ -class IslandoraDerivativeException extends \RuntimeException -{ +class IslandoraDerivativeException extends \RuntimeException { } diff --git a/src/Plugin/Action/AbstractGenerateDerivative.php b/src/Plugin/Action/AbstractGenerateDerivative.php index 339d1d877..b44db477b 100644 --- a/src/Plugin/Action/AbstractGenerateDerivative.php +++ b/src/Plugin/Action/AbstractGenerateDerivative.php @@ -65,7 +65,7 @@ protected function generateData(EntityInterface $entity) { // same as the source media. Dont cause an error, just don't continue. $derivative_media = $this->utils->getMediaWithTerm($entity, $derivative_term); if (!is_null($derivative_media) && $derivative_media->id() == $source_media->id()) { - throw new IslandoraDerivativeException("Halting derivative, as source and target media are the same. Derivative term: [" . $this->configuration['derivative_term_uri'] . "] Source term: [" . $this->configuration['source_term_uri'] . "] Node id: [". $entity->id() . "].", 500); + throw new IslandoraDerivativeException("Halting derivative, as source and target media are the same. Derivative term: [" . $this->configuration['derivative_term_uri'] . "] Source term: [" . $this->configuration['source_term_uri'] . "] Node id: [" . $entity->id() . "].", 500); } $route_params = [ From 7df45a083a21e33c17026ff9629d32abe5a91463 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Tue, 13 Dec 2022 19:22:12 -0400 Subject: [PATCH 043/252] Use new syntax for filehash. --- islandora.module | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/islandora.module b/islandora.module index 5b5446d13..faf24fdc9 100644 --- a/islandora.module +++ b/islandora.module @@ -181,7 +181,8 @@ function islandora_file_insert(FileInterface $file) { */ function islandora_file_update(FileInterface $file) { // Exit early if unchanged. - if ($file->filehash != NULL && $file->original->filehash != NULL && $file->filehash['sha1'] == $file->original->filehash['sha1']) { + if ($file->hasField('sha1') && $file->original->hasField('sha1') + && $file->sha1->getString() == $file->original->sha1->getString()) { return; } From b326d967a692ac0051ce4fed0c3c99bb8243a964 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 14 Dec 2022 10:39:01 -0400 Subject: [PATCH 044/252] Update dependencies. --- composer.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 43533a690..c1bfaa2d9 100644 --- a/composer.json +++ b/composer.json @@ -14,11 +14,11 @@ } ], "require": { - "drupal/context": "^4.0@beta", - "drupal/search_api": "~1.8", + "drupal/context": "^4", + "drupal/search_api": "^1.8", "islandora/jsonld": "^2", "stomp-php/stomp-php": "4.* || ^5", - "drupal/jwt": "^1.0.0-beta5", + "drupal/jwt": "^1.0", "drupal/filehash": "^2", "drupal/prepopulate" : "^2.2", "drupal/eva" : "^3.0", From 12e28f1284ef32052414a0e0a3cd74158813259e Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 14 Dec 2022 10:39:37 -0400 Subject: [PATCH 045/252] Sort dependencies. --- composer.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index c1bfaa2d9..0b443c027 100644 --- a/composer.json +++ b/composer.json @@ -15,21 +15,21 @@ ], "require": { "drupal/context": "^4", - "drupal/search_api": "^1.8", - "islandora/jsonld": "^2", - "stomp-php/stomp-php": "4.* || ^5", - "drupal/jwt": "^1.0", - "drupal/filehash": "^2", - "drupal/prepopulate" : "^2.2", + "drupal/ctools": "^3.8 || ^4", "drupal/eva" : "^3.0", "drupal/features" : "^3.7", + "drupal/file_replace": "^1.1", + "drupal/filehash": "^2", + "drupal/flysystem" : "^2.0@alpha", + "drupal/jwt": "^1.0", "drupal/migrate_plus" : "^5.1 || ^6", "drupal/migrate_source_csv" : "^3.4", + "drupal/prepopulate" : "^2.2", + "drupal/search_api": "^1.8", "drupal/token" : "^1.3", - "drupal/flysystem" : "^2.0@alpha", "islandora/crayfish-commons": "^2", - "drupal/file_replace": "^1.1", - "drupal/ctools": "^3.8 || ^4" + "islandora/jsonld": "^2", + "stomp-php/stomp-php": "4.* || ^5" }, "require-dev": { "phpunit/phpunit": "^6", From cefee615c0477a1067fc703074da7aa6b24a57bd Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 14 Dec 2022 13:54:33 -0400 Subject: [PATCH 046/252] Warn re. tiffs and jp2s in image file derivatives. (#921) * Warn re. tiffs and jp2s in image file derivatives. * Update wording. --- .../src/Plugin/Action/GenerateImageDerivativeFile.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/islandora_image/src/Plugin/Action/GenerateImageDerivativeFile.php b/modules/islandora_image/src/Plugin/Action/GenerateImageDerivativeFile.php index e0420fe8f..a6e067740 100644 --- a/modules/islandora_image/src/Plugin/Action/GenerateImageDerivativeFile.php +++ b/modules/islandora_image/src/Plugin/Action/GenerateImageDerivativeFile.php @@ -51,7 +51,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta '#title' => $this->t('Destination Image field'), '#default_value' => $this->configuration['destination_field_name'], '#description' => $this->t('This Action stores the derivative in an - Image field. If you need to store the result in a File field, use + Image field. If you are creating a TIFF or JP2, instead use "Generate a Derivative File for Media Attachment". Selected target field must be an additional field, not the media\'s main storage field. Selected target field must be present on the media.'), From 6f2955b0613a6b6073801cf677fccd52a8182d80 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 6 Jan 2023 16:01:03 -0400 Subject: [PATCH 047/252] Avoid ::referencedEntities() call when it is not expected to exist. (#923) --- src/MediaSource/MediaSourceService.php | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/MediaSource/MediaSourceService.php b/src/MediaSource/MediaSourceService.php index 60e41672c..533789857 100644 --- a/src/MediaSource/MediaSourceService.php +++ b/src/MediaSource/MediaSourceService.php @@ -3,6 +3,7 @@ namespace Drupal\islandora\MediaSource; use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Field\EntityReferenceFieldItemListInterface; use Drupal\Core\File\FileSystemInterface; use Drupal\Core\Language\LanguageManagerInterface; use Drupal\Core\Session\AccountInterface; @@ -113,8 +114,12 @@ public function getSourceFieldName($media_type) { * @param \Drupal\media\MediaInterface $media * Media whose source field you are searching for. * - * @return \Drupal\file\FileInterface - * File if it exists + * @return \Drupal\file\FileInterface|\Drupal\Core\Entity\EntityInterface|false|null + * The first source entity if there is one, generally expected to be of + * \Drupal\file\FileInterface. Boolean FALSE if there was no such entity. + * NULL if the source field does not refer to Drupal entities (as in, the + * field is not a \Drupal\Core\Field\EntityReferenceFieldItemListInterface + * implementation). * * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException */ @@ -127,10 +132,13 @@ public function getSourceFile(MediaInterface $media) { } // Get the file from the media. - $files = $media->get($source_field)->referencedEntities(); - $file = reset($files); + $source_list = $media->get($source_field); + if ($source_list instanceof EntityReferenceFieldItemListInterface) { + $files = $source_list->referencedEntities(); + return reset($files); + } - return $file; + return NULL; } /** From fe7e450a51ef7b3da0afca615e1ecb13f6cf1cc1 Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 25 Jan 2023 14:06:51 -0400 Subject: [PATCH 048/252] Index `field_weight`'s value. (#924) --- .../field.storage.node.field_weight.yml | 4 +++- .../islandora_core_feature.post_update.php | 20 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 modules/islandora_core_feature/islandora_core_feature.post_update.php diff --git a/modules/islandora_core_feature/config/install/field.storage.node.field_weight.yml b/modules/islandora_core_feature/config/install/field.storage.node.field_weight.yml index 97619cd26..4976d1d60 100644 --- a/modules/islandora_core_feature/config/install/field.storage.node.field_weight.yml +++ b/modules/islandora_core_feature/config/install/field.storage.node.field_weight.yml @@ -14,6 +14,8 @@ module: core locked: false cardinality: 1 translatable: true -indexes: { } +indexes: + value: + - value persist_with_no_fields: false custom_storage: false diff --git a/modules/islandora_core_feature/islandora_core_feature.post_update.php b/modules/islandora_core_feature/islandora_core_feature.post_update.php new file mode 100644 index 000000000..10547231a --- /dev/null +++ b/modules/islandora_core_feature/islandora_core_feature.post_update.php @@ -0,0 +1,20 @@ +getStorage('field_storage_config'); + $field = $storage->load('node.field_weight'); + $indexes = $field->getIndexes(); + $indexes += [ + 'value' => ['value'], + ]; + $field->setIndexes($indexes); + $field->save(); +} From 0d2e5843164a5704a8bf5ae9c01b590ec1ff935d Mon Sep 17 00:00:00 2001 From: Simon Hieu Mai Date: Mon, 30 Jan 2023 11:03:39 -0600 Subject: [PATCH 049/252] Update islandora_advanced_search.module --- .../islandora_advanced_search.module | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/modules/islandora_advanced_search/islandora_advanced_search.module b/modules/islandora_advanced_search/islandora_advanced_search.module index cbf52667a..a389a29dc 100644 --- a/modules/islandora_advanced_search/islandora_advanced_search.module +++ b/modules/islandora_advanced_search/islandora_advanced_search.module @@ -42,22 +42,6 @@ function islandora_advanced_search_theme() { ]; } -/** - * Implements hook_library_info_alter(). - */ -function islandora_advanced_search_library_info_alter(&$libraries, $extension) { - if ($extension == 'facets') { - // Override facets module javascript with customizations. - $path = '/' . drupal_get_path('module', 'islandora_advanced_search') . '/js/facets'; - $libraries['soft-limit']['js'] = [ - "$path/soft-limit.js" => [], - ]; - $libraries['drupal.facets.views-ajax']['js'] = [ - "$path/facets-views-ajax.js" => [], - ]; - } -} - /** * Implements hook_search_api_solr_converted_query_alter(). */ From af224e42cfdd743ca5e22e0716a787e3e4869e88 Mon Sep 17 00:00:00 2001 From: Simon Hieu Mai Date: Mon, 30 Jan 2023 11:04:17 -0600 Subject: [PATCH 050/252] Delete facets-views-ajax.js --- .../js/facets/facets-views-ajax.js | 147 ------------------ 1 file changed, 147 deletions(-) delete mode 100644 modules/islandora_advanced_search/js/facets/facets-views-ajax.js diff --git a/modules/islandora_advanced_search/js/facets/facets-views-ajax.js b/modules/islandora_advanced_search/js/facets/facets-views-ajax.js deleted file mode 100644 index 0b04ea33d..000000000 --- a/modules/islandora_advanced_search/js/facets/facets-views-ajax.js +++ /dev/null @@ -1,147 +0,0 @@ -//# sourceURL=modules/contrib/islandora/modules/islandora_advanced_search/js/facets/facets-view.ajax.js -/** - * @file - * Overrides the facets-view-ajax.js behavior from the 'facets' module. - */ -(function ($, Drupal) { - "use strict"; - - // Generate events on push state. - (function (history) { - var pushState = history.pushState; - history.pushState = function (state, title, url) { - var ret = pushState.apply(this, arguments); - var event = new Event("pushstate"); - window.dispatchEvent(event); - return ret; - }; - })(window.history); - - function reload(url) { - // Update View. - if (drupalSettings && drupalSettings.views && drupalSettings.views.ajaxViews) { - var view_path = drupalSettings.views.ajax_path; - $.each(drupalSettings.views.ajaxViews, function (views_dom_id) { - var views_parameters = Drupal.Views.parseQueryString(url); - var views_arguments = Drupal.Views.parseViewArgs(url, "search"); - var views_settings = $.extend( - {}, - Drupal.views.instances[views_dom_id].settings, - views_arguments, - views_parameters - ); - var views_ajax_settings = - Drupal.views.instances[views_dom_id].element_settings; - views_ajax_settings.submit = views_settings; - views_ajax_settings.url = - view_path + "?" + $.param(Drupal.Views.parseQueryString(url)); - Drupal.ajax(views_ajax_settings).execute(); - }); - } - - // Replace filter, pager, summary, and facet blocks. - var blocks = {}; - $( - ".block[class*='block-plugin-id--islandora-advanced-search-result-pager'], .block[class*='block-plugin-id--views-exposed-filter-block'], .block[class*='block-plugin-id--facet']" - ).each(function () { - var id = $(this).attr("id"); - var block_id = id - .slice("block-".length, id.length) - .replace(/--.*$/g, "") - .replace(/-/g, "_"); - blocks[block_id] = "#" + id; - }); - Drupal.ajax({ - url: Drupal.url("islandora-advanced-search-ajax-blocks"), - submit: { - link: url, - blocks: blocks, - }, - }).execute(); - } - - // On location change reload all the blocks / ajax view. - window.addEventListener("pushstate", function (e) { - reload(window.location.href); - }); - - window.addEventListener("popstate", function (e) { - if (e.state != null) { - reload(window.location.href); - } - }); - - /** - * Push state on form/pager/facet change. - */ - Drupal.behaviors.islandoraAdvancedSearchViewsAjax = { - attach: function (context, settings) { - window.historyInitiated = true; - - // Remove existing behavior from form. - if (settings && settings.views && settings.views.ajaxViews) { - $.each(settings.views.ajaxViews, function (index, settings) { - var exposed_form = $( - "form#views-exposed-form-" + - settings.view_name.replace(/_/g, "-") + - "-" + - settings.view_display_id.replace(/_/g, "-") - ); - exposed_form - .once() - .find("input[type=submit], input[type=image]") - .not("[data-drupal-selector=edit-reset]") - .each(function (index) { - $(this).unbind("click"); - $(this).click(function (e) { - // Let ctrl/cmd click open in a new window. - if (e.shiftKey || e.ctrlKey || e.metaKey) { - return; - } - e.preventDefault(); - e.stopPropagation(); - var href = window.location.href; - var params = Drupal.Views.parseQueryString(href); - // Remove the page if set as submitting the form should always take - // the user to the first page (facets do the same). - delete params.page; - // Include values from the form in the URL. - $.each(exposed_form.serializeArray(), function () { - params[this.name] = this.value; - }); - href = href.split("?")[0] + "?" + $.param(params); - window.history.pushState(null, document.title, href); - }); - }); - }); - } - - // Attach behavior to pager, summary, facet links. - $("[data-drupal-pager-id], [data-drupal-facets-summary-id], [data-drupal-facet-id]") - .once() - .find("a:not(.facets-soft-limit-link)") - .click(function (e) { - // Let ctrl/cmd click open in a new window. - if (e.shiftKey || e.ctrlKey || e.metaKey) { - return; - } - e.preventDefault(); - window.history.pushState(null, document.title, $(this).attr("href")); - }); - - // Trigger on sort change. - $('[data-drupal-pager-id] select[name="order"]') - .once() - .change(function () { - var href = window.location.href; - var params = Drupal.Views.parseQueryString(href); - var selection = $(this).val(); - var option = $('option[value="' + selection + '"]'); - params.sort_order = option.data("sort_order"); - params.sort_by = option.data("sort_by"); - href = href.split("?")[0] + "?" + $.param(params); - window.history.pushState(null, document.title, href); - }); - }, - }; -})(jQuery, Drupal); From da35fb8950ca0efaaf7ffed64a59421eb5f26113 Mon Sep 17 00:00:00 2001 From: Simon Hieu Mai Date: Mon, 30 Jan 2023 11:04:26 -0600 Subject: [PATCH 051/252] Delete soft-limit.js --- .../js/facets/soft-limit.js | 70 ------------------- 1 file changed, 70 deletions(-) delete mode 100644 modules/islandora_advanced_search/js/facets/soft-limit.js diff --git a/modules/islandora_advanced_search/js/facets/soft-limit.js b/modules/islandora_advanced_search/js/facets/soft-limit.js deleted file mode 100644 index a81a267ce..000000000 --- a/modules/islandora_advanced_search/js/facets/soft-limit.js +++ /dev/null @@ -1,70 +0,0 @@ -//# sourceURL=modules/contrib/islandora/modules/islandora_advanced_search/js/facets/soft-limit.js -/** - * @file - * Overrides the soft-limit.js behavior from the 'facets' module. - * As when having many facets the original version causes the page to slow down and snap to hidden when rendering. - */ -(function ($) { - - 'use strict'; - - Drupal.behaviors.facetSoftLimit = { - attach: function (context, settings) { - if (settings.facets.softLimit !== 'undefined') { - $.each(settings.facets.softLimit, function (facet, limit) { - Drupal.facets.applySoftLimit(facet, limit, settings); - }); - } - } - }; - - Drupal.facets = Drupal.facets || {}; - - /** - * Applies the soft limit UI feature to a specific facets list. - * - * @param {string} facet - * The facet id. - * @param {string} limit - * The maximum amount of items to show. - * @param {object} settings - * Settings. - */ - Drupal.facets.applySoftLimit = function (facet, limit, settings) { - var zero_based_limit = (limit - 1); - var facet_id = facet; - var facetsList = $('ul[data-drupal-facet-id="' + facet_id + '"]'); - - // In case of multiple instances of a facet, we need to key them. - if (facetsList.length > 1) { - facetsList.each(function (key, $value) { - $(this).attr('data-drupal-facet-id', facet_id + '-' + key); - }); - } - - // Add "Show more" / "Show less" links. - facetsList.filter(function () { - return $(this).next('ul').length == 1; // Has expanding list. - }).each(function () { - var facet = $(this); - var expand = facet.next('ul'); - var link = expand.next('a'); - var showLessLabel = settings.facets.softLimitSettings[facet_id].showLessLabel; - var showMoreLabel = settings.facets.softLimitSettings[facet_id].showMoreLabel; - link.text(showMoreLabel) - .once() - .on('click', function () { - if (!expand.is(":visible")) { - expand.slideDown(); - $(this).addClass('open').text(showLessLabel); - } - else { - expand.slideUp(); - $(this).removeClass('open').text(showMoreLabel); - } - return false; - }) - }); - }; - -})(jQuery); From c36f7d9978fec175a8bec378b922ab822228d1b9 Mon Sep 17 00:00:00 2001 From: JojoVes Date: Wed, 1 Feb 2023 14:23:10 -0400 Subject: [PATCH 052/252] Replace deprecated 'context' condition annotation with 'context_definitions' (#925) There was a cleanup done for this deprecation in https://github.com/Islandora/islandora/pull/764 before the 'NodeReferencedByNode' condition was made, then the deprecated annotation must have just been missed in reviewing https://github.com/Islandora/islandora/pull/808. --- src/Plugin/Condition/NodeReferencedByNode.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plugin/Condition/NodeReferencedByNode.php b/src/Plugin/Condition/NodeReferencedByNode.php index a2abac808..c5611a3ee 100644 --- a/src/Plugin/Condition/NodeReferencedByNode.php +++ b/src/Plugin/Condition/NodeReferencedByNode.php @@ -16,7 +16,7 @@ * @Condition( * id = "node_referenced_by_node", * label = @Translation("Node is referenced by other nodes"), - * context = { + * context_definitions = { * "node" = @ContextDefinition("entity:node", required = TRUE , label = @Translation("node")) * } * ) From 71c720736ffef366208d01738e20c86104686a6f Mon Sep 17 00:00:00 2001 From: Simon Hieu Mai Date: Thu, 2 Feb 2023 16:03:58 -0600 Subject: [PATCH 053/252] Update islandora_advanced_search.module --- .../islandora_advanced_search.module | 84 ------------------- 1 file changed, 84 deletions(-) diff --git a/modules/islandora_advanced_search/islandora_advanced_search.module b/modules/islandora_advanced_search/islandora_advanced_search.module index a389a29dc..ad70d2f9c 100644 --- a/modules/islandora_advanced_search/islandora_advanced_search.module +++ b/modules/islandora_advanced_search/islandora_advanced_search.module @@ -22,26 +22,6 @@ use Drupal\search_api\Query\QueryInterface as DrupalQueryInterface; use Drupal\views\ViewExecutable; use Solarium\Core\Query\QueryInterface as SolariumQueryInterface; -/** - * Implements hook_theme(). - */ -function islandora_advanced_search_theme() { - return [ - 'facets_item_list__include_exclude_links' => [ - 'template' => 'facets/facets-item-list--include-exclude-links', - 'base hook' => 'facets_item_list', - ], - 'facets_result_item__include_exclude_links' => [ - 'template' => 'facets/facets-result-item--include-exclude-links', - 'base hook' => 'facets_result_item', - ], - 'facets_result_item__summary' => [ - 'template' => 'facets/facets-result-item--summary', - 'base hook' => 'facets_result_item', - ], - ]; -} - /** * Implements hook_search_api_solr_converted_query_alter(). */ @@ -83,20 +63,6 @@ function islandora_advanced_search_form_block_form_alter(&$form, FormStateInterf $form['visibility'][$condition_id] = $condition_form; } -/** - * Implements hook_preprocess_block__facets_summary(). - */ -function islandora_advanced_search_preprocess_block__facets_summary(&$variables) { - // Copy data-attributes to the content as the javascript expects - // there to be no elements between the data declaration and the - // content of the block. - foreach ($variables['attributes'] as $key => $value) { - if (substr($key, 0, 4) === "data") { - $variables['content_attributes'][$key] = $value; - } - } -} - /** * Implements hook_preprocess_preprocess_views_view(). */ @@ -123,53 +89,3 @@ function islandora_advanced_search_views_pre_view(ViewExecutable $view, $display $advanced_search_query = new AdvancedSearchQuery(); $advanced_search_query->alterView(\Drupal::request(), $view, $display_id); } - -/** - * Implements hook_preprocess_facets_summary_item_list(). - */ -function islandora_advanced_search_preprocess_facets_summary_item_list(&$variables) { - foreach ($variables['items'] as &$item) { - $item['attributes']['class'][] = 'facet-summary-item'; - } -} - -/** - * Implements hook_preprocess_facets_item_list(). - */ -function islandora_advanced_search_preprocess_facets_item_list(&$variables) { - $widget = $variables['facet']->getWidget(); - $soft_limit = $widget['config']['soft_limit']; - // Break into two groups less / more which can display be toggled as a single - // element change rather than showing / hiding all
  • elements individually. - // As its slow and causes the page to snap when loading. - $variables['less'] = array_slice($variables['items'], 0, $soft_limit); - $variables['more'] = array_slice($variables['items'], $soft_limit); - $variables['show_more_label'] = $widget['config']['soft_limit_settings']['show_more_label']; -} - -/** - * Implements hook_preprocess_facets_result_item(). - */ -function islandora_advanced_search_preprocess_facets_result_item(&$variables) { - $settings = \Drupal::config(SettingsForm::CONFIG_NAME); - $length = $settings->get(SettingsForm::FACET_TRUNCATE); - if (is_numeric($length)) { - // Limit the length of facets display to at most 32 characters. - if (is_string($variables['value'])) { - $variables['value'] = Unicode::truncate( - $variables['value'], - $length, - TRUE, - TRUE - ); - } - elseif (is_string($variables['value']['text']['#title'])) { - $variables['value']['text']['#title'] = Unicode::truncate( - $variables['value']['text']['#title'], - $length, - TRUE, - TRUE - ); - } - } -} From 488a82b741d4ff52cf0a63152e96c992d4ccf7e9 Mon Sep 17 00:00:00 2001 From: Simon Hieu Mai Date: Thu, 2 Feb 2023 16:23:17 -0600 Subject: [PATCH 054/252] Update islandora_advanced_search.module --- .../islandora_advanced_search/islandora_advanced_search.module | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/islandora_advanced_search/islandora_advanced_search.module b/modules/islandora_advanced_search/islandora_advanced_search.module index ad70d2f9c..f08dd3460 100644 --- a/modules/islandora_advanced_search/islandora_advanced_search.module +++ b/modules/islandora_advanced_search/islandora_advanced_search.module @@ -13,10 +13,8 @@ */ use Drupal\block\Entity\Block; -use Drupal\Component\Utility\Unicode; use Drupal\Core\Form\FormStateInterface; use Drupal\islandora_advanced_search\AdvancedSearchQuery; -use Drupal\islandora_advanced_search\Form\SettingsForm; use Drupal\islandora_advanced_search\Utilities; use Drupal\search_api\Query\QueryInterface as DrupalQueryInterface; use Drupal\views\ViewExecutable; From 2794f01164199525c734ed70d56ae378a2f185a9 Mon Sep 17 00:00:00 2001 From: Ant Brown Date: Thu, 9 Feb 2023 09:30:05 +1300 Subject: [PATCH 055/252] Fix deprecated File::url(), use createFileUrl() instead (#855) * islandora.tokens.inc * See https://www.drupal.org/node/3019830 Co-authored-by: Ant Brown --- islandora.tokens.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/islandora.tokens.inc b/islandora.tokens.inc index 8d1c4b6b2..abbe6474a 100644 --- a/islandora.tokens.inc +++ b/islandora.tokens.inc @@ -79,7 +79,7 @@ function islandora_tokens($type, $tokens, array $data, array $options, Bubbleabl if ($media) { $file = \Drupal::service('islandora.media_source_service')->getSourceFile($media); if (!empty($file)) { - $url = $file->url(); + $url = $file->createFileUrl(); $replacements[$original] = $url; } } From b57f8ff64dea111c1d572ef0bfb2170488ba2f7c Mon Sep 17 00:00:00 2001 From: Seth Shaw Date: Thu, 9 Feb 2023 11:06:57 -0800 Subject: [PATCH 056/252] fix for deprecated Symfony Event class --- composer.json | 2 +- src/Event/StompHeaderEvent.php | 2 +- src/EventGenerator/EmitEvent.php | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 0b443c027..f4956d3d7 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "drupal/file_replace": "^1.1", "drupal/filehash": "^2", "drupal/flysystem" : "^2.0@alpha", - "drupal/jwt": "^1.0", + "drupal/jwt": "^1.1", "drupal/migrate_plus" : "^5.1 || ^6", "drupal/migrate_source_csv" : "^3.4", "drupal/prepopulate" : "^2.2", diff --git a/src/Event/StompHeaderEvent.php b/src/Event/StompHeaderEvent.php index d6d93c22c..1381a9209 100644 --- a/src/Event/StompHeaderEvent.php +++ b/src/Event/StompHeaderEvent.php @@ -6,7 +6,7 @@ use Drupal\Core\Session\AccountInterface; use Symfony\Component\HttpFoundation\ParameterBag; -use Symfony\Component\EventDispatcher\Event; +use Drupal\Component\EventDispatcher\Event; /** * Event used to build headers for STOMP. diff --git a/src/EventGenerator/EmitEvent.php b/src/EventGenerator/EmitEvent.php index fd33fd99c..12700d732 100644 --- a/src/EventGenerator/EmitEvent.php +++ b/src/EventGenerator/EmitEvent.php @@ -160,8 +160,8 @@ public function execute($entity = NULL) { $data = $this->generateData($entity); $event = $this->eventDispatcher->dispatch( - StompHeaderEvent::EVENT_NAME, - new StompHeaderEvent($entity, $user, $data, $this->getConfiguration()) + new StompHeaderEvent($entity, $user, $data, $this->getConfiguration()), + StompHeaderEvent::EVENT_NAME ); $message = new Message( From 74755f8074e1658ece9ee45dde2e34502e348929 Mon Sep 17 00:00:00 2001 From: Lucas van Schaik Date: Fri, 17 Feb 2023 16:56:42 +0100 Subject: [PATCH 057/252] Implement solution for drupal issues 3089660 and 3045666 --- src/IslandoraContextManager.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/IslandoraContextManager.php b/src/IslandoraContextManager.php index 801e3253e..9a318a5b3 100644 --- a/src/IslandoraContextManager.php +++ b/src/IslandoraContextManager.php @@ -48,7 +48,11 @@ public function evaluateContextConditions(ContextInterface $context, array $prov $conditions = $context->getConditions(); // Apply context to any context aware conditions. - $this->applyContexts($conditions, $provided); + // Abort if the application of contexts has been unsuccessful + // similarly to BlockAccessControlHandler::checkAccess(). + if (!$this->applyContexts($conditions, $provided)) { + return FALSE; + } // Set the logic to use when validating the conditions. $logic = $context->requiresAllConditions() @@ -76,6 +80,7 @@ public function evaluateContextConditions(ContextInterface $context, array $prov * TRUE if conditions pass */ protected function applyContexts(ConditionPluginCollection &$conditions, array $provided = []) { + $passed = FALSE; foreach ($conditions as $condition) { if ($condition instanceof ContextAwarePluginInterface) { try { @@ -86,14 +91,15 @@ protected function applyContexts(ConditionPluginCollection &$conditions, array $ $contexts = $provided; } $this->contextHandler->applyContextMapping($condition, $contexts); + $passed = TRUE; } catch (ContextException $e) { - return FALSE; + continue; } } } - return TRUE; + return $passed; } } From 87f475d81c0bca3793c9f3bdc6cf8def4f31ef6b Mon Sep 17 00:00:00 2001 From: Lucas van Schaik Date: Fri, 17 Feb 2023 16:57:50 +0100 Subject: [PATCH 058/252] Check if action is appropriate for entity before executing --- src/PresetReaction/PresetReaction.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/PresetReaction/PresetReaction.php b/src/PresetReaction/PresetReaction.php index 98aa69462..e516eb249 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -56,7 +56,10 @@ public function execute(EntityInterface $entity = NULL) { $action_ids = $config['actions']; foreach ($action_ids as $action_id) { $action = $this->actionStorage->load($action_id); - $action->execute([$entity]); + // Make sure that the action is appropriate for the entity. + if ($entity->getEntityTypeId() === $action->getType()) { + $action->execute([$entity]); + } } } From 4250109c6345c771cab0a5287cd83a4ebadbd93d Mon Sep 17 00:00:00 2001 From: Lucas van Schaik Date: Mon, 20 Feb 2023 21:25:48 +0100 Subject: [PATCH 059/252] Check if conditions exist before applying contexts to them --- src/IslandoraContextManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/IslandoraContextManager.php b/src/IslandoraContextManager.php index 9a318a5b3..b3aec19ca 100644 --- a/src/IslandoraContextManager.php +++ b/src/IslandoraContextManager.php @@ -50,7 +50,7 @@ public function evaluateContextConditions(ContextInterface $context, array $prov // Apply context to any context aware conditions. // Abort if the application of contexts has been unsuccessful // similarly to BlockAccessControlHandler::checkAccess(). - if (!$this->applyContexts($conditions, $provided)) { + if (count($conditions) > 0 && !$this->applyContexts($conditions, $provided)) { return FALSE; } From a409d402aa53a7640ca12f8ce2209ccdf605b89a Mon Sep 17 00:00:00 2001 From: Lucas van Schaik Date: Mon, 20 Feb 2023 21:26:18 +0100 Subject: [PATCH 060/252] Make sure that the action is appropriate: either system or with same entity type --- src/PresetReaction/PresetReaction.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PresetReaction/PresetReaction.php b/src/PresetReaction/PresetReaction.php index e516eb249..532606fc7 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -56,8 +56,8 @@ public function execute(EntityInterface $entity = NULL) { $action_ids = $config['actions']; foreach ($action_ids as $action_id) { $action = $this->actionStorage->load($action_id); - // Make sure that the action is appropriate for the entity. - if ($entity->getEntityTypeId() === $action->getType()) { + // Make sure that the action is appropriate: either system or with same entity type. + if ($action->getType() === 'system' || $entity->getEntityTypeId() === $action->getType()) { $action->execute([$entity]); } } From aba5052308f994d47527e7daddd75854313060b9 Mon Sep 17 00:00:00 2001 From: Lucas van Schaik Date: Tue, 21 Feb 2023 08:06:00 +0100 Subject: [PATCH 061/252] Comment too long --- src/PresetReaction/PresetReaction.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/PresetReaction/PresetReaction.php b/src/PresetReaction/PresetReaction.php index 532606fc7..18a771dc5 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -56,7 +56,8 @@ public function execute(EntityInterface $entity = NULL) { $action_ids = $config['actions']; foreach ($action_ids as $action_id) { $action = $this->actionStorage->load($action_id); - // Make sure that the action is appropriate: either system or with same entity type. + // Make sure that the action is appropriate: + // either system action or with same type as the entity type. if ($action->getType() === 'system' || $entity->getEntityTypeId() === $action->getType()) { $action->execute([$entity]); } From b89da473f12f60a863c87bd49278fac91cfee749 Mon Sep 17 00:00:00 2001 From: Lucas van Schaik Date: Tue, 28 Feb 2023 10:09:18 +0100 Subject: [PATCH 062/252] Be consistent with context module, issue 3177007 --- src/IslandoraContextManager.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/IslandoraContextManager.php b/src/IslandoraContextManager.php index b3aec19ca..11de1fdef 100644 --- a/src/IslandoraContextManager.php +++ b/src/IslandoraContextManager.php @@ -50,7 +50,7 @@ public function evaluateContextConditions(ContextInterface $context, array $prov // Apply context to any context aware conditions. // Abort if the application of contexts has been unsuccessful // similarly to BlockAccessControlHandler::checkAccess(). - if (count($conditions) > 0 && !$this->applyContexts($conditions, $provided)) { + if (!$this->applyContexts($conditions, $provided)) { return FALSE; } @@ -80,6 +80,12 @@ public function evaluateContextConditions(ContextInterface $context, array $prov * TRUE if conditions pass */ protected function applyContexts(ConditionPluginCollection &$conditions, array $provided = []) { + + // If no contexts to check, the return should be TRUE. + // For example, empty is the same as sitewide condition. + if (count($conditions) === 0) { + return TRUE; + } $passed = FALSE; foreach ($conditions as $condition) { if ($condition instanceof ContextAwarePluginInterface) { From c721f9ba07cf4eec61e9883e54a3703d48682934 Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Mon, 13 Mar 2023 13:12:00 -0300 Subject: [PATCH 063/252] Reset contexts before evaluation. (#932) * Reset contexts before evaluation. * Only reset when Islandora's ContextProviders are being used. --- src/IslandoraContextManager.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/IslandoraContextManager.php b/src/IslandoraContextManager.php index 801e3253e..c72281954 100644 --- a/src/IslandoraContextManager.php +++ b/src/IslandoraContextManager.php @@ -13,6 +13,14 @@ */ class IslandoraContextManager extends ContextManager { + /** + * Allow the contexts to be reset before evaluation. + */ + protected function resetContextEvaluation() { + $this->contexts = []; + $this->contextConditionsEvaluated = FALSE; + } + /** * Evaluate all context conditions. * @@ -22,7 +30,11 @@ class IslandoraContextManager extends ContextManager { public function evaluateContexts(array $provided = []) { $this->activeContexts = []; - + // XXX: Ensure that no earlier executed contexts in the request are still + // present when being triggered via Islandora's ContextProviders. + if (!empty($provided)) { + $this->resetContextEvaluation(); + } /** @var \Drupal\context\ContextInterface $context */ foreach ($this->getContexts() as $context) { if ($this->evaluateContextConditions($context, $provided) && !$context->disabled()) { From bb06d8143ccc951c460c687e2fd141cd22f7751f Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 8 Mar 2023 10:25:38 -0400 Subject: [PATCH 064/252] Update Crayfish Commons dependency --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index f4956d3d7..96f3e886d 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "drupal/prepopulate" : "^2.2", "drupal/search_api": "^1.8", "drupal/token" : "^1.3", - "islandora/crayfish-commons": "^2", + "islandora/crayfish-commons": "^3", "islandora/jsonld": "^2", "stomp-php/stomp-php": "4.* || ^5" }, From ee425d2c1fe82d8c25a8a1eeebae1ead01ae0cb1 Mon Sep 17 00:00:00 2001 From: Lucas van Schaik Date: Tue, 14 Mar 2023 11:16:48 +0100 Subject: [PATCH 065/252] Revert "Comment too long" This reverts commit aba5052308f994d47527e7daddd75854313060b9. --- src/PresetReaction/PresetReaction.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/PresetReaction/PresetReaction.php b/src/PresetReaction/PresetReaction.php index 18a771dc5..532606fc7 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -56,8 +56,7 @@ public function execute(EntityInterface $entity = NULL) { $action_ids = $config['actions']; foreach ($action_ids as $action_id) { $action = $this->actionStorage->load($action_id); - // Make sure that the action is appropriate: - // either system action or with same type as the entity type. + // Make sure that the action is appropriate: either system or with same entity type. if ($action->getType() === 'system' || $entity->getEntityTypeId() === $action->getType()) { $action->execute([$entity]); } From 233a65d8714ecd4ba59d0b7b3f26c6c54136b991 Mon Sep 17 00:00:00 2001 From: Lucas van Schaik Date: Tue, 14 Mar 2023 11:18:22 +0100 Subject: [PATCH 066/252] Revert "Make sure that the action is appropriate: either system or with same entity type" This reverts commit a409d402aa53a7640ca12f8ce2209ccdf605b89a. --- src/PresetReaction/PresetReaction.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PresetReaction/PresetReaction.php b/src/PresetReaction/PresetReaction.php index 532606fc7..e516eb249 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -56,8 +56,8 @@ public function execute(EntityInterface $entity = NULL) { $action_ids = $config['actions']; foreach ($action_ids as $action_id) { $action = $this->actionStorage->load($action_id); - // Make sure that the action is appropriate: either system or with same entity type. - if ($action->getType() === 'system' || $entity->getEntityTypeId() === $action->getType()) { + // Make sure that the action is appropriate for the entity. + if ($entity->getEntityTypeId() === $action->getType()) { $action->execute([$entity]); } } From d041ec3bf55e5c32e5ac348da7d947d36365b038 Mon Sep 17 00:00:00 2001 From: Lucas van Schaik Date: Tue, 14 Mar 2023 11:18:30 +0100 Subject: [PATCH 067/252] Revert "Check if action is appropriate for entity before executing" This reverts commit 87f475d81c0bca3793c9f3bdc6cf8def4f31ef6b. --- src/PresetReaction/PresetReaction.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/PresetReaction/PresetReaction.php b/src/PresetReaction/PresetReaction.php index e516eb249..98aa69462 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -56,10 +56,7 @@ public function execute(EntityInterface $entity = NULL) { $action_ids = $config['actions']; foreach ($action_ids as $action_id) { $action = $this->actionStorage->load($action_id); - // Make sure that the action is appropriate for the entity. - if ($entity->getEntityTypeId() === $action->getType()) { - $action->execute([$entity]); - } + $action->execute([$entity]); } } From 539952e89cbe8eaa644af573226fd50eacdf5c7a Mon Sep 17 00:00:00 2001 From: "Noah W. Smith" Date: Fri, 31 Mar 2023 12:55:30 -0400 Subject: [PATCH 068/252] Update maintainer and sponsor info Maintainer switched to TAG; Sponsors sorted, one correction, and links added --- README.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index d891c0e6f..839a14e3e 100644 --- a/README.md +++ b/README.md @@ -91,21 +91,22 @@ Having problems or solved a problem? Check out the Islandora google groups for a Current maintainers: -* [Danny Lamb](https://github.com/dannylamb) +* [Islandora Technical Advisory Group]([https://github.com/dannylamb](https://github.com/Islandora/islandora-community/wiki/Technical-Advisory-Group-%28TAG%29)) ## Sponsors -* UPEI -* discoverygarden inc. -* LYRASIS -* McMaster University -* University of Limerick -* York University -* University of Manitoba -* Simon Fraser University -* PALS * American Philosophical Society -* Common Media Inc. + +* [Born-Digital, Inc.](https://www.born-digital.com/) +* [discoverygarden inc.](https://www.discoverygarden.ca/) +* [LYRASIS](https://www.lyrasis.org/) +* [McMaster University](https://www.mcmaster.ca/) +* [PALS](https://www.mnpals.org/) +* [University of Limerick](https://www.ul.ie/) +* [University of Manitoba](https://umanitoba.ca/) +* [UPEI](https://www.upei.ca/) +* [Simon Fraser University](https://www.sfu.ca/) +* [York University](https://www.yorku.ca/) ## Development From 718af168f4a954dc6a7d470fd49c141c4b4f7084 Mon Sep 17 00:00:00 2001 From: "Noah W. Smith" Date: Fri, 31 Mar 2023 12:57:37 -0400 Subject: [PATCH 069/252] Missed one link; corrected TAG link --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 839a14e3e..32e69ea99 100644 --- a/README.md +++ b/README.md @@ -91,12 +91,11 @@ Having problems or solved a problem? Check out the Islandora google groups for a Current maintainers: -* [Islandora Technical Advisory Group]([https://github.com/dannylamb](https://github.com/Islandora/islandora-community/wiki/Technical-Advisory-Group-%28TAG%29)) +* [Islandora Technical Advisory Group](https://github.com/Islandora/islandora-community/wiki/Technical-Advisory-Group-%28TAG%29) ## Sponsors -* American Philosophical Society - +* [American Philosophical Society](https://www.amphilsoc.org/) * [Born-Digital, Inc.](https://www.born-digital.com/) * [discoverygarden inc.](https://www.discoverygarden.ca/) * [LYRASIS](https://www.lyrasis.org/) From 8bc98e062ffe662a14e06342129903686adb096d Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Fri, 21 Apr 2023 15:46:01 -0300 Subject: [PATCH 070/252] Issue #973 Add hooks to IIIF manifest Views Style plugin. --- .../src/Plugin/views/style/IIIFManifest.php | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index c2a2fbc3c..e30b1d63e 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -4,6 +4,7 @@ use Drupal\views\Plugin\views\style\StylePluginBase; use Drupal\Core\Entity\EntityTypeManagerInterface; +use \Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\Url; @@ -90,11 +91,16 @@ class IIIFManifest extends StylePluginBase { * @var \Drupal\Core\Messenger\MessengerInterface */ protected $messenger; + + /** + * @var \Drupal\Core\Extention\ModuleHandlerInterface; + */ + protected $moduleHandler; /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system, Client $http_client, MessengerInterface $messenger) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system, Client $http_client, MessengerInterface $messenger, ModuleHandlerInterface $moduleHandler) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->serializer = $serializer; @@ -104,6 +110,7 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition $this->fileSystem = $file_system; $this->httpClient = $http_client; $this->messenger = $messenger; + $this->moduleHandler = $moduleHandler; } /** @@ -120,10 +127,21 @@ public static function create(ContainerInterface $container, array $configuratio $container->get('entity_type.manager'), $container->get('file_system'), $container->get('http_client'), - $container->get('messenger') + $container->get('messenger'), + $container->get('module_handler') ); } + /** + * Return the request property. + * + * @return \Symfony\Component\HttpFoundation\Request + * The Symfony request object + */ + public function getRequest() { + return $this->request; + } + /** * {@inheritdoc} */ @@ -170,6 +188,9 @@ public function render() { $content_type = 'json'; + // Give other modules a chance to alter the manifest. + $this->moduleHandler->alter('islandora_iiif_manifest', $json, $this); + return $this->serializer->serialize($json, $content_type, ['views_style_plugin' => $this]); } @@ -288,11 +309,15 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas ]; } + // Give other modules a chance to alter the canvas + $alter_options = ['options' => $this->options, 'views_plugin' => $this]; + $this->moduleHandler->alter('islandora_iiif_manifest_canvas', $tmp_canvas, $row, $alter_options); + $canvases[] = $tmp_canvas; } } } - + return $canvases; } From 8286dfe4235b4a18d649154c38eed916c870de23 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Fri, 21 Apr 2023 16:40:51 -0300 Subject: [PATCH 071/252] Issue #937: Fix PHPCS issues. --- .../src/Plugin/views/style/IIIFManifest.php | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index e30b1d63e..b31d3e397 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -4,7 +4,7 @@ use Drupal\views\Plugin\views\style\StylePluginBase; use Drupal\Core\Entity\EntityTypeManagerInterface; -use \Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\Url; @@ -91,9 +91,11 @@ class IIIFManifest extends StylePluginBase { * @var \Drupal\Core\Messenger\MessengerInterface */ protected $messenger; - + /** - * @var \Drupal\Core\Extention\ModuleHandlerInterface; + * Module Handler for running hooks. + * + * @var \Drupal\Core\Extention\ModuleHandlerInterface */ protected $moduleHandler; @@ -134,7 +136,7 @@ public static function create(ContainerInterface $container, array $configuratio /** * Return the request property. - * + * * @return \Symfony\Component\HttpFoundation\Request * The Symfony request object */ @@ -309,15 +311,18 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas ]; } - // Give other modules a chance to alter the canvas - $alter_options = ['options' => $this->options, 'views_plugin' => $this]; + // Give other modules a chance to alter the canvas. + $alter_options = [ + 'options' => $this->options, + 'views_plugin' => $this + ]; $this->moduleHandler->alter('islandora_iiif_manifest_canvas', $tmp_canvas, $row, $alter_options); $canvases[] = $tmp_canvas; } } } - + return $canvases; } From 994545798b0575cb463c4e4ab31a739a562e42e6 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Fri, 21 Apr 2023 16:57:50 -0300 Subject: [PATCH 072/252] Issue 937: More PHPCS fixes. --- .../islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index b31d3e397..cacb52454 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -94,7 +94,7 @@ class IIIFManifest extends StylePluginBase { /** * Module Handler for running hooks. - * + * * @var \Drupal\Core\Extention\ModuleHandlerInterface */ protected $moduleHandler; @@ -314,7 +314,7 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas // Give other modules a chance to alter the canvas. $alter_options = [ 'options' => $this->options, - 'views_plugin' => $this + 'views_plugin' => $this, ]; $this->moduleHandler->alter('islandora_iiif_manifest_canvas', $tmp_canvas, $row, $alter_options); From 7e09750dee6cef988840cc8ce001a4f0ae07b353 Mon Sep 17 00:00:00 2001 From: Jared Whiklo Date: Wed, 15 Mar 2023 17:03:46 -0500 Subject: [PATCH 073/252] Remove deprecate MimeTypeGuesser Use test upgraded Crayfish-Commons --- composer.json | 2 +- islandora.services.yml | 3 +++ src/Flysystem/Adapter/FedoraAdapter.php | 30 ++++++++++++++++++------- src/Flysystem/Fedora.php | 24 +++++++++++++++----- 4 files changed, 44 insertions(+), 15 deletions(-) diff --git a/composer.json b/composer.json index 96f3e886d..a92aff53d 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "drupal/prepopulate" : "^2.2", "drupal/search_api": "^1.8", "drupal/token" : "^1.3", - "islandora/crayfish-commons": "^3", + "islandora/crayfish-commons": "dev-upgrade-5.4-symfony", "islandora/jsonld": "^2", "stomp-php/stomp-php": "4.* || ^5" }, diff --git a/islandora.services.yml b/islandora.services.yml index 4108e2446..465e8d933 100644 --- a/islandora.services.yml +++ b/islandora.services.yml @@ -31,6 +31,9 @@ services: logger.channel.islandora: parent: logger.channel_base arguments: ['islandora'] + logger.channel.fedora_flysystem: + parent: logger.channel_base + arguments: ['fedora_flysystem'] islandora.media_route_context_provider: class: Drupal\islandora\ContextProvider\MediaRouteContextProvider arguments: ['@current_route_match'] diff --git a/src/Flysystem/Adapter/FedoraAdapter.php b/src/Flysystem/Adapter/FedoraAdapter.php index 58be909c8..eb79220d4 100644 --- a/src/Flysystem/Adapter/FedoraAdapter.php +++ b/src/Flysystem/Adapter/FedoraAdapter.php @@ -2,6 +2,7 @@ namespace Drupal\islandora\Flysystem\Adapter; +use Drupal\Core\Logger\LoggerChannelInterface; use Islandora\Chullo\IFedoraApi; use League\Flysystem\AdapterInterface; use League\Flysystem\Adapter\Polyfill\NotSupportingVisibilityTrait; @@ -9,7 +10,7 @@ use League\Flysystem\Config; use GuzzleHttp\Psr7\Response; use GuzzleHttp\Psr7\StreamWrapper; -use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface; +use Symfony\Component\Mime\MimeTypeGuesserInterface; /** * Fedora adapter for Flysystem. @@ -29,21 +30,34 @@ class FedoraAdapter implements AdapterInterface { /** * Mimetype guesser. * - * @var \Symfony\Component\HttpFoundation\File\Mimetype\MimeTypeGuesserInterface + * @var \Symfony\Component\Mime\MimeTypeGuesserInterface */ protected $mimeTypeGuesser; + /** + * Logger. + * + * @var \Drupal\Core\Logger\LoggerChannelInterface + */ + protected $logger; + /** * Constructs a Fedora adapter for Flysystem. * * @param \Islandora\Chullo\IFedoraApi $fedora * Fedora client. - * @param \Symfony\Component\HttpFoundation\File\Mimetype\MimeTypeGuesserInterface $mime_type_guesser + * @param \Symfony\Component\Mime\MimeTypeGuesserInterface $mime_type_guesser * Mimetype guesser. + * @param \Drupal\Core\Logger\LoggerChannelInterface $logger */ - public function __construct(IFedoraApi $fedora, MimeTypeGuesserInterface $mime_type_guesser) { + public function __construct( + IFedoraApi $fedora, + MimeTypeGuesserInterface $mime_type_guesser, + LoggerChannelInterface $logger + ) { $this->fedora = $fedora; $this->mimeTypeGuesser = $mime_type_guesser; + $this->logger = $logger; } /** @@ -259,7 +273,7 @@ protected function transformToMetadata($uri) { */ public function write($path, $contents, Config $config) { $headers = [ - 'Content-Type' => $this->mimeTypeGuesser->guess($path), + 'Content-Type' => $this->mimeTypeGuesser->guessMimeType($path), ]; if ($this->has($path)) { $fedora_url = $path; @@ -274,17 +288,17 @@ public function write($path, $contents, Config $config) { $headers ); if (isset($response) && $response->getStatusCode() == 201) { - \Drupal::logger('fedora_flysystem')->info('Created a version in Fedora for ' . $fedora_url); + $this->logger->info('Created a version in Fedora for ' . $fedora_url); } else { - \Drupal::logger('fedora_flysystem')->error( + $this->logger->error( "Client error: `Failed to create a Fedora version of $fedora_url`. Response is " . print_r($response, TRUE) ); } } catch (\Exception $e) { - \Drupal::logger('fedora_flysystem')->error('Caught exception when creating version: ' . $e->getMessage() . "\n"); + $this->logger->error('Caught exception when creating version: ' . $e->getMessage() . "\n"); } } diff --git a/src/Flysystem/Fedora.php b/src/Flysystem/Fedora.php index fe7af7bae..a2ae81e3e 100644 --- a/src/Flysystem/Fedora.php +++ b/src/Flysystem/Fedora.php @@ -3,6 +3,7 @@ namespace Drupal\islandora\Flysystem; use Drupal\Core\Language\LanguageManagerInterface; +use Drupal\Core\Logger\LoggerChannelInterface; use Drupal\Core\Logger\RfcLogLevel; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Url; @@ -17,7 +18,7 @@ use Islandora\Chullo\FedoraApi; use Psr\Http\Message\RequestInterface; use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface; +use Symfony\Component\Mime\MimeTypeGuesserInterface; /** * Drupal plugin for the Fedora Flysystem adapter. @@ -38,7 +39,7 @@ class Fedora implements FlysystemPluginInterface, ContainerFactoryPluginInterfac /** * Mimetype guesser. * - * @var \Symfony\Component\HttpFoundation\File\Mimetype\MimeTypeGuesserInterface + * @var \Symfony\Component\Mime\MimeTypeGuesserInterface */ protected $mimeTypeGuesser; @@ -49,24 +50,34 @@ class Fedora implements FlysystemPluginInterface, ContainerFactoryPluginInterfac */ protected $languageManager; + /** + * Logger. + * + * @var \Drupal\Core\Logger\LoggerChannelInterface + */ + protected $logger; + /** * Constructs a Fedora plugin for Flysystem. * * @param \Islandora\Chullo\IFedoraApi $fedora * Fedora client. - * @param \Symfony\Component\HttpFoundation\File\Mimetype\MimeTypeGuesserInterface $mime_type_guesser + * @param \Symfony\Component\Mime\MimeTypeGuesserInterface $mime_type_guesser * Mimetype guesser. * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager * Language manager. + * @param \Drupal\Core\Logger\LoggerChannelInterface $logger */ public function __construct( IFedoraApi $fedora, MimeTypeGuesserInterface $mime_type_guesser, - LanguageManagerInterface $language_manager + LanguageManagerInterface $language_manager, + LoggerChannelInterface $logger ) { $this->fedora = $fedora; $this->mimeTypeGuesser = $mime_type_guesser; $this->languageManager = $language_manager; + $this->logger = $logger; } /** @@ -87,7 +98,8 @@ public static function create(ContainerInterface $container, array $configuratio return new static( $fedora, $container->get('file.mime_type.guesser'), - $container->get('language_manager') + $container->get('language_manager'), + $container->get('logger.channel.fedora_flysystem') ); } @@ -116,7 +128,7 @@ public static function addJwt(JwtAuth $jwt) { * {@inheritdoc} */ public function getAdapter() { - return new FedoraAdapter($this->fedora, $this->mimeTypeGuesser); + return new FedoraAdapter($this->fedora, $this->mimeTypeGuesser, $this->logger); } /** From a4b9f7fc4ee1e132685816a5f1b6e4085b7f1984 Mon Sep 17 00:00:00 2001 From: Jared Whiklo Date: Wed, 22 Mar 2023 12:56:35 -0500 Subject: [PATCH 074/252] Use new package --- composer.json | 5 +++-- islandora.services.yml | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index a92aff53d..a26938622 100644 --- a/composer.json +++ b/composer.json @@ -27,13 +27,14 @@ "drupal/prepopulate" : "^2.2", "drupal/search_api": "^1.8", "drupal/token" : "^1.3", - "islandora/crayfish-commons": "dev-upgrade-5.4-symfony", + "islandora/chullo": "^1.3", + "islandora/fedora-entity-mapper": "1.x-dev", "islandora/jsonld": "^2", "stomp-php/stomp-php": "4.* || ^5" }, "require-dev": { "phpunit/phpunit": "^6", - "squizlabs/php_codesniffer": "2.7.1", + "squizlabs/php_codesniffer": "^2.7.1", "drupal/coder": "*", "sebastian/phpcpd": "*" }, diff --git a/islandora.services.yml b/islandora.services.yml index 465e8d933..74725d803 100644 --- a/islandora.services.yml +++ b/islandora.services.yml @@ -56,7 +56,7 @@ services: class: Drupal\islandora\IslandoraUtils arguments: ['@entity_type.manager', '@entity_field.manager', '@context.manager', '@flysystem_factory', '@language_manager'] islandora.entity_mapper: - class: Islandora\Crayfish\Commons\EntityMapper\EntityMapper + class: Islandora\EntityMapper\EntityMapper islandora.stomp.auth_header_listener: class: Drupal\islandora\EventSubscriber\StompHeaderEventSubscriber arguments: ['@jwt.authentication.jwt'] From 97c3ddbdd1c5aff9c571286d3ea0a8ed5b34c49d Mon Sep 17 00:00:00 2001 From: Jared Whiklo Date: Tue, 18 Apr 2023 14:46:32 -0500 Subject: [PATCH 075/252] Use new chullo static methods --- composer.json | 2 +- src/Flysystem/Fedora.php | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index a26938622..0db75d4a0 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "drupal/prepopulate" : "^2.2", "drupal/search_api": "^1.8", "drupal/token" : "^1.3", - "islandora/chullo": "^1.3", + "islandora/chullo": "dev-update-dependencies", "islandora/fedora-entity-mapper": "1.x-dev", "islandora/jsonld": "^2", "stomp-php/stomp-php": "4.* || ^5" diff --git a/src/Flysystem/Fedora.php b/src/Flysystem/Fedora.php index a2ae81e3e..5a3a68d85 100644 --- a/src/Flysystem/Fedora.php +++ b/src/Flysystem/Fedora.php @@ -88,11 +88,7 @@ public static function create(ContainerInterface $container, array $configuratio // Construct guzzle client to middleware that adds JWT. $stack = HandlerStack::create(); $stack->push(static::addJwt($container->get('jwt.authentication.jwt'))); - $client = new Client([ - 'handler' => $stack, - 'base_uri' => $configuration['root'], - ]); - $fedora = new FedoraApi($client); + $fedora = FedoraApi::createWithHandler($configuration['root'], $stack); // Return it. return new static( From 492338c653677ded0765292465dd54fb506125cc Mon Sep 17 00:00:00 2001 From: Jared Whiklo Date: Wed, 19 Apr 2023 12:27:24 -0500 Subject: [PATCH 076/252] code style --- src/Flysystem/Adapter/FedoraAdapter.php | 11 ++++++----- src/Flysystem/Fedora.php | 14 +++++++------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/Flysystem/Adapter/FedoraAdapter.php b/src/Flysystem/Adapter/FedoraAdapter.php index eb79220d4..4ebc61c59 100644 --- a/src/Flysystem/Adapter/FedoraAdapter.php +++ b/src/Flysystem/Adapter/FedoraAdapter.php @@ -34,11 +34,11 @@ class FedoraAdapter implements AdapterInterface { */ protected $mimeTypeGuesser; - /** - * Logger. - * - * @var \Drupal\Core\Logger\LoggerChannelInterface - */ + /** + * Logger. + * + * @var \Drupal\Core\Logger\LoggerChannelInterface + */ protected $logger; /** @@ -49,6 +49,7 @@ class FedoraAdapter implements AdapterInterface { * @param \Symfony\Component\Mime\MimeTypeGuesserInterface $mime_type_guesser * Mimetype guesser. * @param \Drupal\Core\Logger\LoggerChannelInterface $logger + * The fedora adapter logger channel. */ public function __construct( IFedoraApi $fedora, diff --git a/src/Flysystem/Fedora.php b/src/Flysystem/Fedora.php index 5a3a68d85..0cbf1a12a 100644 --- a/src/Flysystem/Fedora.php +++ b/src/Flysystem/Fedora.php @@ -13,9 +13,8 @@ use Drupal\jwt\Authentication\Provider\JwtAuth; use GuzzleHttp\Exception\ConnectException; use GuzzleHttp\HandlerStack; -use GuzzleHttp\Client; -use Islandora\Chullo\IFedoraApi; use Islandora\Chullo\FedoraApi; +use Islandora\Chullo\IFedoraApi; use Psr\Http\Message\RequestInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Mime\MimeTypeGuesserInterface; @@ -50,11 +49,11 @@ class Fedora implements FlysystemPluginInterface, ContainerFactoryPluginInterfac */ protected $languageManager; - /** - * Logger. - * - * @var \Drupal\Core\Logger\LoggerChannelInterface - */ + /** + * Logger. + * + * @var \Drupal\Core\Logger\LoggerChannelInterface + */ protected $logger; /** @@ -67,6 +66,7 @@ class Fedora implements FlysystemPluginInterface, ContainerFactoryPluginInterfac * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager * Language manager. * @param \Drupal\Core\Logger\LoggerChannelInterface $logger + * The fedora adapter logger channel. */ public function __construct( IFedoraApi $fedora, From a02738bd3f72d301b959bc88ed2bd8d53e2b9bc1 Mon Sep 17 00:00:00 2001 From: Jared Whiklo Date: Wed, 19 Apr 2023 13:00:14 -0500 Subject: [PATCH 077/252] Fix tests --- tests/src/Kernel/FedoraAdapterTest.php | 87 +++++++++++--------------- tests/src/Kernel/FedoraPluginTest.php | 8 ++- 2 files changed, 43 insertions(+), 52 deletions(-) diff --git a/tests/src/Kernel/FedoraAdapterTest.php b/tests/src/Kernel/FedoraAdapterTest.php index 10c5beb11..a3b577e42 100644 --- a/tests/src/Kernel/FedoraAdapterTest.php +++ b/tests/src/Kernel/FedoraAdapterTest.php @@ -2,12 +2,13 @@ namespace Drupal\Tests\islandora\Kernel; +use Drupal\Core\Logger\LoggerChannelInterface; use Drupal\islandora\Flysystem\Adapter\FedoraAdapter; use GuzzleHttp\Psr7\Response; use Islandora\Chullo\IFedoraApi; use League\Flysystem\Config; use Prophecy\Argument; -use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface; +use Symfony\Component\Mime\MimeTypeGuesserInterface; /** * Tests the Fedora adapter for Flysystem. @@ -17,6 +18,30 @@ */ class FedoraAdapterTest extends IslandoraKernelTestBase { + /** + * A mimetype guesser prophecy. + * + * @var \Prophecy\Prophecy\ObjectProphecy + */ + private $mime_guesser; + + /** + * A logger prophecy. + * + * @var \Prophecy\Prophecy\ObjectProphecy + */ + private $logger; + + /** + * @inheritdoc + */ + public function setUp() { + parent::setUp(); + $this->mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) + ->reveal(); + $this->logger = $this->prophesize(LoggerChannelInterface::class)->reveal(); + } + /** * Shared functionality for an adapter. */ @@ -55,10 +80,7 @@ protected function createAdapterForFail() { $prophecy->getResource('', ['Connection' => 'close'])->willReturn($response); $api = $prophecy->reveal(); - $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - - return new FedoraAdapter($api, $mime_guesser); + return new FedoraAdapter($api, $this->mime_guesser, $this->logger); } /** @@ -73,10 +95,7 @@ protected function createAdapterForFile() { $prophecy->getResource('', ['Connection' => 'close'])->willReturn($response); $api = $prophecy->reveal(); - $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - - return new FedoraAdapter($api, $mime_guesser); + return new FedoraAdapter($api, $this->mime_guesser, $this->logger); } /** @@ -98,10 +117,7 @@ protected function createAdapterForDirectory() { $prophecy->getResourceHeaders('', ['Connection' => 'close'])->willReturn($response); $api = $prophecy->reveal(); - $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - - return new FedoraAdapter($api, $mime_guesser); + return new FedoraAdapter($api, $this->mime_guesser, $this->logger); } /** @@ -126,10 +142,7 @@ protected function createAdapterForWrite() { $api = $fedora_prophecy->reveal(); - $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - - return new FedoraAdapter($api, $mime_guesser); + return new FedoraAdapter($api, $this->mime_guesser, $this->logger); } /** @@ -149,10 +162,7 @@ protected function createAdapterForWriteFail() { $api = $fedora_prophecy->reveal(); - $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - - return new FedoraAdapter($api, $mime_guesser); + return new FedoraAdapter($api, $this->mime_guesser, $this->logger); } /** @@ -180,10 +190,7 @@ protected function createAdapterForCreateDir() { $api = $fedora_prophecy->reveal(); - $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - - return new FedoraAdapter($api, $mime_guesser); + return new FedoraAdapter($api, $this->mime_guesser, $this->logger); } /** @@ -199,10 +206,7 @@ protected function createAdapterForDelete() { $fedora_prophecy->getResourceHeaders('', ['Connection' => 'close'])->willReturn($prophecy->reveal()); $api = $fedora_prophecy->reveal(); - $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - - return new FedoraAdapter($api, $mime_guesser); + return new FedoraAdapter($api, $this->mime_guesser, $this->logger); } /** @@ -218,10 +222,7 @@ protected function createAdapterForDeleteFail() { $api = $fedora_prophecy->reveal(); - $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - - return new FedoraAdapter($api, $mime_guesser); + return new FedoraAdapter($api, $this->mime_guesser, $this->logger); } /** @@ -249,10 +250,7 @@ protected function createAdapterForDeleteWithTombstone() { $api = $fedora_prophecy->reveal(); - $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - - return new FedoraAdapter($api, $mime_guesser); + return new FedoraAdapter($api, $this->mime_guesser, $this->logger); } /** @@ -280,10 +278,7 @@ protected function createAdapterForDeleteWithTombstoneFail() { $api = $fedora_prophecy->reveal(); - $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - - return new FedoraAdapter($api, $mime_guesser); + return new FedoraAdapter($api, $this->mime_guesser, $this->logger); } /** @@ -644,10 +639,7 @@ public function testRename() { $api = $fedora_prophecy->reveal(); - $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - - $adapter = new FedoraAdapter($api, $mime_guesser); + $adapter = new FedoraAdapter($api, $this->mime_guesser, $this->logger); $this->assertTrue($adapter->rename('', '') == TRUE, "rename() must return TRUE on success"); } @@ -664,10 +656,7 @@ public function testCreateDirFail() { $api = $fedora_prophecy->reveal(); - $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - - $adapter = new FedoraAdapter($api, $mime_guesser); + $adapter = new FedoraAdapter($api, $this->mime_guesser, $this->logger); $this->assertTrue($adapter->createDir('', $this->prophesize(Config::class) ->reveal()) == FALSE, "createDir() must return FALSE on fail"); diff --git a/tests/src/Kernel/FedoraPluginTest.php b/tests/src/Kernel/FedoraPluginTest.php index 674915078..cd1c83256 100644 --- a/tests/src/Kernel/FedoraPluginTest.php +++ b/tests/src/Kernel/FedoraPluginTest.php @@ -2,11 +2,12 @@ namespace Drupal\Tests\islandora\Kernel; +use Drupal\Core\Logger\LoggerChannelInterface; use Drupal\islandora\Flysystem\Fedora; -use League\Flysystem\AdapterInterface; use Islandora\Chullo\IFedoraApi; +use League\Flysystem\AdapterInterface; use Psr\Http\Message\ResponseInterface; -use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface; +use Symfony\Component\Mime\MimeTypeGuesserInterface; /** * Tests the Fedora plugin for Flysystem. @@ -32,8 +33,9 @@ protected function createPlugin($return_code) { $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class)->reveal(); $language_manager = $this->container->get('language_manager'); + $logger = $this->prophesize(LoggerChannelInterface::class)->reveal(); - return new Fedora($api, $mime_guesser, $language_manager); + return new Fedora($api, $mime_guesser, $language_manager, $logger); } /** From 8370383e83c2f9a64d7186f76e7aa712452a6533 Mon Sep 17 00:00:00 2001 From: Jared Whiklo Date: Wed, 19 Apr 2023 13:40:34 -0500 Subject: [PATCH 078/252] More code style --- tests/src/Kernel/FedoraAdapterTest.php | 36 +++++++++++++------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/src/Kernel/FedoraAdapterTest.php b/tests/src/Kernel/FedoraAdapterTest.php index a3b577e42..e51610637 100644 --- a/tests/src/Kernel/FedoraAdapterTest.php +++ b/tests/src/Kernel/FedoraAdapterTest.php @@ -23,7 +23,7 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { * * @var \Prophecy\Prophecy\ObjectProphecy */ - private $mime_guesser; + private $mimeGuesser; /** * A logger prophecy. @@ -33,13 +33,13 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { private $logger; /** - * @inheritdoc + * {@inheritdoc} */ public function setUp() { - parent::setUp(); - $this->mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - $this->logger = $this->prophesize(LoggerChannelInterface::class)->reveal(); + parent::setUp(); + $this->mimeGuesser = $this->prophesize(MimeTypeGuesserInterface::class) + ->reveal(); + $this->logger = $this->prophesize(LoggerChannelInterface::class)->reveal(); } /** @@ -80,7 +80,7 @@ protected function createAdapterForFail() { $prophecy->getResource('', ['Connection' => 'close'])->willReturn($response); $api = $prophecy->reveal(); - return new FedoraAdapter($api, $this->mime_guesser, $this->logger); + return new FedoraAdapter($api, $this->mimeGuesser, $this->logger); } /** @@ -95,7 +95,7 @@ protected function createAdapterForFile() { $prophecy->getResource('', ['Connection' => 'close'])->willReturn($response); $api = $prophecy->reveal(); - return new FedoraAdapter($api, $this->mime_guesser, $this->logger); + return new FedoraAdapter($api, $this->mimeGuesser, $this->logger); } /** @@ -117,7 +117,7 @@ protected function createAdapterForDirectory() { $prophecy->getResourceHeaders('', ['Connection' => 'close'])->willReturn($response); $api = $prophecy->reveal(); - return new FedoraAdapter($api, $this->mime_guesser, $this->logger); + return new FedoraAdapter($api, $this->mimeGuesser, $this->logger); } /** @@ -142,7 +142,7 @@ protected function createAdapterForWrite() { $api = $fedora_prophecy->reveal(); - return new FedoraAdapter($api, $this->mime_guesser, $this->logger); + return new FedoraAdapter($api, $this->mimeGuesser, $this->logger); } /** @@ -162,7 +162,7 @@ protected function createAdapterForWriteFail() { $api = $fedora_prophecy->reveal(); - return new FedoraAdapter($api, $this->mime_guesser, $this->logger); + return new FedoraAdapter($api, $this->mimeGuesser, $this->logger); } /** @@ -190,7 +190,7 @@ protected function createAdapterForCreateDir() { $api = $fedora_prophecy->reveal(); - return new FedoraAdapter($api, $this->mime_guesser, $this->logger); + return new FedoraAdapter($api, $this->mimeGuesser, $this->logger); } /** @@ -206,7 +206,7 @@ protected function createAdapterForDelete() { $fedora_prophecy->getResourceHeaders('', ['Connection' => 'close'])->willReturn($prophecy->reveal()); $api = $fedora_prophecy->reveal(); - return new FedoraAdapter($api, $this->mime_guesser, $this->logger); + return new FedoraAdapter($api, $this->mimeGuesser, $this->logger); } /** @@ -222,7 +222,7 @@ protected function createAdapterForDeleteFail() { $api = $fedora_prophecy->reveal(); - return new FedoraAdapter($api, $this->mime_guesser, $this->logger); + return new FedoraAdapter($api, $this->mimeGuesser, $this->logger); } /** @@ -250,7 +250,7 @@ protected function createAdapterForDeleteWithTombstone() { $api = $fedora_prophecy->reveal(); - return new FedoraAdapter($api, $this->mime_guesser, $this->logger); + return new FedoraAdapter($api, $this->mimeGuesser, $this->logger); } /** @@ -278,7 +278,7 @@ protected function createAdapterForDeleteWithTombstoneFail() { $api = $fedora_prophecy->reveal(); - return new FedoraAdapter($api, $this->mime_guesser, $this->logger); + return new FedoraAdapter($api, $this->mimeGuesser, $this->logger); } /** @@ -639,7 +639,7 @@ public function testRename() { $api = $fedora_prophecy->reveal(); - $adapter = new FedoraAdapter($api, $this->mime_guesser, $this->logger); + $adapter = new FedoraAdapter($api, $this->mimeGuesser, $this->logger); $this->assertTrue($adapter->rename('', '') == TRUE, "rename() must return TRUE on success"); } @@ -656,7 +656,7 @@ public function testCreateDirFail() { $api = $fedora_prophecy->reveal(); - $adapter = new FedoraAdapter($api, $this->mime_guesser, $this->logger); + $adapter = new FedoraAdapter($api, $this->mimeGuesser, $this->logger); $this->assertTrue($adapter->createDir('', $this->prophesize(Config::class) ->reveal()) == FALSE, "createDir() must return FALSE on fail"); From 3ef2f1038ebcc19b2a43f5263922069d8934532f Mon Sep 17 00:00:00 2001 From: Jared Whiklo Date: Thu, 27 Apr 2023 09:34:09 -0500 Subject: [PATCH 079/252] Update dependencies to tagged versions --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 0db75d4a0..3ceed0e11 100644 --- a/composer.json +++ b/composer.json @@ -27,8 +27,8 @@ "drupal/prepopulate" : "^2.2", "drupal/search_api": "^1.8", "drupal/token" : "^1.3", - "islandora/chullo": "dev-update-dependencies", - "islandora/fedora-entity-mapper": "1.x-dev", + "islandora/chullo": "^2.0", + "islandora/fedora-entity-mapper": "^1.0", "islandora/jsonld": "^2", "stomp-php/stomp-php": "4.* || ^5" }, From e8712d85f750a7bbed075f5a8b09fda9fd2cd1a1 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Tue, 2 May 2023 12:34:47 -0300 Subject: [PATCH 080/252] Issue #939: Fix incorrect IIIF Manifest canvas Ids. --- modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index c2a2fbc3c..90945664b 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -136,7 +136,7 @@ public function render() { $request_url = $this->request->getRequestUri(); // Strip off the last URI component to get the base ID of the URL. // @todo assumming the view is a path like /node/1/manifest.json - $url_components = explode('/', $request_url); + $url_components = explode('/', trim($request_url, '/')); array_pop($url_components); $content_path = implode('/', $url_components); $iiif_base_id = $request_host . '/' . $content_path; From e4fbbb375a9afdb8d1e0d4ce512e0790899911be Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Wed, 3 May 2023 16:42:03 -0300 Subject: [PATCH 081/252] Issue #941: Only add
    tags to plain text extracted text fields. (#942) * Issue #941: Only add
    tags to plain text extracted text fields. * Fix PHPCS errors. * Don't add
    tags to edited OCR text field if it looks like hOCR. * Respond to PHPCS errors. --- .../islandora_text_extraction.module | 4 ++++ .../src/Controller/MediaSourceController.php | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/modules/islandora_text_extraction/islandora_text_extraction.module b/modules/islandora_text_extraction/islandora_text_extraction.module index 5d6f64370..ca330dd42 100644 --- a/modules/islandora_text_extraction/islandora_text_extraction.module +++ b/modules/islandora_text_extraction/islandora_text_extraction.module @@ -40,6 +40,10 @@ function islandora_text_extraction_media_presave(MediaInterface $media) { $file = File::load($file_id); if ($file) { $data = file_get_contents($file->getFileUri()); + // Check if it's already markup like hOCR. + if (substr($data, 0, 5) == 'set('field_edited_text', $data); $media->field_edited_text->format = 'basic_html'; diff --git a/modules/islandora_text_extraction/src/Controller/MediaSourceController.php b/modules/islandora_text_extraction/src/Controller/MediaSourceController.php index 14c36ebdb..f15e42d56 100644 --- a/modules/islandora_text_extraction/src/Controller/MediaSourceController.php +++ b/modules/islandora_text_extraction/src/Controller/MediaSourceController.php @@ -108,7 +108,11 @@ public function attachToMedia( $this->getLogger('islandora')->warning("Field $destination_field is not defined in Media Type {$media->bundle()}"); } if ($media->hasField($destination_text_field)) { - $media->{$destination_text_field}->setValue(nl2br($contents)); + // @todo The request actually has a malformed parameter string, ?text_format=plain_text?connection_close=true. + if (substr($request->query->get('text_format'), 0, 10) == 'plain_text') { + $contents = nl2br($contents); + } + $media->{$destination_text_field}->setValue($contents); } else { $this->getLogger('islandora')->warning("Field $destination_text_field is not defined in Media Type {$media->bundle()}"); From c80e68716861e1315ebf370deaa3b7823194c90a Mon Sep 17 00:00:00 2001 From: kstapelfeldt Date: Fri, 5 May 2023 11:11:59 -0400 Subject: [PATCH 082/252] Update README.md Remove lobster holding 8 sign. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 32e69ea99..546d21923 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ![Islandora](https://cloud.githubusercontent.com/assets/2371345/25624809/f95b0972-2f30-11e7-8992-a8f135402cdc.png) Islandora +# Islandora [![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.4-8892BF.svg?style=flat-square)](https://php.net/) [![Build Status](https://github.com/islandora/islandora/actions/workflows/build-2.x.yml/badge.svg)](https://github.com/Islandora/islandora/actions) From 06f2a5754eba0dc80db567c2ea7872af359eaa1d Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Fri, 26 May 2023 16:41:10 -0300 Subject: [PATCH 083/252] Drupal Rector. --- .../islandora_advanced_search.module | 2 +- .../GenerateAudioDerivativeTest.php | 3 +- .../tests/src/Functional/BreadcrumbsTest.php | 4 +-- .../src/Plugin/views/style/IIIFManifest.php | 34 ++----------------- .../GenerateImageDerivativeTest.php | 3 +- .../src/Controller/MediaSourceController.php | 2 +- .../tests/src/Functional/LoadTest.php | 4 +-- .../GenerateVideoDerivativeTest.php | 3 +- src/EventSubscriber/LinkHeaderSubscriber.php | 6 ++-- .../MediaLinkHeaderSubscriber.php | 4 +-- .../NodeLinkHeaderSubscriber.php | 6 ++-- src/Flysystem/Adapter/FedoraAdapter.php | 14 ++++---- .../AbstractFileSelectionForm.php | 7 +++- tests/src/Functional/AddChildTest.php | 2 +- tests/src/Functional/AddMediaToNodeTest.php | 2 +- .../src/Functional/ContentEntityTypeTest.php | 3 +- tests/src/Functional/DeleteMediaTest.php | 4 +-- .../src/Functional/DerivativeReactionTest.php | 5 +-- .../Functional/GenerateDerivativeTestBase.php | 2 +- tests/src/Functional/IndexingTest.php | 5 +-- .../IslandoraFunctionalTestBase.php | 11 +++--- .../IslandoraImageFormatterTest.php | 2 +- .../Functional/IslandoraSettingsFormTest.php | 17 ++++++---- .../JsonldSelfReferenceReactionTest.php | 13 +++---- .../JsonldTypeAlterReactionTest.php | 14 ++++---- tests/src/Functional/LinkHeaderTest.php | 2 +- .../src/Functional/MediaSourceUpdateTest.php | 2 +- tests/src/Functional/NodeHasTermTest.php | 2 +- .../Functional/ViewModeAlterReactionTest.php | 2 +- .../IntegerWeightTest.php | 2 +- tests/src/Kernel/EventGeneratorTest.php | 2 +- tests/src/Kernel/FedoraAdapterTest.php | 12 ++++--- tests/src/Kernel/IslandoraKernelTestBase.php | 4 +-- tests/src/Kernel/JwtEventSubscriberTest.php | 4 ++- 34 files changed, 102 insertions(+), 102 deletions(-) diff --git a/modules/islandora_advanced_search/islandora_advanced_search.module b/modules/islandora_advanced_search/islandora_advanced_search.module index cbf52667a..7bae23cd9 100644 --- a/modules/islandora_advanced_search/islandora_advanced_search.module +++ b/modules/islandora_advanced_search/islandora_advanced_search.module @@ -48,7 +48,7 @@ function islandora_advanced_search_theme() { function islandora_advanced_search_library_info_alter(&$libraries, $extension) { if ($extension == 'facets') { // Override facets module javascript with customizations. - $path = '/' . drupal_get_path('module', 'islandora_advanced_search') . '/js/facets'; + $path = '/' . \Drupal::service('extension.list.module')->getPath('islandora_advanced_search') . '/js/facets'; $libraries['soft-limit']['js'] = [ "$path/soft-limit.js" => [], ]; diff --git a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php index fc1c6188e..766ceac0a 100644 --- a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php +++ b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php @@ -68,7 +68,8 @@ public function testGenerateAudioDerivativeFromScratch() { 'field_media_of[0][target_id]' => 'Test Node', 'field_tags[0][target_id]' => 'Preservation Master', ]; - $this->drupalPostForm('media/add/' . $this->testMediaType->id(), $values, $this->t('Save')); + $this->drupalGet('media/add/' . $this->testMediaType->id()); + $this->submitForm($values, $this->t('Save')); $expected = [ 'source_uri' => 'test_file.txt', diff --git a/modules/islandora_breadcrumbs/tests/src/Functional/BreadcrumbsTest.php b/modules/islandora_breadcrumbs/tests/src/Functional/BreadcrumbsTest.php index 80f5dbee0..ee35a1ed3 100644 --- a/modules/islandora_breadcrumbs/tests/src/Functional/BreadcrumbsTest.php +++ b/modules/islandora_breadcrumbs/tests/src/Functional/BreadcrumbsTest.php @@ -20,7 +20,7 @@ class BreadcrumbsTest extends IslandoraFunctionalTestBase { * * @var array */ - public static $modules = [ + protected static $modules = [ 'islandora_breadcrumbs', ]; @@ -56,7 +56,7 @@ class BreadcrumbsTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); // Create some nodes. diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 55fe36340..90945664b 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -4,7 +4,6 @@ use Drupal\views\Plugin\views\style\StylePluginBase; use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\Url; @@ -92,17 +91,10 @@ class IIIFManifest extends StylePluginBase { */ protected $messenger; - /** - * Module Handler for running hooks. - * - * @var \Drupal\Core\Extention\ModuleHandlerInterface - */ - protected $moduleHandler; - /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system, Client $http_client, MessengerInterface $messenger, ModuleHandlerInterface $moduleHandler) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system, Client $http_client, MessengerInterface $messenger) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->serializer = $serializer; @@ -112,7 +104,6 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition $this->fileSystem = $file_system; $this->httpClient = $http_client; $this->messenger = $messenger; - $this->moduleHandler = $moduleHandler; } /** @@ -129,21 +120,10 @@ public static function create(ContainerInterface $container, array $configuratio $container->get('entity_type.manager'), $container->get('file_system'), $container->get('http_client'), - $container->get('messenger'), - $container->get('module_handler') + $container->get('messenger') ); } - /** - * Return the request property. - * - * @return \Symfony\Component\HttpFoundation\Request - * The Symfony request object - */ - public function getRequest() { - return $this->request; - } - /** * {@inheritdoc} */ @@ -190,9 +170,6 @@ public function render() { $content_type = 'json'; - // Give other modules a chance to alter the manifest. - $this->moduleHandler->alter('islandora_iiif_manifest', $json, $this); - return $this->serializer->serialize($json, $content_type, ['views_style_plugin' => $this]); } @@ -311,13 +288,6 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas ]; } - // Give other modules a chance to alter the canvas. - $alter_options = [ - 'options' => $this->options, - 'views_plugin' => $this, - ]; - $this->moduleHandler->alter('islandora_iiif_manifest_canvas', $tmp_canvas, $row, $alter_options); - $canvases[] = $tmp_canvas; } } diff --git a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php index b6e016fc1..295eae913 100644 --- a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php +++ b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php @@ -70,7 +70,8 @@ public function testGenerateImageDerivativeFromScratch() { 'field_media_of[0][target_id]' => 'Test Node', 'field_tags[0][target_id]' => 'Preservation Master', ]; - $this->drupalPostForm('media/add/' . $this->testMediaType->id(), $values, $this->t('Save')); + $this->drupalGet('media/add/' . $this->testMediaType->id()); + $this->submitForm($values, $this->t('Save')); $expected = [ 'source_uri' => 'test_file.txt', diff --git a/modules/islandora_text_extraction/src/Controller/MediaSourceController.php b/modules/islandora_text_extraction/src/Controller/MediaSourceController.php index f15e42d56..5518220d1 100644 --- a/modules/islandora_text_extraction/src/Controller/MediaSourceController.php +++ b/modules/islandora_text_extraction/src/Controller/MediaSourceController.php @@ -98,7 +98,7 @@ public function attachToMedia( if (!$this->fileSystem->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS)) { throw new HttpException(500, "The destination directory does not exist, could not be created, or is not writable"); } - $file = file_save_data($contents, $content_location, FileSystemInterface::EXISTS_REPLACE); + $file = \Drupal::service('file.repository')->writeData($contents, $content_location, FileSystemInterface::EXISTS_REPLACE); if ($media->hasField($destination_field)) { $media->{$destination_field}->setValue([ 'target_id' => $file->id(), diff --git a/modules/islandora_text_extraction/tests/src/Functional/LoadTest.php b/modules/islandora_text_extraction/tests/src/Functional/LoadTest.php index 31dca62c8..172ae73ab 100644 --- a/modules/islandora_text_extraction/tests/src/Functional/LoadTest.php +++ b/modules/islandora_text_extraction/tests/src/Functional/LoadTest.php @@ -17,7 +17,7 @@ class LoadTest extends IslandoraFunctionalTestBase { * * @var array */ - public static $modules = ['islandora_text_extraction']; + protected static $modules = ['islandora_text_extraction']; /** * A user with permission to administer site configuration. @@ -29,7 +29,7 @@ class LoadTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); $this->user = $this->drupalCreateUser(['administer site configuration']); $this->drupalLogin($this->user); diff --git a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php index 8714a2f10..17e8bd5b5 100644 --- a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php +++ b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php @@ -65,7 +65,8 @@ public function testGenerateVideoDerivativeFromScratch() { 'field_media_of[0][target_id]' => 'Test Node', 'field_tags[0][target_id]' => 'Preservation Master', ]; - $this->drupalPostForm('media/add/' . $this->testMediaType->id(), $values, $this->t('Save')); + $this->drupalGet('media/add/' . $this->testMediaType->id()); + $this->submitForm($values, $this->t('Save')); $expected = [ 'source_uri' => 'test_file.txt', diff --git a/src/EventSubscriber/LinkHeaderSubscriber.php b/src/EventSubscriber/LinkHeaderSubscriber.php index ce33ce2e1..f7e5725b8 100644 --- a/src/EventSubscriber/LinkHeaderSubscriber.php +++ b/src/EventSubscriber/LinkHeaderSubscriber.php @@ -2,6 +2,7 @@ namespace Drupal\islandora\EventSubscriber; +use Symfony\Component\HttpKernel\Event\ResponseEvent; use Drupal\Core\Access\AccessManagerInterface; use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\Core\Entity\EntityInterface; @@ -13,7 +14,6 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; /** @@ -312,9 +312,9 @@ protected function generateRestLinks(EntityInterface $entity) { /** * Adds resource-specific link headers to appropriate responses. * - * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event + * @param \Symfony\Component\HttpKernel\Event\ResponseEvent $event * Event containing the response. */ - abstract public function onResponse(FilterResponseEvent $event); + abstract public function onResponse(ResponseEvent $event); } diff --git a/src/EventSubscriber/MediaLinkHeaderSubscriber.php b/src/EventSubscriber/MediaLinkHeaderSubscriber.php index 3cebbbaae..0f406cf57 100644 --- a/src/EventSubscriber/MediaLinkHeaderSubscriber.php +++ b/src/EventSubscriber/MediaLinkHeaderSubscriber.php @@ -2,10 +2,10 @@ namespace Drupal\islandora\EventSubscriber; +use Symfony\Component\HttpKernel\Event\ResponseEvent; use Drupal\Core\Url; use Drupal\media\MediaInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Symfony\Component\HttpKernel\Event\FilterResponseEvent; /** * Subscribes to MediaLinkHeader Event. @@ -17,7 +17,7 @@ class MediaLinkHeaderSubscriber extends LinkHeaderSubscriber implements EventSub /** * {@inheritdoc} */ - public function onResponse(FilterResponseEvent $event) { + public function onResponse(ResponseEvent $event) { $response = $event->getResponse(); $media = $this->getObject($response, 'media'); diff --git a/src/EventSubscriber/NodeLinkHeaderSubscriber.php b/src/EventSubscriber/NodeLinkHeaderSubscriber.php index e00533f7a..c4cdaea8c 100644 --- a/src/EventSubscriber/NodeLinkHeaderSubscriber.php +++ b/src/EventSubscriber/NodeLinkHeaderSubscriber.php @@ -2,9 +2,9 @@ namespace Drupal\islandora\EventSubscriber; +use Symfony\Component\HttpKernel\Event\ResponseEvent; use Drupal\node\NodeInterface; use Drupal\islandora\IslandoraUtils; -use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** @@ -17,10 +17,10 @@ class NodeLinkHeaderSubscriber extends LinkHeaderSubscriber implements EventSubs /** * Adds node-specific link headers to appropriate responses. * - * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event + * @param \Symfony\Component\HttpKernel\Event\ResponseEvent $event * Event containing the response. */ - public function onResponse(FilterResponseEvent $event) { + public function onResponse(ResponseEvent $event) { $response = $event->getResponse(); $node = $this->getObject($response, 'node'); diff --git a/src/Flysystem/Adapter/FedoraAdapter.php b/src/Flysystem/Adapter/FedoraAdapter.php index 4ebc61c59..55f8b11d3 100644 --- a/src/Flysystem/Adapter/FedoraAdapter.php +++ b/src/Flysystem/Adapter/FedoraAdapter.php @@ -2,6 +2,8 @@ namespace Drupal\islandora\Flysystem\Adapter; +use GuzzleHttp\Psr7\Header; +use function GuzzleHttp\Psr7\parse_header; use Drupal\Core\Logger\LoggerChannelInterface; use Islandora\Chullo\IFedoraApi; use League\Flysystem\AdapterInterface; @@ -159,11 +161,11 @@ protected function getMetadataFromHeaders(Response $response) { // directory. $type = 'dir'; // phpcs:disable - if (class_exists(\GuzzleHttp\Psr7\Header::class)) { - $links = \GuzzleHttp\Psr7\Header::parse($response->getHeader('Link')); + if (class_exists(Header::class)) { + $links = Header::parse($response->getHeader('Link')); } else { - $links = \GuzzleHttp\Psr7\parse_header($response->getHeader('Link')); + $links = parse_header($response->getHeader('Link')); } // phpcs:enable foreach ($links as $link) { @@ -402,11 +404,11 @@ private function deleteTombstone($path) { if ($response->getStatusCode() == 410) { $return = FALSE; // phpcs:disable - if (class_exists(\GuzzleHttp\Psr7\Header::class)) { - $link_headers = \GuzzleHttp\Psr7\Header::parse($response->getHeader('Link')); + if (class_exists(Header::class)) { + $link_headers = Header::parse($response->getHeader('Link')); } else { - $link_headers = \GuzzleHttp\Psr7\parse_header($response->getHeader('Link')); + $link_headers = parse_header($response->getHeader('Link')); } // phpcs:enable if ($link_headers) { diff --git a/src/Form/AddChildrenWizard/AbstractFileSelectionForm.php b/src/Form/AddChildrenWizard/AbstractFileSelectionForm.php index 6aeed8795..cf6ef3057 100644 --- a/src/Form/AddChildrenWizard/AbstractFileSelectionForm.php +++ b/src/Form/AddChildrenWizard/AbstractFileSelectionForm.php @@ -37,6 +37,11 @@ abstract class AbstractFileSelectionForm extends FormBase { * @var \Drupal\islandora\Form\AddChildrenWizard\AbstractBatchProcessor|null */ protected ?AbstractBatchProcessor $batchProcessor; + private \static $static; + public function __construct(\static $static) + { + $this->static = $static; + } /** * {@inheritdoc} @@ -49,7 +54,7 @@ public static function create(ContainerInterface $container): self { $instance->entityFieldManager = $container->get('entity_field.manager'); $instance->currentUser = $container->get('current_user'); - $instance->batchProcessor = $container->get(static::BATCH_PROCESSOR); + $instance->batchProcessor = $this->static; return $instance; } diff --git a/tests/src/Functional/AddChildTest.php b/tests/src/Functional/AddChildTest.php index 9fc2f9e23..f27f9db98 100644 --- a/tests/src/Functional/AddChildTest.php +++ b/tests/src/Functional/AddChildTest.php @@ -12,7 +12,7 @@ class AddChildTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); $this->parent = diff --git a/tests/src/Functional/AddMediaToNodeTest.php b/tests/src/Functional/AddMediaToNodeTest.php index 329097757..4b0b62c52 100644 --- a/tests/src/Functional/AddMediaToNodeTest.php +++ b/tests/src/Functional/AddMediaToNodeTest.php @@ -31,7 +31,7 @@ class AddMediaToNodeTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); $this->node = $this->container->get('entity_type.manager')->getStorage('node')->create([ diff --git a/tests/src/Functional/ContentEntityTypeTest.php b/tests/src/Functional/ContentEntityTypeTest.php index 362ff7fbb..5ed229486 100644 --- a/tests/src/Functional/ContentEntityTypeTest.php +++ b/tests/src/Functional/ContentEntityTypeTest.php @@ -52,7 +52,8 @@ public function testContentEntityType() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', ]; - $this->drupalPostForm('media/add/' . $this->testMediaType->id(), $values, $this->t('Save')); + $this->drupalGet('media/add/' . $this->testMediaType->id()); + $this->submitForm($values, $this->t('Save')); $this->assertSession()->pageTextNotContains("Hello World!"); } diff --git a/tests/src/Functional/DeleteMediaTest.php b/tests/src/Functional/DeleteMediaTest.php index f112c7006..86895dbbc 100644 --- a/tests/src/Functional/DeleteMediaTest.php +++ b/tests/src/Functional/DeleteMediaTest.php @@ -16,7 +16,7 @@ class DeleteMediaTest extends IslandoraFunctionalTestBase { * * @var array */ - public static $modules = [ + protected static $modules = [ 'media_test_views', 'context_ui', 'field_ui', @@ -47,7 +47,7 @@ class DeleteMediaTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); // Create a test user. diff --git a/tests/src/Functional/DerivativeReactionTest.php b/tests/src/Functional/DerivativeReactionTest.php index e1b1c8276..00e0e5ae5 100644 --- a/tests/src/Functional/DerivativeReactionTest.php +++ b/tests/src/Functional/DerivativeReactionTest.php @@ -19,7 +19,7 @@ class DerivativeReactionTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); $this->node = $this->container->get('entity_type.manager')->getStorage('node')->create([ @@ -52,7 +52,8 @@ public function testExecuteDerivativeReaction() { 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', ]; - $this->drupalPostForm('media/add/' . $this->testMediaType->id(), $values, $this->t('Save')); + $this->drupalGet('media/add/' . $this->testMediaType->id()); + $this->submitForm($values, $this->t('Save')); // field_media_of is set and there's a file, so derivatives should fire. $this->assertSession()->pageTextContains("Hello World!"); diff --git a/tests/src/Functional/GenerateDerivativeTestBase.php b/tests/src/Functional/GenerateDerivativeTestBase.php index 0f67d5919..c5ec9701c 100644 --- a/tests/src/Functional/GenerateDerivativeTestBase.php +++ b/tests/src/Functional/GenerateDerivativeTestBase.php @@ -29,7 +29,7 @@ abstract class GenerateDerivativeTestBase extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); $this->createUserAndLogin(); diff --git a/tests/src/Functional/IndexingTest.php b/tests/src/Functional/IndexingTest.php index e995329d7..ff2152817 100644 --- a/tests/src/Functional/IndexingTest.php +++ b/tests/src/Functional/IndexingTest.php @@ -12,7 +12,7 @@ class IndexingTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); // Create an action that dsm's "Goodbye, Cruel World!". @@ -63,9 +63,10 @@ public function testIndexing() { // Add the Goodbye World reaction. $this->addPresetReaction('test', 'delete', 'goodbye_world'); + $this->drupalGet("$url/delete"); // Delete the node. - $this->drupalPostForm("$url/delete", [], $this->t('Delete')); + $this->submitForm([], $this->t('Delete')); $this->assertSession()->statusCodeEquals(200); // Confirm Goodbye, Cruel World! is printed to the screen. diff --git a/tests/src/Functional/IslandoraFunctionalTestBase.php b/tests/src/Functional/IslandoraFunctionalTestBase.php index 2e4c88e89..2e7235611 100644 --- a/tests/src/Functional/IslandoraFunctionalTestBase.php +++ b/tests/src/Functional/IslandoraFunctionalTestBase.php @@ -88,7 +88,7 @@ class IslandoraFunctionalTestBase extends BrowserTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); // Delete the node rest config that's bootstrapped with Drupal. @@ -314,7 +314,8 @@ protected function addPresetReaction($context_id, $reaction_type, $action_id) { * Create a new node by posting its add form. */ protected function postNodeAddForm($bundle_id, $values, $button_text) { - $this->drupalPostForm("node/add/$bundle_id", $values, $this->t('@text', ['@text' => $button_text])); + $this->drupalGet("node/add/$bundle_id"); + $this->submitForm($values, $this->t('@text', ['@text' => $button_text])); $this->assertSession()->statusCodeEquals(200); } @@ -322,7 +323,8 @@ protected function postNodeAddForm($bundle_id, $values, $button_text) { * Create a new node by posting its add form. */ protected function postTermAddForm($taxomony_id, $values, $button_text) { - $this->drupalPostForm("admin/structure/taxonomy/manage/$taxomony_id/add", $values, $this->t('@text', ['@text' => $button_text])); + $this->drupalGet("admin/structure/taxonomy/manage/$taxomony_id/add"); + $this->submitForm($values, $this->t('@text', ['@text' => $button_text])); $this->assertSession()->statusCodeEquals(200); } @@ -330,7 +332,8 @@ protected function postTermAddForm($taxomony_id, $values, $button_text) { * Edits a node by posting its edit form. */ protected function postEntityEditForm($entity_url, $values, $button_text) { - $this->drupalPostForm("$entity_url/edit", $values, $this->t('@text', ['@text' => $button_text])); + $this->drupalGet("$entity_url/edit"); + $this->submitForm($values, $this->t('@text', ['@text' => $button_text])); $this->assertSession()->statusCodeEquals(200); } diff --git a/tests/src/Functional/IslandoraImageFormatterTest.php b/tests/src/Functional/IslandoraImageFormatterTest.php index 33f6e1e6b..84ea55173 100644 --- a/tests/src/Functional/IslandoraImageFormatterTest.php +++ b/tests/src/Functional/IslandoraImageFormatterTest.php @@ -92,7 +92,7 @@ public function testIslandoraImageFormatter() { ':title' => 'Some Title', ] ); - $this->assertEqual(count($elements), 1, 'Image linked to content formatter displaying points to Node and not Media.'); + $this->assertEquals(count($elements), 1, 'Image linked to content formatter displaying points to Node and not Media.'); } } diff --git a/tests/src/Functional/IslandoraSettingsFormTest.php b/tests/src/Functional/IslandoraSettingsFormTest.php index 92cfc6a29..80a327af1 100644 --- a/tests/src/Functional/IslandoraSettingsFormTest.php +++ b/tests/src/Functional/IslandoraSettingsFormTest.php @@ -14,7 +14,7 @@ class IslandoraSettingsFormTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); // Create a test user. @@ -36,20 +36,25 @@ public function testJwtExpiry() { $this->assertSession()->statusCodeEquals(200); $this->assertSession()->pageTextContains("JWT Expiry"); $this->assertSession()->fieldValueEquals('edit-jwt-expiry', '+2 hour'); + $this->drupalGet('/admin/config/islandora/core'); // Blank is not allowed. - $this->drupalPostForm('/admin/config/islandora/core', ['edit-jwt-expiry' => ""], $this->t('Save configuration')); + $this->submitForm(['edit-jwt-expiry' => ""], $this->t('Save configuration')); $this->assertSession()->pageTextContainsOnce('"" is not a valid time or interval expression.'); + $this->drupalGet('/admin/config/islandora/core'); // Negative is not allowed. - $this->drupalPostForm('/admin/config/islandora/core', ['edit-jwt-expiry' => "-2 hours"], $this->t('Save configuration')); + $this->submitForm(['edit-jwt-expiry' => "-2 hours"], $this->t('Save configuration')); $this->assertSession()->pageTextContainsOnce('Time or interval expression cannot be negative'); + $this->drupalGet('/admin/config/islandora/core'); // Must include an integer value. - $this->drupalPostForm('/admin/config/islandora/core', ['edit-jwt-expiry' => "last hour"], $this->t('Save configuration')); + $this->submitForm(['edit-jwt-expiry' => "last hour"], $this->t('Save configuration')); $this->assertSession()->pageTextContainsOnce('No numeric interval specified, for example "1 day"'); + $this->drupalGet('/admin/config/islandora/core'); // Must have an accepted interval. - $this->drupalPostForm('/admin/config/islandora/core', ['edit-jwt-expiry' => "1 fortnight"], $this->t('Save configuration')); + $this->submitForm(['edit-jwt-expiry' => "1 fortnight"], $this->t('Save configuration')); $this->assertSession()->pageTextContainsOnce('No time interval found, please include one of'); + $this->drupalGet('/admin/config/islandora/core'); // Test a valid setting. - $this->drupalPostForm('/admin/config/islandora/core', ['edit-jwt-expiry' => "2 weeks"], $this->t('Save configuration')); + $this->submitForm(['edit-jwt-expiry' => "2 weeks"], $this->t('Save configuration')); $this->assertSession()->pageTextContainsOnce('The configuration options have been saved.'); } diff --git a/tests/src/Functional/JsonldSelfReferenceReactionTest.php b/tests/src/Functional/JsonldSelfReferenceReactionTest.php index f3c882718..7ad8f0185 100644 --- a/tests/src/Functional/JsonldSelfReferenceReactionTest.php +++ b/tests/src/Functional/JsonldSelfReferenceReactionTest.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\islandora\Functional; +use function GuzzleHttp\json_decode; /** * Class MappingUriPredicateReactionTest. * @@ -13,7 +14,7 @@ class JsonldSelfReferenceReactionTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); $types = ['schema:Thing']; @@ -61,7 +62,7 @@ public function testMappingReaction() { $contents = $this->drupalGet($url . '?_format=jsonld'); $this->assertSession()->statusCodeEquals(200); - $json = \GuzzleHttp\json_decode($contents, TRUE); + $json = json_decode($contents, TRUE); $this->assertArrayHasKey('http://purl.org/dc/terms/title', $json['@graph'][0], 'Missing dcterms:title key'); $this->assertEquals( @@ -103,7 +104,7 @@ public function testMappingReaction() { drupal_flush_all_caches(); $new_contents = $this->drupalGet($url . '?_format=jsonld'); - $json = \GuzzleHttp\json_decode($new_contents, TRUE); + $json = json_decode($new_contents, TRUE); $this->assertEquals( 'Test Node', $json['@graph'][0]['http://purl.org/dc/terms/title'][0]['@value'], @@ -123,7 +124,7 @@ public function testMappingReaction() { $this->assertSession() ->pageTextContains("The context $context_name has been saved"); $new_contents = $this->drupalGet($url . '?_format=jsonld'); - $json = \GuzzleHttp\json_decode($new_contents, TRUE); + $json = json_decode($new_contents, TRUE); $this->assertEquals( 'Test Node', $json['@graph'][0]['http://purl.org/dc/terms/title'][0]['@value'], @@ -161,7 +162,7 @@ public function testMappingReactionForMedia() { $contents = $this->drupalGet($media_url . '?_format=jsonld'); $this->assertSession()->statusCodeEquals(200); - $json = \GuzzleHttp\json_decode($contents, TRUE); + $json = json_decode($contents, TRUE); $this->assertEquals( "$media_url?_format=jsonld", $json['@graph'][0]['@id'], @@ -186,7 +187,7 @@ public function testMappingReactionForMedia() { drupal_flush_all_caches(); $new_contents = $this->drupalGet($media_url . '?_format=jsonld'); - $json = \GuzzleHttp\json_decode($new_contents, TRUE); + $json = json_decode($new_contents, TRUE); $this->assertEquals( "$media_url?_format=jsonld", $json['@graph'][0]['http://www.iana.org/assignments/relation/describedby'][0]['@id'], diff --git a/tests/src/Functional/JsonldTypeAlterReactionTest.php b/tests/src/Functional/JsonldTypeAlterReactionTest.php index e5d21abc6..58e8bf61b 100644 --- a/tests/src/Functional/JsonldTypeAlterReactionTest.php +++ b/tests/src/Functional/JsonldTypeAlterReactionTest.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\islandora\Functional; +use function GuzzleHttp\json_decode; /** * Tests Jsonld Alter Reaction. * @@ -20,17 +21,18 @@ public function testMappingReaction() { 'administer node fields', ]); $this->drupalLogin($account); + $this->drupalGet('admin/structure/types/manage/test_type/fields/add-field'); // Add the typed predicate we will select in the reaction config. // Taken from FieldUiTestTrait->fieldUIAddNewField. - $this->drupalPostForm('admin/structure/types/manage/test_type/fields/add-field', [ + $this->submitForm([ 'new_storage_type' => 'string', 'label' => 'Typed Predicate', 'field_name' => 'type_predicate', ], $this->t('Save and continue')); - $this->drupalPostForm(NULL, [], $this->t('Save field settings')); - $this->drupalPostForm(NULL, [], $this->t('Save settings')); - $this->assertRaw('field_type_predicate', 'Redirected to "Manage fields" page.'); + $this->submitForm([], $this->t('Save field settings')); + $this->submitForm([], $this->t('Save settings')); + $this->assertSession()->responseContains('field_type_predicate'); // Add the test node. $this->postNodeAddForm('test_type', [ @@ -46,7 +48,7 @@ public function testMappingReaction() { $contents = $this->drupalGet($url . '?_format=jsonld'); $this->assertSession()->statusCodeEquals(200); - $json = \GuzzleHttp\json_decode($contents, TRUE); + $json = json_decode($contents, TRUE); $this->assertArrayHasKey('@type', $json['@graph'][0], 'Missing @type'); $this->assertEquals( @@ -81,7 +83,7 @@ public function testMappingReaction() { // Check for the new @type from the field_type_predicate value. $new_contents = $this->drupalGet($url . '?_format=jsonld'); - $json = \GuzzleHttp\json_decode($new_contents, TRUE); + $json = json_decode($new_contents, TRUE); $this->assertTrue( in_array('http://schema.org/Organization', $json['@graph'][0]['@type']), 'Missing altered @type value of http://schema.org/Organization' diff --git a/tests/src/Functional/LinkHeaderTest.php b/tests/src/Functional/LinkHeaderTest.php index 7cb741d55..98b36c68b 100644 --- a/tests/src/Functional/LinkHeaderTest.php +++ b/tests/src/Functional/LinkHeaderTest.php @@ -42,7 +42,7 @@ class LinkHeaderTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); $account = $this->createUserAndLogin(); diff --git a/tests/src/Functional/MediaSourceUpdateTest.php b/tests/src/Functional/MediaSourceUpdateTest.php index fdea6aef9..3c97c6954 100644 --- a/tests/src/Functional/MediaSourceUpdateTest.php +++ b/tests/src/Functional/MediaSourceUpdateTest.php @@ -35,7 +35,7 @@ class MediaSourceUpdateTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); // Make a user with appropriate permissions. diff --git a/tests/src/Functional/NodeHasTermTest.php b/tests/src/Functional/NodeHasTermTest.php index eff5b5c34..2b4ee16f8 100644 --- a/tests/src/Functional/NodeHasTermTest.php +++ b/tests/src/Functional/NodeHasTermTest.php @@ -13,7 +13,7 @@ class NodeHasTermTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); diff --git a/tests/src/Functional/ViewModeAlterReactionTest.php b/tests/src/Functional/ViewModeAlterReactionTest.php index 72cdfe447..19660bda1 100644 --- a/tests/src/Functional/ViewModeAlterReactionTest.php +++ b/tests/src/Functional/ViewModeAlterReactionTest.php @@ -26,7 +26,7 @@ class ViewModeAlterReactionTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); // Node to be referenced via member of. diff --git a/tests/src/FunctionalJavascript/IntegerWeightTest.php b/tests/src/FunctionalJavascript/IntegerWeightTest.php index ba289aa49..2572c191e 100644 --- a/tests/src/FunctionalJavascript/IntegerWeightTest.php +++ b/tests/src/FunctionalJavascript/IntegerWeightTest.php @@ -80,7 +80,7 @@ class IntegerWeightTest extends WebDriverTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); $this->adminUser = $this->drupalCreateUser( diff --git a/tests/src/Kernel/EventGeneratorTest.php b/tests/src/Kernel/EventGeneratorTest.php index c423cda3f..a9c1f0825 100644 --- a/tests/src/Kernel/EventGeneratorTest.php +++ b/tests/src/Kernel/EventGeneratorTest.php @@ -41,7 +41,7 @@ class EventGeneratorTest extends IslandoraKernelTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); // Create a test user. diff --git a/tests/src/Kernel/FedoraAdapterTest.php b/tests/src/Kernel/FedoraAdapterTest.php index e51610637..d6adecbbd 100644 --- a/tests/src/Kernel/FedoraAdapterTest.php +++ b/tests/src/Kernel/FedoraAdapterTest.php @@ -2,6 +2,9 @@ namespace Drupal\Tests\islandora\Kernel; +use Prophecy\PhpUnit\ProphecyTrait; +use GuzzleHttp\Psr7\Utils; +use function GuzzleHttp\Psr7\stream_for; use Drupal\Core\Logger\LoggerChannelInterface; use Drupal\islandora\Flysystem\Adapter\FedoraAdapter; use GuzzleHttp\Psr7\Response; @@ -18,6 +21,7 @@ */ class FedoraAdapterTest extends IslandoraKernelTestBase { + use ProphecyTrait; /** * A mimetype guesser prophecy. * @@ -35,7 +39,7 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); $this->mimeGuesser = $this->prophesize(MimeTypeGuesserInterface::class) ->reveal(); @@ -58,10 +62,10 @@ protected function createAdapterBase() { $prophecy->getHeader('Content-Type')->willReturn(['text/plain']); $prophecy->getHeader('Content-Length')->willReturn([strlen("DERP")]); // phpcs:disable - if (class_exists(\GuzzleHttp\Psr7\Utils::class)) { - $prophecy->getBody()->willReturn(\GuzzleHttp\Psr7\Utils::streamFor("DERP")); + if (class_exists(Utils::class)) { + $prophecy->getBody()->willReturn(Utils::streamFor("DERP")); } else { - $prophecy->getBody()->willReturn(\GuzzleHttp\Psr7\stream_for("DERP")); + $prophecy->getBody()->willReturn(stream_for("DERP")); } // phpcs:enable return $prophecy; diff --git a/tests/src/Kernel/IslandoraKernelTestBase.php b/tests/src/Kernel/IslandoraKernelTestBase.php index 5a95cb682..1c98db3e9 100644 --- a/tests/src/Kernel/IslandoraKernelTestBase.php +++ b/tests/src/Kernel/IslandoraKernelTestBase.php @@ -12,7 +12,7 @@ abstract class IslandoraKernelTestBase extends KernelTestBase { /** * {@inheritdoc} */ - public static $modules = [ + protected static $modules = [ 'system', 'user', 'field', @@ -43,7 +43,7 @@ abstract class IslandoraKernelTestBase extends KernelTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); // Bootstrap minimal Drupal environment to run the tests. diff --git a/tests/src/Kernel/JwtEventSubscriberTest.php b/tests/src/Kernel/JwtEventSubscriberTest.php index f97eab9fb..9493ab78a 100644 --- a/tests/src/Kernel/JwtEventSubscriberTest.php +++ b/tests/src/Kernel/JwtEventSubscriberTest.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\islandora\Kernel; +use Prophecy\PhpUnit\ProphecyTrait; use Drupal\jwt\Authentication\Event\JwtAuthGenerateEvent; use Drupal\jwt\Authentication\Event\JwtAuthValidEvent; use Drupal\jwt\Authentication\Event\JwtAuthValidateEvent; @@ -19,6 +20,7 @@ */ class JwtEventSubscriberTest extends IslandoraKernelTestBase { + use ProphecyTrait; use UserCreationTrait; /** @@ -31,7 +33,7 @@ class JwtEventSubscriberTest extends IslandoraKernelTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); $this->user = $this->createUser(); From 1bdb7323e3a2212300a5b2c52df1fb103f913ec5 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Fri, 2 Jun 2023 16:30:09 -0300 Subject: [PATCH 084/252] Issue #944: Un-hide arguments field in Text Extraction action. --- .../src/Plugin/Action/GenerateOCRDerivative.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php b/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php index 63a714a80..9d1716225 100644 --- a/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php +++ b/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php @@ -37,11 +37,10 @@ public function defaultConfiguration() { */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { $form = parent::buildConfigurationForm($form, $form_state); - $form['mimetype']['#description'] = $this->t('Mimetype to convert to (e.g. application/xml, etc...)'); - $form['mimetype']['#value'] = 'text/plain'; - $form['mimetype']['#type'] = 'textfield'; + - unset($form['args']); + $form['args']['#description'] = $this->t("Arguments to send to Tesseract. To generate hOCR, use:
    -c tessedit_create_hocr=1 -c hocr_font_info=0"); + return $form; } From 2e1df20b0c23ea6ddc094ccb262aa3635b5367d2 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Tue, 6 Jun 2023 19:58:05 -0300 Subject: [PATCH 085/252] Fix PHPCS errors. --- .../src/Plugin/Action/GenerateOCRDerivative.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php b/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php index 9d1716225..272e9f01b 100644 --- a/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php +++ b/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php @@ -37,10 +37,9 @@ public function defaultConfiguration() { */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { $form = parent::buildConfigurationForm($form, $form_state); - $form['args']['#description'] = $this->t("Arguments to send to Tesseract. To generate hOCR, use:
    -c tessedit_create_hocr=1 -c hocr_font_info=0"); - + return $form; } From c1c0f21cb54d8d671fe0a37dc55785975deca257 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Fri, 9 Jun 2023 16:26:18 -0300 Subject: [PATCH 086/252] Issue #947 Add tokens for Original File filename, extension. --- islandora.tokens.inc | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/islandora.tokens.inc b/islandora.tokens.inc index abbe6474a..f69418afe 100644 --- a/islandora.tokens.inc +++ b/islandora.tokens.inc @@ -19,6 +19,18 @@ function islandora_token_info() { 'name' => t('Islandora Tokens'), 'description' => t('Tokens for Islandora objects.'), ]; + $node['media-original-file:filename'] = [ + 'name' => t('Media: Original File filename without extension.'), + 'description' => t('File name without extension of original uploaded file associated with Islandora Object via Media.'), + ]; + $node['media-original-file:basename'] = [ + 'name' => t('Media: Original File filename with extension.'), + 'description' => t('File name with extension of original uploaded file associated with Islandora Object via Media.'), + ]; + $node['media-original-file:extension'] = [ + 'name' => t('Media: Original File extension.'), + 'description' => t('File extension of original uploaded file associated with Islandora Object via Media.'), + ]; $node['media-thumbnail-image:url'] = [ 'name' => t('Media: Thumbnail Image URL.'), 'description' => t('URL of Thumbnail Image associated with Islandora Object via Media.'), @@ -70,6 +82,23 @@ function islandora_tokens($type, $tokens, array $data, array $options, Bubbleabl $islandoraUtils = \Drupal::service('islandora.utils'); foreach ($tokens as $name => $original) { switch ($name) { + case 'media-original-file:basename': + case 'media-original-file:filename': + case 'media-original-file:extension': + $term = $islandoraUtils->getTermForUri('http://pcdm.org/use#OriginalFile'); + $media = $islandoraUtils->getMediaWithTerm($data['node'], $term); + // Is there media? + if ($media) { + $file = \Drupal::service('islandora.media_source_service')->getSourceFile($media); + if (!empty($file)) { + $path_info = pathinfo($file->createFileUrl()); + $key = explode(':', $name)[1]; + if (array_key_exists($key, $path_info)) { + $replacements[$original] = $path_info[$key]; + } + } + } + break; case 'media-thumbnail-image:url': case 'media_thumbnail_image:url': $term = $islandoraUtils->getTermForUri('http://pcdm.org/use#ThumbnailImage'); From 879dc2091d41a256ea8c73fa459ffa38b70d6a5e Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Tue, 13 Jun 2023 15:12:13 -0300 Subject: [PATCH 087/252] Undo overzealous Rector. --- .github/workflows/build-2.x.yml | 1 - .../install/views.view.all_taxonomy_terms.yml | 1 - .../install/views.view.file_checksum.yml | 1 - .../install/views.view.non_fedora_files.yml | 1 - .../src/Plugin/views/style/IIIFManifest.php | 34 +++++++++++++++++-- .../src/Controller/MediaSourceController.php | 18 ++++++++-- .../AbstractFileSelectionForm.php | 7 +--- .../JsonldSelfReferenceReactionTest.php | 1 + .../JsonldTypeAlterReactionTest.php | 1 + 9 files changed, 50 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index 439395b0a..d05222d9c 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -123,4 +123,3 @@ jobs: run: | cd $DRUPAL_DIR/web/core $DRUPAL_DIR/vendor/bin/phpunit --verbose --testsuite "${{ matrix.test-suite }}" - diff --git a/modules/islandora_core_feature/config/install/views.view.all_taxonomy_terms.yml b/modules/islandora_core_feature/config/install/views.view.all_taxonomy_terms.yml index 56b450669..8c3cb0f3d 100644 --- a/modules/islandora_core_feature/config/install/views.view.all_taxonomy_terms.yml +++ b/modules/islandora_core_feature/config/install/views.view.all_taxonomy_terms.yml @@ -168,4 +168,3 @@ display: - url.query_args - user.permissions tags: { } - diff --git a/modules/islandora_core_feature/config/install/views.view.file_checksum.yml b/modules/islandora_core_feature/config/install/views.view.file_checksum.yml index 2c8191013..e529f21ec 100644 --- a/modules/islandora_core_feature/config/install/views.view.file_checksum.yml +++ b/modules/islandora_core_feature/config/install/views.view.file_checksum.yml @@ -304,4 +304,3 @@ display: - url - user.permissions tags: { } - diff --git a/modules/islandora_core_feature/config/install/views.view.non_fedora_files.yml b/modules/islandora_core_feature/config/install/views.view.non_fedora_files.yml index 88b0f308e..b90494f5d 100644 --- a/modules/islandora_core_feature/config/install/views.view.non_fedora_files.yml +++ b/modules/islandora_core_feature/config/install/views.view.non_fedora_files.yml @@ -194,4 +194,3 @@ display: - url.query_args - user.permissions tags: { } - diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 90945664b..55fe36340 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -4,6 +4,7 @@ use Drupal\views\Plugin\views\style\StylePluginBase; use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\Url; @@ -91,10 +92,17 @@ class IIIFManifest extends StylePluginBase { */ protected $messenger; + /** + * Module Handler for running hooks. + * + * @var \Drupal\Core\Extention\ModuleHandlerInterface + */ + protected $moduleHandler; + /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system, Client $http_client, MessengerInterface $messenger) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system, Client $http_client, MessengerInterface $messenger, ModuleHandlerInterface $moduleHandler) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->serializer = $serializer; @@ -104,6 +112,7 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition $this->fileSystem = $file_system; $this->httpClient = $http_client; $this->messenger = $messenger; + $this->moduleHandler = $moduleHandler; } /** @@ -120,10 +129,21 @@ public static function create(ContainerInterface $container, array $configuratio $container->get('entity_type.manager'), $container->get('file_system'), $container->get('http_client'), - $container->get('messenger') + $container->get('messenger'), + $container->get('module_handler') ); } + /** + * Return the request property. + * + * @return \Symfony\Component\HttpFoundation\Request + * The Symfony request object + */ + public function getRequest() { + return $this->request; + } + /** * {@inheritdoc} */ @@ -170,6 +190,9 @@ public function render() { $content_type = 'json'; + // Give other modules a chance to alter the manifest. + $this->moduleHandler->alter('islandora_iiif_manifest', $json, $this); + return $this->serializer->serialize($json, $content_type, ['views_style_plugin' => $this]); } @@ -288,6 +311,13 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas ]; } + // Give other modules a chance to alter the canvas. + $alter_options = [ + 'options' => $this->options, + 'views_plugin' => $this, + ]; + $this->moduleHandler->alter('islandora_iiif_manifest_canvas', $tmp_canvas, $row, $alter_options); + $canvases[] = $tmp_canvas; } } diff --git a/modules/islandora_text_extraction/src/Controller/MediaSourceController.php b/modules/islandora_text_extraction/src/Controller/MediaSourceController.php index 5518220d1..6b8863084 100644 --- a/modules/islandora_text_extraction/src/Controller/MediaSourceController.php +++ b/modules/islandora_text_extraction/src/Controller/MediaSourceController.php @@ -5,6 +5,7 @@ use Drupal\Core\Controller\ControllerBase; use Drupal\Core\File\FileSystem; use Drupal\Core\File\FileSystemInterface; +use Drupal\file\FileRepository; use Drupal\media\Entity\Media; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; @@ -42,14 +43,24 @@ class MediaSourceController extends ControllerBase { */ protected $fileSystem; + /** + * File repository service. + * + * @var \Drupal\file\FileRepository + */ + protected $fileRepository; + /** * MediaSourceController constructor. * * @param \Drupal\Core\File\FileSystem $fileSystem * Filesystem service. + * @param \Drupal\file\FileRepository $fileRepository + * File Repository service. */ - public function __construct(FileSystem $fileSystem) { + public function __construct(FileSystem $fileSystem, FileRepository $fileRepository) { $this->fileSystem = $fileSystem; + $this->fileRepository = $fileRepository; } /** @@ -63,7 +74,8 @@ public function __construct(FileSystem $fileSystem) { */ public static function create(ContainerInterface $container) { return new static( - $container->get('file_system') + $container->get('file_system'), + $container->get('file.repository'), ); } @@ -98,7 +110,7 @@ public function attachToMedia( if (!$this->fileSystem->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS)) { throw new HttpException(500, "The destination directory does not exist, could not be created, or is not writable"); } - $file = \Drupal::service('file.repository')->writeData($contents, $content_location, FileSystemInterface::EXISTS_REPLACE); + $file = $this->fileRepository->writeData($contents, $content_location, FileSystemInterface::EXISTS_REPLACE); if ($media->hasField($destination_field)) { $media->{$destination_field}->setValue([ 'target_id' => $file->id(), diff --git a/src/Form/AddChildrenWizard/AbstractFileSelectionForm.php b/src/Form/AddChildrenWizard/AbstractFileSelectionForm.php index cf6ef3057..6aeed8795 100644 --- a/src/Form/AddChildrenWizard/AbstractFileSelectionForm.php +++ b/src/Form/AddChildrenWizard/AbstractFileSelectionForm.php @@ -37,11 +37,6 @@ abstract class AbstractFileSelectionForm extends FormBase { * @var \Drupal\islandora\Form\AddChildrenWizard\AbstractBatchProcessor|null */ protected ?AbstractBatchProcessor $batchProcessor; - private \static $static; - public function __construct(\static $static) - { - $this->static = $static; - } /** * {@inheritdoc} @@ -54,7 +49,7 @@ public static function create(ContainerInterface $container): self { $instance->entityFieldManager = $container->get('entity_field.manager'); $instance->currentUser = $container->get('current_user'); - $instance->batchProcessor = $this->static; + $instance->batchProcessor = $container->get(static::BATCH_PROCESSOR); return $instance; } diff --git a/tests/src/Functional/JsonldSelfReferenceReactionTest.php b/tests/src/Functional/JsonldSelfReferenceReactionTest.php index 7ad8f0185..92eca07a8 100644 --- a/tests/src/Functional/JsonldSelfReferenceReactionTest.php +++ b/tests/src/Functional/JsonldSelfReferenceReactionTest.php @@ -3,6 +3,7 @@ namespace Drupal\Tests\islandora\Functional; use function GuzzleHttp\json_decode; + /** * Class MappingUriPredicateReactionTest. * diff --git a/tests/src/Functional/JsonldTypeAlterReactionTest.php b/tests/src/Functional/JsonldTypeAlterReactionTest.php index 58e8bf61b..80a6039c2 100644 --- a/tests/src/Functional/JsonldTypeAlterReactionTest.php +++ b/tests/src/Functional/JsonldTypeAlterReactionTest.php @@ -3,6 +3,7 @@ namespace Drupal\Tests\islandora\Functional; use function GuzzleHttp\json_decode; + /** * Tests Jsonld Alter Reaction. * From aa4d10649baec0b99e1831d549deb54d2dd7abff Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 15 Jun 2023 12:03:22 -0300 Subject: [PATCH 088/252] phpcs --- islandora.tokens.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/islandora.tokens.inc b/islandora.tokens.inc index f69418afe..ab7bb0736 100644 --- a/islandora.tokens.inc +++ b/islandora.tokens.inc @@ -99,6 +99,7 @@ function islandora_tokens($type, $tokens, array $data, array $options, Bubbleabl } } break; + case 'media-thumbnail-image:url': case 'media_thumbnail_image:url': $term = $islandoraUtils->getTermForUri('http://pcdm.org/use#ThumbnailImage'); From 8f5154c24eadd4dd3672133f56fb72a5973e7d76 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Thu, 8 Jun 2023 11:31:13 -0300 Subject: [PATCH 089/252] Issue 944: Pull hOCR from separate media in IIIF manifest. --- .../src/Plugin/views/style/IIIFManifest.php | 190 +++++++++++------- 1 file changed, 115 insertions(+), 75 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 55fe36340..49c35208a 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -2,22 +2,23 @@ namespace Drupal\islandora_iiif\Plugin\views\style; -use Drupal\views\Plugin\views\style\StylePluginBase; +use Drupal\Core\Config\ImmutableConfig; +use Drupal\Core\File\FileSystemInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\Field\FieldItemInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\Url; +use Drupal\islandora\IslandoraUtils; +use Drupal\views\Plugin\views\style\StylePluginBase; use Drupal\views\ResultRow; -use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\Serializer\SerializerInterface; -use Symfony\Component\HttpFoundation\Request; -use Drupal\Core\Config\ImmutableConfig; -use Drupal\Core\File\FileSystemInterface; use GuzzleHttp\Client; use GuzzleHttp\Exception\ClientException; use GuzzleHttp\Exception\ConnectException; use GuzzleHttp\Exception\ServerException; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\Serializer\SerializerInterface; +use Symfony\Component\HttpFoundation\Request; /** * Provide serializer format for IIIF Manifest. @@ -33,6 +34,13 @@ */ class IIIFManifest extends StylePluginBase { +/** + * Islandora utility functions. + * + * @var \Drupal\islandora\IslandoraUtils + */ + protected $utils; + /** * {@inheritdoc} */ @@ -92,17 +100,10 @@ class IIIFManifest extends StylePluginBase { */ protected $messenger; - /** - * Module Handler for running hooks. - * - * @var \Drupal\Core\Extention\ModuleHandlerInterface - */ - protected $moduleHandler; - /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system, Client $http_client, MessengerInterface $messenger, ModuleHandlerInterface $moduleHandler) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system, Client $http_client, MessengerInterface $messenger, IslandoraUtils $utils) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->serializer = $serializer; @@ -112,7 +113,8 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition $this->fileSystem = $file_system; $this->httpClient = $http_client; $this->messenger = $messenger; - $this->moduleHandler = $moduleHandler; + $this->utils = $utils; + } /** @@ -130,20 +132,10 @@ public static function create(ContainerInterface $container, array $configuratio $container->get('file_system'), $container->get('http_client'), $container->get('messenger'), - $container->get('module_handler') + $container->get('islandora.utils') ); } - /** - * Return the request property. - * - * @return \Symfony\Component\HttpFoundation\Request - * The Symfony request object - */ - public function getRequest() { - return $this->request; - } - /** * {@inheritdoc} */ @@ -161,6 +153,11 @@ public function render() { $content_path = implode('/', $url_components); $iiif_base_id = $request_host . '/' . $content_path; + /** + * @var \Drupal\taxonomy\TermInterface|null + */ + $structured_text_term = $this->utils->getTermForUri($this->options['structured_text_term_uri']); + // @see https://iiif.io/api/presentation/2.1/#manifest $json += [ '@type' => 'sc:Manifest', @@ -180,7 +177,7 @@ public function render() { // For each row in the View result. foreach ($this->view->result as $row) { // Add the IIIF URL to the image to print out as JSON. - $canvases = $this->getTileSourceFromRow($row, $iiif_address, $iiif_base_id); + $canvases = $this->getTileSourceFromRow($row, $iiif_address, $iiif_base_id, $structured_text_term); foreach ($canvases as $tile_source) { $json['sequences'][0]['canvases'][] = $tile_source; } @@ -190,9 +187,6 @@ public function render() { $content_type = 'json'; - // Give other modules a chance to alter the manifest. - $this->moduleHandler->alter('islandora_iiif_manifest', $json, $this); - return $this->serializer->serialize($json, $content_type, ['views_style_plugin' => $this]); } @@ -206,18 +200,41 @@ public function render() { * @param string $iiif_base_id * The URL for the request, minus the last part of the URL, * which is likely "manifest". + * @param \Drupal\taxonomy\TermInterface|null $structured_text_term + * The term that structured text media references, if any. * * @return array * List of IIIF URLs to display in the Openseadragon viewer. */ - protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_base_id) { + protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_base_id, $structured_text_term) { $canvases = []; foreach (array_filter(array_values($this->options['iiif_tile_field'])) as $iiif_tile_field) { $viewsField = $this->view->field[$iiif_tile_field]; $iiif_ocr_file_field = !empty($this->options['iiif_ocr_file_field']) ? array_filter(array_values($this->options['iiif_ocr_file_field'])) : []; + $ocrField = count($iiif_ocr_file_field) > 0 ? $this->view->field[$iiif_ocr_file_field[0]] : NULL; $entity = $viewsField->getEntity($row); + if ($ocrField) { + $ocr_entity = $entity; + $ocr_field_name = $ocrField->definition['field_name']; + if (!is_null($ocrField_name)) { + $ocrs = $ocr_entity->{$ocr_field_name}; + $ocr = isset($ocrs[$i]) ? $ocrs[$i] : FALSE; + $ocr_url = $ocr->entity->createFileUrl(FALSE); + } + } + else if ($structured_text_term) { + $parent_node = $this->utils->getParentNode($entity); + $ocr_entity_array = $this->utils->getMediaReferencingNodeAndTerm($parent_node, $structured_text_term); + $ocr_entity_id = is_array($ocr_entity_array) ? array_shift($ocr_entity_array) : NULL; + $ocr_entity = $ocr_entity_id ? $this->entityTypeManager->getStorage('media')->load($ocr_entity_id) : NULL; + $ocr_file_source = $ocr_entity ? $ocr_entity->getSource() : NULL; + $ocr_fid = $ocr_file_source->getSourceFieldValue($ocr_entity); + $ocr_file = $this->entityTypeManager->getStorage('file')->load($ocr_fid); + $ocr_url = $ocr_file->createFileUrl(FALSE); + } + if (isset($entity->{$viewsField->definition['field_name']})) { /** @var \Drupal\Core\Field\FieldItemListInterface $images */ @@ -228,11 +245,6 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas continue; } - if (!is_null($ocrField)) { - $ocrs = $entity->{$ocrField->definition['field_name']}; - $ocr = isset($ocrs[$i]) ? $ocrs[$i] : FALSE; - } - // Create the IIIF URL for this file // Visiting $iiif_url will resolve to the info.json for the image. $file_url = $image->entity->createFileUrl(FALSE); @@ -243,35 +255,8 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas $canvas_id = $iiif_base_id . '/canvas/' . $entity->id(); $annotation_id = $iiif_base_id . '/annotation/' . $entity->id(); - // Try to fetch the IIIF metadata for the image. - try { - $info_json = $this->httpClient->get($iiif_url)->getBody(); - $resource = json_decode($info_json, TRUE); - $width = $resource['width']; - $height = $resource['height']; - } - catch (ClientException | ServerException | ConnectException $e) { - // If we couldn't get the info.json from IIIF - // try seeing if we can get it from Drupal. - if (empty($width) || empty($height)) { - // Get the image properties so we know the image width/height. - $properties = $image->getProperties(); - $width = isset($properties['width']) ? $properties['width'] : 0; - $height = isset($properties['height']) ? $properties['height'] : 0; - - // If this is a TIFF AND we don't know the width/height - // see if we can get the image size via PHP's core function. - if ($mime_type === 'image/tiff' && !$width || !$height) { - $uri = $image->entity->getFileUri(); - $path = $this->fileSystem->realpath($uri); - $image_size = getimagesize($path); - if ($image_size) { - $width = $image_size[0]; - $height = $image_size[1]; - } - } - } - } + [$width, $height] = $this->getCanvasDimensions($iiif_url, $image, $mime_type); + $tmp_canvas = [ // @see https://iiif.io/api/presentation/2.1/#canvas '@id' => $canvas_id, @@ -302,22 +287,15 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas ], ]; - if (isset($ocr) && $ocr != FALSE) { + if ($ocr_url) { $tmp_canvas['seeAlso'] = [ - '@id' => $ocr->entity->createFileUrl(FALSE), + '@id' => $ocr_url, 'format' => 'text/vnd.hocr+html', 'profile' => 'http://kba.cloud/hocr-spec', 'label' => 'hOCR embedded text', ]; } - // Give other modules a chance to alter the canvas. - $alter_options = [ - 'options' => $this->options, - 'views_plugin' => $this, - ]; - $this->moduleHandler->alter('islandora_iiif_manifest_canvas', $tmp_canvas, $row, $alter_options); - $canvases[] = $tmp_canvas; } } @@ -326,6 +304,50 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas return $canvases; } + /** + * Try to fetch the IIIF metadata for the image. + * + * @param string $iiif_url + * Base URL of the canvas + * @param FieldItemInterface $image + * The image field. + * @param string $mime_type + * The mime type of the image. + * @return [string] + * The width and height of the image. + */ + protected function getCanvasDimensions(string $iiif_url, FieldItemInterface $image, string $mime_type) { + try { + $info_json = $this->httpClient->get($iiif_url)->getBody(); + $resource = json_decode($info_json, TRUE); + $width = $resource['width']; + $height = $resource['height']; + } + catch (ClientException | ServerException | ConnectException $e) { + // If we couldn't get the info.json from IIIF + // try seeing if we can get it from Drupal. + if (empty($width) || empty($height)) { + // Get the image properties so we know the image width/height. + $properties = $image->getProperties(); + $width = isset($properties['width']) ? $properties['width'] : 0; + $height = isset($properties['height']) ? $properties['height'] : 0; + + // If this is a TIFF AND we don't know the width/height + // see if we can get the image size via PHP's core function. + if ($mime_type === 'image/tiff' && !$width || !$height) { + $uri = $image->entity->getFileUri(); + $path = $this->fileSystem->realpath($uri); + $image_size = getimagesize($path); + if ($image_size) { + $width = $image_size[0]; + $height = $image_size[1]; + } + } + } + } + return [$width, $height]; + } + /** * Pull a title from the node or media passed to this view. * @@ -426,6 +448,15 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { '#options' => $field_options, '#required' => FALSE, ]; + $form['structured_text_term'] = [ + '#type' => 'entity_autocomplete', + '#target_type' => 'taxonomy_term', + '#title' => $this->t('Structured text term'), + '#default_value' => $this->utils->getTermForUri($this->options['structured_text_term_uri']), + '#required' => FALSE, + '#description' => $this->t('Term indicating the media that holds structured text, such as hOCR, for the given object.'), + ]; + } /** @@ -436,6 +467,15 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { */ public function getFormats() { return ['json' => 'json']; + } + + public function submitOptionsForm(&$form, FormStateInterface $form_state) { + $style_options = $form_state->getValue('style_options'); + $tid = $style_options['structured_text_term']; + $term = $this->entityTypeManager->getStorage('taxonomy_term')->load($tid); + $style_options['structured_text_term_uri'] = $this->utils->getUriForTerm($term); + $form_state->setValue('style_options', $style_options); + parent::submitOptionsForm($form, $form_state); } } From 2307dc6936aa259c0676895cb254d04ee2847008 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Thu, 8 Jun 2023 12:30:21 -0300 Subject: [PATCH 090/252] Refactor IIIF Manifest Views Style plugin. --- .../src/Plugin/views/style/IIIFManifest.php | 70 ++++++++++++------- 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 49c35208a..9fde1ed74 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -3,8 +3,9 @@ namespace Drupal\islandora_iiif\Plugin\views\style; use Drupal\Core\Config\ImmutableConfig; -use Drupal\Core\File\FileSystemInterface; +use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\File\FileSystemInterface; use Drupal\Core\Field\FieldItemInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\MessengerInterface; @@ -210,33 +211,9 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas $canvases = []; foreach (array_filter(array_values($this->options['iiif_tile_field'])) as $iiif_tile_field) { $viewsField = $this->view->field[$iiif_tile_field]; - $iiif_ocr_file_field = !empty($this->options['iiif_ocr_file_field']) ? array_filter(array_values($this->options['iiif_ocr_file_field'])) : []; - - $ocrField = count($iiif_ocr_file_field) > 0 ? $this->view->field[$iiif_ocr_file_field[0]] : NULL; $entity = $viewsField->getEntity($row); - if ($ocrField) { - $ocr_entity = $entity; - $ocr_field_name = $ocrField->definition['field_name']; - if (!is_null($ocrField_name)) { - $ocrs = $ocr_entity->{$ocr_field_name}; - $ocr = isset($ocrs[$i]) ? $ocrs[$i] : FALSE; - $ocr_url = $ocr->entity->createFileUrl(FALSE); - } - } - else if ($structured_text_term) { - $parent_node = $this->utils->getParentNode($entity); - $ocr_entity_array = $this->utils->getMediaReferencingNodeAndTerm($parent_node, $structured_text_term); - $ocr_entity_id = is_array($ocr_entity_array) ? array_shift($ocr_entity_array) : NULL; - $ocr_entity = $ocr_entity_id ? $this->entityTypeManager->getStorage('media')->load($ocr_entity_id) : NULL; - $ocr_file_source = $ocr_entity ? $ocr_entity->getSource() : NULL; - $ocr_fid = $ocr_file_source->getSourceFieldValue($ocr_entity); - $ocr_file = $this->entityTypeManager->getStorage('file')->load($ocr_fid); - $ocr_url = $ocr_file->createFileUrl(FALSE); - } - if (isset($entity->{$viewsField->definition['field_name']})) { - /** @var \Drupal\Core\Field\FieldItemListInterface $images */ $images = $entity->{$viewsField->definition['field_name']}; foreach ($images as $i => $image) { @@ -287,7 +264,7 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas ], ]; - if ($ocr_url) { + if ($ocr_url = $this->getOcrUrl($entity, $structured_text_term)) { $tmp_canvas['seeAlso'] = [ '@id' => $ocr_url, 'format' => 'text/vnd.hocr+html', @@ -348,6 +325,47 @@ protected function getCanvasDimensions(string $iiif_url, FieldItemInterface $ima return [$width, $height]; } + /** + * Retrieves a URL text with positional data such as hOCR + * + * @param EntityInterface $entity + * The entity at the current row. + * @param \Drupal\taxonomy\TermInterface|null $structured_text_term + * The term that structured text media references, if any. + + * return String|FALSE + * The absolute URL of the current row's structured text, + * or FALSE if none. + */ + protected function getOcrUrl(EntityInterface $entity, $structured_text_term) { + $ocr_url = FALSE; + $iiif_ocr_file_field = !empty($this->options['iiif_ocr_file_field']) ? array_filter(array_values($this->options['iiif_ocr_file_field'])) : []; + $ocrField = count($iiif_ocr_file_field) > 0 ? $this->view->field[$iiif_ocr_file_field[0]] : NULL; + if ($ocrField) { + $ocr_entity = $entity; + $ocr_field_name = $ocrField->definition['field_name']; + if (!is_null($ocrField_name)) { + $ocrs = $ocr_entity->{$ocr_field_name}; + $ocr = isset($ocrs[$i]) ? $ocrs[$i] : FALSE; + $ocr_url = $ocr->entity->createFileUrl(FALSE); + } + } + else if ($structured_text_term) { + $parent_node = $this->utils->getParentNode($entity); + $ocr_entity_array = $this->utils->getMediaReferencingNodeAndTerm($parent_node, $structured_text_term); + $ocr_entity_id = is_array($ocr_entity_array) ? array_shift($ocr_entity_array) : NULL; + $ocr_entity = $ocr_entity_id ? $this->entityTypeManager->getStorage('media')->load($ocr_entity_id) : NULL; + if ($ocr_entity) { + $ocr_file_source = $ocr_entity->getSource(); + $ocr_fid = $ocr_file_source->getSourceFieldValue($ocr_entity); + $ocr_file = $this->entityTypeManager->getStorage('file')->load($ocr_fid); + $ocr_url = $ocr_file->createFileUrl(FALSE); + } + } + + return $ocr_url; + } + /** * Pull a title from the node or media passed to this view. * From cf7b09f097bf06622709b64b1a98a2c27c716ecc Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Mon, 12 Jun 2023 20:11:14 -0300 Subject: [PATCH 091/252] Update Islandora IIIF README. --- modules/islandora_iiif/README.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/islandora_iiif/README.md b/modules/islandora_iiif/README.md index ab06524be..a5cfc3b0e 100644 --- a/modules/islandora_iiif/README.md +++ b/modules/islandora_iiif/README.md @@ -1,4 +1,4 @@ -# Islandora IIIF +# Islandora IIIF [![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.2-8892BF.svg?style=flat-square)](https://php.net/) [![Contribution Guidelines](http://img.shields.io/badge/CONTRIBUTING-Guidelines-blue.svg)](./CONTRIBUTING.md) @@ -11,7 +11,7 @@ Provides IIIF manifests using views. ## Requirements - `islandora` and `islandora_core_feature` -- A IIIF image server (such as Cantaloupe) +- A IIIF image server (such as Cantaloupe) ## Installation @@ -32,6 +32,14 @@ You can set the following configuration at `admin/config/islandora/iiif`: - IIIF Image server location - The URL to your IIIF image server (without trailing slash). +### Views Style Plugin + +This module implements a Views Style plugin. It provides the following settings: + +1. Tile Source: A field that was added to the views list of fields with the image to be served. This should be a File or Image type field on a Media. +2. Structured Text field: This lets you specify a file field on the same entity as above where OCR text with positional data, e.g., hOCR can be found. +3. Structured Text term: The Islandora term with a Media Use URI where the structured OCR text can be found. This is another option to the above for storing this data in a separate media related to the parent node, rather than on the same media. + ## Documentation Official documentation is available on the [Islandora 8 documentation site](https://islandora.github.io/documentation/). From e1fde43e21408f5da92d2f2112b90355b6798ca0 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Mon, 12 Jun 2023 21:13:00 -0300 Subject: [PATCH 092/252] Address PHPCS errors. --- .../src/Plugin/views/style/IIIFManifest.php | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 9fde1ed74..7bbe03dd3 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -35,7 +35,7 @@ */ class IIIFManifest extends StylePluginBase { -/** + /** * Islandora utility functions. * * @var \Drupal\islandora\IslandoraUtils @@ -233,7 +233,7 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas $annotation_id = $iiif_base_id . '/annotation/' . $entity->id(); [$width, $height] = $this->getCanvasDimensions($iiif_url, $image, $mime_type); - + $tmp_canvas = [ // @see https://iiif.io/api/presentation/2.1/#canvas '@id' => $canvas_id, @@ -283,13 +283,14 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas /** * Try to fetch the IIIF metadata for the image. - * + * * @param string $iiif_url - * Base URL of the canvas - * @param FieldItemInterface $image + * Base URL of the canvas. + * @param \Drupal\Core\Field\FieldItemInterface $image * The image field. * @param string $mime_type * The mime type of the image. + * * @return [string] * The width and height of the image. */ @@ -326,16 +327,16 @@ protected function getCanvasDimensions(string $iiif_url, FieldItemInterface $ima } /** - * Retrieves a URL text with positional data such as hOCR - * - * @param EntityInterface $entity + * Retrieves a URL text with positional data such as hOCR. + * + * @param \Drupal\Core\Entity\EntityInterface $entity * The entity at the current row. * @param \Drupal\taxonomy\TermInterface|null $structured_text_term * The term that structured text media references, if any. - + * * return String|FALSE - * The absolute URL of the current row's structured text, - * or FALSE if none. + * The absolute URL of the current row's structured text, + * or FALSE if none. */ protected function getOcrUrl(EntityInterface $entity, $structured_text_term) { $ocr_url = FALSE; @@ -350,7 +351,7 @@ protected function getOcrUrl(EntityInterface $entity, $structured_text_term) { $ocr_url = $ocr->entity->createFileUrl(FALSE); } } - else if ($structured_text_term) { + elseif ($structured_text_term) { $parent_node = $this->utils->getParentNode($entity); $ocr_entity_array = $this->utils->getMediaReferencingNodeAndTerm($parent_node, $structured_text_term); $ocr_entity_id = is_array($ocr_entity_array) ? array_shift($ocr_entity_array) : NULL; @@ -485,8 +486,19 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { */ public function getFormats() { return ['json' => 'json']; - } + } + /** + * Submit handler for options form. + * Used to store the structured text media term by URL instead of Ttid. + * + * @param array $form + * The form. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The form state object. + * + * @return void + */ public function submitOptionsForm(&$form, FormStateInterface $form_state) { $style_options = $form_state->getValue('style_options'); $tid = $style_options['structured_text_term']; From 4ca6a0c88af26357a7125e4cc75809c55a00070e Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Tue, 13 Jun 2023 22:10:12 -0300 Subject: [PATCH 093/252] Remove term-based hOCR configuration since we can just use Views. --- modules/islandora_iiif/README.md | 4 +- .../src/Plugin/views/style/IIIFManifest.php | 69 +++---------------- 2 files changed, 11 insertions(+), 62 deletions(-) diff --git a/modules/islandora_iiif/README.md b/modules/islandora_iiif/README.md index a5cfc3b0e..c1f89872c 100644 --- a/modules/islandora_iiif/README.md +++ b/modules/islandora_iiif/README.md @@ -37,9 +37,7 @@ You can set the following configuration at `admin/config/islandora/iiif`: This module implements a Views Style plugin. It provides the following settings: 1. Tile Source: A field that was added to the views list of fields with the image to be served. This should be a File or Image type field on a Media. -2. Structured Text field: This lets you specify a file field on the same entity as above where OCR text with positional data, e.g., hOCR can be found. -3. Structured Text term: The Islandora term with a Media Use URI where the structured OCR text can be found. This is another option to the above for storing this data in a separate media related to the parent node, rather than on the same media. - +2. Structured Text field: This lets you specify a file field where OCR text with positional data, e.g., hOCR can be found. ## Documentation Official documentation is available on the [Islandora 8 documentation site](https://islandora.github.io/documentation/). diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 7bbe03dd3..a745e1f7f 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -154,11 +154,6 @@ public function render() { $content_path = implode('/', $url_components); $iiif_base_id = $request_host . '/' . $content_path; - /** - * @var \Drupal\taxonomy\TermInterface|null - */ - $structured_text_term = $this->utils->getTermForUri($this->options['structured_text_term_uri']); - // @see https://iiif.io/api/presentation/2.1/#manifest $json += [ '@type' => 'sc:Manifest', @@ -178,7 +173,7 @@ public function render() { // For each row in the View result. foreach ($this->view->result as $row) { // Add the IIIF URL to the image to print out as JSON. - $canvases = $this->getTileSourceFromRow($row, $iiif_address, $iiif_base_id, $structured_text_term); + $canvases = $this->getTileSourceFromRow($row, $iiif_address, $iiif_base_id); foreach ($canvases as $tile_source) { $json['sequences'][0]['canvases'][] = $tile_source; } @@ -201,13 +196,11 @@ public function render() { * @param string $iiif_base_id * The URL for the request, minus the last part of the URL, * which is likely "manifest". - * @param \Drupal\taxonomy\TermInterface|null $structured_text_term - * The term that structured text media references, if any. * * @return array * List of IIIF URLs to display in the Openseadragon viewer. */ - protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_base_id, $structured_text_term) { + protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_base_id) { $canvases = []; foreach (array_filter(array_values($this->options['iiif_tile_field'])) as $iiif_tile_field) { $viewsField = $this->view->field[$iiif_tile_field]; @@ -264,7 +257,7 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas ], ]; - if ($ocr_url = $this->getOcrUrl($entity, $structured_text_term)) { + if ($ocr_url = $this->getOcrUrl($entity, $row, $i)) { $tmp_canvas['seeAlso'] = [ '@id' => $ocr_url, 'format' => 'text/vnd.hocr+html', @@ -331,36 +324,24 @@ protected function getCanvasDimensions(string $iiif_url, FieldItemInterface $ima * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity at the current row. - * @param \Drupal\taxonomy\TermInterface|null $structured_text_term - * The term that structured text media references, if any. * * return String|FALSE * The absolute URL of the current row's structured text, * or FALSE if none. */ - protected function getOcrUrl(EntityInterface $entity, $structured_text_term) { + protected function getOcrUrl(EntityInterface $entity, $row, $delta) { $ocr_url = FALSE; $iiif_ocr_file_field = !empty($this->options['iiif_ocr_file_field']) ? array_filter(array_values($this->options['iiif_ocr_file_field'])) : []; $ocrField = count($iiif_ocr_file_field) > 0 ? $this->view->field[$iiif_ocr_file_field[0]] : NULL; if ($ocrField) { - $ocr_entity = $entity; + $ocr_entity = $ocrField->getEntity($row); $ocr_field_name = $ocrField->definition['field_name']; - if (!is_null($ocrField_name)) { + if (!is_null($ocr_field_name)) { $ocrs = $ocr_entity->{$ocr_field_name}; - $ocr = isset($ocrs[$i]) ? $ocrs[$i] : FALSE; - $ocr_url = $ocr->entity->createFileUrl(FALSE); - } - } - elseif ($structured_text_term) { - $parent_node = $this->utils->getParentNode($entity); - $ocr_entity_array = $this->utils->getMediaReferencingNodeAndTerm($parent_node, $structured_text_term); - $ocr_entity_id = is_array($ocr_entity_array) ? array_shift($ocr_entity_array) : NULL; - $ocr_entity = $ocr_entity_id ? $this->entityTypeManager->getStorage('media')->load($ocr_entity_id) : NULL; - if ($ocr_entity) { - $ocr_file_source = $ocr_entity->getSource(); - $ocr_fid = $ocr_file_source->getSourceFieldValue($ocr_entity); - $ocr_file = $this->entityTypeManager->getStorage('file')->load($ocr_fid); - $ocr_url = $ocr_file->createFileUrl(FALSE); + $ocr = isset($ocrs[$delta]) ? $ocrs[$delta] : FALSE; + if ($ocr) { + $ocr_url = $ocr->entity->createFileUrl(FALSE); + } } } @@ -467,15 +448,6 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { '#options' => $field_options, '#required' => FALSE, ]; - $form['structured_text_term'] = [ - '#type' => 'entity_autocomplete', - '#target_type' => 'taxonomy_term', - '#title' => $this->t('Structured text term'), - '#default_value' => $this->utils->getTermForUri($this->options['structured_text_term_uri']), - '#required' => FALSE, - '#description' => $this->t('Term indicating the media that holds structured text, such as hOCR, for the given object.'), - ]; - } /** @@ -487,25 +459,4 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { public function getFormats() { return ['json' => 'json']; } - - /** - * Submit handler for options form. - * Used to store the structured text media term by URL instead of Ttid. - * - * @param array $form - * The form. - * @param \Drupal\Core\Form\FormStateInterface $form_state - * The form state object. - * - * @return void - */ - public function submitOptionsForm(&$form, FormStateInterface $form_state) { - $style_options = $form_state->getValue('style_options'); - $tid = $style_options['structured_text_term']; - $term = $this->entityTypeManager->getStorage('taxonomy_term')->load($tid); - $style_options['structured_text_term_uri'] = $this->utils->getUriForTerm($term); - $form_state->setValue('style_options', $style_options); - parent::submitOptionsForm($form, $form_state); - } - } From 97f3b2daf1de975db714a8019ffdc81e348c8aae Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Tue, 13 Jun 2023 22:38:45 -0300 Subject: [PATCH 094/252] Fix PHPCS errors. --- .../islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index a745e1f7f..8527067d7 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -324,8 +324,10 @@ protected function getCanvasDimensions(string $iiif_url, FieldItemInterface $ima * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity at the current row. + * @param int $delta + *. The delta in case there are multiple canvases on one media. * - * return String|FALSE + * @return String|FALSE * The absolute URL of the current row's structured text, * or FALSE if none. */ @@ -459,4 +461,5 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { public function getFormats() { return ['json' => 'json']; } + } From 30296b45662a279af8a52be0dbfc3fd6093048cc Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Tue, 13 Jun 2023 22:57:51 -0300 Subject: [PATCH 095/252] Fix PHPCS errors. --- .../src/Plugin/views/style/IIIFManifest.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 8527067d7..2dfce9798 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -324,14 +324,15 @@ protected function getCanvasDimensions(string $iiif_url, FieldItemInterface $ima * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity at the current row. - * @param int $delta - *. The delta in case there are multiple canvases on one media. - * - * @return String|FALSE + * @param \Drupal\views\ResultRow $row + * Result row. * @param int $delta + * The delta in case there are multiple canvases on one media. + * + * @return string|false * The absolute URL of the current row's structured text, * or FALSE if none. */ - protected function getOcrUrl(EntityInterface $entity, $row, $delta) { + protected function getOcrUrl(EntityInterface $entity, ResultRow $row, $delta) { $ocr_url = FALSE; $iiif_ocr_file_field = !empty($this->options['iiif_ocr_file_field']) ? array_filter(array_values($this->options['iiif_ocr_file_field'])) : []; $ocrField = count($iiif_ocr_file_field) > 0 ? $this->view->field[$iiif_ocr_file_field[0]] : NULL; From 6fe405ee931e138b703a646ad44511445b92fe87 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Wed, 14 Jun 2023 09:06:19 -0300 Subject: [PATCH 096/252] Fix PHPCS errors. --- .../islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 2dfce9798..e52f59f9a 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -324,8 +324,9 @@ protected function getCanvasDimensions(string $iiif_url, FieldItemInterface $ima * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity at the current row. - * @param \Drupal\views\ResultRow $row - * Result row. * @param int $delta + * @param \Drupal\views\ResultRow $row + * Result row. + * @param int $delta * The delta in case there are multiple canvases on one media. * * @return string|false From da3311825c718ba56d03da157b5b6d8bbd55fb13 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Thu, 15 Jun 2023 08:56:20 -0300 Subject: [PATCH 097/252] Remove Islandora Utils from Islandora IIIF. --- .../src/Plugin/views/style/IIIFManifest.php | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index e52f59f9a..63f015d1c 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -10,7 +10,6 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\Url; -use Drupal\islandora\IslandoraUtils; use Drupal\views\Plugin\views\style\StylePluginBase; use Drupal\views\ResultRow; use GuzzleHttp\Client; @@ -35,13 +34,6 @@ */ class IIIFManifest extends StylePluginBase { - /** - * Islandora utility functions. - * - * @var \Drupal\islandora\IslandoraUtils - */ - protected $utils; - /** * {@inheritdoc} */ @@ -104,7 +96,7 @@ class IIIFManifest extends StylePluginBase { /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system, Client $http_client, MessengerInterface $messenger, IslandoraUtils $utils) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system, Client $http_client, MessengerInterface $messenger) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->serializer = $serializer; @@ -114,8 +106,6 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition $this->fileSystem = $file_system; $this->httpClient = $http_client; $this->messenger = $messenger; - $this->utils = $utils; - } /** @@ -132,8 +122,7 @@ public static function create(ContainerInterface $container, array $configuratio $container->get('entity_type.manager'), $container->get('file_system'), $container->get('http_client'), - $container->get('messenger'), - $container->get('islandora.utils') + $container->get('messenger') ); } From cc5b5f838ddd2df4a9dee1c75c67245b60e28da9 Mon Sep 17 00:00:00 2001 From: Seth Shaw <108362375+seth-shaw-asu@users.noreply.github.com> Date: Mon, 19 Jun 2023 09:49:41 -0700 Subject: [PATCH 098/252] bump jwt version (#952) --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 3ceed0e11..bf274cd1d 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "drupal/file_replace": "^1.1", "drupal/filehash": "^2", "drupal/flysystem" : "^2.0@alpha", - "drupal/jwt": "^1.1", + "drupal/jwt": "^1.1 || ^2", "drupal/migrate_plus" : "^5.1 || ^6", "drupal/migrate_source_csv" : "^3.4", "drupal/prepopulate" : "^2.2", From b3f2c006b1c76bf43aacb2d64001d52f5857a566 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 22 Jun 2023 16:02:25 -0300 Subject: [PATCH 099/252] Typo prevented submodule functional tests from running. --- .github/workflows/build-2.x.yml | 2 +- phpunit.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index d05222d9c..261ab1dec 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -28,7 +28,7 @@ jobs: # test-suite functional-javascript will appear to pass but will skip tests; missing chromedriver. test-suite: ["kernel", "functional", "functional-javascript"] # Not yet Drupal 10 ready - see https://github.com/Islandora/islandora/issues/888 - drupal-version: ["9.3.x", "9.4.x", "9.5.x-dev"] + drupal-version: ["9.4.x", "9.5.x-dev"] mysql: ["8.0"] allowed_failure: [false] diff --git a/phpunit.xml b/phpunit.xml index a40917813..46e82e78d 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -58,7 +58,7 @@ ../modules/contrib/islandora/tests/src/Functional - ../modules/contrib/isladnora/modules/*/tests/src/Functional + ../modules/contrib/islandora/modules/*/tests/src/Functional ../modules/contrib/islandora/tests/src/FunctionalJavascript From 1f09439e1e18308a4babad67acefdaf1801fba05 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Fri, 23 Jun 2023 15:01:43 -0300 Subject: [PATCH 100/252] Test: Breadcrumbs config dependencies missing schema. --- .../config/install/islandora_breadcrumbs.breadcrumbs.yml | 6 ------ .../islandora_breadcrumbs/islandora_breadcrumbs.info.yml | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/modules/islandora_breadcrumbs/config/install/islandora_breadcrumbs.breadcrumbs.yml b/modules/islandora_breadcrumbs/config/install/islandora_breadcrumbs.breadcrumbs.yml index ea34ee2ed..aabb58916 100644 --- a/modules/islandora_breadcrumbs/config/install/islandora_breadcrumbs.breadcrumbs.yml +++ b/modules/islandora_breadcrumbs/config/install/islandora_breadcrumbs.breadcrumbs.yml @@ -2,9 +2,3 @@ maxDepth: -1 includeSelf: FALSE referenceFields: - field_member_of -dependencies: - module: - - islandora - enforced: - module: - - islandora_breadcrumbs diff --git a/modules/islandora_breadcrumbs/islandora_breadcrumbs.info.yml b/modules/islandora_breadcrumbs/islandora_breadcrumbs.info.yml index 56a10bc14..c76020cb6 100644 --- a/modules/islandora_breadcrumbs/islandora_breadcrumbs.info.yml +++ b/modules/islandora_breadcrumbs/islandora_breadcrumbs.info.yml @@ -5,4 +5,4 @@ core: 8.x core_version_requirement: ^8 || ^9 package: Islandora dependencies: - - drupal:islandora + - islandora:islandora From 8ee4fb5aff95b74ee8920dbb0b8d7fcbb4141657 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Fri, 23 Jun 2023 15:24:29 -0300 Subject: [PATCH 101/252] Inject fileUrlGenerator into Image Field formatter. --- .../Field/FieldFormatter/IslandoraImageFormatter.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Plugin/Field/FieldFormatter/IslandoraImageFormatter.php b/src/Plugin/Field/FieldFormatter/IslandoraImageFormatter.php index 6c6e87da4..6667f4f4a 100644 --- a/src/Plugin/Field/FieldFormatter/IslandoraImageFormatter.php +++ b/src/Plugin/Field/FieldFormatter/IslandoraImageFormatter.php @@ -5,6 +5,7 @@ use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldItemListInterface; +use Drupal\Core\File\FileUrlGenerator; use Drupal\Core\Session\AccountInterface; use Drupal\image\Plugin\Field\FieldFormatter\ImageFormatter; use Drupal\islandora\IslandoraUtils; @@ -56,6 +57,8 @@ class IslandoraImageFormatter extends ImageFormatter { * The image style storage. * @param \Drupal\islandora\IslandoraUtils $utils * Islandora utils. + * @param \Drupal\Core\File\FileUrlGenerator $file_url_generator + * The File URL Generator. */ public function __construct( $plugin_id, @@ -67,7 +70,8 @@ public function __construct( array $third_party_settings, AccountInterface $current_user, EntityStorageInterface $image_style_storage, - IslandoraUtils $utils + IslandoraUtils $utils, + FileUrlGenerator $file_url_generator ) { parent::__construct( $plugin_id, @@ -78,7 +82,8 @@ public function __construct( $view_mode, $third_party_settings, $current_user, - $image_style_storage + $image_style_storage, + $file_url_generator ); $this->utils = $utils; } @@ -97,7 +102,8 @@ public static function create(ContainerInterface $container, array $configuratio $configuration['third_party_settings'], $container->get('current_user'), $container->get('entity_type.manager')->getStorage('image_style'), - $container->get('islandora.utils') + $container->get('islandora.utils'), + $container->get('file_url_generator') ); } From 41e4dc6ffff3d8e7a0ef8b4037cbffe15dc32bab Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Fri, 23 Jun 2023 16:39:34 -0300 Subject: [PATCH 102/252] Tests were not finding the media use field. --- .../tests/src/Functional/GenerateAudioDerivativeTest.php | 2 +- .../tests/src/Functional/GenerateImageDerivativeTest.php | 2 +- .../tests/src/Functional/GenerateVideoDerivativeTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php index 766ceac0a..b528e8ba7 100644 --- a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php +++ b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php @@ -66,7 +66,7 @@ public function testGenerateAudioDerivativeFromScratch() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', - 'field_tags[0][target_id]' => 'Preservation Master', + 'field_media_use[0][target_id]' => 'foo', # change back to $this->preservationMasterTerm->label() ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); $this->submitForm($values, $this->t('Save')); diff --git a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php index 295eae913..69672e0b7 100644 --- a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php +++ b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php @@ -68,7 +68,7 @@ public function testGenerateImageDerivativeFromScratch() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', - 'field_tags[0][target_id]' => 'Preservation Master', + 'field_media_use[0][target_id]' => 'foo', # change back to $this->preservationMasterTerm->label() ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); $this->submitForm($values, $this->t('Save')); diff --git a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php index 17e8bd5b5..f712e3490 100644 --- a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php +++ b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php @@ -63,7 +63,7 @@ public function testGenerateVideoDerivativeFromScratch() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', - 'field_tags[0][target_id]' => 'Preservation Master', + 'field_media_use[0][target_id]' => 'foo', # change back to $this->preservationMasterTerm->label() ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); $this->submitForm($values, $this->t('Save')); From 54116efbab00aef408fee36e1f0a8848f8a8de77 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Mon, 26 Jun 2023 13:20:54 -0300 Subject: [PATCH 103/252] Use phpcs friendly comment... --- .../tests/src/Functional/GenerateAudioDerivativeTest.php | 2 +- .../tests/src/Functional/GenerateImageDerivativeTest.php | 2 +- .../tests/src/Functional/GenerateVideoDerivativeTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php index b528e8ba7..a74259173 100644 --- a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php +++ b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php @@ -66,7 +66,7 @@ public function testGenerateAudioDerivativeFromScratch() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', - 'field_media_use[0][target_id]' => 'foo', # change back to $this->preservationMasterTerm->label() + 'field_media_use[0][target_id]' => 'foo', // change back to $this->preservationMasterTerm->label() ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); $this->submitForm($values, $this->t('Save')); diff --git a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php index 69672e0b7..2e1f55914 100644 --- a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php +++ b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php @@ -68,7 +68,7 @@ public function testGenerateImageDerivativeFromScratch() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', - 'field_media_use[0][target_id]' => 'foo', # change back to $this->preservationMasterTerm->label() + 'field_media_use[0][target_id]' => 'foo', // change back to $this->preservationMasterTerm->label() ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); $this->submitForm($values, $this->t('Save')); diff --git a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php index f712e3490..3a5569870 100644 --- a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php +++ b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php @@ -63,7 +63,7 @@ public function testGenerateVideoDerivativeFromScratch() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', - 'field_media_use[0][target_id]' => 'foo', # change back to $this->preservationMasterTerm->label() + 'field_media_use[0][target_id]' => 'foo', // change back to $this->preservationMasterTerm->label() ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); $this->submitForm($values, $this->t('Save')); From 760593b4e02fb41cccc93e2fecde14aa66200bef Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Mon, 26 Jun 2023 13:32:33 -0300 Subject: [PATCH 104/252] Remove problematic comments. --- .../tests/src/Functional/GenerateAudioDerivativeTest.php | 2 +- .../tests/src/Functional/GenerateImageDerivativeTest.php | 2 +- .../tests/src/Functional/GenerateVideoDerivativeTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php index a74259173..5c1b616ed 100644 --- a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php +++ b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php @@ -66,7 +66,7 @@ public function testGenerateAudioDerivativeFromScratch() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', - 'field_media_use[0][target_id]' => 'foo', // change back to $this->preservationMasterTerm->label() + 'field_media_use[0][target_id]' => 'foo', ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); $this->submitForm($values, $this->t('Save')); diff --git a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php index 2e1f55914..7544cb650 100644 --- a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php +++ b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php @@ -68,7 +68,7 @@ public function testGenerateImageDerivativeFromScratch() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', - 'field_media_use[0][target_id]' => 'foo', // change back to $this->preservationMasterTerm->label() + 'field_media_use[0][target_id]' => 'foo', ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); $this->submitForm($values, $this->t('Save')); diff --git a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php index 3a5569870..264cebb71 100644 --- a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php +++ b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php @@ -63,7 +63,7 @@ public function testGenerateVideoDerivativeFromScratch() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', - 'field_media_use[0][target_id]' => 'foo', // change back to $this->preservationMasterTerm->label() + 'field_media_use[0][target_id]' => 'foo', ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); $this->submitForm($values, $this->t('Save')); From c49c131ed8a8b3d87820ad5a697427880e9d36b2 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Tue, 27 Jun 2023 12:05:11 -0300 Subject: [PATCH 105/252] Fix tests. --- .../tests/src/Functional/GenerateAudioDerivativeTest.php | 2 +- .../tests/src/Functional/GenerateImageDerivativeTest.php | 2 +- .../tests/src/Functional/GenerateVideoDerivativeTest.php | 2 +- ...core.entity_form_display.media.test_media_type.default.yml | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php index 5c1b616ed..6b85cd1b5 100644 --- a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php +++ b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php @@ -66,7 +66,7 @@ public function testGenerateAudioDerivativeFromScratch() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', - 'field_media_use[0][target_id]' => 'foo', + 'field_media_use[0][target_id]' => $this->preservationMasterTerm->label(), ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); $this->submitForm($values, $this->t('Save')); diff --git a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php index 7544cb650..44cdda589 100644 --- a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php +++ b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php @@ -68,7 +68,7 @@ public function testGenerateImageDerivativeFromScratch() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', - 'field_media_use[0][target_id]' => 'foo', + 'field_media_use[0][target_id]' => $this->preservationMasterTerm->label(), ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); $this->submitForm($values, $this->t('Save')); diff --git a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php index 264cebb71..de06ba2f7 100644 --- a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php +++ b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php @@ -63,7 +63,7 @@ public function testGenerateVideoDerivativeFromScratch() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', - 'field_media_use[0][target_id]' => 'foo', + 'field_media_use[0][target_id]' => $this->preservationMasterTerm->label(), ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); $this->submitForm($values, $this->t('Save')); diff --git a/tests/fixtures/config/core.entity_form_display.media.test_media_type.default.yml b/tests/fixtures/config/core.entity_form_display.media.test_media_type.default.yml index 19fe419b6..d261542de 100644 --- a/tests/fixtures/config/core.entity_form_display.media.test_media_type.default.yml +++ b/tests/fixtures/config/core.entity_form_display.media.test_media_type.default.yml @@ -3,7 +3,7 @@ status: true dependencies: config: - field.field.media.test_media_type.field_media_of - - field.field.media.test_media_type.field_tags + - field.field.media.test_media_type.field_media_use - media.type.test_media_type module: - path @@ -37,7 +37,7 @@ content: size: 60 placeholder: '' third_party_settings: { } - field_tags: + field_media_use: type: entity_reference_autocomplete weight: 3 region: content From dd514a3eb0d66438de08098317c5dee2715e566d Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Tue, 27 Jun 2023 12:23:44 -0300 Subject: [PATCH 106/252] Add accessCheck FALSE to all queries. --- src/IslandoraUtils.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/IslandoraUtils.php b/src/IslandoraUtils.php index f81cb7472..41f84cbe6 100644 --- a/src/IslandoraUtils.php +++ b/src/IslandoraUtils.php @@ -148,6 +148,7 @@ public function getMedia(NodeInterface $node) { return []; } $mids = $this->entityTypeManager->getStorage('media')->getQuery() + ->accessCheck(FALSE) ->condition(self::MEDIA_OF_FIELD, $node->id()) ->execute(); if (empty($mids)) { @@ -208,6 +209,7 @@ function ($field) { // Query for media that reference this file. $query = $this->entityTypeManager->getStorage('media')->getQuery(); + $query->accessCheck(FALSE); $group = $query->orConditionGroup(); foreach ($conditions as $condition) { $group->condition($condition, $fid); @@ -252,6 +254,7 @@ public function getTermForUri($uri) { } $results = $query + ->accessCheck(FALSE) ->condition($orGroup) ->execute(); @@ -498,6 +501,7 @@ public function getMediaReferencingNodeAndTerm(NodeInterface $node, TermInterfac array_walk($node_fields, $remove_entity); $query = $this->entityTypeManager->getStorage('media')->getQuery(); + $query->accessCheck(FALSE); $taxon_condition = $this->getEntityQueryOrCondition($query, $term_fields, $term->id()); $query->condition($taxon_condition); $node_condition = $this->getEntityQueryOrCondition($query, $node_fields, $node->id()); From 4eae6363836dcee079fd31b547823ee38e634a2d Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Tue, 27 Jun 2023 13:10:48 -0300 Subject: [PATCH 107/252] Change to check access (true). --- src/IslandoraUtils.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/IslandoraUtils.php b/src/IslandoraUtils.php index 41f84cbe6..a2df75896 100644 --- a/src/IslandoraUtils.php +++ b/src/IslandoraUtils.php @@ -148,7 +148,7 @@ public function getMedia(NodeInterface $node) { return []; } $mids = $this->entityTypeManager->getStorage('media')->getQuery() - ->accessCheck(FALSE) + ->accessCheck(TRUE) ->condition(self::MEDIA_OF_FIELD, $node->id()) ->execute(); if (empty($mids)) { @@ -209,7 +209,7 @@ function ($field) { // Query for media that reference this file. $query = $this->entityTypeManager->getStorage('media')->getQuery(); - $query->accessCheck(FALSE); + $query->accessCheck(TRUE); $group = $query->orConditionGroup(); foreach ($conditions as $condition) { $group->condition($condition, $fid); @@ -254,7 +254,7 @@ public function getTermForUri($uri) { } $results = $query - ->accessCheck(FALSE) + ->accessCheck(TRUE) ->condition($orGroup) ->execute(); @@ -501,7 +501,7 @@ public function getMediaReferencingNodeAndTerm(NodeInterface $node, TermInterfac array_walk($node_fields, $remove_entity); $query = $this->entityTypeManager->getStorage('media')->getQuery(); - $query->accessCheck(FALSE); + $query->accessCheck(TRUE); $taxon_condition = $this->getEntityQueryOrCondition($query, $term_fields, $term->id()); $query->condition($taxon_condition); $node_condition = $this->getEntityQueryOrCondition($query, $node_fields, $node->id()); From 05fc3f9b880190164e3998b2ae0e4fa142b6c44c Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 28 Jun 2023 10:00:43 -0300 Subject: [PATCH 108/252] Test on 8.1. --- .github/workflows/build-2.x.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index 261ab1dec..27506495e 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -24,11 +24,11 @@ jobs: fail-fast: false matrix: # PHP 8.1 fails - see https://github.com/Islandora/islandora/issues/887 - php-versions: ["7.4", "8.0"] + php-versions: ["7.4", "8.0", "8.1"] # test-suite functional-javascript will appear to pass but will skip tests; missing chromedriver. test-suite: ["kernel", "functional", "functional-javascript"] # Not yet Drupal 10 ready - see https://github.com/Islandora/islandora/issues/888 - drupal-version: ["9.4.x", "9.5.x-dev"] + drupal-version: ["9.4.x", "9.5.x"] mysql: ["8.0"] allowed_failure: [false] From 0d7f5d927f13cce5b4081ba58f007ab648f1bb7b Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 29 Jun 2023 13:34:11 -0300 Subject: [PATCH 109/252] Update fixtures to have config UUIDs. --- ..._display.media.test_media_type.default.yml | 5 ++++ ...ty_form_display.node.test_type.default.yml | 29 ++++++++++++++----- ..._form_display.node.test_type.secondary.yml | 8 +++-- .../core.entity_form_mode.node.secondary.yml | 5 ++-- ...ty_view_display.node.test_type.default.yml | 15 ++++++++-- ...ity_view_display.node.test_type.teaser.yml | 16 ++++++---- .../config/rest.resource.entity.file.yml | 2 ++ .../config/rest.resource.entity.media.yml | 3 +- .../config/rest.resource.entity.node.yml | 1 + .../rest.resource.entity.taxonomy_term.yml | 1 + 10 files changed, 64 insertions(+), 21 deletions(-) diff --git a/tests/fixtures/config/core.entity_form_display.media.test_media_type.default.yml b/tests/fixtures/config/core.entity_form_display.media.test_media_type.default.yml index d261542de..ea8eac008 100644 --- a/tests/fixtures/config/core.entity_form_display.media.test_media_type.default.yml +++ b/tests/fixtures/config/core.entity_form_display.media.test_media_type.default.yml @@ -1,7 +1,9 @@ +uuid: 9151a0fe-7729-4943-b506-dd6f8d12ceac langcode: en status: true dependencies: config: + - field.field.media.test_media_type.field_media_file - field.field.media.test_media_type.field_media_of - field.field.media.test_media_type.field_media_use - media.type.test_media_type @@ -34,6 +36,7 @@ content: region: content settings: match_operator: CONTAINS + match_limit: 10 size: 60 placeholder: '' third_party_settings: { } @@ -43,6 +46,7 @@ content: region: content settings: match_operator: CONTAINS + match_limit: 10 size: 60 placeholder: '' third_party_settings: { } @@ -64,6 +68,7 @@ content: weight: 4 settings: match_operator: CONTAINS + match_limit: 10 size: 60 placeholder: '' region: content diff --git a/tests/fixtures/config/core.entity_form_display.node.test_type.default.yml b/tests/fixtures/config/core.entity_form_display.node.test_type.default.yml index 2560ec6e7..68724265a 100644 --- a/tests/fixtures/config/core.entity_form_display.node.test_type.default.yml +++ b/tests/fixtures/config/core.entity_form_display.node.test_type.default.yml @@ -1,12 +1,13 @@ +uuid: 90a6909f-a2aa-44e8-8b61-4cd54ec6974f langcode: en status: true dependencies: config: - field.field.node.test_type.field_member_of + - field.field.node.test_type.field_model - node.type.test_type module: - path - - text id: node.test_type.default targetEntityType: node bundle: test_type @@ -19,14 +20,25 @@ content: settings: { } third_party_settings: { } field_member_of: + type: entity_reference_autocomplete weight: 122 + region: content settings: match_operator: CONTAINS + match_limit: 10 size: 60 placeholder: '' third_party_settings: { } + field_model: type: entity_reference_autocomplete + weight: 123 region: content + settings: + match_operator: CONTAINS + match_limit: 10 + size: 60 + placeholder: '' + third_party_settings: { } langcode: type: language_select weight: 2 @@ -42,24 +54,24 @@ content: third_party_settings: { } promote: type: boolean_checkbox - settings: - display_label: true weight: 15 region: content + settings: + display_label: true third_party_settings: { } status: type: boolean_checkbox - settings: - display_label: true weight: 120 region: content + settings: + display_label: true third_party_settings: { } sticky: type: boolean_checkbox - settings: - display_label: true weight: 16 region: content + settings: + display_label: true third_party_settings: { } title: type: string_textfield @@ -72,10 +84,11 @@ content: uid: type: entity_reference_autocomplete weight: 5 + region: content settings: match_operator: CONTAINS + match_limit: 10 size: 60 placeholder: '' - region: content third_party_settings: { } hidden: { } diff --git a/tests/fixtures/config/core.entity_form_display.node.test_type.secondary.yml b/tests/fixtures/config/core.entity_form_display.node.test_type.secondary.yml index b1fdb88ec..f8f05beb1 100644 --- a/tests/fixtures/config/core.entity_form_display.node.test_type.secondary.yml +++ b/tests/fixtures/config/core.entity_form_display.node.test_type.secondary.yml @@ -1,12 +1,12 @@ +uuid: e24c2b3c-60e4-4ff5-99cb-80e5e67e7b04 langcode: en status: true dependencies: config: + - core.entity_form_mode.node.secondary - field.field.node.test_type.field_member_of + - field.field.node.test_type.field_model - node.type.test_type - module: - - path - - text id: node.test_type.secondary targetEntityType: node bundle: test_type @@ -23,6 +23,8 @@ content: hidden: created: true field_media: true + field_member_of: true + field_model: true field_node: true langcode: true path: true diff --git a/tests/fixtures/config/core.entity_form_mode.node.secondary.yml b/tests/fixtures/config/core.entity_form_mode.node.secondary.yml index 07f45bbe2..e1fc76345 100644 --- a/tests/fixtures/config/core.entity_form_mode.node.secondary.yml +++ b/tests/fixtures/config/core.entity_form_mode.node.secondary.yml @@ -1,9 +1,10 @@ +uuid: d9f22219-ff4c-48cc-a98a-6ccaad7a880d langcode: en status: true dependencies: module: - node id: node.secondary -label: Secondary +label: Secondary targetEntityType: node -cache: true +cache: true \ No newline at end of file diff --git a/tests/fixtures/config/core.entity_view_display.node.test_type.default.yml b/tests/fixtures/config/core.entity_view_display.node.test_type.default.yml index cf798265b..e4414e611 100644 --- a/tests/fixtures/config/core.entity_view_display.node.test_type.default.yml +++ b/tests/fixtures/config/core.entity_view_display.node.test_type.default.yml @@ -1,11 +1,12 @@ +uuid: 36f4aecf-0e14-4281-a213-ca7d129da52a langcode: en status: true dependencies: config: - field.field.node.test_type.field_member_of + - field.field.node.test_type.field_model - node.type.test_type module: - - text - user id: node.test_type.default targetEntityType: node @@ -13,14 +14,24 @@ bundle: test_type mode: default content: field_member_of: - weight: 102 + type: entity_reference_label label: above settings: link: true third_party_settings: { } + weight: 102 + region: content + field_model: type: entity_reference_label + label: above + settings: + link: true + third_party_settings: { } + weight: 103 region: content links: + settings: { } + third_party_settings: { } weight: 100 region: content hidden: diff --git a/tests/fixtures/config/core.entity_view_display.node.test_type.teaser.yml b/tests/fixtures/config/core.entity_view_display.node.test_type.teaser.yml index d67060f72..f72954281 100644 --- a/tests/fixtures/config/core.entity_view_display.node.test_type.teaser.yml +++ b/tests/fixtures/config/core.entity_view_display.node.test_type.teaser.yml @@ -1,19 +1,25 @@ -uuid: 0308339a-a9e5-4a04-8ce2-9f62ed504e34 +uuid: b337f462-8e64-4853-be65-9e03b94515bf langcode: en status: true dependencies: config: - core.entity_view_mode.node.teaser + - field.field.node.test_type.field_member_of + - field.field.node.test_type.field_model - node.type.test_type module: - - text - user id: node.test_type.teaser targetEntityType: node bundle: test_type mode: teaser content: + links: + settings: { } + third_party_settings: { } + weight: 100 + region: content hidden: - body: true - links: true - langcode: true + field_member_of: true + field_model: true + langcode: true \ No newline at end of file diff --git a/tests/fixtures/config/rest.resource.entity.file.yml b/tests/fixtures/config/rest.resource.entity.file.yml index 6a136c3cb..dbd6bb62c 100644 --- a/tests/fixtures/config/rest.resource.entity.file.yml +++ b/tests/fixtures/config/rest.resource.entity.file.yml @@ -1,3 +1,4 @@ +uuid: 11c4e25e-6b06-4270-b934-243e4f4aade1 langcode: en status: true dependencies: @@ -26,3 +27,4 @@ configuration: supported_auth: - basic_auth - jwt_auth + - cookie diff --git a/tests/fixtures/config/rest.resource.entity.media.yml b/tests/fixtures/config/rest.resource.entity.media.yml index 3ed0286e7..cd89243d3 100644 --- a/tests/fixtures/config/rest.resource.entity.media.yml +++ b/tests/fixtures/config/rest.resource.entity.media.yml @@ -1,3 +1,4 @@ +uuid: 9a5633b1-6a1a-40b2-8482-c24cf44122ff langcode: en status: true dependencies: @@ -5,7 +6,7 @@ dependencies: - basic_auth - jsonld - jwt - - media_entity + - media - serialization - user id: entity.media diff --git a/tests/fixtures/config/rest.resource.entity.node.yml b/tests/fixtures/config/rest.resource.entity.node.yml index e7d4c7cc3..a3e253e2e 100644 --- a/tests/fixtures/config/rest.resource.entity.node.yml +++ b/tests/fixtures/config/rest.resource.entity.node.yml @@ -1,3 +1,4 @@ +uuid: 08a90469-0355-4b41-a4d6-cb6b53072b8c langcode: en status: true dependencies: diff --git a/tests/fixtures/config/rest.resource.entity.taxonomy_term.yml b/tests/fixtures/config/rest.resource.entity.taxonomy_term.yml index 25b6fbb26..16d96c3ef 100644 --- a/tests/fixtures/config/rest.resource.entity.taxonomy_term.yml +++ b/tests/fixtures/config/rest.resource.entity.taxonomy_term.yml @@ -1,3 +1,4 @@ +uuid: 7534e393-12a7-498c-a4a3-a7bbe4ff9a5d langcode: en status: true dependencies: From 58ab9a3b7023f43818200ef92fab286c6650eef5 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 29 Jun 2023 13:34:43 -0300 Subject: [PATCH 110/252] Stop using deprecated FILE_STATUS_PERMANENT. --- tests/src/Functional/DeleteNodeWithMediaAndFile.php | 2 +- tests/src/Functional/IslandoraFunctionalTestBase.php | 2 +- tests/src/Functional/IslandoraImageFormatterTest.php | 2 +- tests/src/Functional/JsonldTypeAlterReactionTest.php | 2 +- tests/src/Functional/MediaSourceUpdateTest.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/src/Functional/DeleteNodeWithMediaAndFile.php b/tests/src/Functional/DeleteNodeWithMediaAndFile.php index 40e469c5c..5ee19b7ce 100644 --- a/tests/src/Functional/DeleteNodeWithMediaAndFile.php +++ b/tests/src/Functional/DeleteNodeWithMediaAndFile.php @@ -42,8 +42,8 @@ public function testDeleteNodeWithMediaAndFile() { 'uri' => "public://test.jpeg", 'filename' => "test.jpeg", 'filemime' => "image/jpeg", - 'status' => FILE_STATUS_PERMANENT, ]); + $file->setPermanent(); $file->save(); $this->drupalGet("node/1/delete"); diff --git a/tests/src/Functional/IslandoraFunctionalTestBase.php b/tests/src/Functional/IslandoraFunctionalTestBase.php index 2e7235611..016788d05 100644 --- a/tests/src/Functional/IslandoraFunctionalTestBase.php +++ b/tests/src/Functional/IslandoraFunctionalTestBase.php @@ -438,8 +438,8 @@ protected function makeMediaAndFile(AccountInterface $account) { 'uri' => "public://test_file.txt", 'filename' => "test_file.txt", 'filemime' => "text/plain", - 'status' => FILE_STATUS_PERMANENT, ]); + $file->setPermanent(); $file->save(); // Get the source field for the media. diff --git a/tests/src/Functional/IslandoraImageFormatterTest.php b/tests/src/Functional/IslandoraImageFormatterTest.php index 84ea55173..1b40f7a8d 100644 --- a/tests/src/Functional/IslandoraImageFormatterTest.php +++ b/tests/src/Functional/IslandoraImageFormatterTest.php @@ -59,8 +59,8 @@ public function testIslandoraImageFormatter() { 'uri' => "public://test.jpeg", 'filename' => "test.jpeg", 'filemime' => "image/jpeg", - 'status' => FILE_STATUS_PERMANENT, ]); + $file->setPermanent(); $file->save(); // Make the media, and associate it with the image and node. diff --git a/tests/src/Functional/JsonldTypeAlterReactionTest.php b/tests/src/Functional/JsonldTypeAlterReactionTest.php index 80a6039c2..658244aee 100644 --- a/tests/src/Functional/JsonldTypeAlterReactionTest.php +++ b/tests/src/Functional/JsonldTypeAlterReactionTest.php @@ -30,7 +30,7 @@ public function testMappingReaction() { 'new_storage_type' => 'string', 'label' => 'Typed Predicate', 'field_name' => 'type_predicate', - ], $this->t('Save and continue')); + ], 'Save and continue'); $this->submitForm([], $this->t('Save field settings')); $this->submitForm([], $this->t('Save settings')); $this->assertSession()->responseContains('field_type_predicate'); diff --git a/tests/src/Functional/MediaSourceUpdateTest.php b/tests/src/Functional/MediaSourceUpdateTest.php index 3c97c6954..3938e9b47 100644 --- a/tests/src/Functional/MediaSourceUpdateTest.php +++ b/tests/src/Functional/MediaSourceUpdateTest.php @@ -52,8 +52,8 @@ public function setUp(): void { 'uri' => "public://test_file.txt", 'filename' => "test_file.txt", 'filemime' => "text/plain", - 'status' => FILE_STATUS_PERMANENT, ]); + $this->file->setPermanent(); $this->file->save(); // Get the source field for the media. From ece94a24f57bdc8a55396bf7fff9f8b3137a5fce Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Fri, 30 Jun 2023 10:06:28 -0300 Subject: [PATCH 111/252] Fix a typo. (#958) --- .../src/Plugin/Action/GenerateOCRDerivativeFile.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivativeFile.php b/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivativeFile.php index 4ff0d93fc..565d7564c 100644 --- a/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivativeFile.php +++ b/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivativeFile.php @@ -99,7 +99,7 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s break; case 'plain_text': - $his->configuration['args'] = ''; + $this->configuration['args'] = ''; break; } } From f474f7b7453e5ac982398ae7f1bc558665ec35b6 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Fri, 30 Jun 2023 10:30:47 -0300 Subject: [PATCH 112/252] Remove duplicate line. --- tests/src/Kernel/EventGeneratorTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/src/Kernel/EventGeneratorTest.php b/tests/src/Kernel/EventGeneratorTest.php index a9c1f0825..28a4ec03b 100644 --- a/tests/src/Kernel/EventGeneratorTest.php +++ b/tests/src/Kernel/EventGeneratorTest.php @@ -116,7 +116,6 @@ public function testGenerateDeleteEvent() { ['event' => 'delete', 'queue' => 'islandora-indexing-fcrepo-delete'] ); $msg = json_decode($json, TRUE); - $msg = json_decode($json, TRUE); $this->assertBasicStructure($msg); $this->assertTrue($msg["type"] == "Delete", "Event must be of type 'Delete'."); From 354341988bf2d2f2a0cb3579b1246f58e6faeb81 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Mon, 3 Jul 2023 20:04:57 -0300 Subject: [PATCH 113/252] Drupal 10 Compatibility from Upgrade Status --- .github/workflows/build-2.x.yml | 6 +-- islandora.info.yml | 37 +++++++++---------- .../islandora_advanced_search.info.yml | 2 +- .../src/Form/AdvancedSearchForm.php | 2 +- .../src/Plugin/Block/AdvancedSearchBlock.php | 2 +- .../Plugin/Block/SearchResultsPagerBlock.php | 2 +- .../islandora_audio/islandora_audio.info.yml | 3 +- .../islandora_breadcrumbs.info.yml | 3 +- .../islandora_core_feature.info.yml | 3 +- .../islandora_iiif/islandora_iiif.info.yml | 3 +- .../islandora_image/islandora_image.info.yml | 3 +- .../islandora_text_extraction.info.yml | 3 +- ...slandora_text_extraction_defaults.info.yml | 3 +- .../islandora_video/islandora_video.info.yml | 3 +- src/EventGenerator/EventGenerator.php | 1 + src/Flysystem/Adapter/FedoraAdapter.php | 19 ++-------- src/Plugin/Condition/NodeReferencedByNode.php | 1 + tests/src/Kernel/FedoraAdapterTest.php | 9 +---- tests/src/Kernel/FedoraPluginTest.php | 3 ++ 19 files changed, 42 insertions(+), 66 deletions(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index 27506495e..6c78bcf9c 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -23,12 +23,10 @@ jobs: strategy: fail-fast: false matrix: - # PHP 8.1 fails - see https://github.com/Islandora/islandora/issues/887 - php-versions: ["7.4", "8.0", "8.1"] + php-versions: ["8.1"] # test-suite functional-javascript will appear to pass but will skip tests; missing chromedriver. test-suite: ["kernel", "functional", "functional-javascript"] - # Not yet Drupal 10 ready - see https://github.com/Islandora/islandora/issues/888 - drupal-version: ["9.4.x", "9.5.x"] + drupal-version: ["9.5.x", "10.0.x", "10.1.x"] mysql: ["8.0"] allowed_failure: [false] diff --git a/islandora.info.yml b/islandora.info.yml index 0336d89d3..34e8118ac 100644 --- a/islandora.info.yml +++ b/islandora.info.yml @@ -4,32 +4,31 @@ name: 'islandora' description: "Islandora Core" type: module package: Islandora -core: 8.x -core_version_requirement: ^8 || ^9 +core_version_requirement: ^9 || ^10 dependencies: + - context:context_ui + - ctools:ctools + - drupal:action + - drupal:basic_auth - drupal:block + - drupal:content_translation + - drupal:link + - drupal:media - drupal:node - - drupal:path - - drupal:text - drupal:options - - drupal:link - - jsonld:jsonld - - search_api:search_api - - jwt:jwt + - drupal:path - drupal:rest - - filehash:filehash - - drupal:basic_auth - - context:context_ui - - drupal:action - - eva:eva - drupal:taxonomy + - drupal:text - drupal:views_ui - - drupal:media - - prepopulate:prepopulate + - eva:eva - features:features_ui - - migrate_source_csv:migrate_source_csv - - drupal:content_translation + - file_replace:file_replace + - filehash:filehash - flysystem:flysystem + - jsonld:jsonld + - jwt:jwt + - migrate_source_csv:migrate_source_csv + - prepopulate:prepopulate + - search_api:search_api - token:token - - file_replace:file_replace - - ctools:ctools diff --git a/modules/islandora_advanced_search/islandora_advanced_search.info.yml b/modules/islandora_advanced_search/islandora_advanced_search.info.yml index 524e9dc74..19fae53a5 100644 --- a/modules/islandora_advanced_search/islandora_advanced_search.info.yml +++ b/modules/islandora_advanced_search/islandora_advanced_search.info.yml @@ -4,7 +4,7 @@ name: 'Islandora Advanced Search' description: "Creates an Advanced Search block and other enhancements to search." type: module package: Islandora -core_version_requirement: ^8 || ^9 +core_version_requirement: ^9 || ^10 dependencies: - drupal:facets - drupal:facets_summary diff --git a/modules/islandora_advanced_search/src/Form/AdvancedSearchForm.php b/modules/islandora_advanced_search/src/Form/AdvancedSearchForm.php index c00ce5665..09dd1646d 100644 --- a/modules/islandora_advanced_search/src/Form/AdvancedSearchForm.php +++ b/modules/islandora_advanced_search/src/Form/AdvancedSearchForm.php @@ -71,7 +71,7 @@ public function __construct(Request $request, RouteMatchInterface $current_route */ public static function create(ContainerInterface $container) { return new static( - $container->get('request_stack')->getMasterRequest(), + $container->get('request_stack')->getMainRequest(), $container->get('current_route_match') ); } diff --git a/modules/islandora_advanced_search/src/Plugin/Block/AdvancedSearchBlock.php b/modules/islandora_advanced_search/src/Plugin/Block/AdvancedSearchBlock.php index c5f5adb8c..2aa77f124 100644 --- a/modules/islandora_advanced_search/src/Plugin/Block/AdvancedSearchBlock.php +++ b/modules/islandora_advanced_search/src/Plugin/Block/AdvancedSearchBlock.php @@ -108,7 +108,7 @@ public static function create(ContainerInterface $container, array $configuratio $plugin_definition, $container->get('plugin.manager.search_api.display'), $container->get('form_builder'), - $container->get('request_stack')->getMasterRequest() + $container->get('request_stack')->getMainRequest() ); } diff --git a/modules/islandora_advanced_search/src/Plugin/Block/SearchResultsPagerBlock.php b/modules/islandora_advanced_search/src/Plugin/Block/SearchResultsPagerBlock.php index f2e4a1703..e1e477d83 100644 --- a/modules/islandora_advanced_search/src/Plugin/Block/SearchResultsPagerBlock.php +++ b/modules/islandora_advanced_search/src/Plugin/Block/SearchResultsPagerBlock.php @@ -58,7 +58,7 @@ public static function create(ContainerInterface $container, array $configuratio $configuration, $plugin_id, $plugin_definition, - $container->get('request_stack')->getMasterRequest() + $container->get('request_stack')->getMainRequest() ); } diff --git a/modules/islandora_audio/islandora_audio.info.yml b/modules/islandora_audio/islandora_audio.info.yml index 998590f57..5e6beb5ae 100644 --- a/modules/islandora_audio/islandora_audio.info.yml +++ b/modules/islandora_audio/islandora_audio.info.yml @@ -2,7 +2,6 @@ name: 'Islandora Audio' description: 'Islandora audio derivative actions' type: module package: Islandora -core: 8.x -core_version_requirement: ^8 || ^9 +core_version_requirement: ^9 || ^10 dependencies: - drupal:islandora diff --git a/modules/islandora_breadcrumbs/islandora_breadcrumbs.info.yml b/modules/islandora_breadcrumbs/islandora_breadcrumbs.info.yml index c76020cb6..661ec70a2 100644 --- a/modules/islandora_breadcrumbs/islandora_breadcrumbs.info.yml +++ b/modules/islandora_breadcrumbs/islandora_breadcrumbs.info.yml @@ -1,8 +1,7 @@ name: 'Islandora Breadcrumbs' type: module description: 'Builds breadcrumbs based on field_member_of relationships.' -core: 8.x -core_version_requirement: ^8 || ^9 +core_version_requirement: ^9 || ^10 package: Islandora dependencies: - islandora:islandora diff --git a/modules/islandora_core_feature/islandora_core_feature.info.yml b/modules/islandora_core_feature/islandora_core_feature.info.yml index bf4f8d7a6..6976eb8ca 100755 --- a/modules/islandora_core_feature/islandora_core_feature.info.yml +++ b/modules/islandora_core_feature/islandora_core_feature.info.yml @@ -1,8 +1,7 @@ name: 'Islandora Core Feature' description: 'Minimum configuration required for Islandora.' type: module -core: 8.x -core_version_requirement: ^8 || ^9 +core_version_requirement: ^9 || ^10 dependencies: - drupal:basic_auth - drupal:content_translation diff --git a/modules/islandora_iiif/islandora_iiif.info.yml b/modules/islandora_iiif/islandora_iiif.info.yml index 0492158a2..39b835c09 100644 --- a/modules/islandora_iiif/islandora_iiif.info.yml +++ b/modules/islandora_iiif/islandora_iiif.info.yml @@ -1,8 +1,7 @@ name: 'Islandora IIIF' type: module description: 'IIIF support for Islandora' -core: 8.x -core_version_requirement: ^8 || ^9 +core_version_requirement: ^9 || ^10 package: Islandora dependencies: - drupal:islandora diff --git a/modules/islandora_image/islandora_image.info.yml b/modules/islandora_image/islandora_image.info.yml index 87076462c..277966f38 100644 --- a/modules/islandora_image/islandora_image.info.yml +++ b/modules/islandora_image/islandora_image.info.yml @@ -1,8 +1,7 @@ name: 'Islandora Image' type: module description: 'Islandora Image derivative actions' -core: 8.x -core_version_requirement: ^8 || ^9 +core_version_requirement: ^9 || ^10 package: Islandora dependencies: - drupal:islandora diff --git a/modules/islandora_text_extraction/islandora_text_extraction.info.yml b/modules/islandora_text_extraction/islandora_text_extraction.info.yml index 67687f901..fb768e2ab 100644 --- a/modules/islandora_text_extraction/islandora_text_extraction.info.yml +++ b/modules/islandora_text_extraction/islandora_text_extraction.info.yml @@ -1,8 +1,7 @@ name: 'Islandora Text Extraction' type: module description: 'Islandora 8 module to connect to Hypercube microservice, and to get text from PDF ingest' -core: 8.x -core_version_requirement: ^8 || ^9 +core_version_requirement: ^9 || ^10 package: 'Islandora' dependencies: - drupal:islandora diff --git a/modules/islandora_text_extraction_defaults/islandora_text_extraction_defaults.info.yml b/modules/islandora_text_extraction_defaults/islandora_text_extraction_defaults.info.yml index 5b9aa14f7..8596dbd32 100644 --- a/modules/islandora_text_extraction_defaults/islandora_text_extraction_defaults.info.yml +++ b/modules/islandora_text_extraction_defaults/islandora_text_extraction_defaults.info.yml @@ -1,8 +1,7 @@ name: 'Islandora Text Extraction Defaults' type: module description: 'Default config for the Islandora Text Extraction module.' -core: 8.x -core_version_requirement: ^8 || ^9 +core_version_requirement: ^9 || ^10 package: Islandora dependencies: - drupal:field diff --git a/modules/islandora_video/islandora_video.info.yml b/modules/islandora_video/islandora_video.info.yml index 48eb82f2f..aa51af113 100644 --- a/modules/islandora_video/islandora_video.info.yml +++ b/modules/islandora_video/islandora_video.info.yml @@ -2,7 +2,6 @@ name: 'Islandora Video' description: 'Islandora video derivative actions' type: module package: Islandora -core: 8.x -core_version_requirement: ^8 || ^9 +core_version_requirement: ^9 || ^10 dependencies: - drupal:islandora diff --git a/src/EventGenerator/EventGenerator.php b/src/EventGenerator/EventGenerator.php index 6b3a4c5cf..b975f6083 100644 --- a/src/EventGenerator/EventGenerator.php +++ b/src/EventGenerator/EventGenerator.php @@ -192,6 +192,7 @@ protected function isNewRevision(EntityInterface $entity) { protected function getRevisionIds(Media $media, EntityStorageInterface $media_storage) { $result = $media_storage->getQuery() ->allRevisions() + ->accessCheck(TRUE) ->condition($media->getEntityType()->getKey('id'), $media->id()) ->sort($media->getEntityType()->getKey('revision'), 'DESC') ->execute(); diff --git a/src/Flysystem/Adapter/FedoraAdapter.php b/src/Flysystem/Adapter/FedoraAdapter.php index 55f8b11d3..cf24cb779 100644 --- a/src/Flysystem/Adapter/FedoraAdapter.php +++ b/src/Flysystem/Adapter/FedoraAdapter.php @@ -160,14 +160,8 @@ protected function getMetadataFromHeaders(Response $response) { // NonRDFSource's are considered files. Everything else is a // directory. $type = 'dir'; - // phpcs:disable - if (class_exists(Header::class)) { - $links = Header::parse($response->getHeader('Link')); - } - else { - $links = parse_header($response->getHeader('Link')); - } - // phpcs:enable + $links = Header::parse($response->getHeader('Link')); + foreach ($links as $link) { if ($link['rel'] == 'type' && $link[0] == '') { $type = 'file'; @@ -403,14 +397,7 @@ private function deleteTombstone($path) { $return = NULL; if ($response->getStatusCode() == 410) { $return = FALSE; - // phpcs:disable - if (class_exists(Header::class)) { - $link_headers = Header::parse($response->getHeader('Link')); - } - else { - $link_headers = parse_header($response->getHeader('Link')); - } - // phpcs:enable + $link_headers = Header::parse($response->getHeader('Link')); if ($link_headers) { $tombstones = array_filter($link_headers, function ($o) { return (isset($o['rel']) && $o['rel'] == 'hasTombstone'); diff --git a/src/Plugin/Condition/NodeReferencedByNode.php b/src/Plugin/Condition/NodeReferencedByNode.php index c5611a3ee..d6db01ea0 100644 --- a/src/Plugin/Condition/NodeReferencedByNode.php +++ b/src/Plugin/Condition/NodeReferencedByNode.php @@ -128,6 +128,7 @@ protected function evaluateEntity(EntityInterface $entity) { $config = FieldStorageConfig::loadByName('node', $reference_field); if ($config) { $id_count = \Drupal::entityQuery('node') + ->accessCheck(TRUE) ->condition($reference_field, $entity->id()) ->count() ->execute(); diff --git a/tests/src/Kernel/FedoraAdapterTest.php b/tests/src/Kernel/FedoraAdapterTest.php index d6adecbbd..4a9d45b5a 100644 --- a/tests/src/Kernel/FedoraAdapterTest.php +++ b/tests/src/Kernel/FedoraAdapterTest.php @@ -61,13 +61,8 @@ protected function createAdapterBase() { ]); $prophecy->getHeader('Content-Type')->willReturn(['text/plain']); $prophecy->getHeader('Content-Length')->willReturn([strlen("DERP")]); - // phpcs:disable - if (class_exists(Utils::class)) { - $prophecy->getBody()->willReturn(Utils::streamFor("DERP")); - } else { - $prophecy->getBody()->willReturn(stream_for("DERP")); - } - // phpcs:enable + $prophecy->getBody()->willReturn(Utils::streamFor("DERP")); + return $prophecy; } diff --git a/tests/src/Kernel/FedoraPluginTest.php b/tests/src/Kernel/FedoraPluginTest.php index cd1c83256..92a8137ca 100644 --- a/tests/src/Kernel/FedoraPluginTest.php +++ b/tests/src/Kernel/FedoraPluginTest.php @@ -6,6 +6,7 @@ use Drupal\islandora\Flysystem\Fedora; use Islandora\Chullo\IFedoraApi; use League\Flysystem\AdapterInterface; +use Prophecy\PhpUnit\ProphecyTrait; use Psr\Http\Message\ResponseInterface; use Symfony\Component\Mime\MimeTypeGuesserInterface; @@ -17,6 +18,8 @@ */ class FedoraPluginTest extends IslandoraKernelTestBase { + use ProphecyTrait; + /** * Mocks up a plugin. */ From bf17ed9bbc39456c1c8d70e897bd1e40943fd349 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Mon, 3 Jul 2023 20:18:03 -0300 Subject: [PATCH 114/252] Allow contexts module in RC. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index bf274cd1d..48ee9a4a7 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "drupal/context": "^4", + "drupal/context": "^4 || ^5@RC", "drupal/ctools": "^3.8 || ^4", "drupal/eva" : "^3.0", "drupal/features" : "^3.7", From 0665310346b0deae8b4032438c5f098c6abc12ce Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Mon, 3 Jul 2023 20:20:04 -0300 Subject: [PATCH 115/252] Remove unused use statements. --- src/Flysystem/Adapter/FedoraAdapter.php | 1 - tests/src/Kernel/FedoraAdapterTest.php | 1 - 2 files changed, 2 deletions(-) diff --git a/src/Flysystem/Adapter/FedoraAdapter.php b/src/Flysystem/Adapter/FedoraAdapter.php index cf24cb779..0871827e1 100644 --- a/src/Flysystem/Adapter/FedoraAdapter.php +++ b/src/Flysystem/Adapter/FedoraAdapter.php @@ -3,7 +3,6 @@ namespace Drupal\islandora\Flysystem\Adapter; use GuzzleHttp\Psr7\Header; -use function GuzzleHttp\Psr7\parse_header; use Drupal\Core\Logger\LoggerChannelInterface; use Islandora\Chullo\IFedoraApi; use League\Flysystem\AdapterInterface; diff --git a/tests/src/Kernel/FedoraAdapterTest.php b/tests/src/Kernel/FedoraAdapterTest.php index 4a9d45b5a..08db253c5 100644 --- a/tests/src/Kernel/FedoraAdapterTest.php +++ b/tests/src/Kernel/FedoraAdapterTest.php @@ -4,7 +4,6 @@ use Prophecy\PhpUnit\ProphecyTrait; use GuzzleHttp\Psr7\Utils; -use function GuzzleHttp\Psr7\stream_for; use Drupal\Core\Logger\LoggerChannelInterface; use Drupal\islandora\Flysystem\Adapter\FedoraAdapter; use GuzzleHttp\Psr7\Response; From 8f77733c84b441a97dcb5a5e3f670664d5fc843c Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Mon, 3 Jul 2023 20:28:43 -0300 Subject: [PATCH 116/252] Allow jsonld 3.x. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 48ee9a4a7..1cc5f74d9 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,7 @@ "drupal/token" : "^1.3", "islandora/chullo": "^2.0", "islandora/fedora-entity-mapper": "^1.0", - "islandora/jsonld": "^2", + "islandora/jsonld": "^2 || ^3", "stomp-php/stomp-php": "4.* || ^5" }, "require-dev": { From 2040952740d571ff7eb5e95339914dd7ac95c289 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Tue, 4 Jul 2023 09:17:48 -0300 Subject: [PATCH 117/252] Integer weight selector test module to D10. --- .../integer_weight_test_views.info.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/modules/integer_weight_test_views/integer_weight_test_views.info.yml b/tests/modules/integer_weight_test_views/integer_weight_test_views.info.yml index 7e2981427..77b12ec37 100644 --- a/tests/modules/integer_weight_test_views/integer_weight_test_views.info.yml +++ b/tests/modules/integer_weight_test_views/integer_weight_test_views.info.yml @@ -2,7 +2,7 @@ name: 'Integer weight test views' type: module description: 'Provides default views for integer weight views tests.' package: Testing -core_version_requirement: ^8 || ^9 +core_version_requirement: ^8 || ^9 || ^10 dependencies: - drupal:node - drupal:views From cb2e1c4809c76c4f6fe6812c0dbcee7d96aeab17 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Tue, 4 Jul 2023 09:23:38 -0300 Subject: [PATCH 118/252] Remove 8 for consistency. --- .../integer_weight_test_views.info.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/modules/integer_weight_test_views/integer_weight_test_views.info.yml b/tests/modules/integer_weight_test_views/integer_weight_test_views.info.yml index 77b12ec37..013c7dd86 100644 --- a/tests/modules/integer_weight_test_views/integer_weight_test_views.info.yml +++ b/tests/modules/integer_weight_test_views/integer_weight_test_views.info.yml @@ -2,7 +2,7 @@ name: 'Integer weight test views' type: module description: 'Provides default views for integer weight views tests.' package: Testing -core_version_requirement: ^8 || ^9 || ^10 +core_version_requirement: ^9 || ^10 dependencies: - drupal:node - drupal:views From a77bd2d949157c2590df9bf14634747725ce8b33 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Tue, 4 Jul 2023 15:57:30 -0300 Subject: [PATCH 119/252] Return array not string. --- .../integer_weight_test_views.info.yml | 2 +- tests/src/Kernel/FedoraAdapterTest.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/modules/integer_weight_test_views/integer_weight_test_views.info.yml b/tests/modules/integer_weight_test_views/integer_weight_test_views.info.yml index 013c7dd86..77b12ec37 100644 --- a/tests/modules/integer_weight_test_views/integer_weight_test_views.info.yml +++ b/tests/modules/integer_weight_test_views/integer_weight_test_views.info.yml @@ -2,7 +2,7 @@ name: 'Integer weight test views' type: module description: 'Provides default views for integer weight views tests.' package: Testing -core_version_requirement: ^9 || ^10 +core_version_requirement: ^8 || ^9 || ^10 dependencies: - drupal:node - drupal:views diff --git a/tests/src/Kernel/FedoraAdapterTest.php b/tests/src/Kernel/FedoraAdapterTest.php index 08db253c5..9067d369e 100644 --- a/tests/src/Kernel/FedoraAdapterTest.php +++ b/tests/src/Kernel/FedoraAdapterTest.php @@ -235,7 +235,7 @@ protected function createAdapterForDeleteWithTombstone() { $head_prophecy = $this->prophesize(Response::class); $head_prophecy->getStatusCode()->willReturn(410); $head_prophecy->getHeader('Link') - ->willReturn('; rel="hasTombstone"'); + ->willReturn(['; rel="hasTombstone"']); $tombstone_prophecy = $this->prophesize(Response::class); $tombstone_prophecy->getStatusCode()->willReturn(204); @@ -263,7 +263,7 @@ protected function createAdapterForDeleteWithTombstoneFail() { $head_prophecy = $this->prophesize(Response::class); $head_prophecy->getStatusCode()->willReturn(410); $head_prophecy->getHeader('Link') - ->willReturn('; rel="hasTombstone"'); + ->willReturn(['; rel="hasTombstone"']); $tombstone_prophecy = $this->prophesize(Response::class); $tombstone_prophecy->getStatusCode()->willReturn(500); From 8686dbf74b29f0e18e2e142255a12604f50ee4f5 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Tue, 4 Jul 2023 19:01:09 -0300 Subject: [PATCH 120/252] Avoid duplicate counts of the same file being deleted. --- src/Form/ConfirmDeleteMediaAndFile.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Form/ConfirmDeleteMediaAndFile.php b/src/Form/ConfirmDeleteMediaAndFile.php index 64c1bff3c..d5dc9750b 100644 --- a/src/Form/ConfirmDeleteMediaAndFile.php +++ b/src/Form/ConfirmDeleteMediaAndFile.php @@ -137,8 +137,11 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $inaccessible_entities[] = $file; continue; } - $delete_files[$file->id()] = $file; - $total_count++; + if (!array_key_exists($file->id(), $delete_files)) { + $delete_files[$file->id()] = $file; + $total_count++; + } + } } } From 2376f7783107de247285b8e68063e88cbda1f7a7 Mon Sep 17 00:00:00 2001 From: JojoVes Date: Wed, 1 Feb 2023 14:23:10 -0400 Subject: [PATCH 121/252] Replace deprecated 'context' condition annotation with 'context_definitions' (#925) There was a cleanup done for this deprecation in https://github.com/Islandora/islandora/pull/764 before the 'NodeReferencedByNode' condition was made, then the deprecated annotation must have just been missed in reviewing https://github.com/Islandora/islandora/pull/808. --- src/Plugin/Condition/NodeReferencedByNode.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plugin/Condition/NodeReferencedByNode.php b/src/Plugin/Condition/NodeReferencedByNode.php index a2abac808..c5611a3ee 100644 --- a/src/Plugin/Condition/NodeReferencedByNode.php +++ b/src/Plugin/Condition/NodeReferencedByNode.php @@ -16,7 +16,7 @@ * @Condition( * id = "node_referenced_by_node", * label = @Translation("Node is referenced by other nodes"), - * context = { + * context_definitions = { * "node" = @ContextDefinition("entity:node", required = TRUE , label = @Translation("node")) * } * ) From ee2b964a076ca4df93af55c1045997ca1ea03603 Mon Sep 17 00:00:00 2001 From: Ant Brown Date: Thu, 9 Feb 2023 09:30:05 +1300 Subject: [PATCH 122/252] Fix deprecated File::url(), use createFileUrl() instead (#855) * islandora.tokens.inc * See https://www.drupal.org/node/3019830 Co-authored-by: Ant Brown --- islandora.tokens.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/islandora.tokens.inc b/islandora.tokens.inc index 8d1c4b6b2..abbe6474a 100644 --- a/islandora.tokens.inc +++ b/islandora.tokens.inc @@ -79,7 +79,7 @@ function islandora_tokens($type, $tokens, array $data, array $options, Bubbleabl if ($media) { $file = \Drupal::service('islandora.media_source_service')->getSourceFile($media); if (!empty($file)) { - $url = $file->url(); + $url = $file->createFileUrl(); $replacements[$original] = $url; } } From 4e091e524fe98b94322b48f1e73ff8d195ce6e8c Mon Sep 17 00:00:00 2001 From: Seth Shaw Date: Thu, 9 Feb 2023 11:06:57 -0800 Subject: [PATCH 123/252] fix for deprecated Symfony Event class --- composer.json | 2 +- src/Event/StompHeaderEvent.php | 2 +- src/EventGenerator/EmitEvent.php | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 0b443c027..f4956d3d7 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "drupal/file_replace": "^1.1", "drupal/filehash": "^2", "drupal/flysystem" : "^2.0@alpha", - "drupal/jwt": "^1.0", + "drupal/jwt": "^1.1", "drupal/migrate_plus" : "^5.1 || ^6", "drupal/migrate_source_csv" : "^3.4", "drupal/prepopulate" : "^2.2", diff --git a/src/Event/StompHeaderEvent.php b/src/Event/StompHeaderEvent.php index d6d93c22c..1381a9209 100644 --- a/src/Event/StompHeaderEvent.php +++ b/src/Event/StompHeaderEvent.php @@ -6,7 +6,7 @@ use Drupal\Core\Session\AccountInterface; use Symfony\Component\HttpFoundation\ParameterBag; -use Symfony\Component\EventDispatcher\Event; +use Drupal\Component\EventDispatcher\Event; /** * Event used to build headers for STOMP. diff --git a/src/EventGenerator/EmitEvent.php b/src/EventGenerator/EmitEvent.php index fd33fd99c..12700d732 100644 --- a/src/EventGenerator/EmitEvent.php +++ b/src/EventGenerator/EmitEvent.php @@ -160,8 +160,8 @@ public function execute($entity = NULL) { $data = $this->generateData($entity); $event = $this->eventDispatcher->dispatch( - StompHeaderEvent::EVENT_NAME, - new StompHeaderEvent($entity, $user, $data, $this->getConfiguration()) + new StompHeaderEvent($entity, $user, $data, $this->getConfiguration()), + StompHeaderEvent::EVENT_NAME ); $message = new Message( From 46cd2f99503af623456ddfcf78dc5dc767891ebd Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Mon, 13 Mar 2023 13:12:00 -0300 Subject: [PATCH 124/252] Reset contexts before evaluation. (#932) * Reset contexts before evaluation. * Only reset when Islandora's ContextProviders are being used. --- src/IslandoraContextManager.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/IslandoraContextManager.php b/src/IslandoraContextManager.php index 801e3253e..c72281954 100644 --- a/src/IslandoraContextManager.php +++ b/src/IslandoraContextManager.php @@ -13,6 +13,14 @@ */ class IslandoraContextManager extends ContextManager { + /** + * Allow the contexts to be reset before evaluation. + */ + protected function resetContextEvaluation() { + $this->contexts = []; + $this->contextConditionsEvaluated = FALSE; + } + /** * Evaluate all context conditions. * @@ -22,7 +30,11 @@ class IslandoraContextManager extends ContextManager { public function evaluateContexts(array $provided = []) { $this->activeContexts = []; - + // XXX: Ensure that no earlier executed contexts in the request are still + // present when being triggered via Islandora's ContextProviders. + if (!empty($provided)) { + $this->resetContextEvaluation(); + } /** @var \Drupal\context\ContextInterface $context */ foreach ($this->getContexts() as $context) { if ($this->evaluateContextConditions($context, $provided) && !$context->disabled()) { From c67f3185ec3ca293a96a44e65a8369c3026208f0 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 8 Mar 2023 10:25:38 -0400 Subject: [PATCH 125/252] Update Crayfish Commons dependency --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index f4956d3d7..96f3e886d 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "drupal/prepopulate" : "^2.2", "drupal/search_api": "^1.8", "drupal/token" : "^1.3", - "islandora/crayfish-commons": "^2", + "islandora/crayfish-commons": "^3", "islandora/jsonld": "^2", "stomp-php/stomp-php": "4.* || ^5" }, From 709938cf291baba1b6748b05b8d94a3f54185d60 Mon Sep 17 00:00:00 2001 From: Lucas van Schaik Date: Fri, 17 Feb 2023 16:56:42 +0100 Subject: [PATCH 126/252] Implement solution for drupal issues 3089660 and 3045666 --- src/IslandoraContextManager.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/IslandoraContextManager.php b/src/IslandoraContextManager.php index c72281954..a8f18772f 100644 --- a/src/IslandoraContextManager.php +++ b/src/IslandoraContextManager.php @@ -60,7 +60,11 @@ public function evaluateContextConditions(ContextInterface $context, array $prov $conditions = $context->getConditions(); // Apply context to any context aware conditions. - $this->applyContexts($conditions, $provided); + // Abort if the application of contexts has been unsuccessful + // similarly to BlockAccessControlHandler::checkAccess(). + if (!$this->applyContexts($conditions, $provided)) { + return FALSE; + } // Set the logic to use when validating the conditions. $logic = $context->requiresAllConditions() @@ -88,6 +92,7 @@ public function evaluateContextConditions(ContextInterface $context, array $prov * TRUE if conditions pass */ protected function applyContexts(ConditionPluginCollection &$conditions, array $provided = []) { + $passed = FALSE; foreach ($conditions as $condition) { if ($condition instanceof ContextAwarePluginInterface) { try { @@ -98,14 +103,15 @@ protected function applyContexts(ConditionPluginCollection &$conditions, array $ $contexts = $provided; } $this->contextHandler->applyContextMapping($condition, $contexts); + $passed = TRUE; } catch (ContextException $e) { - return FALSE; + continue; } } } - return TRUE; + return $passed; } } From 9f83322902457ce390e21b818d72a1722db51929 Mon Sep 17 00:00:00 2001 From: Lucas van Schaik Date: Fri, 17 Feb 2023 16:57:50 +0100 Subject: [PATCH 127/252] Check if action is appropriate for entity before executing --- src/PresetReaction/PresetReaction.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/PresetReaction/PresetReaction.php b/src/PresetReaction/PresetReaction.php index 98aa69462..e516eb249 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -56,7 +56,10 @@ public function execute(EntityInterface $entity = NULL) { $action_ids = $config['actions']; foreach ($action_ids as $action_id) { $action = $this->actionStorage->load($action_id); - $action->execute([$entity]); + // Make sure that the action is appropriate for the entity. + if ($entity->getEntityTypeId() === $action->getType()) { + $action->execute([$entity]); + } } } From 2c48c8795fb10f2d6764688ffb1555be82cec833 Mon Sep 17 00:00:00 2001 From: Lucas van Schaik Date: Mon, 20 Feb 2023 21:25:48 +0100 Subject: [PATCH 128/252] Check if conditions exist before applying contexts to them --- src/IslandoraContextManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/IslandoraContextManager.php b/src/IslandoraContextManager.php index a8f18772f..15fac41f6 100644 --- a/src/IslandoraContextManager.php +++ b/src/IslandoraContextManager.php @@ -62,7 +62,7 @@ public function evaluateContextConditions(ContextInterface $context, array $prov // Apply context to any context aware conditions. // Abort if the application of contexts has been unsuccessful // similarly to BlockAccessControlHandler::checkAccess(). - if (!$this->applyContexts($conditions, $provided)) { + if (count($conditions) > 0 && !$this->applyContexts($conditions, $provided)) { return FALSE; } From 50685aebe6353c5acb4ea16a0d529d8eca3cd130 Mon Sep 17 00:00:00 2001 From: Lucas van Schaik Date: Mon, 20 Feb 2023 21:26:18 +0100 Subject: [PATCH 129/252] Make sure that the action is appropriate: either system or with same entity type --- src/PresetReaction/PresetReaction.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PresetReaction/PresetReaction.php b/src/PresetReaction/PresetReaction.php index e516eb249..532606fc7 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -56,8 +56,8 @@ public function execute(EntityInterface $entity = NULL) { $action_ids = $config['actions']; foreach ($action_ids as $action_id) { $action = $this->actionStorage->load($action_id); - // Make sure that the action is appropriate for the entity. - if ($entity->getEntityTypeId() === $action->getType()) { + // Make sure that the action is appropriate: either system or with same entity type. + if ($action->getType() === 'system' || $entity->getEntityTypeId() === $action->getType()) { $action->execute([$entity]); } } From 088f1fcdd06939af1916ac6e909ac52bd0af3e17 Mon Sep 17 00:00:00 2001 From: Lucas van Schaik Date: Tue, 21 Feb 2023 08:06:00 +0100 Subject: [PATCH 130/252] Comment too long --- src/PresetReaction/PresetReaction.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/PresetReaction/PresetReaction.php b/src/PresetReaction/PresetReaction.php index 532606fc7..18a771dc5 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -56,7 +56,8 @@ public function execute(EntityInterface $entity = NULL) { $action_ids = $config['actions']; foreach ($action_ids as $action_id) { $action = $this->actionStorage->load($action_id); - // Make sure that the action is appropriate: either system or with same entity type. + // Make sure that the action is appropriate: + // either system action or with same type as the entity type. if ($action->getType() === 'system' || $entity->getEntityTypeId() === $action->getType()) { $action->execute([$entity]); } From 1bbb48f70fed5229d1e446a652223927963c0936 Mon Sep 17 00:00:00 2001 From: Lucas van Schaik Date: Tue, 28 Feb 2023 10:09:18 +0100 Subject: [PATCH 131/252] Be consistent with context module, issue 3177007 --- src/IslandoraContextManager.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/IslandoraContextManager.php b/src/IslandoraContextManager.php index 15fac41f6..9fd93fbc2 100644 --- a/src/IslandoraContextManager.php +++ b/src/IslandoraContextManager.php @@ -62,7 +62,7 @@ public function evaluateContextConditions(ContextInterface $context, array $prov // Apply context to any context aware conditions. // Abort if the application of contexts has been unsuccessful // similarly to BlockAccessControlHandler::checkAccess(). - if (count($conditions) > 0 && !$this->applyContexts($conditions, $provided)) { + if (!$this->applyContexts($conditions, $provided)) { return FALSE; } @@ -92,6 +92,12 @@ public function evaluateContextConditions(ContextInterface $context, array $prov * TRUE if conditions pass */ protected function applyContexts(ConditionPluginCollection &$conditions, array $provided = []) { + + // If no contexts to check, the return should be TRUE. + // For example, empty is the same as sitewide condition. + if (count($conditions) === 0) { + return TRUE; + } $passed = FALSE; foreach ($conditions as $condition) { if ($condition instanceof ContextAwarePluginInterface) { From b82accf7635dd67e1c7621049c9500cd0a61c60a Mon Sep 17 00:00:00 2001 From: Lucas van Schaik Date: Tue, 14 Mar 2023 11:16:48 +0100 Subject: [PATCH 132/252] Revert "Comment too long" This reverts commit aba5052308f994d47527e7daddd75854313060b9. --- src/PresetReaction/PresetReaction.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/PresetReaction/PresetReaction.php b/src/PresetReaction/PresetReaction.php index 18a771dc5..532606fc7 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -56,8 +56,7 @@ public function execute(EntityInterface $entity = NULL) { $action_ids = $config['actions']; foreach ($action_ids as $action_id) { $action = $this->actionStorage->load($action_id); - // Make sure that the action is appropriate: - // either system action or with same type as the entity type. + // Make sure that the action is appropriate: either system or with same entity type. if ($action->getType() === 'system' || $entity->getEntityTypeId() === $action->getType()) { $action->execute([$entity]); } From 4bcc7d441783395c8f018ed537b2ca61cb87a7ea Mon Sep 17 00:00:00 2001 From: Lucas van Schaik Date: Tue, 14 Mar 2023 11:18:22 +0100 Subject: [PATCH 133/252] Revert "Make sure that the action is appropriate: either system or with same entity type" This reverts commit a409d402aa53a7640ca12f8ce2209ccdf605b89a. --- src/PresetReaction/PresetReaction.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PresetReaction/PresetReaction.php b/src/PresetReaction/PresetReaction.php index 532606fc7..e516eb249 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -56,8 +56,8 @@ public function execute(EntityInterface $entity = NULL) { $action_ids = $config['actions']; foreach ($action_ids as $action_id) { $action = $this->actionStorage->load($action_id); - // Make sure that the action is appropriate: either system or with same entity type. - if ($action->getType() === 'system' || $entity->getEntityTypeId() === $action->getType()) { + // Make sure that the action is appropriate for the entity. + if ($entity->getEntityTypeId() === $action->getType()) { $action->execute([$entity]); } } From ee451667d4954573264d961bb29440a8b93f77b0 Mon Sep 17 00:00:00 2001 From: Lucas van Schaik Date: Tue, 14 Mar 2023 11:18:30 +0100 Subject: [PATCH 134/252] Revert "Check if action is appropriate for entity before executing" This reverts commit 87f475d81c0bca3793c9f3bdc6cf8def4f31ef6b. --- src/PresetReaction/PresetReaction.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/PresetReaction/PresetReaction.php b/src/PresetReaction/PresetReaction.php index e516eb249..98aa69462 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -56,10 +56,7 @@ public function execute(EntityInterface $entity = NULL) { $action_ids = $config['actions']; foreach ($action_ids as $action_id) { $action = $this->actionStorage->load($action_id); - // Make sure that the action is appropriate for the entity. - if ($entity->getEntityTypeId() === $action->getType()) { - $action->execute([$entity]); - } + $action->execute([$entity]); } } From 7d54a42d4804f4f54918832aa7df0a153bbf0407 Mon Sep 17 00:00:00 2001 From: "Noah W. Smith" Date: Fri, 31 Mar 2023 12:55:30 -0400 Subject: [PATCH 135/252] Update maintainer and sponsor info Maintainer switched to TAG; Sponsors sorted, one correction, and links added --- README.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index d891c0e6f..839a14e3e 100644 --- a/README.md +++ b/README.md @@ -91,21 +91,22 @@ Having problems or solved a problem? Check out the Islandora google groups for a Current maintainers: -* [Danny Lamb](https://github.com/dannylamb) +* [Islandora Technical Advisory Group]([https://github.com/dannylamb](https://github.com/Islandora/islandora-community/wiki/Technical-Advisory-Group-%28TAG%29)) ## Sponsors -* UPEI -* discoverygarden inc. -* LYRASIS -* McMaster University -* University of Limerick -* York University -* University of Manitoba -* Simon Fraser University -* PALS * American Philosophical Society -* Common Media Inc. + +* [Born-Digital, Inc.](https://www.born-digital.com/) +* [discoverygarden inc.](https://www.discoverygarden.ca/) +* [LYRASIS](https://www.lyrasis.org/) +* [McMaster University](https://www.mcmaster.ca/) +* [PALS](https://www.mnpals.org/) +* [University of Limerick](https://www.ul.ie/) +* [University of Manitoba](https://umanitoba.ca/) +* [UPEI](https://www.upei.ca/) +* [Simon Fraser University](https://www.sfu.ca/) +* [York University](https://www.yorku.ca/) ## Development From 58da2a6af1f7ea548ad6952811e02d944491bf31 Mon Sep 17 00:00:00 2001 From: "Noah W. Smith" Date: Fri, 31 Mar 2023 12:57:37 -0400 Subject: [PATCH 136/252] Missed one link; corrected TAG link --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 839a14e3e..32e69ea99 100644 --- a/README.md +++ b/README.md @@ -91,12 +91,11 @@ Having problems or solved a problem? Check out the Islandora google groups for a Current maintainers: -* [Islandora Technical Advisory Group]([https://github.com/dannylamb](https://github.com/Islandora/islandora-community/wiki/Technical-Advisory-Group-%28TAG%29)) +* [Islandora Technical Advisory Group](https://github.com/Islandora/islandora-community/wiki/Technical-Advisory-Group-%28TAG%29) ## Sponsors -* American Philosophical Society - +* [American Philosophical Society](https://www.amphilsoc.org/) * [Born-Digital, Inc.](https://www.born-digital.com/) * [discoverygarden inc.](https://www.discoverygarden.ca/) * [LYRASIS](https://www.lyrasis.org/) From 8ce1ad2cda65cfa73c535c170de02130ec5fecba Mon Sep 17 00:00:00 2001 From: Jared Whiklo Date: Wed, 15 Mar 2023 17:03:46 -0500 Subject: [PATCH 137/252] Remove deprecate MimeTypeGuesser Use test upgraded Crayfish-Commons --- composer.json | 2 +- islandora.services.yml | 3 +++ src/Flysystem/Adapter/FedoraAdapter.php | 30 ++++++++++++++++++------- src/Flysystem/Fedora.php | 24 +++++++++++++++----- 4 files changed, 44 insertions(+), 15 deletions(-) diff --git a/composer.json b/composer.json index 96f3e886d..a92aff53d 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "drupal/prepopulate" : "^2.2", "drupal/search_api": "^1.8", "drupal/token" : "^1.3", - "islandora/crayfish-commons": "^3", + "islandora/crayfish-commons": "dev-upgrade-5.4-symfony", "islandora/jsonld": "^2", "stomp-php/stomp-php": "4.* || ^5" }, diff --git a/islandora.services.yml b/islandora.services.yml index 4108e2446..465e8d933 100644 --- a/islandora.services.yml +++ b/islandora.services.yml @@ -31,6 +31,9 @@ services: logger.channel.islandora: parent: logger.channel_base arguments: ['islandora'] + logger.channel.fedora_flysystem: + parent: logger.channel_base + arguments: ['fedora_flysystem'] islandora.media_route_context_provider: class: Drupal\islandora\ContextProvider\MediaRouteContextProvider arguments: ['@current_route_match'] diff --git a/src/Flysystem/Adapter/FedoraAdapter.php b/src/Flysystem/Adapter/FedoraAdapter.php index 58be909c8..eb79220d4 100644 --- a/src/Flysystem/Adapter/FedoraAdapter.php +++ b/src/Flysystem/Adapter/FedoraAdapter.php @@ -2,6 +2,7 @@ namespace Drupal\islandora\Flysystem\Adapter; +use Drupal\Core\Logger\LoggerChannelInterface; use Islandora\Chullo\IFedoraApi; use League\Flysystem\AdapterInterface; use League\Flysystem\Adapter\Polyfill\NotSupportingVisibilityTrait; @@ -9,7 +10,7 @@ use League\Flysystem\Config; use GuzzleHttp\Psr7\Response; use GuzzleHttp\Psr7\StreamWrapper; -use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface; +use Symfony\Component\Mime\MimeTypeGuesserInterface; /** * Fedora adapter for Flysystem. @@ -29,21 +30,34 @@ class FedoraAdapter implements AdapterInterface { /** * Mimetype guesser. * - * @var \Symfony\Component\HttpFoundation\File\Mimetype\MimeTypeGuesserInterface + * @var \Symfony\Component\Mime\MimeTypeGuesserInterface */ protected $mimeTypeGuesser; + /** + * Logger. + * + * @var \Drupal\Core\Logger\LoggerChannelInterface + */ + protected $logger; + /** * Constructs a Fedora adapter for Flysystem. * * @param \Islandora\Chullo\IFedoraApi $fedora * Fedora client. - * @param \Symfony\Component\HttpFoundation\File\Mimetype\MimeTypeGuesserInterface $mime_type_guesser + * @param \Symfony\Component\Mime\MimeTypeGuesserInterface $mime_type_guesser * Mimetype guesser. + * @param \Drupal\Core\Logger\LoggerChannelInterface $logger */ - public function __construct(IFedoraApi $fedora, MimeTypeGuesserInterface $mime_type_guesser) { + public function __construct( + IFedoraApi $fedora, + MimeTypeGuesserInterface $mime_type_guesser, + LoggerChannelInterface $logger + ) { $this->fedora = $fedora; $this->mimeTypeGuesser = $mime_type_guesser; + $this->logger = $logger; } /** @@ -259,7 +273,7 @@ protected function transformToMetadata($uri) { */ public function write($path, $contents, Config $config) { $headers = [ - 'Content-Type' => $this->mimeTypeGuesser->guess($path), + 'Content-Type' => $this->mimeTypeGuesser->guessMimeType($path), ]; if ($this->has($path)) { $fedora_url = $path; @@ -274,17 +288,17 @@ public function write($path, $contents, Config $config) { $headers ); if (isset($response) && $response->getStatusCode() == 201) { - \Drupal::logger('fedora_flysystem')->info('Created a version in Fedora for ' . $fedora_url); + $this->logger->info('Created a version in Fedora for ' . $fedora_url); } else { - \Drupal::logger('fedora_flysystem')->error( + $this->logger->error( "Client error: `Failed to create a Fedora version of $fedora_url`. Response is " . print_r($response, TRUE) ); } } catch (\Exception $e) { - \Drupal::logger('fedora_flysystem')->error('Caught exception when creating version: ' . $e->getMessage() . "\n"); + $this->logger->error('Caught exception when creating version: ' . $e->getMessage() . "\n"); } } diff --git a/src/Flysystem/Fedora.php b/src/Flysystem/Fedora.php index fe7af7bae..a2ae81e3e 100644 --- a/src/Flysystem/Fedora.php +++ b/src/Flysystem/Fedora.php @@ -3,6 +3,7 @@ namespace Drupal\islandora\Flysystem; use Drupal\Core\Language\LanguageManagerInterface; +use Drupal\Core\Logger\LoggerChannelInterface; use Drupal\Core\Logger\RfcLogLevel; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Url; @@ -17,7 +18,7 @@ use Islandora\Chullo\FedoraApi; use Psr\Http\Message\RequestInterface; use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface; +use Symfony\Component\Mime\MimeTypeGuesserInterface; /** * Drupal plugin for the Fedora Flysystem adapter. @@ -38,7 +39,7 @@ class Fedora implements FlysystemPluginInterface, ContainerFactoryPluginInterfac /** * Mimetype guesser. * - * @var \Symfony\Component\HttpFoundation\File\Mimetype\MimeTypeGuesserInterface + * @var \Symfony\Component\Mime\MimeTypeGuesserInterface */ protected $mimeTypeGuesser; @@ -49,24 +50,34 @@ class Fedora implements FlysystemPluginInterface, ContainerFactoryPluginInterfac */ protected $languageManager; + /** + * Logger. + * + * @var \Drupal\Core\Logger\LoggerChannelInterface + */ + protected $logger; + /** * Constructs a Fedora plugin for Flysystem. * * @param \Islandora\Chullo\IFedoraApi $fedora * Fedora client. - * @param \Symfony\Component\HttpFoundation\File\Mimetype\MimeTypeGuesserInterface $mime_type_guesser + * @param \Symfony\Component\Mime\MimeTypeGuesserInterface $mime_type_guesser * Mimetype guesser. * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager * Language manager. + * @param \Drupal\Core\Logger\LoggerChannelInterface $logger */ public function __construct( IFedoraApi $fedora, MimeTypeGuesserInterface $mime_type_guesser, - LanguageManagerInterface $language_manager + LanguageManagerInterface $language_manager, + LoggerChannelInterface $logger ) { $this->fedora = $fedora; $this->mimeTypeGuesser = $mime_type_guesser; $this->languageManager = $language_manager; + $this->logger = $logger; } /** @@ -87,7 +98,8 @@ public static function create(ContainerInterface $container, array $configuratio return new static( $fedora, $container->get('file.mime_type.guesser'), - $container->get('language_manager') + $container->get('language_manager'), + $container->get('logger.channel.fedora_flysystem') ); } @@ -116,7 +128,7 @@ public static function addJwt(JwtAuth $jwt) { * {@inheritdoc} */ public function getAdapter() { - return new FedoraAdapter($this->fedora, $this->mimeTypeGuesser); + return new FedoraAdapter($this->fedora, $this->mimeTypeGuesser, $this->logger); } /** From 2c1d88f400f5a948b39ab957f56e4ea9a6bdefe5 Mon Sep 17 00:00:00 2001 From: Jared Whiklo Date: Wed, 22 Mar 2023 12:56:35 -0500 Subject: [PATCH 138/252] Use new package --- composer.json | 5 +++-- islandora.services.yml | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index a92aff53d..a26938622 100644 --- a/composer.json +++ b/composer.json @@ -27,13 +27,14 @@ "drupal/prepopulate" : "^2.2", "drupal/search_api": "^1.8", "drupal/token" : "^1.3", - "islandora/crayfish-commons": "dev-upgrade-5.4-symfony", + "islandora/chullo": "^1.3", + "islandora/fedora-entity-mapper": "1.x-dev", "islandora/jsonld": "^2", "stomp-php/stomp-php": "4.* || ^5" }, "require-dev": { "phpunit/phpunit": "^6", - "squizlabs/php_codesniffer": "2.7.1", + "squizlabs/php_codesniffer": "^2.7.1", "drupal/coder": "*", "sebastian/phpcpd": "*" }, diff --git a/islandora.services.yml b/islandora.services.yml index 465e8d933..74725d803 100644 --- a/islandora.services.yml +++ b/islandora.services.yml @@ -56,7 +56,7 @@ services: class: Drupal\islandora\IslandoraUtils arguments: ['@entity_type.manager', '@entity_field.manager', '@context.manager', '@flysystem_factory', '@language_manager'] islandora.entity_mapper: - class: Islandora\Crayfish\Commons\EntityMapper\EntityMapper + class: Islandora\EntityMapper\EntityMapper islandora.stomp.auth_header_listener: class: Drupal\islandora\EventSubscriber\StompHeaderEventSubscriber arguments: ['@jwt.authentication.jwt'] From 5dd96b8f22b878431961ac7f47d224f51628ff61 Mon Sep 17 00:00:00 2001 From: Jared Whiklo Date: Tue, 18 Apr 2023 14:46:32 -0500 Subject: [PATCH 139/252] Use new chullo static methods --- composer.json | 2 +- src/Flysystem/Fedora.php | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index a26938622..0db75d4a0 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "drupal/prepopulate" : "^2.2", "drupal/search_api": "^1.8", "drupal/token" : "^1.3", - "islandora/chullo": "^1.3", + "islandora/chullo": "dev-update-dependencies", "islandora/fedora-entity-mapper": "1.x-dev", "islandora/jsonld": "^2", "stomp-php/stomp-php": "4.* || ^5" diff --git a/src/Flysystem/Fedora.php b/src/Flysystem/Fedora.php index a2ae81e3e..5a3a68d85 100644 --- a/src/Flysystem/Fedora.php +++ b/src/Flysystem/Fedora.php @@ -88,11 +88,7 @@ public static function create(ContainerInterface $container, array $configuratio // Construct guzzle client to middleware that adds JWT. $stack = HandlerStack::create(); $stack->push(static::addJwt($container->get('jwt.authentication.jwt'))); - $client = new Client([ - 'handler' => $stack, - 'base_uri' => $configuration['root'], - ]); - $fedora = new FedoraApi($client); + $fedora = FedoraApi::createWithHandler($configuration['root'], $stack); // Return it. return new static( From 860abf3c06573def2a514fde29bf8316bb138930 Mon Sep 17 00:00:00 2001 From: Jared Whiklo Date: Wed, 19 Apr 2023 12:27:24 -0500 Subject: [PATCH 140/252] code style --- src/Flysystem/Adapter/FedoraAdapter.php | 11 ++++++----- src/Flysystem/Fedora.php | 14 +++++++------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/Flysystem/Adapter/FedoraAdapter.php b/src/Flysystem/Adapter/FedoraAdapter.php index eb79220d4..4ebc61c59 100644 --- a/src/Flysystem/Adapter/FedoraAdapter.php +++ b/src/Flysystem/Adapter/FedoraAdapter.php @@ -34,11 +34,11 @@ class FedoraAdapter implements AdapterInterface { */ protected $mimeTypeGuesser; - /** - * Logger. - * - * @var \Drupal\Core\Logger\LoggerChannelInterface - */ + /** + * Logger. + * + * @var \Drupal\Core\Logger\LoggerChannelInterface + */ protected $logger; /** @@ -49,6 +49,7 @@ class FedoraAdapter implements AdapterInterface { * @param \Symfony\Component\Mime\MimeTypeGuesserInterface $mime_type_guesser * Mimetype guesser. * @param \Drupal\Core\Logger\LoggerChannelInterface $logger + * The fedora adapter logger channel. */ public function __construct( IFedoraApi $fedora, diff --git a/src/Flysystem/Fedora.php b/src/Flysystem/Fedora.php index 5a3a68d85..0cbf1a12a 100644 --- a/src/Flysystem/Fedora.php +++ b/src/Flysystem/Fedora.php @@ -13,9 +13,8 @@ use Drupal\jwt\Authentication\Provider\JwtAuth; use GuzzleHttp\Exception\ConnectException; use GuzzleHttp\HandlerStack; -use GuzzleHttp\Client; -use Islandora\Chullo\IFedoraApi; use Islandora\Chullo\FedoraApi; +use Islandora\Chullo\IFedoraApi; use Psr\Http\Message\RequestInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Mime\MimeTypeGuesserInterface; @@ -50,11 +49,11 @@ class Fedora implements FlysystemPluginInterface, ContainerFactoryPluginInterfac */ protected $languageManager; - /** - * Logger. - * - * @var \Drupal\Core\Logger\LoggerChannelInterface - */ + /** + * Logger. + * + * @var \Drupal\Core\Logger\LoggerChannelInterface + */ protected $logger; /** @@ -67,6 +66,7 @@ class Fedora implements FlysystemPluginInterface, ContainerFactoryPluginInterfac * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager * Language manager. * @param \Drupal\Core\Logger\LoggerChannelInterface $logger + * The fedora adapter logger channel. */ public function __construct( IFedoraApi $fedora, From ba93ad35a34cd3313e2e56198ad070d0d88092d5 Mon Sep 17 00:00:00 2001 From: Jared Whiklo Date: Wed, 19 Apr 2023 13:00:14 -0500 Subject: [PATCH 141/252] Fix tests --- tests/src/Kernel/FedoraAdapterTest.php | 87 +++++++++++--------------- tests/src/Kernel/FedoraPluginTest.php | 8 ++- 2 files changed, 43 insertions(+), 52 deletions(-) diff --git a/tests/src/Kernel/FedoraAdapterTest.php b/tests/src/Kernel/FedoraAdapterTest.php index 10c5beb11..a3b577e42 100644 --- a/tests/src/Kernel/FedoraAdapterTest.php +++ b/tests/src/Kernel/FedoraAdapterTest.php @@ -2,12 +2,13 @@ namespace Drupal\Tests\islandora\Kernel; +use Drupal\Core\Logger\LoggerChannelInterface; use Drupal\islandora\Flysystem\Adapter\FedoraAdapter; use GuzzleHttp\Psr7\Response; use Islandora\Chullo\IFedoraApi; use League\Flysystem\Config; use Prophecy\Argument; -use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface; +use Symfony\Component\Mime\MimeTypeGuesserInterface; /** * Tests the Fedora adapter for Flysystem. @@ -17,6 +18,30 @@ */ class FedoraAdapterTest extends IslandoraKernelTestBase { + /** + * A mimetype guesser prophecy. + * + * @var \Prophecy\Prophecy\ObjectProphecy + */ + private $mime_guesser; + + /** + * A logger prophecy. + * + * @var \Prophecy\Prophecy\ObjectProphecy + */ + private $logger; + + /** + * @inheritdoc + */ + public function setUp() { + parent::setUp(); + $this->mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) + ->reveal(); + $this->logger = $this->prophesize(LoggerChannelInterface::class)->reveal(); + } + /** * Shared functionality for an adapter. */ @@ -55,10 +80,7 @@ protected function createAdapterForFail() { $prophecy->getResource('', ['Connection' => 'close'])->willReturn($response); $api = $prophecy->reveal(); - $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - - return new FedoraAdapter($api, $mime_guesser); + return new FedoraAdapter($api, $this->mime_guesser, $this->logger); } /** @@ -73,10 +95,7 @@ protected function createAdapterForFile() { $prophecy->getResource('', ['Connection' => 'close'])->willReturn($response); $api = $prophecy->reveal(); - $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - - return new FedoraAdapter($api, $mime_guesser); + return new FedoraAdapter($api, $this->mime_guesser, $this->logger); } /** @@ -98,10 +117,7 @@ protected function createAdapterForDirectory() { $prophecy->getResourceHeaders('', ['Connection' => 'close'])->willReturn($response); $api = $prophecy->reveal(); - $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - - return new FedoraAdapter($api, $mime_guesser); + return new FedoraAdapter($api, $this->mime_guesser, $this->logger); } /** @@ -126,10 +142,7 @@ protected function createAdapterForWrite() { $api = $fedora_prophecy->reveal(); - $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - - return new FedoraAdapter($api, $mime_guesser); + return new FedoraAdapter($api, $this->mime_guesser, $this->logger); } /** @@ -149,10 +162,7 @@ protected function createAdapterForWriteFail() { $api = $fedora_prophecy->reveal(); - $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - - return new FedoraAdapter($api, $mime_guesser); + return new FedoraAdapter($api, $this->mime_guesser, $this->logger); } /** @@ -180,10 +190,7 @@ protected function createAdapterForCreateDir() { $api = $fedora_prophecy->reveal(); - $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - - return new FedoraAdapter($api, $mime_guesser); + return new FedoraAdapter($api, $this->mime_guesser, $this->logger); } /** @@ -199,10 +206,7 @@ protected function createAdapterForDelete() { $fedora_prophecy->getResourceHeaders('', ['Connection' => 'close'])->willReturn($prophecy->reveal()); $api = $fedora_prophecy->reveal(); - $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - - return new FedoraAdapter($api, $mime_guesser); + return new FedoraAdapter($api, $this->mime_guesser, $this->logger); } /** @@ -218,10 +222,7 @@ protected function createAdapterForDeleteFail() { $api = $fedora_prophecy->reveal(); - $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - - return new FedoraAdapter($api, $mime_guesser); + return new FedoraAdapter($api, $this->mime_guesser, $this->logger); } /** @@ -249,10 +250,7 @@ protected function createAdapterForDeleteWithTombstone() { $api = $fedora_prophecy->reveal(); - $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - - return new FedoraAdapter($api, $mime_guesser); + return new FedoraAdapter($api, $this->mime_guesser, $this->logger); } /** @@ -280,10 +278,7 @@ protected function createAdapterForDeleteWithTombstoneFail() { $api = $fedora_prophecy->reveal(); - $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - - return new FedoraAdapter($api, $mime_guesser); + return new FedoraAdapter($api, $this->mime_guesser, $this->logger); } /** @@ -644,10 +639,7 @@ public function testRename() { $api = $fedora_prophecy->reveal(); - $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - - $adapter = new FedoraAdapter($api, $mime_guesser); + $adapter = new FedoraAdapter($api, $this->mime_guesser, $this->logger); $this->assertTrue($adapter->rename('', '') == TRUE, "rename() must return TRUE on success"); } @@ -664,10 +656,7 @@ public function testCreateDirFail() { $api = $fedora_prophecy->reveal(); - $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - - $adapter = new FedoraAdapter($api, $mime_guesser); + $adapter = new FedoraAdapter($api, $this->mime_guesser, $this->logger); $this->assertTrue($adapter->createDir('', $this->prophesize(Config::class) ->reveal()) == FALSE, "createDir() must return FALSE on fail"); diff --git a/tests/src/Kernel/FedoraPluginTest.php b/tests/src/Kernel/FedoraPluginTest.php index 674915078..cd1c83256 100644 --- a/tests/src/Kernel/FedoraPluginTest.php +++ b/tests/src/Kernel/FedoraPluginTest.php @@ -2,11 +2,12 @@ namespace Drupal\Tests\islandora\Kernel; +use Drupal\Core\Logger\LoggerChannelInterface; use Drupal\islandora\Flysystem\Fedora; -use League\Flysystem\AdapterInterface; use Islandora\Chullo\IFedoraApi; +use League\Flysystem\AdapterInterface; use Psr\Http\Message\ResponseInterface; -use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface; +use Symfony\Component\Mime\MimeTypeGuesserInterface; /** * Tests the Fedora plugin for Flysystem. @@ -32,8 +33,9 @@ protected function createPlugin($return_code) { $mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class)->reveal(); $language_manager = $this->container->get('language_manager'); + $logger = $this->prophesize(LoggerChannelInterface::class)->reveal(); - return new Fedora($api, $mime_guesser, $language_manager); + return new Fedora($api, $mime_guesser, $language_manager, $logger); } /** From ff4e0cafc4dd59b0703516a1cccd19356be58d96 Mon Sep 17 00:00:00 2001 From: Jared Whiklo Date: Wed, 19 Apr 2023 13:40:34 -0500 Subject: [PATCH 142/252] More code style --- tests/src/Kernel/FedoraAdapterTest.php | 36 +++++++++++++------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/src/Kernel/FedoraAdapterTest.php b/tests/src/Kernel/FedoraAdapterTest.php index a3b577e42..e51610637 100644 --- a/tests/src/Kernel/FedoraAdapterTest.php +++ b/tests/src/Kernel/FedoraAdapterTest.php @@ -23,7 +23,7 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { * * @var \Prophecy\Prophecy\ObjectProphecy */ - private $mime_guesser; + private $mimeGuesser; /** * A logger prophecy. @@ -33,13 +33,13 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { private $logger; /** - * @inheritdoc + * {@inheritdoc} */ public function setUp() { - parent::setUp(); - $this->mime_guesser = $this->prophesize(MimeTypeGuesserInterface::class) - ->reveal(); - $this->logger = $this->prophesize(LoggerChannelInterface::class)->reveal(); + parent::setUp(); + $this->mimeGuesser = $this->prophesize(MimeTypeGuesserInterface::class) + ->reveal(); + $this->logger = $this->prophesize(LoggerChannelInterface::class)->reveal(); } /** @@ -80,7 +80,7 @@ protected function createAdapterForFail() { $prophecy->getResource('', ['Connection' => 'close'])->willReturn($response); $api = $prophecy->reveal(); - return new FedoraAdapter($api, $this->mime_guesser, $this->logger); + return new FedoraAdapter($api, $this->mimeGuesser, $this->logger); } /** @@ -95,7 +95,7 @@ protected function createAdapterForFile() { $prophecy->getResource('', ['Connection' => 'close'])->willReturn($response); $api = $prophecy->reveal(); - return new FedoraAdapter($api, $this->mime_guesser, $this->logger); + return new FedoraAdapter($api, $this->mimeGuesser, $this->logger); } /** @@ -117,7 +117,7 @@ protected function createAdapterForDirectory() { $prophecy->getResourceHeaders('', ['Connection' => 'close'])->willReturn($response); $api = $prophecy->reveal(); - return new FedoraAdapter($api, $this->mime_guesser, $this->logger); + return new FedoraAdapter($api, $this->mimeGuesser, $this->logger); } /** @@ -142,7 +142,7 @@ protected function createAdapterForWrite() { $api = $fedora_prophecy->reveal(); - return new FedoraAdapter($api, $this->mime_guesser, $this->logger); + return new FedoraAdapter($api, $this->mimeGuesser, $this->logger); } /** @@ -162,7 +162,7 @@ protected function createAdapterForWriteFail() { $api = $fedora_prophecy->reveal(); - return new FedoraAdapter($api, $this->mime_guesser, $this->logger); + return new FedoraAdapter($api, $this->mimeGuesser, $this->logger); } /** @@ -190,7 +190,7 @@ protected function createAdapterForCreateDir() { $api = $fedora_prophecy->reveal(); - return new FedoraAdapter($api, $this->mime_guesser, $this->logger); + return new FedoraAdapter($api, $this->mimeGuesser, $this->logger); } /** @@ -206,7 +206,7 @@ protected function createAdapterForDelete() { $fedora_prophecy->getResourceHeaders('', ['Connection' => 'close'])->willReturn($prophecy->reveal()); $api = $fedora_prophecy->reveal(); - return new FedoraAdapter($api, $this->mime_guesser, $this->logger); + return new FedoraAdapter($api, $this->mimeGuesser, $this->logger); } /** @@ -222,7 +222,7 @@ protected function createAdapterForDeleteFail() { $api = $fedora_prophecy->reveal(); - return new FedoraAdapter($api, $this->mime_guesser, $this->logger); + return new FedoraAdapter($api, $this->mimeGuesser, $this->logger); } /** @@ -250,7 +250,7 @@ protected function createAdapterForDeleteWithTombstone() { $api = $fedora_prophecy->reveal(); - return new FedoraAdapter($api, $this->mime_guesser, $this->logger); + return new FedoraAdapter($api, $this->mimeGuesser, $this->logger); } /** @@ -278,7 +278,7 @@ protected function createAdapterForDeleteWithTombstoneFail() { $api = $fedora_prophecy->reveal(); - return new FedoraAdapter($api, $this->mime_guesser, $this->logger); + return new FedoraAdapter($api, $this->mimeGuesser, $this->logger); } /** @@ -639,7 +639,7 @@ public function testRename() { $api = $fedora_prophecy->reveal(); - $adapter = new FedoraAdapter($api, $this->mime_guesser, $this->logger); + $adapter = new FedoraAdapter($api, $this->mimeGuesser, $this->logger); $this->assertTrue($adapter->rename('', '') == TRUE, "rename() must return TRUE on success"); } @@ -656,7 +656,7 @@ public function testCreateDirFail() { $api = $fedora_prophecy->reveal(); - $adapter = new FedoraAdapter($api, $this->mime_guesser, $this->logger); + $adapter = new FedoraAdapter($api, $this->mimeGuesser, $this->logger); $this->assertTrue($adapter->createDir('', $this->prophesize(Config::class) ->reveal()) == FALSE, "createDir() must return FALSE on fail"); From 7b0ff739cd8bd8f354b2085c34ae93a72bfac55b Mon Sep 17 00:00:00 2001 From: Jared Whiklo Date: Thu, 27 Apr 2023 09:34:09 -0500 Subject: [PATCH 143/252] Update dependencies to tagged versions --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 0db75d4a0..3ceed0e11 100644 --- a/composer.json +++ b/composer.json @@ -27,8 +27,8 @@ "drupal/prepopulate" : "^2.2", "drupal/search_api": "^1.8", "drupal/token" : "^1.3", - "islandora/chullo": "dev-update-dependencies", - "islandora/fedora-entity-mapper": "1.x-dev", + "islandora/chullo": "^2.0", + "islandora/fedora-entity-mapper": "^1.0", "islandora/jsonld": "^2", "stomp-php/stomp-php": "4.* || ^5" }, From 138eab201673bdeed163dcbe2a1db7476c3f5fb6 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Wed, 3 May 2023 16:42:03 -0300 Subject: [PATCH 144/252] Issue #941: Only add
    tags to plain text extracted text fields. (#942) * Issue #941: Only add
    tags to plain text extracted text fields. * Fix PHPCS errors. * Don't add
    tags to edited OCR text field if it looks like hOCR. * Respond to PHPCS errors. --- .../islandora_text_extraction.module | 4 ++++ .../src/Controller/MediaSourceController.php | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/modules/islandora_text_extraction/islandora_text_extraction.module b/modules/islandora_text_extraction/islandora_text_extraction.module index 5d6f64370..ca330dd42 100644 --- a/modules/islandora_text_extraction/islandora_text_extraction.module +++ b/modules/islandora_text_extraction/islandora_text_extraction.module @@ -40,6 +40,10 @@ function islandora_text_extraction_media_presave(MediaInterface $media) { $file = File::load($file_id); if ($file) { $data = file_get_contents($file->getFileUri()); + // Check if it's already markup like hOCR. + if (substr($data, 0, 5) == 'set('field_edited_text', $data); $media->field_edited_text->format = 'basic_html'; diff --git a/modules/islandora_text_extraction/src/Controller/MediaSourceController.php b/modules/islandora_text_extraction/src/Controller/MediaSourceController.php index 14c36ebdb..f15e42d56 100644 --- a/modules/islandora_text_extraction/src/Controller/MediaSourceController.php +++ b/modules/islandora_text_extraction/src/Controller/MediaSourceController.php @@ -108,7 +108,11 @@ public function attachToMedia( $this->getLogger('islandora')->warning("Field $destination_field is not defined in Media Type {$media->bundle()}"); } if ($media->hasField($destination_text_field)) { - $media->{$destination_text_field}->setValue(nl2br($contents)); + // @todo The request actually has a malformed parameter string, ?text_format=plain_text?connection_close=true. + if (substr($request->query->get('text_format'), 0, 10) == 'plain_text') { + $contents = nl2br($contents); + } + $media->{$destination_text_field}->setValue($contents); } else { $this->getLogger('islandora')->warning("Field $destination_text_field is not defined in Media Type {$media->bundle()}"); From 06dd1651ac6a57a868a8e6bac63b2ff38f9eaeeb Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Tue, 2 May 2023 12:34:47 -0300 Subject: [PATCH 145/252] Issue #939: Fix incorrect IIIF Manifest canvas Ids. --- modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index c2a2fbc3c..90945664b 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -136,7 +136,7 @@ public function render() { $request_url = $this->request->getRequestUri(); // Strip off the last URI component to get the base ID of the URL. // @todo assumming the view is a path like /node/1/manifest.json - $url_components = explode('/', $request_url); + $url_components = explode('/', trim($request_url, '/')); array_pop($url_components); $content_path = implode('/', $url_components); $iiif_base_id = $request_host . '/' . $content_path; From 0bd05b6c449b1c7ec586e025b0ba5f816809c6bc Mon Sep 17 00:00:00 2001 From: kstapelfeldt Date: Fri, 5 May 2023 11:11:59 -0400 Subject: [PATCH 146/252] Update README.md Remove lobster holding 8 sign. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 32e69ea99..546d21923 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ![Islandora](https://cloud.githubusercontent.com/assets/2371345/25624809/f95b0972-2f30-11e7-8992-a8f135402cdc.png) Islandora +# Islandora [![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.4-8892BF.svg?style=flat-square)](https://php.net/) [![Build Status](https://github.com/islandora/islandora/actions/workflows/build-2.x.yml/badge.svg)](https://github.com/Islandora/islandora/actions) From 78baec07e844819db630d4520f40d61d84b3a4a9 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Fri, 21 Apr 2023 15:46:01 -0300 Subject: [PATCH 147/252] Issue #973 Add hooks to IIIF manifest Views Style plugin. --- .../src/Plugin/views/style/IIIFManifest.php | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 90945664b..ed0541767 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -4,6 +4,7 @@ use Drupal\views\Plugin\views\style\StylePluginBase; use Drupal\Core\Entity\EntityTypeManagerInterface; +use \Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\Url; @@ -90,11 +91,16 @@ class IIIFManifest extends StylePluginBase { * @var \Drupal\Core\Messenger\MessengerInterface */ protected $messenger; + + /** + * @var \Drupal\Core\Extention\ModuleHandlerInterface; + */ + protected $moduleHandler; /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system, Client $http_client, MessengerInterface $messenger) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system, Client $http_client, MessengerInterface $messenger, ModuleHandlerInterface $moduleHandler) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->serializer = $serializer; @@ -104,6 +110,7 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition $this->fileSystem = $file_system; $this->httpClient = $http_client; $this->messenger = $messenger; + $this->moduleHandler = $moduleHandler; } /** @@ -120,10 +127,21 @@ public static function create(ContainerInterface $container, array $configuratio $container->get('entity_type.manager'), $container->get('file_system'), $container->get('http_client'), - $container->get('messenger') + $container->get('messenger'), + $container->get('module_handler') ); } + /** + * Return the request property. + * + * @return \Symfony\Component\HttpFoundation\Request + * The Symfony request object + */ + public function getRequest() { + return $this->request; + } + /** * {@inheritdoc} */ @@ -170,6 +188,9 @@ public function render() { $content_type = 'json'; + // Give other modules a chance to alter the manifest. + $this->moduleHandler->alter('islandora_iiif_manifest', $json, $this); + return $this->serializer->serialize($json, $content_type, ['views_style_plugin' => $this]); } @@ -288,11 +309,15 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas ]; } + // Give other modules a chance to alter the canvas + $alter_options = ['options' => $this->options, 'views_plugin' => $this]; + $this->moduleHandler->alter('islandora_iiif_manifest_canvas', $tmp_canvas, $row, $alter_options); + $canvases[] = $tmp_canvas; } } } - + return $canvases; } From 43f32d1bcfbbbc279ae3678e6b610fbe59c3bbad Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Fri, 21 Apr 2023 16:40:51 -0300 Subject: [PATCH 148/252] Issue #937: Fix PHPCS issues. --- .../src/Plugin/views/style/IIIFManifest.php | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index ed0541767..3501ada57 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -4,7 +4,7 @@ use Drupal\views\Plugin\views\style\StylePluginBase; use Drupal\Core\Entity\EntityTypeManagerInterface; -use \Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\Url; @@ -91,9 +91,11 @@ class IIIFManifest extends StylePluginBase { * @var \Drupal\Core\Messenger\MessengerInterface */ protected $messenger; - + /** - * @var \Drupal\Core\Extention\ModuleHandlerInterface; + * Module Handler for running hooks. + * + * @var \Drupal\Core\Extention\ModuleHandlerInterface */ protected $moduleHandler; @@ -134,7 +136,7 @@ public static function create(ContainerInterface $container, array $configuratio /** * Return the request property. - * + * * @return \Symfony\Component\HttpFoundation\Request * The Symfony request object */ @@ -309,15 +311,18 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas ]; } - // Give other modules a chance to alter the canvas - $alter_options = ['options' => $this->options, 'views_plugin' => $this]; + // Give other modules a chance to alter the canvas. + $alter_options = [ + 'options' => $this->options, + 'views_plugin' => $this + ]; $this->moduleHandler->alter('islandora_iiif_manifest_canvas', $tmp_canvas, $row, $alter_options); $canvases[] = $tmp_canvas; } } } - + return $canvases; } From 5bc1584dd7189add4b1101075507d62a3358b738 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Fri, 21 Apr 2023 16:57:50 -0300 Subject: [PATCH 149/252] Issue 937: More PHPCS fixes. --- .../islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 3501ada57..55fe36340 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -94,7 +94,7 @@ class IIIFManifest extends StylePluginBase { /** * Module Handler for running hooks. - * + * * @var \Drupal\Core\Extention\ModuleHandlerInterface */ protected $moduleHandler; @@ -314,7 +314,7 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas // Give other modules a chance to alter the canvas. $alter_options = [ 'options' => $this->options, - 'views_plugin' => $this + 'views_plugin' => $this, ]; $this->moduleHandler->alter('islandora_iiif_manifest_canvas', $tmp_canvas, $row, $alter_options); From 17b5049578fb7152f5d032c06137628b45024761 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Fri, 2 Jun 2023 16:30:09 -0300 Subject: [PATCH 150/252] Issue #944: Un-hide arguments field in Text Extraction action. --- .../src/Plugin/Action/GenerateOCRDerivative.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php b/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php index 63a714a80..9d1716225 100644 --- a/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php +++ b/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php @@ -37,11 +37,10 @@ public function defaultConfiguration() { */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { $form = parent::buildConfigurationForm($form, $form_state); - $form['mimetype']['#description'] = $this->t('Mimetype to convert to (e.g. application/xml, etc...)'); - $form['mimetype']['#value'] = 'text/plain'; - $form['mimetype']['#type'] = 'textfield'; + - unset($form['args']); + $form['args']['#description'] = $this->t("Arguments to send to Tesseract. To generate hOCR, use:
    -c tessedit_create_hocr=1 -c hocr_font_info=0"); + return $form; } From 61c6e737c103f88bb9d9c2895327ea211473747b Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Tue, 6 Jun 2023 19:58:05 -0300 Subject: [PATCH 151/252] Fix PHPCS errors. --- .../src/Plugin/Action/GenerateOCRDerivative.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php b/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php index 9d1716225..272e9f01b 100644 --- a/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php +++ b/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php @@ -37,10 +37,9 @@ public function defaultConfiguration() { */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { $form = parent::buildConfigurationForm($form, $form_state); - $form['args']['#description'] = $this->t("Arguments to send to Tesseract. To generate hOCR, use:
    -c tessedit_create_hocr=1 -c hocr_font_info=0"); - + return $form; } From a7eaacc1d5086fb0d2c21f78cae17e7970b0ffb5 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Fri, 9 Jun 2023 16:26:18 -0300 Subject: [PATCH 152/252] Issue #947 Add tokens for Original File filename, extension. --- islandora.tokens.inc | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/islandora.tokens.inc b/islandora.tokens.inc index abbe6474a..f69418afe 100644 --- a/islandora.tokens.inc +++ b/islandora.tokens.inc @@ -19,6 +19,18 @@ function islandora_token_info() { 'name' => t('Islandora Tokens'), 'description' => t('Tokens for Islandora objects.'), ]; + $node['media-original-file:filename'] = [ + 'name' => t('Media: Original File filename without extension.'), + 'description' => t('File name without extension of original uploaded file associated with Islandora Object via Media.'), + ]; + $node['media-original-file:basename'] = [ + 'name' => t('Media: Original File filename with extension.'), + 'description' => t('File name with extension of original uploaded file associated with Islandora Object via Media.'), + ]; + $node['media-original-file:extension'] = [ + 'name' => t('Media: Original File extension.'), + 'description' => t('File extension of original uploaded file associated with Islandora Object via Media.'), + ]; $node['media-thumbnail-image:url'] = [ 'name' => t('Media: Thumbnail Image URL.'), 'description' => t('URL of Thumbnail Image associated with Islandora Object via Media.'), @@ -70,6 +82,23 @@ function islandora_tokens($type, $tokens, array $data, array $options, Bubbleabl $islandoraUtils = \Drupal::service('islandora.utils'); foreach ($tokens as $name => $original) { switch ($name) { + case 'media-original-file:basename': + case 'media-original-file:filename': + case 'media-original-file:extension': + $term = $islandoraUtils->getTermForUri('http://pcdm.org/use#OriginalFile'); + $media = $islandoraUtils->getMediaWithTerm($data['node'], $term); + // Is there media? + if ($media) { + $file = \Drupal::service('islandora.media_source_service')->getSourceFile($media); + if (!empty($file)) { + $path_info = pathinfo($file->createFileUrl()); + $key = explode(':', $name)[1]; + if (array_key_exists($key, $path_info)) { + $replacements[$original] = $path_info[$key]; + } + } + } + break; case 'media-thumbnail-image:url': case 'media_thumbnail_image:url': $term = $islandoraUtils->getTermForUri('http://pcdm.org/use#ThumbnailImage'); From 374ab02d07f4ce56d1afc8ceb23974335c6f1d62 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 15 Jun 2023 12:03:22 -0300 Subject: [PATCH 153/252] phpcs --- islandora.tokens.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/islandora.tokens.inc b/islandora.tokens.inc index f69418afe..ab7bb0736 100644 --- a/islandora.tokens.inc +++ b/islandora.tokens.inc @@ -99,6 +99,7 @@ function islandora_tokens($type, $tokens, array $data, array $options, Bubbleabl } } break; + case 'media-thumbnail-image:url': case 'media_thumbnail_image:url': $term = $islandoraUtils->getTermForUri('http://pcdm.org/use#ThumbnailImage'); From 622eaab6a0b3c6d7c4868b0789646cbaabcbd6e5 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Thu, 8 Jun 2023 11:31:13 -0300 Subject: [PATCH 154/252] Issue 944: Pull hOCR from separate media in IIIF manifest. --- .../src/Plugin/views/style/IIIFManifest.php | 190 +++++++++++------- 1 file changed, 115 insertions(+), 75 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 55fe36340..49c35208a 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -2,22 +2,23 @@ namespace Drupal\islandora_iiif\Plugin\views\style; -use Drupal\views\Plugin\views\style\StylePluginBase; +use Drupal\Core\Config\ImmutableConfig; +use Drupal\Core\File\FileSystemInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\Field\FieldItemInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\Url; +use Drupal\islandora\IslandoraUtils; +use Drupal\views\Plugin\views\style\StylePluginBase; use Drupal\views\ResultRow; -use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\Serializer\SerializerInterface; -use Symfony\Component\HttpFoundation\Request; -use Drupal\Core\Config\ImmutableConfig; -use Drupal\Core\File\FileSystemInterface; use GuzzleHttp\Client; use GuzzleHttp\Exception\ClientException; use GuzzleHttp\Exception\ConnectException; use GuzzleHttp\Exception\ServerException; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\Serializer\SerializerInterface; +use Symfony\Component\HttpFoundation\Request; /** * Provide serializer format for IIIF Manifest. @@ -33,6 +34,13 @@ */ class IIIFManifest extends StylePluginBase { +/** + * Islandora utility functions. + * + * @var \Drupal\islandora\IslandoraUtils + */ + protected $utils; + /** * {@inheritdoc} */ @@ -92,17 +100,10 @@ class IIIFManifest extends StylePluginBase { */ protected $messenger; - /** - * Module Handler for running hooks. - * - * @var \Drupal\Core\Extention\ModuleHandlerInterface - */ - protected $moduleHandler; - /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system, Client $http_client, MessengerInterface $messenger, ModuleHandlerInterface $moduleHandler) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system, Client $http_client, MessengerInterface $messenger, IslandoraUtils $utils) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->serializer = $serializer; @@ -112,7 +113,8 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition $this->fileSystem = $file_system; $this->httpClient = $http_client; $this->messenger = $messenger; - $this->moduleHandler = $moduleHandler; + $this->utils = $utils; + } /** @@ -130,20 +132,10 @@ public static function create(ContainerInterface $container, array $configuratio $container->get('file_system'), $container->get('http_client'), $container->get('messenger'), - $container->get('module_handler') + $container->get('islandora.utils') ); } - /** - * Return the request property. - * - * @return \Symfony\Component\HttpFoundation\Request - * The Symfony request object - */ - public function getRequest() { - return $this->request; - } - /** * {@inheritdoc} */ @@ -161,6 +153,11 @@ public function render() { $content_path = implode('/', $url_components); $iiif_base_id = $request_host . '/' . $content_path; + /** + * @var \Drupal\taxonomy\TermInterface|null + */ + $structured_text_term = $this->utils->getTermForUri($this->options['structured_text_term_uri']); + // @see https://iiif.io/api/presentation/2.1/#manifest $json += [ '@type' => 'sc:Manifest', @@ -180,7 +177,7 @@ public function render() { // For each row in the View result. foreach ($this->view->result as $row) { // Add the IIIF URL to the image to print out as JSON. - $canvases = $this->getTileSourceFromRow($row, $iiif_address, $iiif_base_id); + $canvases = $this->getTileSourceFromRow($row, $iiif_address, $iiif_base_id, $structured_text_term); foreach ($canvases as $tile_source) { $json['sequences'][0]['canvases'][] = $tile_source; } @@ -190,9 +187,6 @@ public function render() { $content_type = 'json'; - // Give other modules a chance to alter the manifest. - $this->moduleHandler->alter('islandora_iiif_manifest', $json, $this); - return $this->serializer->serialize($json, $content_type, ['views_style_plugin' => $this]); } @@ -206,18 +200,41 @@ public function render() { * @param string $iiif_base_id * The URL for the request, minus the last part of the URL, * which is likely "manifest". + * @param \Drupal\taxonomy\TermInterface|null $structured_text_term + * The term that structured text media references, if any. * * @return array * List of IIIF URLs to display in the Openseadragon viewer. */ - protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_base_id) { + protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_base_id, $structured_text_term) { $canvases = []; foreach (array_filter(array_values($this->options['iiif_tile_field'])) as $iiif_tile_field) { $viewsField = $this->view->field[$iiif_tile_field]; $iiif_ocr_file_field = !empty($this->options['iiif_ocr_file_field']) ? array_filter(array_values($this->options['iiif_ocr_file_field'])) : []; + $ocrField = count($iiif_ocr_file_field) > 0 ? $this->view->field[$iiif_ocr_file_field[0]] : NULL; $entity = $viewsField->getEntity($row); + if ($ocrField) { + $ocr_entity = $entity; + $ocr_field_name = $ocrField->definition['field_name']; + if (!is_null($ocrField_name)) { + $ocrs = $ocr_entity->{$ocr_field_name}; + $ocr = isset($ocrs[$i]) ? $ocrs[$i] : FALSE; + $ocr_url = $ocr->entity->createFileUrl(FALSE); + } + } + else if ($structured_text_term) { + $parent_node = $this->utils->getParentNode($entity); + $ocr_entity_array = $this->utils->getMediaReferencingNodeAndTerm($parent_node, $structured_text_term); + $ocr_entity_id = is_array($ocr_entity_array) ? array_shift($ocr_entity_array) : NULL; + $ocr_entity = $ocr_entity_id ? $this->entityTypeManager->getStorage('media')->load($ocr_entity_id) : NULL; + $ocr_file_source = $ocr_entity ? $ocr_entity->getSource() : NULL; + $ocr_fid = $ocr_file_source->getSourceFieldValue($ocr_entity); + $ocr_file = $this->entityTypeManager->getStorage('file')->load($ocr_fid); + $ocr_url = $ocr_file->createFileUrl(FALSE); + } + if (isset($entity->{$viewsField->definition['field_name']})) { /** @var \Drupal\Core\Field\FieldItemListInterface $images */ @@ -228,11 +245,6 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas continue; } - if (!is_null($ocrField)) { - $ocrs = $entity->{$ocrField->definition['field_name']}; - $ocr = isset($ocrs[$i]) ? $ocrs[$i] : FALSE; - } - // Create the IIIF URL for this file // Visiting $iiif_url will resolve to the info.json for the image. $file_url = $image->entity->createFileUrl(FALSE); @@ -243,35 +255,8 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas $canvas_id = $iiif_base_id . '/canvas/' . $entity->id(); $annotation_id = $iiif_base_id . '/annotation/' . $entity->id(); - // Try to fetch the IIIF metadata for the image. - try { - $info_json = $this->httpClient->get($iiif_url)->getBody(); - $resource = json_decode($info_json, TRUE); - $width = $resource['width']; - $height = $resource['height']; - } - catch (ClientException | ServerException | ConnectException $e) { - // If we couldn't get the info.json from IIIF - // try seeing if we can get it from Drupal. - if (empty($width) || empty($height)) { - // Get the image properties so we know the image width/height. - $properties = $image->getProperties(); - $width = isset($properties['width']) ? $properties['width'] : 0; - $height = isset($properties['height']) ? $properties['height'] : 0; - - // If this is a TIFF AND we don't know the width/height - // see if we can get the image size via PHP's core function. - if ($mime_type === 'image/tiff' && !$width || !$height) { - $uri = $image->entity->getFileUri(); - $path = $this->fileSystem->realpath($uri); - $image_size = getimagesize($path); - if ($image_size) { - $width = $image_size[0]; - $height = $image_size[1]; - } - } - } - } + [$width, $height] = $this->getCanvasDimensions($iiif_url, $image, $mime_type); + $tmp_canvas = [ // @see https://iiif.io/api/presentation/2.1/#canvas '@id' => $canvas_id, @@ -302,22 +287,15 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas ], ]; - if (isset($ocr) && $ocr != FALSE) { + if ($ocr_url) { $tmp_canvas['seeAlso'] = [ - '@id' => $ocr->entity->createFileUrl(FALSE), + '@id' => $ocr_url, 'format' => 'text/vnd.hocr+html', 'profile' => 'http://kba.cloud/hocr-spec', 'label' => 'hOCR embedded text', ]; } - // Give other modules a chance to alter the canvas. - $alter_options = [ - 'options' => $this->options, - 'views_plugin' => $this, - ]; - $this->moduleHandler->alter('islandora_iiif_manifest_canvas', $tmp_canvas, $row, $alter_options); - $canvases[] = $tmp_canvas; } } @@ -326,6 +304,50 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas return $canvases; } + /** + * Try to fetch the IIIF metadata for the image. + * + * @param string $iiif_url + * Base URL of the canvas + * @param FieldItemInterface $image + * The image field. + * @param string $mime_type + * The mime type of the image. + * @return [string] + * The width and height of the image. + */ + protected function getCanvasDimensions(string $iiif_url, FieldItemInterface $image, string $mime_type) { + try { + $info_json = $this->httpClient->get($iiif_url)->getBody(); + $resource = json_decode($info_json, TRUE); + $width = $resource['width']; + $height = $resource['height']; + } + catch (ClientException | ServerException | ConnectException $e) { + // If we couldn't get the info.json from IIIF + // try seeing if we can get it from Drupal. + if (empty($width) || empty($height)) { + // Get the image properties so we know the image width/height. + $properties = $image->getProperties(); + $width = isset($properties['width']) ? $properties['width'] : 0; + $height = isset($properties['height']) ? $properties['height'] : 0; + + // If this is a TIFF AND we don't know the width/height + // see if we can get the image size via PHP's core function. + if ($mime_type === 'image/tiff' && !$width || !$height) { + $uri = $image->entity->getFileUri(); + $path = $this->fileSystem->realpath($uri); + $image_size = getimagesize($path); + if ($image_size) { + $width = $image_size[0]; + $height = $image_size[1]; + } + } + } + } + return [$width, $height]; + } + /** * Pull a title from the node or media passed to this view. * @@ -426,6 +448,15 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { '#options' => $field_options, '#required' => FALSE, ]; + $form['structured_text_term'] = [ + '#type' => 'entity_autocomplete', + '#target_type' => 'taxonomy_term', + '#title' => $this->t('Structured text term'), + '#default_value' => $this->utils->getTermForUri($this->options['structured_text_term_uri']), + '#required' => FALSE, + '#description' => $this->t('Term indicating the media that holds structured text, such as hOCR, for the given object.'), + ]; + } /** @@ -436,6 +467,15 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { */ public function getFormats() { return ['json' => 'json']; + } + + public function submitOptionsForm(&$form, FormStateInterface $form_state) { + $style_options = $form_state->getValue('style_options'); + $tid = $style_options['structured_text_term']; + $term = $this->entityTypeManager->getStorage('taxonomy_term')->load($tid); + $style_options['structured_text_term_uri'] = $this->utils->getUriForTerm($term); + $form_state->setValue('style_options', $style_options); + parent::submitOptionsForm($form, $form_state); } } From 9ef3bcf440255d54ebb63d57bf72c7ea0822c60f Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Thu, 8 Jun 2023 12:30:21 -0300 Subject: [PATCH 155/252] Refactor IIIF Manifest Views Style plugin. --- .../src/Plugin/views/style/IIIFManifest.php | 70 ++++++++++++------- 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 49c35208a..9fde1ed74 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -3,8 +3,9 @@ namespace Drupal\islandora_iiif\Plugin\views\style; use Drupal\Core\Config\ImmutableConfig; -use Drupal\Core\File\FileSystemInterface; +use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\File\FileSystemInterface; use Drupal\Core\Field\FieldItemInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\MessengerInterface; @@ -210,33 +211,9 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas $canvases = []; foreach (array_filter(array_values($this->options['iiif_tile_field'])) as $iiif_tile_field) { $viewsField = $this->view->field[$iiif_tile_field]; - $iiif_ocr_file_field = !empty($this->options['iiif_ocr_file_field']) ? array_filter(array_values($this->options['iiif_ocr_file_field'])) : []; - - $ocrField = count($iiif_ocr_file_field) > 0 ? $this->view->field[$iiif_ocr_file_field[0]] : NULL; $entity = $viewsField->getEntity($row); - if ($ocrField) { - $ocr_entity = $entity; - $ocr_field_name = $ocrField->definition['field_name']; - if (!is_null($ocrField_name)) { - $ocrs = $ocr_entity->{$ocr_field_name}; - $ocr = isset($ocrs[$i]) ? $ocrs[$i] : FALSE; - $ocr_url = $ocr->entity->createFileUrl(FALSE); - } - } - else if ($structured_text_term) { - $parent_node = $this->utils->getParentNode($entity); - $ocr_entity_array = $this->utils->getMediaReferencingNodeAndTerm($parent_node, $structured_text_term); - $ocr_entity_id = is_array($ocr_entity_array) ? array_shift($ocr_entity_array) : NULL; - $ocr_entity = $ocr_entity_id ? $this->entityTypeManager->getStorage('media')->load($ocr_entity_id) : NULL; - $ocr_file_source = $ocr_entity ? $ocr_entity->getSource() : NULL; - $ocr_fid = $ocr_file_source->getSourceFieldValue($ocr_entity); - $ocr_file = $this->entityTypeManager->getStorage('file')->load($ocr_fid); - $ocr_url = $ocr_file->createFileUrl(FALSE); - } - if (isset($entity->{$viewsField->definition['field_name']})) { - /** @var \Drupal\Core\Field\FieldItemListInterface $images */ $images = $entity->{$viewsField->definition['field_name']}; foreach ($images as $i => $image) { @@ -287,7 +264,7 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas ], ]; - if ($ocr_url) { + if ($ocr_url = $this->getOcrUrl($entity, $structured_text_term)) { $tmp_canvas['seeAlso'] = [ '@id' => $ocr_url, 'format' => 'text/vnd.hocr+html', @@ -348,6 +325,47 @@ protected function getCanvasDimensions(string $iiif_url, FieldItemInterface $ima return [$width, $height]; } + /** + * Retrieves a URL text with positional data such as hOCR + * + * @param EntityInterface $entity + * The entity at the current row. + * @param \Drupal\taxonomy\TermInterface|null $structured_text_term + * The term that structured text media references, if any. + + * return String|FALSE + * The absolute URL of the current row's structured text, + * or FALSE if none. + */ + protected function getOcrUrl(EntityInterface $entity, $structured_text_term) { + $ocr_url = FALSE; + $iiif_ocr_file_field = !empty($this->options['iiif_ocr_file_field']) ? array_filter(array_values($this->options['iiif_ocr_file_field'])) : []; + $ocrField = count($iiif_ocr_file_field) > 0 ? $this->view->field[$iiif_ocr_file_field[0]] : NULL; + if ($ocrField) { + $ocr_entity = $entity; + $ocr_field_name = $ocrField->definition['field_name']; + if (!is_null($ocrField_name)) { + $ocrs = $ocr_entity->{$ocr_field_name}; + $ocr = isset($ocrs[$i]) ? $ocrs[$i] : FALSE; + $ocr_url = $ocr->entity->createFileUrl(FALSE); + } + } + else if ($structured_text_term) { + $parent_node = $this->utils->getParentNode($entity); + $ocr_entity_array = $this->utils->getMediaReferencingNodeAndTerm($parent_node, $structured_text_term); + $ocr_entity_id = is_array($ocr_entity_array) ? array_shift($ocr_entity_array) : NULL; + $ocr_entity = $ocr_entity_id ? $this->entityTypeManager->getStorage('media')->load($ocr_entity_id) : NULL; + if ($ocr_entity) { + $ocr_file_source = $ocr_entity->getSource(); + $ocr_fid = $ocr_file_source->getSourceFieldValue($ocr_entity); + $ocr_file = $this->entityTypeManager->getStorage('file')->load($ocr_fid); + $ocr_url = $ocr_file->createFileUrl(FALSE); + } + } + + return $ocr_url; + } + /** * Pull a title from the node or media passed to this view. * From 723f1023656f8c6858bee3599164f9d91f076f89 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Mon, 12 Jun 2023 20:11:14 -0300 Subject: [PATCH 156/252] Update Islandora IIIF README. --- modules/islandora_iiif/README.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/islandora_iiif/README.md b/modules/islandora_iiif/README.md index ab06524be..a5cfc3b0e 100644 --- a/modules/islandora_iiif/README.md +++ b/modules/islandora_iiif/README.md @@ -1,4 +1,4 @@ -# Islandora IIIF +# Islandora IIIF [![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.2-8892BF.svg?style=flat-square)](https://php.net/) [![Contribution Guidelines](http://img.shields.io/badge/CONTRIBUTING-Guidelines-blue.svg)](./CONTRIBUTING.md) @@ -11,7 +11,7 @@ Provides IIIF manifests using views. ## Requirements - `islandora` and `islandora_core_feature` -- A IIIF image server (such as Cantaloupe) +- A IIIF image server (such as Cantaloupe) ## Installation @@ -32,6 +32,14 @@ You can set the following configuration at `admin/config/islandora/iiif`: - IIIF Image server location - The URL to your IIIF image server (without trailing slash). +### Views Style Plugin + +This module implements a Views Style plugin. It provides the following settings: + +1. Tile Source: A field that was added to the views list of fields with the image to be served. This should be a File or Image type field on a Media. +2. Structured Text field: This lets you specify a file field on the same entity as above where OCR text with positional data, e.g., hOCR can be found. +3. Structured Text term: The Islandora term with a Media Use URI where the structured OCR text can be found. This is another option to the above for storing this data in a separate media related to the parent node, rather than on the same media. + ## Documentation Official documentation is available on the [Islandora 8 documentation site](https://islandora.github.io/documentation/). From 7527b1fa6fadda346709a0d6850b983cad8d7802 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Mon, 12 Jun 2023 21:13:00 -0300 Subject: [PATCH 157/252] Address PHPCS errors. --- .../src/Plugin/views/style/IIIFManifest.php | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 9fde1ed74..7bbe03dd3 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -35,7 +35,7 @@ */ class IIIFManifest extends StylePluginBase { -/** + /** * Islandora utility functions. * * @var \Drupal\islandora\IslandoraUtils @@ -233,7 +233,7 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas $annotation_id = $iiif_base_id . '/annotation/' . $entity->id(); [$width, $height] = $this->getCanvasDimensions($iiif_url, $image, $mime_type); - + $tmp_canvas = [ // @see https://iiif.io/api/presentation/2.1/#canvas '@id' => $canvas_id, @@ -283,13 +283,14 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas /** * Try to fetch the IIIF metadata for the image. - * + * * @param string $iiif_url - * Base URL of the canvas - * @param FieldItemInterface $image + * Base URL of the canvas. + * @param \Drupal\Core\Field\FieldItemInterface $image * The image field. * @param string $mime_type * The mime type of the image. + * * @return [string] * The width and height of the image. */ @@ -326,16 +327,16 @@ protected function getCanvasDimensions(string $iiif_url, FieldItemInterface $ima } /** - * Retrieves a URL text with positional data such as hOCR - * - * @param EntityInterface $entity + * Retrieves a URL text with positional data such as hOCR. + * + * @param \Drupal\Core\Entity\EntityInterface $entity * The entity at the current row. * @param \Drupal\taxonomy\TermInterface|null $structured_text_term * The term that structured text media references, if any. - + * * return String|FALSE - * The absolute URL of the current row's structured text, - * or FALSE if none. + * The absolute URL of the current row's structured text, + * or FALSE if none. */ protected function getOcrUrl(EntityInterface $entity, $structured_text_term) { $ocr_url = FALSE; @@ -350,7 +351,7 @@ protected function getOcrUrl(EntityInterface $entity, $structured_text_term) { $ocr_url = $ocr->entity->createFileUrl(FALSE); } } - else if ($structured_text_term) { + elseif ($structured_text_term) { $parent_node = $this->utils->getParentNode($entity); $ocr_entity_array = $this->utils->getMediaReferencingNodeAndTerm($parent_node, $structured_text_term); $ocr_entity_id = is_array($ocr_entity_array) ? array_shift($ocr_entity_array) : NULL; @@ -485,8 +486,19 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { */ public function getFormats() { return ['json' => 'json']; - } + } + /** + * Submit handler for options form. + * Used to store the structured text media term by URL instead of Ttid. + * + * @param array $form + * The form. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The form state object. + * + * @return void + */ public function submitOptionsForm(&$form, FormStateInterface $form_state) { $style_options = $form_state->getValue('style_options'); $tid = $style_options['structured_text_term']; From f41dc59f1bd08e698bf266d913042d19178f032c Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Tue, 13 Jun 2023 22:10:12 -0300 Subject: [PATCH 158/252] Remove term-based hOCR configuration since we can just use Views. --- modules/islandora_iiif/README.md | 4 +- .../src/Plugin/views/style/IIIFManifest.php | 69 +++---------------- 2 files changed, 11 insertions(+), 62 deletions(-) diff --git a/modules/islandora_iiif/README.md b/modules/islandora_iiif/README.md index a5cfc3b0e..c1f89872c 100644 --- a/modules/islandora_iiif/README.md +++ b/modules/islandora_iiif/README.md @@ -37,9 +37,7 @@ You can set the following configuration at `admin/config/islandora/iiif`: This module implements a Views Style plugin. It provides the following settings: 1. Tile Source: A field that was added to the views list of fields with the image to be served. This should be a File or Image type field on a Media. -2. Structured Text field: This lets you specify a file field on the same entity as above where OCR text with positional data, e.g., hOCR can be found. -3. Structured Text term: The Islandora term with a Media Use URI where the structured OCR text can be found. This is another option to the above for storing this data in a separate media related to the parent node, rather than on the same media. - +2. Structured Text field: This lets you specify a file field where OCR text with positional data, e.g., hOCR can be found. ## Documentation Official documentation is available on the [Islandora 8 documentation site](https://islandora.github.io/documentation/). diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 7bbe03dd3..a745e1f7f 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -154,11 +154,6 @@ public function render() { $content_path = implode('/', $url_components); $iiif_base_id = $request_host . '/' . $content_path; - /** - * @var \Drupal\taxonomy\TermInterface|null - */ - $structured_text_term = $this->utils->getTermForUri($this->options['structured_text_term_uri']); - // @see https://iiif.io/api/presentation/2.1/#manifest $json += [ '@type' => 'sc:Manifest', @@ -178,7 +173,7 @@ public function render() { // For each row in the View result. foreach ($this->view->result as $row) { // Add the IIIF URL to the image to print out as JSON. - $canvases = $this->getTileSourceFromRow($row, $iiif_address, $iiif_base_id, $structured_text_term); + $canvases = $this->getTileSourceFromRow($row, $iiif_address, $iiif_base_id); foreach ($canvases as $tile_source) { $json['sequences'][0]['canvases'][] = $tile_source; } @@ -201,13 +196,11 @@ public function render() { * @param string $iiif_base_id * The URL for the request, minus the last part of the URL, * which is likely "manifest". - * @param \Drupal\taxonomy\TermInterface|null $structured_text_term - * The term that structured text media references, if any. * * @return array * List of IIIF URLs to display in the Openseadragon viewer. */ - protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_base_id, $structured_text_term) { + protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_base_id) { $canvases = []; foreach (array_filter(array_values($this->options['iiif_tile_field'])) as $iiif_tile_field) { $viewsField = $this->view->field[$iiif_tile_field]; @@ -264,7 +257,7 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas ], ]; - if ($ocr_url = $this->getOcrUrl($entity, $structured_text_term)) { + if ($ocr_url = $this->getOcrUrl($entity, $row, $i)) { $tmp_canvas['seeAlso'] = [ '@id' => $ocr_url, 'format' => 'text/vnd.hocr+html', @@ -331,36 +324,24 @@ protected function getCanvasDimensions(string $iiif_url, FieldItemInterface $ima * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity at the current row. - * @param \Drupal\taxonomy\TermInterface|null $structured_text_term - * The term that structured text media references, if any. * * return String|FALSE * The absolute URL of the current row's structured text, * or FALSE if none. */ - protected function getOcrUrl(EntityInterface $entity, $structured_text_term) { + protected function getOcrUrl(EntityInterface $entity, $row, $delta) { $ocr_url = FALSE; $iiif_ocr_file_field = !empty($this->options['iiif_ocr_file_field']) ? array_filter(array_values($this->options['iiif_ocr_file_field'])) : []; $ocrField = count($iiif_ocr_file_field) > 0 ? $this->view->field[$iiif_ocr_file_field[0]] : NULL; if ($ocrField) { - $ocr_entity = $entity; + $ocr_entity = $ocrField->getEntity($row); $ocr_field_name = $ocrField->definition['field_name']; - if (!is_null($ocrField_name)) { + if (!is_null($ocr_field_name)) { $ocrs = $ocr_entity->{$ocr_field_name}; - $ocr = isset($ocrs[$i]) ? $ocrs[$i] : FALSE; - $ocr_url = $ocr->entity->createFileUrl(FALSE); - } - } - elseif ($structured_text_term) { - $parent_node = $this->utils->getParentNode($entity); - $ocr_entity_array = $this->utils->getMediaReferencingNodeAndTerm($parent_node, $structured_text_term); - $ocr_entity_id = is_array($ocr_entity_array) ? array_shift($ocr_entity_array) : NULL; - $ocr_entity = $ocr_entity_id ? $this->entityTypeManager->getStorage('media')->load($ocr_entity_id) : NULL; - if ($ocr_entity) { - $ocr_file_source = $ocr_entity->getSource(); - $ocr_fid = $ocr_file_source->getSourceFieldValue($ocr_entity); - $ocr_file = $this->entityTypeManager->getStorage('file')->load($ocr_fid); - $ocr_url = $ocr_file->createFileUrl(FALSE); + $ocr = isset($ocrs[$delta]) ? $ocrs[$delta] : FALSE; + if ($ocr) { + $ocr_url = $ocr->entity->createFileUrl(FALSE); + } } } @@ -467,15 +448,6 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { '#options' => $field_options, '#required' => FALSE, ]; - $form['structured_text_term'] = [ - '#type' => 'entity_autocomplete', - '#target_type' => 'taxonomy_term', - '#title' => $this->t('Structured text term'), - '#default_value' => $this->utils->getTermForUri($this->options['structured_text_term_uri']), - '#required' => FALSE, - '#description' => $this->t('Term indicating the media that holds structured text, such as hOCR, for the given object.'), - ]; - } /** @@ -487,25 +459,4 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { public function getFormats() { return ['json' => 'json']; } - - /** - * Submit handler for options form. - * Used to store the structured text media term by URL instead of Ttid. - * - * @param array $form - * The form. - * @param \Drupal\Core\Form\FormStateInterface $form_state - * The form state object. - * - * @return void - */ - public function submitOptionsForm(&$form, FormStateInterface $form_state) { - $style_options = $form_state->getValue('style_options'); - $tid = $style_options['structured_text_term']; - $term = $this->entityTypeManager->getStorage('taxonomy_term')->load($tid); - $style_options['structured_text_term_uri'] = $this->utils->getUriForTerm($term); - $form_state->setValue('style_options', $style_options); - parent::submitOptionsForm($form, $form_state); - } - } From cf243f368d013bda19e519d99dd49b54c11c2a4e Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Tue, 13 Jun 2023 22:38:45 -0300 Subject: [PATCH 159/252] Fix PHPCS errors. --- .../islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index a745e1f7f..8527067d7 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -324,8 +324,10 @@ protected function getCanvasDimensions(string $iiif_url, FieldItemInterface $ima * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity at the current row. + * @param int $delta + *. The delta in case there are multiple canvases on one media. * - * return String|FALSE + * @return String|FALSE * The absolute URL of the current row's structured text, * or FALSE if none. */ @@ -459,4 +461,5 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { public function getFormats() { return ['json' => 'json']; } + } From 9f5eceea072f5ee79aabb404bf904362fa2821b0 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Tue, 13 Jun 2023 22:57:51 -0300 Subject: [PATCH 160/252] Fix PHPCS errors. --- .../src/Plugin/views/style/IIIFManifest.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 8527067d7..2dfce9798 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -324,14 +324,15 @@ protected function getCanvasDimensions(string $iiif_url, FieldItemInterface $ima * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity at the current row. - * @param int $delta - *. The delta in case there are multiple canvases on one media. - * - * @return String|FALSE + * @param \Drupal\views\ResultRow $row + * Result row. * @param int $delta + * The delta in case there are multiple canvases on one media. + * + * @return string|false * The absolute URL of the current row's structured text, * or FALSE if none. */ - protected function getOcrUrl(EntityInterface $entity, $row, $delta) { + protected function getOcrUrl(EntityInterface $entity, ResultRow $row, $delta) { $ocr_url = FALSE; $iiif_ocr_file_field = !empty($this->options['iiif_ocr_file_field']) ? array_filter(array_values($this->options['iiif_ocr_file_field'])) : []; $ocrField = count($iiif_ocr_file_field) > 0 ? $this->view->field[$iiif_ocr_file_field[0]] : NULL; From d4cac7299314436b5a5664ba91ed874b45180a31 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Wed, 14 Jun 2023 09:06:19 -0300 Subject: [PATCH 161/252] Fix PHPCS errors. --- .../islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 2dfce9798..e52f59f9a 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -324,8 +324,9 @@ protected function getCanvasDimensions(string $iiif_url, FieldItemInterface $ima * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity at the current row. - * @param \Drupal\views\ResultRow $row - * Result row. * @param int $delta + * @param \Drupal\views\ResultRow $row + * Result row. + * @param int $delta * The delta in case there are multiple canvases on one media. * * @return string|false From e492b92d9f22199289d9663c841f8642fc439741 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Thu, 15 Jun 2023 08:56:20 -0300 Subject: [PATCH 162/252] Remove Islandora Utils from Islandora IIIF. --- .../src/Plugin/views/style/IIIFManifest.php | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index e52f59f9a..63f015d1c 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -10,7 +10,6 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\Url; -use Drupal\islandora\IslandoraUtils; use Drupal\views\Plugin\views\style\StylePluginBase; use Drupal\views\ResultRow; use GuzzleHttp\Client; @@ -35,13 +34,6 @@ */ class IIIFManifest extends StylePluginBase { - /** - * Islandora utility functions. - * - * @var \Drupal\islandora\IslandoraUtils - */ - protected $utils; - /** * {@inheritdoc} */ @@ -104,7 +96,7 @@ class IIIFManifest extends StylePluginBase { /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system, Client $http_client, MessengerInterface $messenger, IslandoraUtils $utils) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system, Client $http_client, MessengerInterface $messenger) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->serializer = $serializer; @@ -114,8 +106,6 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition $this->fileSystem = $file_system; $this->httpClient = $http_client; $this->messenger = $messenger; - $this->utils = $utils; - } /** @@ -132,8 +122,7 @@ public static function create(ContainerInterface $container, array $configuratio $container->get('entity_type.manager'), $container->get('file_system'), $container->get('http_client'), - $container->get('messenger'), - $container->get('islandora.utils') + $container->get('messenger') ); } From 91490ddbe21d9f79fcde716e87b6007c3ad51f53 Mon Sep 17 00:00:00 2001 From: Seth Shaw <108362375+seth-shaw-asu@users.noreply.github.com> Date: Mon, 19 Jun 2023 09:49:41 -0700 Subject: [PATCH 163/252] bump jwt version (#952) --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 3ceed0e11..bf274cd1d 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "drupal/file_replace": "^1.1", "drupal/filehash": "^2", "drupal/flysystem" : "^2.0@alpha", - "drupal/jwt": "^1.1", + "drupal/jwt": "^1.1 || ^2", "drupal/migrate_plus" : "^5.1 || ^6", "drupal/migrate_source_csv" : "^3.4", "drupal/prepopulate" : "^2.2", From 7d7f97746abaa22156da0cc7dd17427d56e1ff0c Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Fri, 26 May 2023 16:41:10 -0300 Subject: [PATCH 164/252] Drupal Rector. --- .../Functional/GenerateAudioDerivativeTest.php | 3 ++- .../tests/src/Functional/BreadcrumbsTest.php | 4 ++-- .../Functional/GenerateImageDerivativeTest.php | 3 ++- .../src/Controller/MediaSourceController.php | 2 +- .../tests/src/Functional/LoadTest.php | 4 ++-- .../Functional/GenerateVideoDerivativeTest.php | 3 ++- src/EventSubscriber/LinkHeaderSubscriber.php | 6 +++--- .../MediaLinkHeaderSubscriber.php | 4 ++-- .../NodeLinkHeaderSubscriber.php | 6 +++--- src/Flysystem/Adapter/FedoraAdapter.php | 14 ++++++++------ .../AbstractFileSelectionForm.php | 7 ++++++- tests/src/Functional/AddChildTest.php | 2 +- tests/src/Functional/AddMediaToNodeTest.php | 2 +- tests/src/Functional/ContentEntityTypeTest.php | 3 ++- tests/src/Functional/DeleteMediaTest.php | 4 ++-- tests/src/Functional/DerivativeReactionTest.php | 5 +++-- .../Functional/GenerateDerivativeTestBase.php | 2 +- tests/src/Functional/IndexingTest.php | 5 +++-- .../Functional/IslandoraFunctionalTestBase.php | 11 +++++++---- .../Functional/IslandoraImageFormatterTest.php | 2 +- .../Functional/IslandoraSettingsFormTest.php | 17 +++++++++++------ .../JsonldSelfReferenceReactionTest.php | 13 +++++++------ .../Functional/JsonldTypeAlterReactionTest.php | 14 ++++++++------ tests/src/Functional/LinkHeaderTest.php | 2 +- tests/src/Functional/MediaSourceUpdateTest.php | 2 +- tests/src/Functional/NodeHasTermTest.php | 2 +- .../Functional/ViewModeAlterReactionTest.php | 2 +- .../FunctionalJavascript/IntegerWeightTest.php | 2 +- tests/src/Kernel/EventGeneratorTest.php | 2 +- tests/src/Kernel/FedoraAdapterTest.php | 12 ++++++++---- tests/src/Kernel/IslandoraKernelTestBase.php | 4 ++-- tests/src/Kernel/JwtEventSubscriberTest.php | 4 +++- 32 files changed, 99 insertions(+), 69 deletions(-) diff --git a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php index fc1c6188e..766ceac0a 100644 --- a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php +++ b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php @@ -68,7 +68,8 @@ public function testGenerateAudioDerivativeFromScratch() { 'field_media_of[0][target_id]' => 'Test Node', 'field_tags[0][target_id]' => 'Preservation Master', ]; - $this->drupalPostForm('media/add/' . $this->testMediaType->id(), $values, $this->t('Save')); + $this->drupalGet('media/add/' . $this->testMediaType->id()); + $this->submitForm($values, $this->t('Save')); $expected = [ 'source_uri' => 'test_file.txt', diff --git a/modules/islandora_breadcrumbs/tests/src/Functional/BreadcrumbsTest.php b/modules/islandora_breadcrumbs/tests/src/Functional/BreadcrumbsTest.php index 80f5dbee0..ee35a1ed3 100644 --- a/modules/islandora_breadcrumbs/tests/src/Functional/BreadcrumbsTest.php +++ b/modules/islandora_breadcrumbs/tests/src/Functional/BreadcrumbsTest.php @@ -20,7 +20,7 @@ class BreadcrumbsTest extends IslandoraFunctionalTestBase { * * @var array */ - public static $modules = [ + protected static $modules = [ 'islandora_breadcrumbs', ]; @@ -56,7 +56,7 @@ class BreadcrumbsTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); // Create some nodes. diff --git a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php index b6e016fc1..295eae913 100644 --- a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php +++ b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php @@ -70,7 +70,8 @@ public function testGenerateImageDerivativeFromScratch() { 'field_media_of[0][target_id]' => 'Test Node', 'field_tags[0][target_id]' => 'Preservation Master', ]; - $this->drupalPostForm('media/add/' . $this->testMediaType->id(), $values, $this->t('Save')); + $this->drupalGet('media/add/' . $this->testMediaType->id()); + $this->submitForm($values, $this->t('Save')); $expected = [ 'source_uri' => 'test_file.txt', diff --git a/modules/islandora_text_extraction/src/Controller/MediaSourceController.php b/modules/islandora_text_extraction/src/Controller/MediaSourceController.php index f15e42d56..5518220d1 100644 --- a/modules/islandora_text_extraction/src/Controller/MediaSourceController.php +++ b/modules/islandora_text_extraction/src/Controller/MediaSourceController.php @@ -98,7 +98,7 @@ public function attachToMedia( if (!$this->fileSystem->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS)) { throw new HttpException(500, "The destination directory does not exist, could not be created, or is not writable"); } - $file = file_save_data($contents, $content_location, FileSystemInterface::EXISTS_REPLACE); + $file = \Drupal::service('file.repository')->writeData($contents, $content_location, FileSystemInterface::EXISTS_REPLACE); if ($media->hasField($destination_field)) { $media->{$destination_field}->setValue([ 'target_id' => $file->id(), diff --git a/modules/islandora_text_extraction/tests/src/Functional/LoadTest.php b/modules/islandora_text_extraction/tests/src/Functional/LoadTest.php index 31dca62c8..172ae73ab 100644 --- a/modules/islandora_text_extraction/tests/src/Functional/LoadTest.php +++ b/modules/islandora_text_extraction/tests/src/Functional/LoadTest.php @@ -17,7 +17,7 @@ class LoadTest extends IslandoraFunctionalTestBase { * * @var array */ - public static $modules = ['islandora_text_extraction']; + protected static $modules = ['islandora_text_extraction']; /** * A user with permission to administer site configuration. @@ -29,7 +29,7 @@ class LoadTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); $this->user = $this->drupalCreateUser(['administer site configuration']); $this->drupalLogin($this->user); diff --git a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php index 8714a2f10..17e8bd5b5 100644 --- a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php +++ b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php @@ -65,7 +65,8 @@ public function testGenerateVideoDerivativeFromScratch() { 'field_media_of[0][target_id]' => 'Test Node', 'field_tags[0][target_id]' => 'Preservation Master', ]; - $this->drupalPostForm('media/add/' . $this->testMediaType->id(), $values, $this->t('Save')); + $this->drupalGet('media/add/' . $this->testMediaType->id()); + $this->submitForm($values, $this->t('Save')); $expected = [ 'source_uri' => 'test_file.txt', diff --git a/src/EventSubscriber/LinkHeaderSubscriber.php b/src/EventSubscriber/LinkHeaderSubscriber.php index ce33ce2e1..f7e5725b8 100644 --- a/src/EventSubscriber/LinkHeaderSubscriber.php +++ b/src/EventSubscriber/LinkHeaderSubscriber.php @@ -2,6 +2,7 @@ namespace Drupal\islandora\EventSubscriber; +use Symfony\Component\HttpKernel\Event\ResponseEvent; use Drupal\Core\Access\AccessManagerInterface; use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\Core\Entity\EntityInterface; @@ -13,7 +14,6 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; /** @@ -312,9 +312,9 @@ protected function generateRestLinks(EntityInterface $entity) { /** * Adds resource-specific link headers to appropriate responses. * - * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event + * @param \Symfony\Component\HttpKernel\Event\ResponseEvent $event * Event containing the response. */ - abstract public function onResponse(FilterResponseEvent $event); + abstract public function onResponse(ResponseEvent $event); } diff --git a/src/EventSubscriber/MediaLinkHeaderSubscriber.php b/src/EventSubscriber/MediaLinkHeaderSubscriber.php index 3cebbbaae..0f406cf57 100644 --- a/src/EventSubscriber/MediaLinkHeaderSubscriber.php +++ b/src/EventSubscriber/MediaLinkHeaderSubscriber.php @@ -2,10 +2,10 @@ namespace Drupal\islandora\EventSubscriber; +use Symfony\Component\HttpKernel\Event\ResponseEvent; use Drupal\Core\Url; use Drupal\media\MediaInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Symfony\Component\HttpKernel\Event\FilterResponseEvent; /** * Subscribes to MediaLinkHeader Event. @@ -17,7 +17,7 @@ class MediaLinkHeaderSubscriber extends LinkHeaderSubscriber implements EventSub /** * {@inheritdoc} */ - public function onResponse(FilterResponseEvent $event) { + public function onResponse(ResponseEvent $event) { $response = $event->getResponse(); $media = $this->getObject($response, 'media'); diff --git a/src/EventSubscriber/NodeLinkHeaderSubscriber.php b/src/EventSubscriber/NodeLinkHeaderSubscriber.php index e00533f7a..c4cdaea8c 100644 --- a/src/EventSubscriber/NodeLinkHeaderSubscriber.php +++ b/src/EventSubscriber/NodeLinkHeaderSubscriber.php @@ -2,9 +2,9 @@ namespace Drupal\islandora\EventSubscriber; +use Symfony\Component\HttpKernel\Event\ResponseEvent; use Drupal\node\NodeInterface; use Drupal\islandora\IslandoraUtils; -use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** @@ -17,10 +17,10 @@ class NodeLinkHeaderSubscriber extends LinkHeaderSubscriber implements EventSubs /** * Adds node-specific link headers to appropriate responses. * - * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event + * @param \Symfony\Component\HttpKernel\Event\ResponseEvent $event * Event containing the response. */ - public function onResponse(FilterResponseEvent $event) { + public function onResponse(ResponseEvent $event) { $response = $event->getResponse(); $node = $this->getObject($response, 'node'); diff --git a/src/Flysystem/Adapter/FedoraAdapter.php b/src/Flysystem/Adapter/FedoraAdapter.php index 4ebc61c59..55f8b11d3 100644 --- a/src/Flysystem/Adapter/FedoraAdapter.php +++ b/src/Flysystem/Adapter/FedoraAdapter.php @@ -2,6 +2,8 @@ namespace Drupal\islandora\Flysystem\Adapter; +use GuzzleHttp\Psr7\Header; +use function GuzzleHttp\Psr7\parse_header; use Drupal\Core\Logger\LoggerChannelInterface; use Islandora\Chullo\IFedoraApi; use League\Flysystem\AdapterInterface; @@ -159,11 +161,11 @@ protected function getMetadataFromHeaders(Response $response) { // directory. $type = 'dir'; // phpcs:disable - if (class_exists(\GuzzleHttp\Psr7\Header::class)) { - $links = \GuzzleHttp\Psr7\Header::parse($response->getHeader('Link')); + if (class_exists(Header::class)) { + $links = Header::parse($response->getHeader('Link')); } else { - $links = \GuzzleHttp\Psr7\parse_header($response->getHeader('Link')); + $links = parse_header($response->getHeader('Link')); } // phpcs:enable foreach ($links as $link) { @@ -402,11 +404,11 @@ private function deleteTombstone($path) { if ($response->getStatusCode() == 410) { $return = FALSE; // phpcs:disable - if (class_exists(\GuzzleHttp\Psr7\Header::class)) { - $link_headers = \GuzzleHttp\Psr7\Header::parse($response->getHeader('Link')); + if (class_exists(Header::class)) { + $link_headers = Header::parse($response->getHeader('Link')); } else { - $link_headers = \GuzzleHttp\Psr7\parse_header($response->getHeader('Link')); + $link_headers = parse_header($response->getHeader('Link')); } // phpcs:enable if ($link_headers) { diff --git a/src/Form/AddChildrenWizard/AbstractFileSelectionForm.php b/src/Form/AddChildrenWizard/AbstractFileSelectionForm.php index 6aeed8795..cf6ef3057 100644 --- a/src/Form/AddChildrenWizard/AbstractFileSelectionForm.php +++ b/src/Form/AddChildrenWizard/AbstractFileSelectionForm.php @@ -37,6 +37,11 @@ abstract class AbstractFileSelectionForm extends FormBase { * @var \Drupal\islandora\Form\AddChildrenWizard\AbstractBatchProcessor|null */ protected ?AbstractBatchProcessor $batchProcessor; + private \static $static; + public function __construct(\static $static) + { + $this->static = $static; + } /** * {@inheritdoc} @@ -49,7 +54,7 @@ public static function create(ContainerInterface $container): self { $instance->entityFieldManager = $container->get('entity_field.manager'); $instance->currentUser = $container->get('current_user'); - $instance->batchProcessor = $container->get(static::BATCH_PROCESSOR); + $instance->batchProcessor = $this->static; return $instance; } diff --git a/tests/src/Functional/AddChildTest.php b/tests/src/Functional/AddChildTest.php index 9fc2f9e23..f27f9db98 100644 --- a/tests/src/Functional/AddChildTest.php +++ b/tests/src/Functional/AddChildTest.php @@ -12,7 +12,7 @@ class AddChildTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); $this->parent = diff --git a/tests/src/Functional/AddMediaToNodeTest.php b/tests/src/Functional/AddMediaToNodeTest.php index 329097757..4b0b62c52 100644 --- a/tests/src/Functional/AddMediaToNodeTest.php +++ b/tests/src/Functional/AddMediaToNodeTest.php @@ -31,7 +31,7 @@ class AddMediaToNodeTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); $this->node = $this->container->get('entity_type.manager')->getStorage('node')->create([ diff --git a/tests/src/Functional/ContentEntityTypeTest.php b/tests/src/Functional/ContentEntityTypeTest.php index 362ff7fbb..5ed229486 100644 --- a/tests/src/Functional/ContentEntityTypeTest.php +++ b/tests/src/Functional/ContentEntityTypeTest.php @@ -52,7 +52,8 @@ public function testContentEntityType() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', ]; - $this->drupalPostForm('media/add/' . $this->testMediaType->id(), $values, $this->t('Save')); + $this->drupalGet('media/add/' . $this->testMediaType->id()); + $this->submitForm($values, $this->t('Save')); $this->assertSession()->pageTextNotContains("Hello World!"); } diff --git a/tests/src/Functional/DeleteMediaTest.php b/tests/src/Functional/DeleteMediaTest.php index f112c7006..86895dbbc 100644 --- a/tests/src/Functional/DeleteMediaTest.php +++ b/tests/src/Functional/DeleteMediaTest.php @@ -16,7 +16,7 @@ class DeleteMediaTest extends IslandoraFunctionalTestBase { * * @var array */ - public static $modules = [ + protected static $modules = [ 'media_test_views', 'context_ui', 'field_ui', @@ -47,7 +47,7 @@ class DeleteMediaTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); // Create a test user. diff --git a/tests/src/Functional/DerivativeReactionTest.php b/tests/src/Functional/DerivativeReactionTest.php index e1b1c8276..00e0e5ae5 100644 --- a/tests/src/Functional/DerivativeReactionTest.php +++ b/tests/src/Functional/DerivativeReactionTest.php @@ -19,7 +19,7 @@ class DerivativeReactionTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); $this->node = $this->container->get('entity_type.manager')->getStorage('node')->create([ @@ -52,7 +52,8 @@ public function testExecuteDerivativeReaction() { 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', ]; - $this->drupalPostForm('media/add/' . $this->testMediaType->id(), $values, $this->t('Save')); + $this->drupalGet('media/add/' . $this->testMediaType->id()); + $this->submitForm($values, $this->t('Save')); // field_media_of is set and there's a file, so derivatives should fire. $this->assertSession()->pageTextContains("Hello World!"); diff --git a/tests/src/Functional/GenerateDerivativeTestBase.php b/tests/src/Functional/GenerateDerivativeTestBase.php index 0f67d5919..c5ec9701c 100644 --- a/tests/src/Functional/GenerateDerivativeTestBase.php +++ b/tests/src/Functional/GenerateDerivativeTestBase.php @@ -29,7 +29,7 @@ abstract class GenerateDerivativeTestBase extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); $this->createUserAndLogin(); diff --git a/tests/src/Functional/IndexingTest.php b/tests/src/Functional/IndexingTest.php index e995329d7..ff2152817 100644 --- a/tests/src/Functional/IndexingTest.php +++ b/tests/src/Functional/IndexingTest.php @@ -12,7 +12,7 @@ class IndexingTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); // Create an action that dsm's "Goodbye, Cruel World!". @@ -63,9 +63,10 @@ public function testIndexing() { // Add the Goodbye World reaction. $this->addPresetReaction('test', 'delete', 'goodbye_world'); + $this->drupalGet("$url/delete"); // Delete the node. - $this->drupalPostForm("$url/delete", [], $this->t('Delete')); + $this->submitForm([], $this->t('Delete')); $this->assertSession()->statusCodeEquals(200); // Confirm Goodbye, Cruel World! is printed to the screen. diff --git a/tests/src/Functional/IslandoraFunctionalTestBase.php b/tests/src/Functional/IslandoraFunctionalTestBase.php index 2e4c88e89..2e7235611 100644 --- a/tests/src/Functional/IslandoraFunctionalTestBase.php +++ b/tests/src/Functional/IslandoraFunctionalTestBase.php @@ -88,7 +88,7 @@ class IslandoraFunctionalTestBase extends BrowserTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); // Delete the node rest config that's bootstrapped with Drupal. @@ -314,7 +314,8 @@ protected function addPresetReaction($context_id, $reaction_type, $action_id) { * Create a new node by posting its add form. */ protected function postNodeAddForm($bundle_id, $values, $button_text) { - $this->drupalPostForm("node/add/$bundle_id", $values, $this->t('@text', ['@text' => $button_text])); + $this->drupalGet("node/add/$bundle_id"); + $this->submitForm($values, $this->t('@text', ['@text' => $button_text])); $this->assertSession()->statusCodeEquals(200); } @@ -322,7 +323,8 @@ protected function postNodeAddForm($bundle_id, $values, $button_text) { * Create a new node by posting its add form. */ protected function postTermAddForm($taxomony_id, $values, $button_text) { - $this->drupalPostForm("admin/structure/taxonomy/manage/$taxomony_id/add", $values, $this->t('@text', ['@text' => $button_text])); + $this->drupalGet("admin/structure/taxonomy/manage/$taxomony_id/add"); + $this->submitForm($values, $this->t('@text', ['@text' => $button_text])); $this->assertSession()->statusCodeEquals(200); } @@ -330,7 +332,8 @@ protected function postTermAddForm($taxomony_id, $values, $button_text) { * Edits a node by posting its edit form. */ protected function postEntityEditForm($entity_url, $values, $button_text) { - $this->drupalPostForm("$entity_url/edit", $values, $this->t('@text', ['@text' => $button_text])); + $this->drupalGet("$entity_url/edit"); + $this->submitForm($values, $this->t('@text', ['@text' => $button_text])); $this->assertSession()->statusCodeEquals(200); } diff --git a/tests/src/Functional/IslandoraImageFormatterTest.php b/tests/src/Functional/IslandoraImageFormatterTest.php index 33f6e1e6b..84ea55173 100644 --- a/tests/src/Functional/IslandoraImageFormatterTest.php +++ b/tests/src/Functional/IslandoraImageFormatterTest.php @@ -92,7 +92,7 @@ public function testIslandoraImageFormatter() { ':title' => 'Some Title', ] ); - $this->assertEqual(count($elements), 1, 'Image linked to content formatter displaying points to Node and not Media.'); + $this->assertEquals(count($elements), 1, 'Image linked to content formatter displaying points to Node and not Media.'); } } diff --git a/tests/src/Functional/IslandoraSettingsFormTest.php b/tests/src/Functional/IslandoraSettingsFormTest.php index 92cfc6a29..80a327af1 100644 --- a/tests/src/Functional/IslandoraSettingsFormTest.php +++ b/tests/src/Functional/IslandoraSettingsFormTest.php @@ -14,7 +14,7 @@ class IslandoraSettingsFormTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); // Create a test user. @@ -36,20 +36,25 @@ public function testJwtExpiry() { $this->assertSession()->statusCodeEquals(200); $this->assertSession()->pageTextContains("JWT Expiry"); $this->assertSession()->fieldValueEquals('edit-jwt-expiry', '+2 hour'); + $this->drupalGet('/admin/config/islandora/core'); // Blank is not allowed. - $this->drupalPostForm('/admin/config/islandora/core', ['edit-jwt-expiry' => ""], $this->t('Save configuration')); + $this->submitForm(['edit-jwt-expiry' => ""], $this->t('Save configuration')); $this->assertSession()->pageTextContainsOnce('"" is not a valid time or interval expression.'); + $this->drupalGet('/admin/config/islandora/core'); // Negative is not allowed. - $this->drupalPostForm('/admin/config/islandora/core', ['edit-jwt-expiry' => "-2 hours"], $this->t('Save configuration')); + $this->submitForm(['edit-jwt-expiry' => "-2 hours"], $this->t('Save configuration')); $this->assertSession()->pageTextContainsOnce('Time or interval expression cannot be negative'); + $this->drupalGet('/admin/config/islandora/core'); // Must include an integer value. - $this->drupalPostForm('/admin/config/islandora/core', ['edit-jwt-expiry' => "last hour"], $this->t('Save configuration')); + $this->submitForm(['edit-jwt-expiry' => "last hour"], $this->t('Save configuration')); $this->assertSession()->pageTextContainsOnce('No numeric interval specified, for example "1 day"'); + $this->drupalGet('/admin/config/islandora/core'); // Must have an accepted interval. - $this->drupalPostForm('/admin/config/islandora/core', ['edit-jwt-expiry' => "1 fortnight"], $this->t('Save configuration')); + $this->submitForm(['edit-jwt-expiry' => "1 fortnight"], $this->t('Save configuration')); $this->assertSession()->pageTextContainsOnce('No time interval found, please include one of'); + $this->drupalGet('/admin/config/islandora/core'); // Test a valid setting. - $this->drupalPostForm('/admin/config/islandora/core', ['edit-jwt-expiry' => "2 weeks"], $this->t('Save configuration')); + $this->submitForm(['edit-jwt-expiry' => "2 weeks"], $this->t('Save configuration')); $this->assertSession()->pageTextContainsOnce('The configuration options have been saved.'); } diff --git a/tests/src/Functional/JsonldSelfReferenceReactionTest.php b/tests/src/Functional/JsonldSelfReferenceReactionTest.php index f3c882718..7ad8f0185 100644 --- a/tests/src/Functional/JsonldSelfReferenceReactionTest.php +++ b/tests/src/Functional/JsonldSelfReferenceReactionTest.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\islandora\Functional; +use function GuzzleHttp\json_decode; /** * Class MappingUriPredicateReactionTest. * @@ -13,7 +14,7 @@ class JsonldSelfReferenceReactionTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); $types = ['schema:Thing']; @@ -61,7 +62,7 @@ public function testMappingReaction() { $contents = $this->drupalGet($url . '?_format=jsonld'); $this->assertSession()->statusCodeEquals(200); - $json = \GuzzleHttp\json_decode($contents, TRUE); + $json = json_decode($contents, TRUE); $this->assertArrayHasKey('http://purl.org/dc/terms/title', $json['@graph'][0], 'Missing dcterms:title key'); $this->assertEquals( @@ -103,7 +104,7 @@ public function testMappingReaction() { drupal_flush_all_caches(); $new_contents = $this->drupalGet($url . '?_format=jsonld'); - $json = \GuzzleHttp\json_decode($new_contents, TRUE); + $json = json_decode($new_contents, TRUE); $this->assertEquals( 'Test Node', $json['@graph'][0]['http://purl.org/dc/terms/title'][0]['@value'], @@ -123,7 +124,7 @@ public function testMappingReaction() { $this->assertSession() ->pageTextContains("The context $context_name has been saved"); $new_contents = $this->drupalGet($url . '?_format=jsonld'); - $json = \GuzzleHttp\json_decode($new_contents, TRUE); + $json = json_decode($new_contents, TRUE); $this->assertEquals( 'Test Node', $json['@graph'][0]['http://purl.org/dc/terms/title'][0]['@value'], @@ -161,7 +162,7 @@ public function testMappingReactionForMedia() { $contents = $this->drupalGet($media_url . '?_format=jsonld'); $this->assertSession()->statusCodeEquals(200); - $json = \GuzzleHttp\json_decode($contents, TRUE); + $json = json_decode($contents, TRUE); $this->assertEquals( "$media_url?_format=jsonld", $json['@graph'][0]['@id'], @@ -186,7 +187,7 @@ public function testMappingReactionForMedia() { drupal_flush_all_caches(); $new_contents = $this->drupalGet($media_url . '?_format=jsonld'); - $json = \GuzzleHttp\json_decode($new_contents, TRUE); + $json = json_decode($new_contents, TRUE); $this->assertEquals( "$media_url?_format=jsonld", $json['@graph'][0]['http://www.iana.org/assignments/relation/describedby'][0]['@id'], diff --git a/tests/src/Functional/JsonldTypeAlterReactionTest.php b/tests/src/Functional/JsonldTypeAlterReactionTest.php index e5d21abc6..58e8bf61b 100644 --- a/tests/src/Functional/JsonldTypeAlterReactionTest.php +++ b/tests/src/Functional/JsonldTypeAlterReactionTest.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\islandora\Functional; +use function GuzzleHttp\json_decode; /** * Tests Jsonld Alter Reaction. * @@ -20,17 +21,18 @@ public function testMappingReaction() { 'administer node fields', ]); $this->drupalLogin($account); + $this->drupalGet('admin/structure/types/manage/test_type/fields/add-field'); // Add the typed predicate we will select in the reaction config. // Taken from FieldUiTestTrait->fieldUIAddNewField. - $this->drupalPostForm('admin/structure/types/manage/test_type/fields/add-field', [ + $this->submitForm([ 'new_storage_type' => 'string', 'label' => 'Typed Predicate', 'field_name' => 'type_predicate', ], $this->t('Save and continue')); - $this->drupalPostForm(NULL, [], $this->t('Save field settings')); - $this->drupalPostForm(NULL, [], $this->t('Save settings')); - $this->assertRaw('field_type_predicate', 'Redirected to "Manage fields" page.'); + $this->submitForm([], $this->t('Save field settings')); + $this->submitForm([], $this->t('Save settings')); + $this->assertSession()->responseContains('field_type_predicate'); // Add the test node. $this->postNodeAddForm('test_type', [ @@ -46,7 +48,7 @@ public function testMappingReaction() { $contents = $this->drupalGet($url . '?_format=jsonld'); $this->assertSession()->statusCodeEquals(200); - $json = \GuzzleHttp\json_decode($contents, TRUE); + $json = json_decode($contents, TRUE); $this->assertArrayHasKey('@type', $json['@graph'][0], 'Missing @type'); $this->assertEquals( @@ -81,7 +83,7 @@ public function testMappingReaction() { // Check for the new @type from the field_type_predicate value. $new_contents = $this->drupalGet($url . '?_format=jsonld'); - $json = \GuzzleHttp\json_decode($new_contents, TRUE); + $json = json_decode($new_contents, TRUE); $this->assertTrue( in_array('http://schema.org/Organization', $json['@graph'][0]['@type']), 'Missing altered @type value of http://schema.org/Organization' diff --git a/tests/src/Functional/LinkHeaderTest.php b/tests/src/Functional/LinkHeaderTest.php index 7cb741d55..98b36c68b 100644 --- a/tests/src/Functional/LinkHeaderTest.php +++ b/tests/src/Functional/LinkHeaderTest.php @@ -42,7 +42,7 @@ class LinkHeaderTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); $account = $this->createUserAndLogin(); diff --git a/tests/src/Functional/MediaSourceUpdateTest.php b/tests/src/Functional/MediaSourceUpdateTest.php index fdea6aef9..3c97c6954 100644 --- a/tests/src/Functional/MediaSourceUpdateTest.php +++ b/tests/src/Functional/MediaSourceUpdateTest.php @@ -35,7 +35,7 @@ class MediaSourceUpdateTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); // Make a user with appropriate permissions. diff --git a/tests/src/Functional/NodeHasTermTest.php b/tests/src/Functional/NodeHasTermTest.php index eff5b5c34..2b4ee16f8 100644 --- a/tests/src/Functional/NodeHasTermTest.php +++ b/tests/src/Functional/NodeHasTermTest.php @@ -13,7 +13,7 @@ class NodeHasTermTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); diff --git a/tests/src/Functional/ViewModeAlterReactionTest.php b/tests/src/Functional/ViewModeAlterReactionTest.php index 72cdfe447..19660bda1 100644 --- a/tests/src/Functional/ViewModeAlterReactionTest.php +++ b/tests/src/Functional/ViewModeAlterReactionTest.php @@ -26,7 +26,7 @@ class ViewModeAlterReactionTest extends IslandoraFunctionalTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); // Node to be referenced via member of. diff --git a/tests/src/FunctionalJavascript/IntegerWeightTest.php b/tests/src/FunctionalJavascript/IntegerWeightTest.php index ba289aa49..2572c191e 100644 --- a/tests/src/FunctionalJavascript/IntegerWeightTest.php +++ b/tests/src/FunctionalJavascript/IntegerWeightTest.php @@ -80,7 +80,7 @@ class IntegerWeightTest extends WebDriverTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); $this->adminUser = $this->drupalCreateUser( diff --git a/tests/src/Kernel/EventGeneratorTest.php b/tests/src/Kernel/EventGeneratorTest.php index c423cda3f..a9c1f0825 100644 --- a/tests/src/Kernel/EventGeneratorTest.php +++ b/tests/src/Kernel/EventGeneratorTest.php @@ -41,7 +41,7 @@ class EventGeneratorTest extends IslandoraKernelTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); // Create a test user. diff --git a/tests/src/Kernel/FedoraAdapterTest.php b/tests/src/Kernel/FedoraAdapterTest.php index e51610637..d6adecbbd 100644 --- a/tests/src/Kernel/FedoraAdapterTest.php +++ b/tests/src/Kernel/FedoraAdapterTest.php @@ -2,6 +2,9 @@ namespace Drupal\Tests\islandora\Kernel; +use Prophecy\PhpUnit\ProphecyTrait; +use GuzzleHttp\Psr7\Utils; +use function GuzzleHttp\Psr7\stream_for; use Drupal\Core\Logger\LoggerChannelInterface; use Drupal\islandora\Flysystem\Adapter\FedoraAdapter; use GuzzleHttp\Psr7\Response; @@ -18,6 +21,7 @@ */ class FedoraAdapterTest extends IslandoraKernelTestBase { + use ProphecyTrait; /** * A mimetype guesser prophecy. * @@ -35,7 +39,7 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); $this->mimeGuesser = $this->prophesize(MimeTypeGuesserInterface::class) ->reveal(); @@ -58,10 +62,10 @@ protected function createAdapterBase() { $prophecy->getHeader('Content-Type')->willReturn(['text/plain']); $prophecy->getHeader('Content-Length')->willReturn([strlen("DERP")]); // phpcs:disable - if (class_exists(\GuzzleHttp\Psr7\Utils::class)) { - $prophecy->getBody()->willReturn(\GuzzleHttp\Psr7\Utils::streamFor("DERP")); + if (class_exists(Utils::class)) { + $prophecy->getBody()->willReturn(Utils::streamFor("DERP")); } else { - $prophecy->getBody()->willReturn(\GuzzleHttp\Psr7\stream_for("DERP")); + $prophecy->getBody()->willReturn(stream_for("DERP")); } // phpcs:enable return $prophecy; diff --git a/tests/src/Kernel/IslandoraKernelTestBase.php b/tests/src/Kernel/IslandoraKernelTestBase.php index 5a95cb682..1c98db3e9 100644 --- a/tests/src/Kernel/IslandoraKernelTestBase.php +++ b/tests/src/Kernel/IslandoraKernelTestBase.php @@ -12,7 +12,7 @@ abstract class IslandoraKernelTestBase extends KernelTestBase { /** * {@inheritdoc} */ - public static $modules = [ + protected static $modules = [ 'system', 'user', 'field', @@ -43,7 +43,7 @@ abstract class IslandoraKernelTestBase extends KernelTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); // Bootstrap minimal Drupal environment to run the tests. diff --git a/tests/src/Kernel/JwtEventSubscriberTest.php b/tests/src/Kernel/JwtEventSubscriberTest.php index f97eab9fb..9493ab78a 100644 --- a/tests/src/Kernel/JwtEventSubscriberTest.php +++ b/tests/src/Kernel/JwtEventSubscriberTest.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\islandora\Kernel; +use Prophecy\PhpUnit\ProphecyTrait; use Drupal\jwt\Authentication\Event\JwtAuthGenerateEvent; use Drupal\jwt\Authentication\Event\JwtAuthValidEvent; use Drupal\jwt\Authentication\Event\JwtAuthValidateEvent; @@ -19,6 +20,7 @@ */ class JwtEventSubscriberTest extends IslandoraKernelTestBase { + use ProphecyTrait; use UserCreationTrait; /** @@ -31,7 +33,7 @@ class JwtEventSubscriberTest extends IslandoraKernelTestBase { /** * {@inheritdoc} */ - public function setUp() { + public function setUp(): void { parent::setUp(); $this->user = $this->createUser(); From 2c332348dca507b090b3514048454ec998baf4e1 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Tue, 13 Jun 2023 15:12:13 -0300 Subject: [PATCH 165/252] Undo overzealous Rector. --- .github/workflows/build-2.x.yml | 1 - .../install/views.view.all_taxonomy_terms.yml | 1 - .../install/views.view.file_checksum.yml | 1 - .../install/views.view.non_fedora_files.yml | 1 - .../src/Plugin/views/style/IIIFManifest.php | 33 +++++++++++++++++-- .../src/Controller/MediaSourceController.php | 18 ++++++++-- .../AbstractFileSelectionForm.php | 7 +--- .../JsonldSelfReferenceReactionTest.php | 1 + .../JsonldTypeAlterReactionTest.php | 1 + 9 files changed, 49 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index 439395b0a..d05222d9c 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -123,4 +123,3 @@ jobs: run: | cd $DRUPAL_DIR/web/core $DRUPAL_DIR/vendor/bin/phpunit --verbose --testsuite "${{ matrix.test-suite }}" - diff --git a/modules/islandora_core_feature/config/install/views.view.all_taxonomy_terms.yml b/modules/islandora_core_feature/config/install/views.view.all_taxonomy_terms.yml index 56b450669..8c3cb0f3d 100644 --- a/modules/islandora_core_feature/config/install/views.view.all_taxonomy_terms.yml +++ b/modules/islandora_core_feature/config/install/views.view.all_taxonomy_terms.yml @@ -168,4 +168,3 @@ display: - url.query_args - user.permissions tags: { } - diff --git a/modules/islandora_core_feature/config/install/views.view.file_checksum.yml b/modules/islandora_core_feature/config/install/views.view.file_checksum.yml index 2c8191013..e529f21ec 100644 --- a/modules/islandora_core_feature/config/install/views.view.file_checksum.yml +++ b/modules/islandora_core_feature/config/install/views.view.file_checksum.yml @@ -304,4 +304,3 @@ display: - url - user.permissions tags: { } - diff --git a/modules/islandora_core_feature/config/install/views.view.non_fedora_files.yml b/modules/islandora_core_feature/config/install/views.view.non_fedora_files.yml index 88b0f308e..b90494f5d 100644 --- a/modules/islandora_core_feature/config/install/views.view.non_fedora_files.yml +++ b/modules/islandora_core_feature/config/install/views.view.non_fedora_files.yml @@ -194,4 +194,3 @@ display: - url.query_args - user.permissions tags: { } - diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 63f015d1c..b76628d72 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -93,10 +93,17 @@ class IIIFManifest extends StylePluginBase { */ protected $messenger; + /** + * Module Handler for running hooks. + * + * @var \Drupal\Core\Extention\ModuleHandlerInterface + */ + protected $moduleHandler; + /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system, Client $http_client, MessengerInterface $messenger) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system, Client $http_client, MessengerInterface $messenger, ModuleHandlerInterface $moduleHandler) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->serializer = $serializer; @@ -106,6 +113,7 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition $this->fileSystem = $file_system; $this->httpClient = $http_client; $this->messenger = $messenger; + $this->moduleHandler = $moduleHandler; } /** @@ -122,10 +130,21 @@ public static function create(ContainerInterface $container, array $configuratio $container->get('entity_type.manager'), $container->get('file_system'), $container->get('http_client'), - $container->get('messenger') + $container->get('messenger'), + $container->get('module_handler') ); } + /** + * Return the request property. + * + * @return \Symfony\Component\HttpFoundation\Request + * The Symfony request object + */ + public function getRequest() { + return $this->request; + } + /** * {@inheritdoc} */ @@ -172,6 +191,9 @@ public function render() { $content_type = 'json'; + // Give other modules a chance to alter the manifest. + $this->moduleHandler->alter('islandora_iiif_manifest', $json, $this); + return $this->serializer->serialize($json, $content_type, ['views_style_plugin' => $this]); } @@ -255,6 +277,13 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas ]; } + // Give other modules a chance to alter the canvas. + $alter_options = [ + 'options' => $this->options, + 'views_plugin' => $this, + ]; + $this->moduleHandler->alter('islandora_iiif_manifest_canvas', $tmp_canvas, $row, $alter_options); + $canvases[] = $tmp_canvas; } } diff --git a/modules/islandora_text_extraction/src/Controller/MediaSourceController.php b/modules/islandora_text_extraction/src/Controller/MediaSourceController.php index 5518220d1..6b8863084 100644 --- a/modules/islandora_text_extraction/src/Controller/MediaSourceController.php +++ b/modules/islandora_text_extraction/src/Controller/MediaSourceController.php @@ -5,6 +5,7 @@ use Drupal\Core\Controller\ControllerBase; use Drupal\Core\File\FileSystem; use Drupal\Core\File\FileSystemInterface; +use Drupal\file\FileRepository; use Drupal\media\Entity\Media; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; @@ -42,14 +43,24 @@ class MediaSourceController extends ControllerBase { */ protected $fileSystem; + /** + * File repository service. + * + * @var \Drupal\file\FileRepository + */ + protected $fileRepository; + /** * MediaSourceController constructor. * * @param \Drupal\Core\File\FileSystem $fileSystem * Filesystem service. + * @param \Drupal\file\FileRepository $fileRepository + * File Repository service. */ - public function __construct(FileSystem $fileSystem) { + public function __construct(FileSystem $fileSystem, FileRepository $fileRepository) { $this->fileSystem = $fileSystem; + $this->fileRepository = $fileRepository; } /** @@ -63,7 +74,8 @@ public function __construct(FileSystem $fileSystem) { */ public static function create(ContainerInterface $container) { return new static( - $container->get('file_system') + $container->get('file_system'), + $container->get('file.repository'), ); } @@ -98,7 +110,7 @@ public function attachToMedia( if (!$this->fileSystem->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS)) { throw new HttpException(500, "The destination directory does not exist, could not be created, or is not writable"); } - $file = \Drupal::service('file.repository')->writeData($contents, $content_location, FileSystemInterface::EXISTS_REPLACE); + $file = $this->fileRepository->writeData($contents, $content_location, FileSystemInterface::EXISTS_REPLACE); if ($media->hasField($destination_field)) { $media->{$destination_field}->setValue([ 'target_id' => $file->id(), diff --git a/src/Form/AddChildrenWizard/AbstractFileSelectionForm.php b/src/Form/AddChildrenWizard/AbstractFileSelectionForm.php index cf6ef3057..6aeed8795 100644 --- a/src/Form/AddChildrenWizard/AbstractFileSelectionForm.php +++ b/src/Form/AddChildrenWizard/AbstractFileSelectionForm.php @@ -37,11 +37,6 @@ abstract class AbstractFileSelectionForm extends FormBase { * @var \Drupal\islandora\Form\AddChildrenWizard\AbstractBatchProcessor|null */ protected ?AbstractBatchProcessor $batchProcessor; - private \static $static; - public function __construct(\static $static) - { - $this->static = $static; - } /** * {@inheritdoc} @@ -54,7 +49,7 @@ public static function create(ContainerInterface $container): self { $instance->entityFieldManager = $container->get('entity_field.manager'); $instance->currentUser = $container->get('current_user'); - $instance->batchProcessor = $this->static; + $instance->batchProcessor = $container->get(static::BATCH_PROCESSOR); return $instance; } diff --git a/tests/src/Functional/JsonldSelfReferenceReactionTest.php b/tests/src/Functional/JsonldSelfReferenceReactionTest.php index 7ad8f0185..92eca07a8 100644 --- a/tests/src/Functional/JsonldSelfReferenceReactionTest.php +++ b/tests/src/Functional/JsonldSelfReferenceReactionTest.php @@ -3,6 +3,7 @@ namespace Drupal\Tests\islandora\Functional; use function GuzzleHttp\json_decode; + /** * Class MappingUriPredicateReactionTest. * diff --git a/tests/src/Functional/JsonldTypeAlterReactionTest.php b/tests/src/Functional/JsonldTypeAlterReactionTest.php index 58e8bf61b..80a6039c2 100644 --- a/tests/src/Functional/JsonldTypeAlterReactionTest.php +++ b/tests/src/Functional/JsonldTypeAlterReactionTest.php @@ -3,6 +3,7 @@ namespace Drupal\Tests\islandora\Functional; use function GuzzleHttp\json_decode; + /** * Tests Jsonld Alter Reaction. * From ffd128db80c46f4e480f70d99726e4786f6a1621 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 22 Jun 2023 16:02:25 -0300 Subject: [PATCH 166/252] Typo prevented submodule functional tests from running. --- .github/workflows/build-2.x.yml | 2 +- phpunit.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index d05222d9c..261ab1dec 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -28,7 +28,7 @@ jobs: # test-suite functional-javascript will appear to pass but will skip tests; missing chromedriver. test-suite: ["kernel", "functional", "functional-javascript"] # Not yet Drupal 10 ready - see https://github.com/Islandora/islandora/issues/888 - drupal-version: ["9.3.x", "9.4.x", "9.5.x-dev"] + drupal-version: ["9.4.x", "9.5.x-dev"] mysql: ["8.0"] allowed_failure: [false] diff --git a/phpunit.xml b/phpunit.xml index a40917813..46e82e78d 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -58,7 +58,7 @@
    ../modules/contrib/islandora/tests/src/Functional - ../modules/contrib/isladnora/modules/*/tests/src/Functional + ../modules/contrib/islandora/modules/*/tests/src/Functional ../modules/contrib/islandora/tests/src/FunctionalJavascript From 9cabfc2e23ca3f7dbfd962f817201b2c0f8fb97e Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Fri, 30 Jun 2023 10:06:28 -0300 Subject: [PATCH 167/252] Fix a typo. (#958) --- .../src/Plugin/Action/GenerateOCRDerivativeFile.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivativeFile.php b/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivativeFile.php index 4ff0d93fc..565d7564c 100644 --- a/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivativeFile.php +++ b/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivativeFile.php @@ -99,7 +99,7 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s break; case 'plain_text': - $his->configuration['args'] = ''; + $this->configuration['args'] = ''; break; } } From 8f8e6a3c35bd5afb193272547203c4ee807dc24d Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Fri, 23 Jun 2023 15:01:43 -0300 Subject: [PATCH 168/252] Test: Breadcrumbs config dependencies missing schema. --- .../config/install/islandora_breadcrumbs.breadcrumbs.yml | 6 ------ .../islandora_breadcrumbs/islandora_breadcrumbs.info.yml | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/modules/islandora_breadcrumbs/config/install/islandora_breadcrumbs.breadcrumbs.yml b/modules/islandora_breadcrumbs/config/install/islandora_breadcrumbs.breadcrumbs.yml index ea34ee2ed..aabb58916 100644 --- a/modules/islandora_breadcrumbs/config/install/islandora_breadcrumbs.breadcrumbs.yml +++ b/modules/islandora_breadcrumbs/config/install/islandora_breadcrumbs.breadcrumbs.yml @@ -2,9 +2,3 @@ maxDepth: -1 includeSelf: FALSE referenceFields: - field_member_of -dependencies: - module: - - islandora - enforced: - module: - - islandora_breadcrumbs diff --git a/modules/islandora_breadcrumbs/islandora_breadcrumbs.info.yml b/modules/islandora_breadcrumbs/islandora_breadcrumbs.info.yml index 56a10bc14..c76020cb6 100644 --- a/modules/islandora_breadcrumbs/islandora_breadcrumbs.info.yml +++ b/modules/islandora_breadcrumbs/islandora_breadcrumbs.info.yml @@ -5,4 +5,4 @@ core: 8.x core_version_requirement: ^8 || ^9 package: Islandora dependencies: - - drupal:islandora + - islandora:islandora From 7470327871a1bb2b8732a7e11c5ad4dc5eb879d4 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Fri, 23 Jun 2023 15:24:29 -0300 Subject: [PATCH 169/252] Inject fileUrlGenerator into Image Field formatter. --- .../Field/FieldFormatter/IslandoraImageFormatter.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Plugin/Field/FieldFormatter/IslandoraImageFormatter.php b/src/Plugin/Field/FieldFormatter/IslandoraImageFormatter.php index 6c6e87da4..6667f4f4a 100644 --- a/src/Plugin/Field/FieldFormatter/IslandoraImageFormatter.php +++ b/src/Plugin/Field/FieldFormatter/IslandoraImageFormatter.php @@ -5,6 +5,7 @@ use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldItemListInterface; +use Drupal\Core\File\FileUrlGenerator; use Drupal\Core\Session\AccountInterface; use Drupal\image\Plugin\Field\FieldFormatter\ImageFormatter; use Drupal\islandora\IslandoraUtils; @@ -56,6 +57,8 @@ class IslandoraImageFormatter extends ImageFormatter { * The image style storage. * @param \Drupal\islandora\IslandoraUtils $utils * Islandora utils. + * @param \Drupal\Core\File\FileUrlGenerator $file_url_generator + * The File URL Generator. */ public function __construct( $plugin_id, @@ -67,7 +70,8 @@ public function __construct( array $third_party_settings, AccountInterface $current_user, EntityStorageInterface $image_style_storage, - IslandoraUtils $utils + IslandoraUtils $utils, + FileUrlGenerator $file_url_generator ) { parent::__construct( $plugin_id, @@ -78,7 +82,8 @@ public function __construct( $view_mode, $third_party_settings, $current_user, - $image_style_storage + $image_style_storage, + $file_url_generator ); $this->utils = $utils; } @@ -97,7 +102,8 @@ public static function create(ContainerInterface $container, array $configuratio $configuration['third_party_settings'], $container->get('current_user'), $container->get('entity_type.manager')->getStorage('image_style'), - $container->get('islandora.utils') + $container->get('islandora.utils'), + $container->get('file_url_generator') ); } From e4dc48fca2dab39c7ab709c445a3fe14551052ea Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Fri, 23 Jun 2023 16:39:34 -0300 Subject: [PATCH 170/252] Tests were not finding the media use field. --- .../tests/src/Functional/GenerateAudioDerivativeTest.php | 2 +- .../tests/src/Functional/GenerateImageDerivativeTest.php | 2 +- .../tests/src/Functional/GenerateVideoDerivativeTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php index 766ceac0a..b528e8ba7 100644 --- a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php +++ b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php @@ -66,7 +66,7 @@ public function testGenerateAudioDerivativeFromScratch() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', - 'field_tags[0][target_id]' => 'Preservation Master', + 'field_media_use[0][target_id]' => 'foo', # change back to $this->preservationMasterTerm->label() ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); $this->submitForm($values, $this->t('Save')); diff --git a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php index 295eae913..69672e0b7 100644 --- a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php +++ b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php @@ -68,7 +68,7 @@ public function testGenerateImageDerivativeFromScratch() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', - 'field_tags[0][target_id]' => 'Preservation Master', + 'field_media_use[0][target_id]' => 'foo', # change back to $this->preservationMasterTerm->label() ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); $this->submitForm($values, $this->t('Save')); diff --git a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php index 17e8bd5b5..f712e3490 100644 --- a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php +++ b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php @@ -63,7 +63,7 @@ public function testGenerateVideoDerivativeFromScratch() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', - 'field_tags[0][target_id]' => 'Preservation Master', + 'field_media_use[0][target_id]' => 'foo', # change back to $this->preservationMasterTerm->label() ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); $this->submitForm($values, $this->t('Save')); From 52947f3f9676983c7d19f4e4489ec4aa3d374265 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Mon, 26 Jun 2023 13:20:54 -0300 Subject: [PATCH 171/252] Use phpcs friendly comment... --- .../tests/src/Functional/GenerateAudioDerivativeTest.php | 2 +- .../tests/src/Functional/GenerateImageDerivativeTest.php | 2 +- .../tests/src/Functional/GenerateVideoDerivativeTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php index b528e8ba7..a74259173 100644 --- a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php +++ b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php @@ -66,7 +66,7 @@ public function testGenerateAudioDerivativeFromScratch() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', - 'field_media_use[0][target_id]' => 'foo', # change back to $this->preservationMasterTerm->label() + 'field_media_use[0][target_id]' => 'foo', // change back to $this->preservationMasterTerm->label() ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); $this->submitForm($values, $this->t('Save')); diff --git a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php index 69672e0b7..2e1f55914 100644 --- a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php +++ b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php @@ -68,7 +68,7 @@ public function testGenerateImageDerivativeFromScratch() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', - 'field_media_use[0][target_id]' => 'foo', # change back to $this->preservationMasterTerm->label() + 'field_media_use[0][target_id]' => 'foo', // change back to $this->preservationMasterTerm->label() ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); $this->submitForm($values, $this->t('Save')); diff --git a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php index f712e3490..3a5569870 100644 --- a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php +++ b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php @@ -63,7 +63,7 @@ public function testGenerateVideoDerivativeFromScratch() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', - 'field_media_use[0][target_id]' => 'foo', # change back to $this->preservationMasterTerm->label() + 'field_media_use[0][target_id]' => 'foo', // change back to $this->preservationMasterTerm->label() ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); $this->submitForm($values, $this->t('Save')); From e67e8e5f25a20740af8a0647aedc033aa5c06ba1 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Mon, 26 Jun 2023 13:32:33 -0300 Subject: [PATCH 172/252] Remove problematic comments. --- .../tests/src/Functional/GenerateAudioDerivativeTest.php | 2 +- .../tests/src/Functional/GenerateImageDerivativeTest.php | 2 +- .../tests/src/Functional/GenerateVideoDerivativeTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php index a74259173..5c1b616ed 100644 --- a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php +++ b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php @@ -66,7 +66,7 @@ public function testGenerateAudioDerivativeFromScratch() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', - 'field_media_use[0][target_id]' => 'foo', // change back to $this->preservationMasterTerm->label() + 'field_media_use[0][target_id]' => 'foo', ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); $this->submitForm($values, $this->t('Save')); diff --git a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php index 2e1f55914..7544cb650 100644 --- a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php +++ b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php @@ -68,7 +68,7 @@ public function testGenerateImageDerivativeFromScratch() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', - 'field_media_use[0][target_id]' => 'foo', // change back to $this->preservationMasterTerm->label() + 'field_media_use[0][target_id]' => 'foo', ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); $this->submitForm($values, $this->t('Save')); diff --git a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php index 3a5569870..264cebb71 100644 --- a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php +++ b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php @@ -63,7 +63,7 @@ public function testGenerateVideoDerivativeFromScratch() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', - 'field_media_use[0][target_id]' => 'foo', // change back to $this->preservationMasterTerm->label() + 'field_media_use[0][target_id]' => 'foo', ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); $this->submitForm($values, $this->t('Save')); From 8ef277527b2ee715331a1c46e28a3ee90c62f5c9 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Tue, 27 Jun 2023 12:05:11 -0300 Subject: [PATCH 173/252] Fix tests. --- .../tests/src/Functional/GenerateAudioDerivativeTest.php | 2 +- .../tests/src/Functional/GenerateImageDerivativeTest.php | 2 +- .../tests/src/Functional/GenerateVideoDerivativeTest.php | 2 +- ...core.entity_form_display.media.test_media_type.default.yml | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php index 5c1b616ed..6b85cd1b5 100644 --- a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php +++ b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php @@ -66,7 +66,7 @@ public function testGenerateAudioDerivativeFromScratch() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', - 'field_media_use[0][target_id]' => 'foo', + 'field_media_use[0][target_id]' => $this->preservationMasterTerm->label(), ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); $this->submitForm($values, $this->t('Save')); diff --git a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php index 7544cb650..44cdda589 100644 --- a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php +++ b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php @@ -68,7 +68,7 @@ public function testGenerateImageDerivativeFromScratch() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', - 'field_media_use[0][target_id]' => 'foo', + 'field_media_use[0][target_id]' => $this->preservationMasterTerm->label(), ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); $this->submitForm($values, $this->t('Save')); diff --git a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php index 264cebb71..de06ba2f7 100644 --- a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php +++ b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php @@ -63,7 +63,7 @@ public function testGenerateVideoDerivativeFromScratch() { 'name[0][value]' => 'Test Media', 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', 'field_media_of[0][target_id]' => 'Test Node', - 'field_media_use[0][target_id]' => 'foo', + 'field_media_use[0][target_id]' => $this->preservationMasterTerm->label(), ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); $this->submitForm($values, $this->t('Save')); diff --git a/tests/fixtures/config/core.entity_form_display.media.test_media_type.default.yml b/tests/fixtures/config/core.entity_form_display.media.test_media_type.default.yml index 19fe419b6..d261542de 100644 --- a/tests/fixtures/config/core.entity_form_display.media.test_media_type.default.yml +++ b/tests/fixtures/config/core.entity_form_display.media.test_media_type.default.yml @@ -3,7 +3,7 @@ status: true dependencies: config: - field.field.media.test_media_type.field_media_of - - field.field.media.test_media_type.field_tags + - field.field.media.test_media_type.field_media_use - media.type.test_media_type module: - path @@ -37,7 +37,7 @@ content: size: 60 placeholder: '' third_party_settings: { } - field_tags: + field_media_use: type: entity_reference_autocomplete weight: 3 region: content From a88486ca285c5325c9b60d63151b10b218f93070 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Tue, 27 Jun 2023 12:23:44 -0300 Subject: [PATCH 174/252] Add accessCheck FALSE to all queries. --- src/IslandoraUtils.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/IslandoraUtils.php b/src/IslandoraUtils.php index f81cb7472..41f84cbe6 100644 --- a/src/IslandoraUtils.php +++ b/src/IslandoraUtils.php @@ -148,6 +148,7 @@ public function getMedia(NodeInterface $node) { return []; } $mids = $this->entityTypeManager->getStorage('media')->getQuery() + ->accessCheck(FALSE) ->condition(self::MEDIA_OF_FIELD, $node->id()) ->execute(); if (empty($mids)) { @@ -208,6 +209,7 @@ function ($field) { // Query for media that reference this file. $query = $this->entityTypeManager->getStorage('media')->getQuery(); + $query->accessCheck(FALSE); $group = $query->orConditionGroup(); foreach ($conditions as $condition) { $group->condition($condition, $fid); @@ -252,6 +254,7 @@ public function getTermForUri($uri) { } $results = $query + ->accessCheck(FALSE) ->condition($orGroup) ->execute(); @@ -498,6 +501,7 @@ public function getMediaReferencingNodeAndTerm(NodeInterface $node, TermInterfac array_walk($node_fields, $remove_entity); $query = $this->entityTypeManager->getStorage('media')->getQuery(); + $query->accessCheck(FALSE); $taxon_condition = $this->getEntityQueryOrCondition($query, $term_fields, $term->id()); $query->condition($taxon_condition); $node_condition = $this->getEntityQueryOrCondition($query, $node_fields, $node->id()); From d293d7702a2de0417ee78afcd92aad2f52e06924 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Tue, 27 Jun 2023 13:10:48 -0300 Subject: [PATCH 175/252] Change to check access (true). --- src/IslandoraUtils.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/IslandoraUtils.php b/src/IslandoraUtils.php index 41f84cbe6..a2df75896 100644 --- a/src/IslandoraUtils.php +++ b/src/IslandoraUtils.php @@ -148,7 +148,7 @@ public function getMedia(NodeInterface $node) { return []; } $mids = $this->entityTypeManager->getStorage('media')->getQuery() - ->accessCheck(FALSE) + ->accessCheck(TRUE) ->condition(self::MEDIA_OF_FIELD, $node->id()) ->execute(); if (empty($mids)) { @@ -209,7 +209,7 @@ function ($field) { // Query for media that reference this file. $query = $this->entityTypeManager->getStorage('media')->getQuery(); - $query->accessCheck(FALSE); + $query->accessCheck(TRUE); $group = $query->orConditionGroup(); foreach ($conditions as $condition) { $group->condition($condition, $fid); @@ -254,7 +254,7 @@ public function getTermForUri($uri) { } $results = $query - ->accessCheck(FALSE) + ->accessCheck(TRUE) ->condition($orGroup) ->execute(); @@ -501,7 +501,7 @@ public function getMediaReferencingNodeAndTerm(NodeInterface $node, TermInterfac array_walk($node_fields, $remove_entity); $query = $this->entityTypeManager->getStorage('media')->getQuery(); - $query->accessCheck(FALSE); + $query->accessCheck(TRUE); $taxon_condition = $this->getEntityQueryOrCondition($query, $term_fields, $term->id()); $query->condition($taxon_condition); $node_condition = $this->getEntityQueryOrCondition($query, $node_fields, $node->id()); From d1861de270a3c7cf5d87cb8be8e2b71a0510047a Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 28 Jun 2023 10:00:43 -0300 Subject: [PATCH 176/252] Test on 8.1. --- .github/workflows/build-2.x.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index 261ab1dec..27506495e 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -24,11 +24,11 @@ jobs: fail-fast: false matrix: # PHP 8.1 fails - see https://github.com/Islandora/islandora/issues/887 - php-versions: ["7.4", "8.0"] + php-versions: ["7.4", "8.0", "8.1"] # test-suite functional-javascript will appear to pass but will skip tests; missing chromedriver. test-suite: ["kernel", "functional", "functional-javascript"] # Not yet Drupal 10 ready - see https://github.com/Islandora/islandora/issues/888 - drupal-version: ["9.4.x", "9.5.x-dev"] + drupal-version: ["9.4.x", "9.5.x"] mysql: ["8.0"] allowed_failure: [false] From 8adc44859cd679c759766af49fa5edf42c2a1452 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 29 Jun 2023 13:34:11 -0300 Subject: [PATCH 177/252] Update fixtures to have config UUIDs. --- ..._display.media.test_media_type.default.yml | 5 ++++ ...ty_form_display.node.test_type.default.yml | 29 ++++++++++++++----- ..._form_display.node.test_type.secondary.yml | 8 +++-- .../core.entity_form_mode.node.secondary.yml | 5 ++-- ...ty_view_display.node.test_type.default.yml | 15 ++++++++-- ...ity_view_display.node.test_type.teaser.yml | 16 ++++++---- .../config/rest.resource.entity.file.yml | 2 ++ .../config/rest.resource.entity.media.yml | 3 +- .../config/rest.resource.entity.node.yml | 1 + .../rest.resource.entity.taxonomy_term.yml | 1 + 10 files changed, 64 insertions(+), 21 deletions(-) diff --git a/tests/fixtures/config/core.entity_form_display.media.test_media_type.default.yml b/tests/fixtures/config/core.entity_form_display.media.test_media_type.default.yml index d261542de..ea8eac008 100644 --- a/tests/fixtures/config/core.entity_form_display.media.test_media_type.default.yml +++ b/tests/fixtures/config/core.entity_form_display.media.test_media_type.default.yml @@ -1,7 +1,9 @@ +uuid: 9151a0fe-7729-4943-b506-dd6f8d12ceac langcode: en status: true dependencies: config: + - field.field.media.test_media_type.field_media_file - field.field.media.test_media_type.field_media_of - field.field.media.test_media_type.field_media_use - media.type.test_media_type @@ -34,6 +36,7 @@ content: region: content settings: match_operator: CONTAINS + match_limit: 10 size: 60 placeholder: '' third_party_settings: { } @@ -43,6 +46,7 @@ content: region: content settings: match_operator: CONTAINS + match_limit: 10 size: 60 placeholder: '' third_party_settings: { } @@ -64,6 +68,7 @@ content: weight: 4 settings: match_operator: CONTAINS + match_limit: 10 size: 60 placeholder: '' region: content diff --git a/tests/fixtures/config/core.entity_form_display.node.test_type.default.yml b/tests/fixtures/config/core.entity_form_display.node.test_type.default.yml index 2560ec6e7..68724265a 100644 --- a/tests/fixtures/config/core.entity_form_display.node.test_type.default.yml +++ b/tests/fixtures/config/core.entity_form_display.node.test_type.default.yml @@ -1,12 +1,13 @@ +uuid: 90a6909f-a2aa-44e8-8b61-4cd54ec6974f langcode: en status: true dependencies: config: - field.field.node.test_type.field_member_of + - field.field.node.test_type.field_model - node.type.test_type module: - path - - text id: node.test_type.default targetEntityType: node bundle: test_type @@ -19,14 +20,25 @@ content: settings: { } third_party_settings: { } field_member_of: + type: entity_reference_autocomplete weight: 122 + region: content settings: match_operator: CONTAINS + match_limit: 10 size: 60 placeholder: '' third_party_settings: { } + field_model: type: entity_reference_autocomplete + weight: 123 region: content + settings: + match_operator: CONTAINS + match_limit: 10 + size: 60 + placeholder: '' + third_party_settings: { } langcode: type: language_select weight: 2 @@ -42,24 +54,24 @@ content: third_party_settings: { } promote: type: boolean_checkbox - settings: - display_label: true weight: 15 region: content + settings: + display_label: true third_party_settings: { } status: type: boolean_checkbox - settings: - display_label: true weight: 120 region: content + settings: + display_label: true third_party_settings: { } sticky: type: boolean_checkbox - settings: - display_label: true weight: 16 region: content + settings: + display_label: true third_party_settings: { } title: type: string_textfield @@ -72,10 +84,11 @@ content: uid: type: entity_reference_autocomplete weight: 5 + region: content settings: match_operator: CONTAINS + match_limit: 10 size: 60 placeholder: '' - region: content third_party_settings: { } hidden: { } diff --git a/tests/fixtures/config/core.entity_form_display.node.test_type.secondary.yml b/tests/fixtures/config/core.entity_form_display.node.test_type.secondary.yml index b1fdb88ec..f8f05beb1 100644 --- a/tests/fixtures/config/core.entity_form_display.node.test_type.secondary.yml +++ b/tests/fixtures/config/core.entity_form_display.node.test_type.secondary.yml @@ -1,12 +1,12 @@ +uuid: e24c2b3c-60e4-4ff5-99cb-80e5e67e7b04 langcode: en status: true dependencies: config: + - core.entity_form_mode.node.secondary - field.field.node.test_type.field_member_of + - field.field.node.test_type.field_model - node.type.test_type - module: - - path - - text id: node.test_type.secondary targetEntityType: node bundle: test_type @@ -23,6 +23,8 @@ content: hidden: created: true field_media: true + field_member_of: true + field_model: true field_node: true langcode: true path: true diff --git a/tests/fixtures/config/core.entity_form_mode.node.secondary.yml b/tests/fixtures/config/core.entity_form_mode.node.secondary.yml index 07f45bbe2..e1fc76345 100644 --- a/tests/fixtures/config/core.entity_form_mode.node.secondary.yml +++ b/tests/fixtures/config/core.entity_form_mode.node.secondary.yml @@ -1,9 +1,10 @@ +uuid: d9f22219-ff4c-48cc-a98a-6ccaad7a880d langcode: en status: true dependencies: module: - node id: node.secondary -label: Secondary +label: Secondary targetEntityType: node -cache: true +cache: true \ No newline at end of file diff --git a/tests/fixtures/config/core.entity_view_display.node.test_type.default.yml b/tests/fixtures/config/core.entity_view_display.node.test_type.default.yml index cf798265b..e4414e611 100644 --- a/tests/fixtures/config/core.entity_view_display.node.test_type.default.yml +++ b/tests/fixtures/config/core.entity_view_display.node.test_type.default.yml @@ -1,11 +1,12 @@ +uuid: 36f4aecf-0e14-4281-a213-ca7d129da52a langcode: en status: true dependencies: config: - field.field.node.test_type.field_member_of + - field.field.node.test_type.field_model - node.type.test_type module: - - text - user id: node.test_type.default targetEntityType: node @@ -13,14 +14,24 @@ bundle: test_type mode: default content: field_member_of: - weight: 102 + type: entity_reference_label label: above settings: link: true third_party_settings: { } + weight: 102 + region: content + field_model: type: entity_reference_label + label: above + settings: + link: true + third_party_settings: { } + weight: 103 region: content links: + settings: { } + third_party_settings: { } weight: 100 region: content hidden: diff --git a/tests/fixtures/config/core.entity_view_display.node.test_type.teaser.yml b/tests/fixtures/config/core.entity_view_display.node.test_type.teaser.yml index d67060f72..f72954281 100644 --- a/tests/fixtures/config/core.entity_view_display.node.test_type.teaser.yml +++ b/tests/fixtures/config/core.entity_view_display.node.test_type.teaser.yml @@ -1,19 +1,25 @@ -uuid: 0308339a-a9e5-4a04-8ce2-9f62ed504e34 +uuid: b337f462-8e64-4853-be65-9e03b94515bf langcode: en status: true dependencies: config: - core.entity_view_mode.node.teaser + - field.field.node.test_type.field_member_of + - field.field.node.test_type.field_model - node.type.test_type module: - - text - user id: node.test_type.teaser targetEntityType: node bundle: test_type mode: teaser content: + links: + settings: { } + third_party_settings: { } + weight: 100 + region: content hidden: - body: true - links: true - langcode: true + field_member_of: true + field_model: true + langcode: true \ No newline at end of file diff --git a/tests/fixtures/config/rest.resource.entity.file.yml b/tests/fixtures/config/rest.resource.entity.file.yml index 6a136c3cb..dbd6bb62c 100644 --- a/tests/fixtures/config/rest.resource.entity.file.yml +++ b/tests/fixtures/config/rest.resource.entity.file.yml @@ -1,3 +1,4 @@ +uuid: 11c4e25e-6b06-4270-b934-243e4f4aade1 langcode: en status: true dependencies: @@ -26,3 +27,4 @@ configuration: supported_auth: - basic_auth - jwt_auth + - cookie diff --git a/tests/fixtures/config/rest.resource.entity.media.yml b/tests/fixtures/config/rest.resource.entity.media.yml index 3ed0286e7..cd89243d3 100644 --- a/tests/fixtures/config/rest.resource.entity.media.yml +++ b/tests/fixtures/config/rest.resource.entity.media.yml @@ -1,3 +1,4 @@ +uuid: 9a5633b1-6a1a-40b2-8482-c24cf44122ff langcode: en status: true dependencies: @@ -5,7 +6,7 @@ dependencies: - basic_auth - jsonld - jwt - - media_entity + - media - serialization - user id: entity.media diff --git a/tests/fixtures/config/rest.resource.entity.node.yml b/tests/fixtures/config/rest.resource.entity.node.yml index e7d4c7cc3..a3e253e2e 100644 --- a/tests/fixtures/config/rest.resource.entity.node.yml +++ b/tests/fixtures/config/rest.resource.entity.node.yml @@ -1,3 +1,4 @@ +uuid: 08a90469-0355-4b41-a4d6-cb6b53072b8c langcode: en status: true dependencies: diff --git a/tests/fixtures/config/rest.resource.entity.taxonomy_term.yml b/tests/fixtures/config/rest.resource.entity.taxonomy_term.yml index 25b6fbb26..16d96c3ef 100644 --- a/tests/fixtures/config/rest.resource.entity.taxonomy_term.yml +++ b/tests/fixtures/config/rest.resource.entity.taxonomy_term.yml @@ -1,3 +1,4 @@ +uuid: 7534e393-12a7-498c-a4a3-a7bbe4ff9a5d langcode: en status: true dependencies: From aec8178846c23bb952b1f9902d86296528b9864f Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 29 Jun 2023 13:34:43 -0300 Subject: [PATCH 178/252] Stop using deprecated FILE_STATUS_PERMANENT. --- tests/src/Functional/DeleteNodeWithMediaAndFile.php | 2 +- tests/src/Functional/IslandoraFunctionalTestBase.php | 2 +- tests/src/Functional/IslandoraImageFormatterTest.php | 2 +- tests/src/Functional/JsonldTypeAlterReactionTest.php | 2 +- tests/src/Functional/MediaSourceUpdateTest.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/src/Functional/DeleteNodeWithMediaAndFile.php b/tests/src/Functional/DeleteNodeWithMediaAndFile.php index 40e469c5c..5ee19b7ce 100644 --- a/tests/src/Functional/DeleteNodeWithMediaAndFile.php +++ b/tests/src/Functional/DeleteNodeWithMediaAndFile.php @@ -42,8 +42,8 @@ public function testDeleteNodeWithMediaAndFile() { 'uri' => "public://test.jpeg", 'filename' => "test.jpeg", 'filemime' => "image/jpeg", - 'status' => FILE_STATUS_PERMANENT, ]); + $file->setPermanent(); $file->save(); $this->drupalGet("node/1/delete"); diff --git a/tests/src/Functional/IslandoraFunctionalTestBase.php b/tests/src/Functional/IslandoraFunctionalTestBase.php index 2e7235611..016788d05 100644 --- a/tests/src/Functional/IslandoraFunctionalTestBase.php +++ b/tests/src/Functional/IslandoraFunctionalTestBase.php @@ -438,8 +438,8 @@ protected function makeMediaAndFile(AccountInterface $account) { 'uri' => "public://test_file.txt", 'filename' => "test_file.txt", 'filemime' => "text/plain", - 'status' => FILE_STATUS_PERMANENT, ]); + $file->setPermanent(); $file->save(); // Get the source field for the media. diff --git a/tests/src/Functional/IslandoraImageFormatterTest.php b/tests/src/Functional/IslandoraImageFormatterTest.php index 84ea55173..1b40f7a8d 100644 --- a/tests/src/Functional/IslandoraImageFormatterTest.php +++ b/tests/src/Functional/IslandoraImageFormatterTest.php @@ -59,8 +59,8 @@ public function testIslandoraImageFormatter() { 'uri' => "public://test.jpeg", 'filename' => "test.jpeg", 'filemime' => "image/jpeg", - 'status' => FILE_STATUS_PERMANENT, ]); + $file->setPermanent(); $file->save(); // Make the media, and associate it with the image and node. diff --git a/tests/src/Functional/JsonldTypeAlterReactionTest.php b/tests/src/Functional/JsonldTypeAlterReactionTest.php index 80a6039c2..658244aee 100644 --- a/tests/src/Functional/JsonldTypeAlterReactionTest.php +++ b/tests/src/Functional/JsonldTypeAlterReactionTest.php @@ -30,7 +30,7 @@ public function testMappingReaction() { 'new_storage_type' => 'string', 'label' => 'Typed Predicate', 'field_name' => 'type_predicate', - ], $this->t('Save and continue')); + ], 'Save and continue'); $this->submitForm([], $this->t('Save field settings')); $this->submitForm([], $this->t('Save settings')); $this->assertSession()->responseContains('field_type_predicate'); diff --git a/tests/src/Functional/MediaSourceUpdateTest.php b/tests/src/Functional/MediaSourceUpdateTest.php index 3c97c6954..3938e9b47 100644 --- a/tests/src/Functional/MediaSourceUpdateTest.php +++ b/tests/src/Functional/MediaSourceUpdateTest.php @@ -52,8 +52,8 @@ public function setUp(): void { 'uri' => "public://test_file.txt", 'filename' => "test_file.txt", 'filemime' => "text/plain", - 'status' => FILE_STATUS_PERMANENT, ]); + $this->file->setPermanent(); $this->file->save(); // Get the source field for the media. From 621b7a2c7d074cb98b99d1581a8e179c0a403a31 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Fri, 30 Jun 2023 10:30:47 -0300 Subject: [PATCH 179/252] Remove duplicate line. --- tests/src/Kernel/EventGeneratorTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/src/Kernel/EventGeneratorTest.php b/tests/src/Kernel/EventGeneratorTest.php index a9c1f0825..28a4ec03b 100644 --- a/tests/src/Kernel/EventGeneratorTest.php +++ b/tests/src/Kernel/EventGeneratorTest.php @@ -116,7 +116,6 @@ public function testGenerateDeleteEvent() { ['event' => 'delete', 'queue' => 'islandora-indexing-fcrepo-delete'] ); $msg = json_decode($json, TRUE); - $msg = json_decode($json, TRUE); $this->assertBasicStructure($msg); $this->assertTrue($msg["type"] == "Delete", "Event must be of type 'Delete'."); From 91016fd2379ac3cd6a0517c8331909603e0a0808 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 6 Jul 2023 14:51:23 -0300 Subject: [PATCH 180/252] Don't delete files in the thumbnail field. --- src/Form/ConfirmDeleteMediaAndFile.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Form/ConfirmDeleteMediaAndFile.php b/src/Form/ConfirmDeleteMediaAndFile.php index d5dc9750b..a9613871f 100644 --- a/src/Form/ConfirmDeleteMediaAndFile.php +++ b/src/Form/ConfirmDeleteMediaAndFile.php @@ -128,6 +128,9 @@ public function submitForm(array &$form, FormStateInterface $form_state) { // Check for files. $fields = $this->entityFieldManager->getFieldDefinitions('media', $entity->bundle()); foreach ($fields as $field) { + if ($field->getName() == 'thumbnail') { + continue; + } $type = $field->getType(); if ($type == 'file' || $type == 'image') { $target_id = $entity->get($field->getName())->target_id; From 6d59c526d3d6eac8096319d5ed63e75eb2be155c Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 6 Jul 2023 14:51:50 -0300 Subject: [PATCH 181/252] In Drupal 10.1, include new file delete permission. --- tests/src/Functional/DeleteMediaTest.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/src/Functional/DeleteMediaTest.php b/tests/src/Functional/DeleteMediaTest.php index 86895dbbc..4328d92da 100644 --- a/tests/src/Functional/DeleteMediaTest.php +++ b/tests/src/Functional/DeleteMediaTest.php @@ -50,8 +50,14 @@ class DeleteMediaTest extends IslandoraFunctionalTestBase { public function setUp(): void { parent::setUp(); + if (floatval(\Drupal::VERSION) >= 10.1) { + $permissions = ['create media', 'delete any media', 'delete any files']; + } else { + $permissions = ['create media', 'delete any media']; + } + // Create a test user. - $this->account = $this->createUser(['create media', 'delete any media']); + $this->account = $this->createUser($permissions); list($this->file, $this->media) = $this->makeMediaAndFile($this->account); } From 5c09a1e3f4312f7333b711ae88304656733b1c00 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 6 Jul 2023 14:54:17 -0300 Subject: [PATCH 182/252] Use a better version compare call. --- tests/src/Functional/DeleteMediaTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/Functional/DeleteMediaTest.php b/tests/src/Functional/DeleteMediaTest.php index 4328d92da..586250cc8 100644 --- a/tests/src/Functional/DeleteMediaTest.php +++ b/tests/src/Functional/DeleteMediaTest.php @@ -50,7 +50,7 @@ class DeleteMediaTest extends IslandoraFunctionalTestBase { public function setUp(): void { parent::setUp(); - if (floatval(\Drupal::VERSION) >= 10.1) { + if (version_compare(\Drupal::VERSION, '10.1', '>=')){ $permissions = ['create media', 'delete any media', 'delete any files']; } else { $permissions = ['create media', 'delete any media']; From 6b05ff5f99b77d4300a36b32ce7e18bd55e796e8 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 6 Jul 2023 14:58:53 -0300 Subject: [PATCH 183/252] typo in permission name. --- tests/src/Functional/DeleteMediaTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/Functional/DeleteMediaTest.php b/tests/src/Functional/DeleteMediaTest.php index 586250cc8..7ca809222 100644 --- a/tests/src/Functional/DeleteMediaTest.php +++ b/tests/src/Functional/DeleteMediaTest.php @@ -51,7 +51,7 @@ public function setUp(): void { parent::setUp(); if (version_compare(\Drupal::VERSION, '10.1', '>=')){ - $permissions = ['create media', 'delete any media', 'delete any files']; + $permissions = ['create media', 'delete any media', 'delete any file']; } else { $permissions = ['create media', 'delete any media']; } From 408776437b38f780942f300534539f9336e6af96 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 6 Jul 2023 15:04:48 -0300 Subject: [PATCH 184/252] phpcs. --- tests/src/Functional/DeleteMediaTest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/src/Functional/DeleteMediaTest.php b/tests/src/Functional/DeleteMediaTest.php index 7ca809222..c52eca31f 100644 --- a/tests/src/Functional/DeleteMediaTest.php +++ b/tests/src/Functional/DeleteMediaTest.php @@ -50,9 +50,10 @@ class DeleteMediaTest extends IslandoraFunctionalTestBase { public function setUp(): void { parent::setUp(); - if (version_compare(\Drupal::VERSION, '10.1', '>=')){ + if (version_compare(\Drupal::VERSION, '10.1', '>=')) { $permissions = ['create media', 'delete any media', 'delete any file']; - } else { + } + else { $permissions = ['create media', 'delete any media']; } From ac818a0f27a52dd9c782767fb98609806b89bf1f Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Tue, 11 Jul 2023 13:27:20 -0300 Subject: [PATCH 185/252] Issue #961: Put back accidentally-removed IIIF Manifest alter hooks. (#962) * Issue #961: Put back accidentally-removed IIIF Manifest alter hooks. * Address PHPCS errors. * Address PHPCS errors. * Addresss PHPCS errors. --------- Co-authored-by: Rosie Le Faive --- modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index b76628d72..b5175ed9d 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -5,6 +5,7 @@ use Drupal\Core\Config\ImmutableConfig; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\File\FileSystemInterface; use Drupal\Core\Field\FieldItemInterface; use Drupal\Core\Form\FormStateInterface; From 0fe2a8f559ccf32533d327c78f6f2422bc072c64 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Tue, 11 Jul 2023 13:42:42 -0300 Subject: [PATCH 186/252] Update features spec. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 1cc5f74d9..7706ec74b 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ "drupal/context": "^4 || ^5@RC", "drupal/ctools": "^3.8 || ^4", "drupal/eva" : "^3.0", - "drupal/features" : "^3.7", + "drupal/features" : "^3.13", "drupal/file_replace": "^1.1", "drupal/filehash": "^2", "drupal/flysystem" : "^2.0@alpha", From 5331b0b7d5e436c538a60e2bbf7e8b6d608cc248 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 26 Jul 2023 10:23:52 -0400 Subject: [PATCH 187/252] Add push to Gitlab action. (#966) * Add push to Gitlab action. * Only push 2.x branch. --- .github/workflows/gitlab-mirror.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/gitlab-mirror.yml diff --git a/.github/workflows/gitlab-mirror.yml b/.github/workflows/gitlab-mirror.yml new file mode 100644 index 000000000..9e3629fd0 --- /dev/null +++ b/.github/workflows/gitlab-mirror.yml @@ -0,0 +1,23 @@ +name: Mirror and run GitLab CI + +on: + push: + branches: [2.x] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Mirror + trigger CI + uses: SvanBoxel/gitlab-mirror-and-ci-action@master + with: + args: "https://git.drupalcode.org/project/islandora" + env: + FOLLOW_TAGS: "true" + FORCE_PUSH: "false" + GITLAB_HOSTNAME: "git.drupal.org" + GITLAB_USERNAME: "project_34868_bot" + GITLAB_PASSWORD: ${{ secrets.GITLAB_PASSWORD }} + GITLAB_PROJECT_ID: "34868" + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 4eef5f566df50c381f08f0487de52a33efc3e45d Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 27 Jul 2023 15:16:07 -0400 Subject: [PATCH 188/252] Deprecate advanced_search. --- .../islandora_advanced_search.info.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/islandora_advanced_search/islandora_advanced_search.info.yml b/modules/islandora_advanced_search/islandora_advanced_search.info.yml index 19fae53a5..a5ad90efb 100644 --- a/modules/islandora_advanced_search/islandora_advanced_search.info.yml +++ b/modules/islandora_advanced_search/islandora_advanced_search.info.yml @@ -9,3 +9,5 @@ dependencies: - drupal:facets - drupal:facets_summary - drupal:search_api_solr +lifecycle: deprecated +lifecycle_link: https://groups.google.com/g/islandora/c/SEOAWJrfE_M From 11afd42c8ae5dc715a22dc79b09465224fa2a31e Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Mon, 7 Aug 2023 09:34:12 -0400 Subject: [PATCH 189/252] Issue #964: Allow relative paths in IIIF manifests. (#965) * Issue #964: Allow relative paths in IIIF manifests. * Address PHPCS error. * Fix missing use statement. --- .../config/schema/islandora_iiif.schema.yml | 3 +++ .../islandora_iiif/src/Form/IslandoraIIIFConfigForm.php | 9 +++++++++ .../src/Plugin/views/style/IIIFManifest.php | 8 +++++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/modules/islandora_iiif/config/schema/islandora_iiif.schema.yml b/modules/islandora_iiif/config/schema/islandora_iiif.schema.yml index fc62c5c4c..f9e870efa 100644 --- a/modules/islandora_iiif/config/schema/islandora_iiif.schema.yml +++ b/modules/islandora_iiif/config/schema/islandora_iiif.schema.yml @@ -5,6 +5,9 @@ islandora_iiif.settings: iiif_server: type: string label: 'IIIF Server Url' + use_relative_paths: + type: boolean + label: 'Use relative paths in manifest.' views.style.iiif_manifest: type: views_style diff --git a/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php b/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php index dc750a5a9..f09a01430 100644 --- a/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php +++ b/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php @@ -73,6 +73,14 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#description' => $this->t('Please enter the image server location without trailing slash. e.g. http://www.example.org/iiif/2.'), '#default_value' => $config->get('iiif_server'), ]; + + $form['use_relative_paths'] = [ + '#type' => 'checkbox', + '#title' => $this->t("Use relative file paths in manifest."), + '#description' => $this->t("Check this if your IIIF Server is configured to access files locally. If unchecked, the absolute URL will be given and the IIIF server will make requests to this site to retrieve images."), + '#default_value' => $config->get('use_relative_paths'), + ]; + return parent::buildForm($form, $form_state); } @@ -99,6 +107,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $this->config('islandora_iiif.settings') ->set('iiif_server', $form_state->getValue('iiif_server')) + ->set('use_relative_paths', $form_state->getValue('use_relative_paths')) ->save(); } diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index b5175ed9d..9d31d760d 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -229,7 +229,13 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas // Create the IIIF URL for this file // Visiting $iiif_url will resolve to the info.json for the image. - $file_url = $image->entity->createFileUrl(FALSE); + if ($this->iiifConfig->get('use_relative_paths')) { + $file_url = ltrim($image->entity->createFileUrl(TRUE), '/'); + } + else { + $file_url = $image->entity->createFileUrl(FALSE); + } + $mime_type = $image->entity->getMimeType(); $iiif_url = rtrim($iiif_address, '/') . '/' . urlencode($file_url); From 71f0945e3cbf818d3846bd355966dffc82b36c62 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Wed, 16 Aug 2023 11:09:52 -0300 Subject: [PATCH 190/252] =?UTF-8?q?959=20Use=20image=20dimension=20propert?= =?UTF-8?q?ies=20in=20IIIF=20Manifest=20if=20they=20exist=E2=80=A6=20(#969?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 959-use-image-dimensions Use image dimension properties if they exist when generating IIIF manifests. 959-use-image-dimensions Address PHPCS error. 959-use-image-dimensions Address PHPCS error. * 959-use-image-dimensions Make image dimension values numeric per the spec. --- .../islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 9d31d760d..5a2fb63b3 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -313,6 +313,12 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas * The width and height of the image. */ protected function getCanvasDimensions(string $iiif_url, FieldItemInterface $image, string $mime_type) { + + if (isset($image->width) && is_numeric($image->width) + && isset($image->height) && is_numeric($image->height)) { + return [intval($image->width), intval($image->height)]; + } + try { $info_json = $this->httpClient->get($iiif_url)->getBody(); $resource = json_decode($info_json, TRUE); From 0408edb93f1ff2ea8047289b59eef3a50e23a54c Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 6 Sep 2023 14:05:34 -0300 Subject: [PATCH 191/252] Push tags to gitlab. (#974) * Push tags to gitlab. * Update gitlab-mirror.yml * Update build-2.x.yml for deprecated github actions. --- .github/workflows/build-2.x.yml | 6 +++--- .github/workflows/gitlab-mirror.yml | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index 6c78bcf9c..041eca7a1 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -53,12 +53,12 @@ jobs: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: path: build_dir - name: Checkout islandora_ci - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: islandora/islandora_ci ref: github-actions @@ -84,7 +84,7 @@ jobs: echo "PHPUNIT_FILE=$GITHUB_WORKSPACE/build_dir/phpunit.xml" >> $GITHUB_ENV - name: Cache Composer dependencies - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: /tmp/composer-cache key: ${{ runner.os }}-${{ hashFiles('**/composer.lock') }} diff --git a/.github/workflows/gitlab-mirror.yml b/.github/workflows/gitlab-mirror.yml index 9e3629fd0..726d8e9c9 100644 --- a/.github/workflows/gitlab-mirror.yml +++ b/.github/workflows/gitlab-mirror.yml @@ -3,12 +3,13 @@ name: Mirror and run GitLab CI on: push: branches: [2.x] + tags: '*' jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 - name: Mirror + trigger CI uses: SvanBoxel/gitlab-mirror-and-ci-action@master with: From d1357d347dcf6c203dd9fb56ae504bcd78e48b33 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 7 Sep 2023 09:51:08 -0300 Subject: [PATCH 192/252] Revert gitlab mirror to checkout v1. --- .github/workflows/gitlab-mirror.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gitlab-mirror.yml b/.github/workflows/gitlab-mirror.yml index 726d8e9c9..f2af6e783 100644 --- a/.github/workflows/gitlab-mirror.yml +++ b/.github/workflows/gitlab-mirror.yml @@ -9,7 +9,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v1 - name: Mirror + trigger CI uses: SvanBoxel/gitlab-mirror-and-ci-action@master with: From 5d83504778296f2387b29d5e919960e1d45424c8 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Fri, 8 Sep 2023 14:17:14 -0300 Subject: [PATCH 193/252] Revert "Revert gitlab mirror to checkout v1." --- .github/workflows/gitlab-mirror.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gitlab-mirror.yml b/.github/workflows/gitlab-mirror.yml index f2af6e783..726d8e9c9 100644 --- a/.github/workflows/gitlab-mirror.yml +++ b/.github/workflows/gitlab-mirror.yml @@ -9,7 +9,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 - name: Mirror + trigger CI uses: SvanBoxel/gitlab-mirror-and-ci-action@master with: From e3399d3968d06fa0cf58e12fe8d6ebf1b5e75d7b Mon Sep 17 00:00:00 2001 From: dannylamb Date: Wed, 20 Sep 2023 10:57:29 -0300 Subject: [PATCH 194/252] =?UTF-8?q?Stripping=20out=20json=20metadata=20in?= =?UTF-8?q?=20the=20queue=20messages=20except=20for=20the=20ones=E2=80=A6?= =?UTF-8?q?=20(#973)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Stripping out json metadata in the queue messages except for the ones java is expecting * coding standards --- src/EventGenerator/EventGenerator.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/EventGenerator/EventGenerator.php b/src/EventGenerator/EventGenerator.php index b975f6083..4c29e44ba 100644 --- a/src/EventGenerator/EventGenerator.php +++ b/src/EventGenerator/EventGenerator.php @@ -147,8 +147,19 @@ public function generateEvent(EntityInterface $entity, UserInterface $user, arra } } - unset($data["event"]); - unset($data["queue"]); + $allowed_keys = [ + "file_upload_uri", + "fedora_uri", + "source_uri", + "destination_uri", + "args", + "mimetype", + "source_field", + ]; + $keys_to_unset = array_diff(array_keys($data), $allowed_keys); + foreach ($keys_to_unset as $key) { + unset($data[$key]); + } if (!empty($data)) { $event["attachment"] = [ From 91253bef14a0dfb1ebe722bd37ec60991960fca3 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 20 Sep 2023 12:37:39 -0300 Subject: [PATCH 195/252] Declare httpClient variable. --- .../islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 7 +++++++ workbench.log | 1 + 2 files changed, 8 insertions(+) create mode 100644 workbench.log diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 5a2fb63b3..804153abf 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -87,6 +87,13 @@ class IIIFManifest extends StylePluginBase { */ protected $fileSystem; + /** + * The Guzzle HTTP Client. + * + * @var \GuzzleHttp\Client + */ + protected $httpClient; + /** * The messenger. * diff --git a/workbench.log b/workbench.log new file mode 100644 index 000000000..5b26cadf5 --- /dev/null +++ b/workbench.log @@ -0,0 +1 @@ +20-Sep-23 11:45:33 - ERROR - Error: Configuration file "config.yml" not found. From 84c6ca85d8fd181fd6ab55be128d9221a4e88a9d Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 20 Sep 2023 14:08:06 -0300 Subject: [PATCH 196/252] Remove extra file. --- workbench.log | 1 - 1 file changed, 1 deletion(-) delete mode 100644 workbench.log diff --git a/workbench.log b/workbench.log deleted file mode 100644 index 5b26cadf5..000000000 --- a/workbench.log +++ /dev/null @@ -1 +0,0 @@ -20-Sep-23 11:45:33 - ERROR - Error: Configuration file "config.yml" not found. From fdfdd874721146bd4c171a3f1ca39284409e49be Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Tue, 8 Aug 2023 10:02:33 -0300 Subject: [PATCH 197/252] Add media save redirect. --- islandora.module | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/islandora.module b/islandora.module index 691767140..8d4bc9059 100644 --- a/islandora.module +++ b/islandora.module @@ -332,6 +332,7 @@ function islandora_form_alter(&$form, FormStateInterface $form_state, $form_id) if ($node) { $form['name']['widget'][0]['value']['#default_value'] = $node->getTitle(); } + $form['actions']['submit']['#submit'][] = 'islandora_media_custom_form_submit'; } } @@ -387,6 +388,20 @@ function islandora_form_alter(&$form, FormStateInterface $form_state, $form_id) return $form; } +/** + * Redirect submit handler for media save. + */ +function islandora_media_custom_form_submit(&$form, FormStateInterface $form_state) { + $params = \Drupal::request()->query->all(); + + if (!empty($params)) { + $target_id = $params['edit']['field_media_of']['widget'][0]['target_id']; + $url = Url::fromRoute('entity.node.canonical', ['node' => $target_id]); + $form_state->setRedirectUrl($url); + } + +} + /** * Implements a submit handler for the delete form. */ From c2cd14cfd56c4daf98f6ba748333ccaba2fa6c0d Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Fri, 11 Aug 2023 14:57:14 -0300 Subject: [PATCH 198/252] Add config option to redirect after media add. --- config/schema/islandora.schema.yml | 3 +++ islandora.install | 14 ++++++++++++++ islandora.module | 16 +++++++++------- src/Form/IslandoraSettingsForm.php | 9 +++++++++ 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/config/schema/islandora.schema.yml b/config/schema/islandora.schema.yml index 86b65fd0c..89c1b58a5 100644 --- a/config/schema/islandora.schema.yml +++ b/config/schema/islandora.schema.yml @@ -17,6 +17,9 @@ islandora.settings: delete_media_and_files: type: boolean label: 'Node Delete with Media and Files' + redirect_after_media_save: + type: boolean + label: 'Redirect to node after media save.' upload_form_location: type: string label: 'Upload Form Location' diff --git a/islandora.install b/islandora.install index ad2eb8e1c..01e5a467b 100644 --- a/islandora.install +++ b/islandora.install @@ -212,3 +212,17 @@ function islandora_update_8007() { // have the here, just in case? throw new UpdateException('Failed; hit the end of the update hook implementation, which is not expected.'); } + +/** + * Set config to no redirect after media save. + */ +function islandora_update_8008() { + $config = \Drupal::configFactory()->getEditable('islandora.settings'); + if ($config) { + $config->set('redirect_after_media_save', FALSE); + $config->save(TRUE); + return t('A new configuration option, "Redirect after media save" is now available. + It has been turned off to preserve existing behaviour. To enable this setting visit + Configuration > Islandora > Core Settings.'); + } +} diff --git a/islandora.module b/islandora.module index 8d4bc9059..8d443e1c0 100644 --- a/islandora.module +++ b/islandora.module @@ -392,14 +392,16 @@ function islandora_form_alter(&$form, FormStateInterface $form_state, $form_id) * Redirect submit handler for media save. */ function islandora_media_custom_form_submit(&$form, FormStateInterface $form_state) { - $params = \Drupal::request()->query->all(); - - if (!empty($params)) { - $target_id = $params['edit']['field_media_of']['widget'][0]['target_id']; - $url = Url::fromRoute('entity.node.canonical', ['node' => $target_id]); - $form_state->setRedirectUrl($url); + // Check configuration to see whether a redirect is desired. + $redirect = \Drupal::config('islandora.settings')->get('redirect_after_media_save'); + if ($redirect) { + $params = \Drupal::request()->query->all(); + if (!empty($params)) { + $target_id = $params['edit']['field_media_of']['widget'][0]['target_id']; + $url = Url::fromRoute('view.media_of.page_1', ['node' => $target_id]); + $form_state->setRedirectUrl($url); + } } - } /** diff --git a/src/Form/IslandoraSettingsForm.php b/src/Form/IslandoraSettingsForm.php index 90e0b4204..77d8aa278 100644 --- a/src/Form/IslandoraSettingsForm.php +++ b/src/Form/IslandoraSettingsForm.php @@ -43,6 +43,7 @@ class IslandoraSettingsForm extends ConfigFormBase { ]; const GEMINI_PSEUDO_FIELD = 'field_gemini_uri'; const NODE_DELETE_MEDIA_AND_FILES = 'delete_media_and_files'; + const REDIRECT_AFTER_MEDIA_SAVE = 'redirect_after_media_save'; /** * To list the available bundle types. @@ -210,6 +211,13 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#default_value' => (bool) $config->get(self::NODE_DELETE_MEDIA_AND_FILES), ]; + $form[self::REDIRECT_AFTER_MEDIA_SAVE] = [ + '#type' => 'checkbox', + '#title' => $this->t('Redirect after media save.'), + '#description' => $this->t('Redirect to node page after creation of media.'), + '#default_value' => (bool) $config->get(self::REDIRECT_AFTER_MEDIA_SAVE), + ]; + $form[self::FEDORA_URL] = [ '#type' => 'textfield', '#title' => $this->t('Fedora URL'), @@ -361,6 +369,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { ->set(self::UPLOAD_FORM_ALLOWED_MIMETYPES, $form_state->getValue(self::UPLOAD_FORM_ALLOWED_MIMETYPES)) ->set(self::GEMINI_PSEUDO, $new_pseudo_types) ->set(self::NODE_DELETE_MEDIA_AND_FILES, $form_state->getValue(self::NODE_DELETE_MEDIA_AND_FILES)) + ->set(self::REDIRECT_AFTER_MEDIA_SAVE, $form_state->getValue(self::REDIRECT_AFTER_MEDIA_SAVE)) ->save(); parent::submitForm($form, $form_state); From d6e07491d25f35b63abe821f2e698b2cd0bb3bfc Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Fri, 11 Aug 2023 15:00:42 -0300 Subject: [PATCH 199/252] UI text improvement. --- src/Form/IslandoraSettingsForm.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Form/IslandoraSettingsForm.php b/src/Form/IslandoraSettingsForm.php index 77d8aa278..6a2662f94 100644 --- a/src/Form/IslandoraSettingsForm.php +++ b/src/Form/IslandoraSettingsForm.php @@ -214,7 +214,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { $form[self::REDIRECT_AFTER_MEDIA_SAVE] = [ '#type' => 'checkbox', '#title' => $this->t('Redirect after media save.'), - '#description' => $this->t('Redirect to node page after creation of media.'), + '#description' => $this->t('Redirect to node-specific media list after creation of media.'), '#default_value' => (bool) $config->get(self::REDIRECT_AFTER_MEDIA_SAVE), ]; From 76eb4717a25fd0f17823864204fc7eaa4c4775ac Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 27 Sep 2023 12:39:54 -0300 Subject: [PATCH 200/252] Specify fetch-depth during mirroring to gitlab. --- .github/workflows/gitlab-mirror.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/gitlab-mirror.yml b/.github/workflows/gitlab-mirror.yml index 726d8e9c9..f59207e8a 100644 --- a/.github/workflows/gitlab-mirror.yml +++ b/.github/workflows/gitlab-mirror.yml @@ -10,6 +10,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + with: + fetch-depth: 0 - name: Mirror + trigger CI uses: SvanBoxel/gitlab-mirror-and-ci-action@master with: From 572ffcf2e1c823a769173088af8f83773a4615c4 Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 18 Oct 2023 14:14:42 -0300 Subject: [PATCH 201/252] Fix up typo. (#984) --- src/Controller/ManageMembersController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controller/ManageMembersController.php b/src/Controller/ManageMembersController.php index 9827ff350..c7b2df6a4 100644 --- a/src/Controller/ManageMembersController.php +++ b/src/Controller/ManageMembersController.php @@ -29,7 +29,7 @@ class ManageMembersController extends EntityController { * * @var \Drupal\Core\Entity\EntityFieldManagerInterface */ - protected $entityFieldManger; + protected $entityFieldManager; /** * The renderer. From f077af677bc6cf6282b2604f80c83d7fb74d3bcc Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Mon, 23 Oct 2023 13:50:10 -0300 Subject: [PATCH 202/252] Add COI integration to islandora settings form. --- src/Form/IslandoraSettingsForm.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Form/IslandoraSettingsForm.php b/src/Form/IslandoraSettingsForm.php index 6a2662f94..33b1a87cf 100644 --- a/src/Form/IslandoraSettingsForm.php +++ b/src/Form/IslandoraSettingsForm.php @@ -129,6 +129,9 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#type' => 'textfield', '#title' => $this->t('URL'), '#default_value' => $config->get(self::BROKER_URL), + '#config' => [ + 'key' => 'islandora.settings:' . self::BROKER_URL, + ], ]; $broker_user = $config->get(self::BROKER_USER); $form['broker_info']['provide_user_creds'] = [ @@ -149,6 +152,9 @@ public function buildForm(array $form, FormStateInterface $form_state) { $state_selector => ['checked' => TRUE], ], ], + '#config' => [ + 'key' => 'islandora.settings:' . self::BROKER_USER, + ], ]; $form['broker_info'][self::BROKER_PASSWORD] = [ '#type' => 'password', @@ -159,6 +165,9 @@ public function buildForm(array $form, FormStateInterface $form_state) { $state_selector => ['checked' => TRUE], ], ], + '#config' => [ + 'key' => 'islandora.settings:' . self::BROKER_PASSWORD, + ], ]; $form[self::JWT_EXPIRY] = [ '#type' => 'textfield', @@ -221,7 +230,11 @@ public function buildForm(array $form, FormStateInterface $form_state) { $form[self::FEDORA_URL] = [ '#type' => 'textfield', '#title' => $this->t('Fedora URL'), - '#attributes' => ['readonly' => 'readonly'], + '#description' => $this->t('Read-only. This value is set in settings.php as the URL for the Fedora flysystem.'), + '#attributes' => [ + 'readonly' => 'readonly', + 'disabled' => 'disabled', + ], '#default_value' => $fedora_url, ]; From 6cfaca36e7e27b1be71939db831a11b961844eb9 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Mon, 23 Oct 2023 16:28:39 -0300 Subject: [PATCH 203/252] Update src/Form/IslandoraSettingsForm.php Co-authored-by: Adam --- src/Form/IslandoraSettingsForm.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Form/IslandoraSettingsForm.php b/src/Form/IslandoraSettingsForm.php index 33b1a87cf..ad4c83b3e 100644 --- a/src/Form/IslandoraSettingsForm.php +++ b/src/Form/IslandoraSettingsForm.php @@ -167,6 +167,7 @@ public function buildForm(array $form, FormStateInterface $form_state) { ], '#config' => [ 'key' => 'islandora.settings:' . self::BROKER_PASSWORD, + 'secret' => TRUE, ], ]; $form[self::JWT_EXPIRY] = [ From c05236ac8c49b9fcbc77893b9bb837703be99de2 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Tue, 24 Oct 2023 09:27:50 -0300 Subject: [PATCH 204/252] Add COI integration to IIIF module. --- modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php b/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php index f09a01430..a99539a3c 100644 --- a/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php +++ b/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php @@ -72,6 +72,9 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#title' => $this->t('IIIF Image server location'), '#description' => $this->t('Please enter the image server location without trailing slash. e.g. http://www.example.org/iiif/2.'), '#default_value' => $config->get('iiif_server'), + '#config' => [ + 'key' => 'islandora_iiif.settings:iiif_server', + ], ]; $form['use_relative_paths'] = [ From 16617a9dd7d78b4e6fd3592e87a3ce59cb400dcc Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 26 Oct 2023 13:02:18 -0300 Subject: [PATCH 205/252] Composer suggest COI. --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 7706ec74b..1c6496679 100644 --- a/composer.json +++ b/composer.json @@ -40,6 +40,7 @@ }, "suggest": { "drupal/transliterate_filenames": "Sanitizes filenames when they are uploaded so they don't break your repository." + "drupal/coi": "Some configuration fields work with Config Override Inspector." }, "license": "GPL-2.0-or-later", "authors": [ From 2c91dc6f589b4d36aeb8fb3af086e2672d53346c Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 26 Oct 2023 13:08:01 -0300 Subject: [PATCH 206/252] syntax. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 1c6496679..34107d37b 100644 --- a/composer.json +++ b/composer.json @@ -39,7 +39,7 @@ "sebastian/phpcpd": "*" }, "suggest": { - "drupal/transliterate_filenames": "Sanitizes filenames when they are uploaded so they don't break your repository." + "drupal/transliterate_filenames": "Sanitizes filenames when they are uploaded so they don't break your repository.", "drupal/coi": "Some configuration fields work with Config Override Inspector." }, "license": "GPL-2.0-or-later", From d5556f445d3834c074428e774273fd37d7f2effb Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 1 Nov 2023 14:40:25 -0300 Subject: [PATCH 207/252] Add PHP 8.2 and Drupal 10.2 to testing matrix (#987) * Add PHP 8.2 and Drupal 10.2 to testing matrix * Use `name` key when creating test content type. * Remove `gemini_url` from schema. * Remove gemini_url from islandora.settings.yml * Update OcrTextFormatter.php * Remove Drupal 10.2 from matrix, known fail. --- .github/workflows/build-2.x.yml | 4 ++-- config/install/islandora.settings.yml | 1 - config/schema/islandora.schema.yml | 3 --- .../src/Plugin/Field/FieldFormatter/OcrTextFormatter.php | 5 +++-- tests/src/Kernel/EventGeneratorTest.php | 2 +- 5 files changed, 6 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index 041eca7a1..396b9a0b9 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -23,10 +23,10 @@ jobs: strategy: fail-fast: false matrix: - php-versions: ["8.1"] + php-versions: ["8.1", "8.2"] # test-suite functional-javascript will appear to pass but will skip tests; missing chromedriver. test-suite: ["kernel", "functional", "functional-javascript"] - drupal-version: ["9.5.x", "10.0.x", "10.1.x"] + drupal-version: ["10.0.x", "10.1.x"] # Fails on 10.2 until https://github.com/Islandora/islandora/issues/989 is resolved. mysql: ["8.0"] allowed_failure: [false] diff --git a/config/install/islandora.settings.yml b/config/install/islandora.settings.yml index 179d42132..1497c291e 100644 --- a/config/install/islandora.settings.yml +++ b/config/install/islandora.settings.yml @@ -1,5 +1,4 @@ broker_url: 'tcp://localhost:61613' jwt_expiry: '+2 hour' -gemini_url: '' delete_media_and_files: TRUE gemini_pseudo_bundles: [] diff --git a/config/schema/islandora.schema.yml b/config/schema/islandora.schema.yml index 89c1b58a5..49de998b3 100644 --- a/config/schema/islandora.schema.yml +++ b/config/schema/islandora.schema.yml @@ -26,9 +26,6 @@ islandora.settings: upload_form_allowed_mimetypes: type: string label: 'Upload Form Allowed Extensions' - gemini_url: - type: uri - label: 'Url to Gemini microservice' gemini_pseudo_bundles: type: sequence label: 'List of node, media and taxonomy terms that should include the linked Fedora URI' diff --git a/modules/islandora_text_extraction/src/Plugin/Field/FieldFormatter/OcrTextFormatter.php b/modules/islandora_text_extraction/src/Plugin/Field/FieldFormatter/OcrTextFormatter.php index 2e0669437..055e76d97 100644 --- a/modules/islandora_text_extraction/src/Plugin/Field/FieldFormatter/OcrTextFormatter.php +++ b/modules/islandora_text_extraction/src/Plugin/Field/FieldFormatter/OcrTextFormatter.php @@ -132,8 +132,9 @@ protected function viewValue(FieldItemInterface $item) { $fileItem = $item->getValue(); $file = $this->entityTypeManager->getStorage('file')->load($fileItem['target_id']); $contents = file_get_contents($file->getFileUri()); - if (mb_detect_encoding($contents) != 'UTF-8') { - $contents = utf8_encode($contents); + $detected_encoding = mb_detect_encoding($contents); + if ($detected_encoding != 'UTF-8') { + $contents = mb_convert_encoding($contents, 'UTF-8', $detected_encoding); } $contents = nl2br($contents); return $contents; diff --git a/tests/src/Kernel/EventGeneratorTest.php b/tests/src/Kernel/EventGeneratorTest.php index 28a4ec03b..34a5ae925 100644 --- a/tests/src/Kernel/EventGeneratorTest.php +++ b/tests/src/Kernel/EventGeneratorTest.php @@ -49,7 +49,7 @@ public function setUp(): void { $test_type = NodeType::create([ 'type' => 'test_type', - 'label' => 'Test Type', + 'name' => 'Test Type', ]); $test_type->save(); From 095e0ecf676816ee93ae27107946fb0f15bc6b05 Mon Sep 17 00:00:00 2001 From: Adam <607975+adam-vessey@users.noreply.github.com> Date: Thu, 2 Nov 2023 16:12:34 -0300 Subject: [PATCH 208/252] Update to use the new hook. (#992) `hook_field_widget_WIDGET_TYPE_form_alter()` was deprecated in Drupal 9.2.0 and removed in Drupal 10; however, it was what this functionality was using. It has been replaced with `hook_field_widget_single_element_WIDGET_TYPE_form_alter()`. See: https://www.drupal.org/node/3180429 --- islandora.module | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/islandora.module b/islandora.module index 8d443e1c0..d3dfa01d9 100644 --- a/islandora.module +++ b/islandora.module @@ -545,14 +545,14 @@ function islandora_object_delete_form_submit($form, FormStateInterface $form_sta } /** - * Implements hook_field_widget_WIDGET_TYPE_form_alter(). + * Implements hook_field_widget_single_element_WIDGET_TYPE_form_alter(). */ -function islandora_field_widget_image_image_form_alter(&$element, $form_state, $context) { +function islandora_field_widget_single_element_image_image_form_alter(&$element, $form_state, $context) { $element['#process'][] = 'islandora_add_default_image_alt_text'; } /** - * Callback for hook_field_widget_WIDGET_TYPE_form_alter(). + * Callback for hook_field_widget_single_element_WIDGET_TYPE_form_alter(). */ function islandora_add_default_image_alt_text($element, $form_state, $form) { if ($element['alt']['#access']) { From f29fef2bac4c458c01274ac8989b9438722fa826 Mon Sep 17 00:00:00 2001 From: Joe Corall Date: Mon, 6 Nov 2023 07:56:43 -0500 Subject: [PATCH 209/252] Do not render the pdf_url metatag if there is no value (#985) * Do not render the pdf_url metatag if there is no value * Always return a string --- islandora.tokens.inc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/islandora.tokens.inc b/islandora.tokens.inc index ab7bb0736..f528dee3d 100644 --- a/islandora.tokens.inc +++ b/islandora.tokens.inc @@ -134,7 +134,7 @@ function islandora_tokens($type, $tokens, array $data, array $options, Bubbleabl break; case 'pdf_url': - $replacements[$original] = ' ' . islandora_url_to_service_file_media_by_mimetype($data['node'], 'application/pdf'); + $replacements[$original] = islandora_url_to_service_file_media_by_mimetype($data['node'], 'application/pdf'); break; } } @@ -188,4 +188,5 @@ function islandora_url_to_service_file_media_by_mimetype($node, $mime_type) { } } } + return ''; } From 4b2b9b221b3545a0a98c75e71a8439ec34b9dd60 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 8 Nov 2023 14:07:08 -0400 Subject: [PATCH 210/252] Fix tests (#991) --- .github/workflows/build-2.x.yml | 2 +- .../JsonldTypeAlterReactionTest.php | 39 ++++++++++++++++--- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index 396b9a0b9..8e4e19bed 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -26,7 +26,7 @@ jobs: php-versions: ["8.1", "8.2"] # test-suite functional-javascript will appear to pass but will skip tests; missing chromedriver. test-suite: ["kernel", "functional", "functional-javascript"] - drupal-version: ["10.0.x", "10.1.x"] # Fails on 10.2 until https://github.com/Islandora/islandora/issues/989 is resolved. + drupal-version: ["10.0.x", "10.1.x", "10.2.x-dev"] mysql: ["8.0"] allowed_failure: [false] diff --git a/tests/src/Functional/JsonldTypeAlterReactionTest.php b/tests/src/Functional/JsonldTypeAlterReactionTest.php index 658244aee..75ae41dd3 100644 --- a/tests/src/Functional/JsonldTypeAlterReactionTest.php +++ b/tests/src/Functional/JsonldTypeAlterReactionTest.php @@ -26,12 +26,39 @@ public function testMappingReaction() { // Add the typed predicate we will select in the reaction config. // Taken from FieldUiTestTrait->fieldUIAddNewField. - $this->submitForm([ - 'new_storage_type' => 'string', - 'label' => 'Typed Predicate', - 'field_name' => 'type_predicate', - ], 'Save and continue'); - $this->submitForm([], $this->t('Save field settings')); + if (version_compare(\Drupal::VERSION, '10.2.x-dev', 'lt')) { + $this->submitForm([ + 'new_storage_type' => 'string', + 'label' => 'Typed Predicate', + 'field_name' => 'type_predicate', + ], 'Save and continue'); + $this->submitForm([], $this->t('Save field settings')); + } + else { + $this->getSession()->getPage()->selectFieldOption('new_storage_type', 'plain_text'); + // First need to submit the form with the elements displayed + // on initial page load. The form is using AJAX to send a second element + // after we selected the radio button above + // we can instead get the second element by submitting the form + // and having it throw an error since the required field is missing. + // @todo refactor this as a functional javascript test. + $this->submitForm([ + 'new_storage_type' => 'plain_text', + 'label' => 'Typed Predicate', + 'field_name' => 'type_predicate', + ], $this->t('Continue')); + + // Now we can proceed, selecting the plain text (i.e. string) + // for the second element now that the element is displayed after + // the initial form submission. + $this->getSession()->getPage()->selectFieldOption('group_field_options_wrapper', 'string'); + $this->submitForm([ + 'new_storage_type' => 'plain_text', + 'label' => 'Typed Predicate', + 'field_name' => 'type_predicate', + 'group_field_options_wrapper' => 'string', + ], $this->t('Continue')); + } $this->submitForm([], $this->t('Save settings')); $this->assertSession()->responseContains('field_type_predicate'); From 056695c79c4aff6b29b0fe7c938eecd5bfb39298 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 8 Nov 2023 16:52:58 -0400 Subject: [PATCH 211/252] 8.2 deprecations from tests (#995) --- tests/src/Functional/AddChildTest.php | 8 +++++++- tests/src/Functional/JsonldSelfReferenceReactionTest.php | 7 +++++++ tests/src/Kernel/FedoraAdapterTest.php | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/tests/src/Functional/AddChildTest.php b/tests/src/Functional/AddChildTest.php index f27f9db98..ed5282c73 100644 --- a/tests/src/Functional/AddChildTest.php +++ b/tests/src/Functional/AddChildTest.php @@ -9,13 +9,19 @@ */ class AddChildTest extends IslandoraFunctionalTestBase { + /** + * The taxonomy term representing "Collection" items. + * + * @var \Drupal\taxonomy\TermInterface + */ + protected $collectionTerm; + /** * {@inheritdoc} */ public function setUp(): void { parent::setUp(); - $this->parent = $this->collectionTerm = $this->container->get('entity_type.manager')->getStorage('taxonomy_term')->create([ 'name' => 'Collection', 'vid' => $this->testVocabulary->id(), diff --git a/tests/src/Functional/JsonldSelfReferenceReactionTest.php b/tests/src/Functional/JsonldSelfReferenceReactionTest.php index 92eca07a8..1b4e24ec7 100644 --- a/tests/src/Functional/JsonldSelfReferenceReactionTest.php +++ b/tests/src/Functional/JsonldSelfReferenceReactionTest.php @@ -12,6 +12,13 @@ */ class JsonldSelfReferenceReactionTest extends IslandoraFunctionalTestBase { + /** + * An RDF Mapping object. + * + * @var \Drupal\rdf\Entity\RdfMapping + */ + protected $rdfMapping; + /** * {@inheritdoc} */ diff --git a/tests/src/Kernel/FedoraAdapterTest.php b/tests/src/Kernel/FedoraAdapterTest.php index 9067d369e..6d8fee284 100644 --- a/tests/src/Kernel/FedoraAdapterTest.php +++ b/tests/src/Kernel/FedoraAdapterTest.php @@ -354,7 +354,7 @@ public function testRead() { $metadata = $adapter->read(''); $this->assertFileMetadata($metadata); - $this->assertTrue($metadata['contents'] == "DERP", "Expecting 'content' of 'DERP', received '${metadata['contents']}'"); + $this->assertTrue($metadata['contents'] == "DERP", "Expecting 'content' of 'DERP', received '{$metadata['contents']}'"); } /** From c6341649ca40822195e2e2257986a71cc958e26b Mon Sep 17 00:00:00 2001 From: Seth Shaw <108362375+seth-shaw-asu@users.noreply.github.com> Date: Wed, 29 Nov 2023 10:10:01 -0800 Subject: [PATCH 212/252] Use FileUrlGeneratorInterface (#996) * Use FileUrlGeneratorInterface * Use FileUrlGeneratorInterface --- src/Plugin/Field/FieldFormatter/IslandoraImageFormatter.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Plugin/Field/FieldFormatter/IslandoraImageFormatter.php b/src/Plugin/Field/FieldFormatter/IslandoraImageFormatter.php index 6667f4f4a..deb6c7690 100644 --- a/src/Plugin/Field/FieldFormatter/IslandoraImageFormatter.php +++ b/src/Plugin/Field/FieldFormatter/IslandoraImageFormatter.php @@ -5,7 +5,7 @@ use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldItemListInterface; -use Drupal\Core\File\FileUrlGenerator; +use Drupal\Core\File\FileUrlGeneratorInterface; use Drupal\Core\Session\AccountInterface; use Drupal\image\Plugin\Field\FieldFormatter\ImageFormatter; use Drupal\islandora\IslandoraUtils; @@ -57,7 +57,7 @@ class IslandoraImageFormatter extends ImageFormatter { * The image style storage. * @param \Drupal\islandora\IslandoraUtils $utils * Islandora utils. - * @param \Drupal\Core\File\FileUrlGenerator $file_url_generator + * @param \Drupal\Core\File\FileUrlGeneratorInterface $file_url_generator * The File URL Generator. */ public function __construct( @@ -71,7 +71,7 @@ public function __construct( AccountInterface $current_user, EntityStorageInterface $image_style_storage, IslandoraUtils $utils, - FileUrlGenerator $file_url_generator + FileUrlGeneratorInterface $file_url_generator ) { parent::__construct( $plugin_id, From b65881625a6205c8e70667d8aeef16545a49a320 Mon Sep 17 00:00:00 2001 From: ajstanley Date: Sat, 2 Dec 2023 15:15:14 -0400 Subject: [PATCH 213/252] change to Boooean logic --- modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 804153abf..779d3d06b 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -343,7 +343,7 @@ protected function getCanvasDimensions(string $iiif_url, FieldItemInterface $ima // If this is a TIFF AND we don't know the width/height // see if we can get the image size via PHP's core function. - if ($mime_type === 'image/tiff' && !$width || !$height) { + if ($mime_type === 'image/tiff' && !($width || !$height)) { $uri = $image->entity->getFileUri(); $path = $this->fileSystem->realpath($uri); $image_size = getimagesize($path); From c93c1ff940b26ddf8bfee935d4788df44afad108 Mon Sep 17 00:00:00 2001 From: ajstanley Date: Sat, 2 Dec 2023 15:54:15 -0400 Subject: [PATCH 214/252] change to Boolean logic --- modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 779d3d06b..4360e2c2e 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -343,7 +343,7 @@ protected function getCanvasDimensions(string $iiif_url, FieldItemInterface $ima // If this is a TIFF AND we don't know the width/height // see if we can get the image size via PHP's core function. - if ($mime_type === 'image/tiff' && !($width || !$height)) { + if ($mime_type === 'image/tiff' && (!$width || !$height)) { $uri = $image->entity->getFileUri(); $path = $this->fileSystem->realpath($uri); $image_size = getimagesize($path); From 4404dff2466b60a886b765c384de6677540d73a9 Mon Sep 17 00:00:00 2001 From: ajstanley Date: Sat, 2 Dec 2023 16:00:27 -0400 Subject: [PATCH 215/252] reverting accidental commit --- modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 4360e2c2e..804153abf 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -343,7 +343,7 @@ protected function getCanvasDimensions(string $iiif_url, FieldItemInterface $ima // If this is a TIFF AND we don't know the width/height // see if we can get the image size via PHP's core function. - if ($mime_type === 'image/tiff' && (!$width || !$height)) { + if ($mime_type === 'image/tiff' && !$width || !$height) { $uri = $image->entity->getFileUri(); $path = $this->fileSystem->realpath($uri); $image_size = getimagesize($path); From 28174c3ce4f35e6281fed1c8a2b0b08a9b419198 Mon Sep 17 00:00:00 2001 From: Alan Stanley Date: Mon, 4 Dec 2023 09:45:39 -0400 Subject: [PATCH 216/252] Change to Boolean logic (#999) --- modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 804153abf..4360e2c2e 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -343,7 +343,7 @@ protected function getCanvasDimensions(string $iiif_url, FieldItemInterface $ima // If this is a TIFF AND we don't know the width/height // see if we can get the image size via PHP's core function. - if ($mime_type === 'image/tiff' && !$width || !$height) { + if ($mime_type === 'image/tiff' && (!$width || !$height)) { $uri = $image->entity->getFileUri(); $path = $this->fileSystem->realpath($uri); $image_size = getimagesize($path); From d0e0c299212eb3810979c151e4aef9a219a5eb8d Mon Sep 17 00:00:00 2001 From: Alan Stanley Date: Wed, 20 Dec 2023 14:13:10 -0400 Subject: [PATCH 217/252] Issue 1000 (#1001) * Change to Boolean logic * added forward slash to path * Made Viewer display configurable --------- Co-authored-by: Rosie Le Faive --- .../config/schema/islandora_iiif.schema.yml | 7 ++++-- .../src/Form/IslandoraIIIFConfigForm.php | 14 +++++++++++ .../src/Plugin/views/style/IIIFManifest.php | 24 ++++++++++++++++--- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/modules/islandora_iiif/config/schema/islandora_iiif.schema.yml b/modules/islandora_iiif/config/schema/islandora_iiif.schema.yml index f9e870efa..1f91450fa 100644 --- a/modules/islandora_iiif/config/schema/islandora_iiif.schema.yml +++ b/modules/islandora_iiif/config/schema/islandora_iiif.schema.yml @@ -6,8 +6,11 @@ islandora_iiif.settings: type: string label: 'IIIF Server Url' use_relative_paths: - type: boolean - label: 'Use relative paths in manifest.' + type: boolean + label: 'Use relative paths in manifest.' + show_title: + type: string + label: 'Show title in view' views.style.iiif_manifest: type: views_style diff --git a/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php b/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php index a99539a3c..41bd84a4e 100644 --- a/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php +++ b/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php @@ -66,6 +66,11 @@ public function getFormId() { * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { + $options = [ + 'none' => $this->t('None'), + 'view' => $this->t("From view title"), + 'node' => $this->t("From node title"), + ]; $config = $this->config('islandora_iiif.settings'); $form['iiif_server'] = [ '#type' => 'url', @@ -84,6 +89,14 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#default_value' => $config->get('use_relative_paths'), ]; + $form['show_title'] = [ + '#type' => 'select', + '#options' => $options, + '#title' => $this->t("Show title in viewer."), + '#description' => $this->t("Show title on your viewer, if viewer allows"), + '#default_value' => $config->get('show_title'), + ]; + return parent::buildForm($form, $form_state); } @@ -111,6 +124,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $this->config('islandora_iiif.settings') ->set('iiif_server', $form_state->getValue('iiif_server')) ->set('use_relative_paths', $form_state->getValue('use_relative_paths')) + ->set('show_title', $form_state->getValue('show_title')) ->save(); } diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 4360e2c2e..2fc8a431a 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -167,15 +167,33 @@ public function render() { // @todo assumming the view is a path like /node/1/manifest.json $url_components = explode('/', trim($request_url, '/')); array_pop($url_components); - $content_path = implode('/', $url_components); - $iiif_base_id = $request_host . '/' . $content_path; + $content_path = '/' . implode('/', $url_components); + $iiif_base_id = "{$request_host}{$content_path}"; + $display = $this->iiifConfig->get('show_title'); + switch ($display) { + case 'none': + $label = ''; + break; + + case 'view': + $label = $this->view->getTitle(); + break; + + case 'node': + $label = $this->getEntityTitle($content_path); + + break; + + default: + $label = $this->t("IIIF Manifest"); + } // @see https://iiif.io/api/presentation/2.1/#manifest $json += [ '@type' => 'sc:Manifest', '@id' => $request_url, // If the View has a title, set the View title as the manifest label. - 'label' => $this->view->getTitle() ?: $this->getEntityTitle($content_path), + 'label' => $label, '@context' => 'http://iiif.io/api/presentation/2/context.json', // @see https://iiif.io/api/presentation/2.1/#sequence 'sequences' => [ From 3065c87874b7da0440fff494d0e51c938b855fd7 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Fri, 29 Dec 2023 12:47:29 -0500 Subject: [PATCH 218/252] Remove Feature-ness of Islandora Core Feature. (#968) * Remove Feature-ness of Islandora Core Feature. * Remove features bundle config. * Remove from composer.json. * Remove dependency on Features UI. * Rename install dir to optional. * Update text_extraction_defaults and remove 'fim' from workflows. --- .github/workflows/build-2.x.yml | 1 - composer.json | 1 - islandora.info.yml | 1 - .../install/features.bundle.islandora.yml | 100 ------------------ .../core.entity_view_mode.media.source.yml | 0 ...islandora_media_use.field_external_uri.yml | 0 ...rm.islandora_models.field_external_uri.yml | 0 .../field.storage.media.field_file_size.yml | 0 .../field.storage.media.field_height.yml | 0 ...d.storage.media.field_media_audio_file.yml | 0 ...eld.storage.media.field_media_document.yml | 0 .../field.storage.media.field_media_file.yml | 0 .../field.storage.media.field_media_image.yml | 0 .../field.storage.media.field_media_of.yml | 0 .../field.storage.media.field_media_use.yml | 0 ...d.storage.media.field_media_video_file.yml | 0 .../field.storage.media.field_mime_type.yml | 0 ...ield.storage.media.field_original_name.yml | 0 .../field.storage.media.field_width.yml | 0 .../field.storage.node.field_member_of.yml | 0 .../field.storage.node.field_model.yml | 0 .../field.storage.node.field_weight.yml | 0 ...orage.taxonomy_term.field_external_uri.yml | 0 .../filehash.settings.yml | 0 .../migrate_plus.migration.islandora_tags.yml | 0 ...migrate_plus.migration_group.islandora.yml | 0 .../rest.resource.entity.file.yml | 0 .../rest.resource.entity.media.yml | 0 .../rest.resource.entity.node.yml | 0 .../rest.resource.entity.taxonomy_term.yml | 0 ...delete_file_as_fedora_external_content.yml | 0 ...m.action.delete_media_from_triplestore.yml | 0 .../system.action.delete_node_from_fedora.yml | 0 ...em.action.delete_node_from_triplestore.yml | 0 ....action.delete_taxonomy_term_in_fedora.yml | 0 ...on.delete_taxonomy_term_in_triplestore.yml | 0 ....index_file_as_fedora_external_content.yml | 0 .../system.action.index_media_in_fedora.yml | 0 ...stem.action.index_media_in_triplestore.yml | 0 .../system.action.index_node_in_fedora.yml | 0 ...ystem.action.index_node_in_triplestore.yml | 0 ...m.action.index_taxonomy_term_in_fedora.yml | 0 ...index_taxonomy_term_in_the_triplestore.yml | 0 ...axonomy.vocabulary.islandora_media_use.yml | 0 .../taxonomy.vocabulary.islandora_models.yml | 0 .../views.view.all_taxonomy_terms.yml | 0 .../views.view.display_media.yml | 0 .../views.view.file_checksum.yml | 0 .../views.view.manage_members.yml | 0 .../views.view.media_of.yml | 0 .../views.view.non_fedora_files.yml | 0 .../views.view.reorder_children.yml | 0 .../islandora_core_feature.features.yml | 16 --- .../islandora_core_feature.info.yml | 1 - ...m_display.media.extracted_text.default.yml | 0 ...w_display.media.extracted_text.default.yml | 0 ...media.extracted_text.field_edited_text.yml | 0 ....media.extracted_text.field_media_file.yml | 0 ...ld.media.extracted_text.field_media_of.yml | 0 ...d.media.extracted_text.field_media_use.yml | 0 ...d.media.extracted_text.field_mime_type.yml | 0 .../field.storage.media.field_edited_text.yml | 0 ....content_settings.media.extracted_text.yml | 0 .../media.type.extracted_text.yml | 0 .../rdf.mapping.media.extracted_text.yml | 0 .../system.action.get_ocr_from_image.yml | 0 ...dora_text_extraction_defaults.features.yml | 2 - 67 files changed, 122 deletions(-) delete mode 100644 modules/islandora_core_feature/config/install/features.bundle.islandora.yml rename modules/islandora_core_feature/config/{install => optional}/core.entity_view_mode.media.source.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/field.field.taxonomy_term.islandora_media_use.field_external_uri.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/field.field.taxonomy_term.islandora_models.field_external_uri.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/field.storage.media.field_file_size.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/field.storage.media.field_height.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/field.storage.media.field_media_audio_file.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/field.storage.media.field_media_document.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/field.storage.media.field_media_file.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/field.storage.media.field_media_image.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/field.storage.media.field_media_of.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/field.storage.media.field_media_use.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/field.storage.media.field_media_video_file.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/field.storage.media.field_mime_type.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/field.storage.media.field_original_name.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/field.storage.media.field_width.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/field.storage.node.field_member_of.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/field.storage.node.field_model.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/field.storage.node.field_weight.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/field.storage.taxonomy_term.field_external_uri.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/filehash.settings.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/migrate_plus.migration.islandora_tags.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/migrate_plus.migration_group.islandora.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/rest.resource.entity.file.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/rest.resource.entity.media.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/rest.resource.entity.node.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/rest.resource.entity.taxonomy_term.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/system.action.delete_file_as_fedora_external_content.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/system.action.delete_media_from_triplestore.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/system.action.delete_node_from_fedora.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/system.action.delete_node_from_triplestore.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/system.action.delete_taxonomy_term_in_fedora.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/system.action.delete_taxonomy_term_in_triplestore.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/system.action.index_file_as_fedora_external_content.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/system.action.index_media_in_fedora.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/system.action.index_media_in_triplestore.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/system.action.index_node_in_fedora.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/system.action.index_node_in_triplestore.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/system.action.index_taxonomy_term_in_fedora.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/system.action.index_taxonomy_term_in_the_triplestore.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/taxonomy.vocabulary.islandora_media_use.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/taxonomy.vocabulary.islandora_models.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/views.view.all_taxonomy_terms.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/views.view.display_media.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/views.view.file_checksum.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/views.view.manage_members.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/views.view.media_of.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/views.view.non_fedora_files.yml (100%) rename modules/islandora_core_feature/config/{install => optional}/views.view.reorder_children.yml (100%) delete mode 100755 modules/islandora_core_feature/islandora_core_feature.features.yml rename modules/islandora_text_extraction_defaults/config/{install => optional}/core.entity_form_display.media.extracted_text.default.yml (100%) rename modules/islandora_text_extraction_defaults/config/{install => optional}/core.entity_view_display.media.extracted_text.default.yml (100%) rename modules/islandora_text_extraction_defaults/config/{install => optional}/field.field.media.extracted_text.field_edited_text.yml (100%) rename modules/islandora_text_extraction_defaults/config/{install => optional}/field.field.media.extracted_text.field_media_file.yml (100%) rename modules/islandora_text_extraction_defaults/config/{install => optional}/field.field.media.extracted_text.field_media_of.yml (100%) rename modules/islandora_text_extraction_defaults/config/{install => optional}/field.field.media.extracted_text.field_media_use.yml (100%) rename modules/islandora_text_extraction_defaults/config/{install => optional}/field.field.media.extracted_text.field_mime_type.yml (100%) rename modules/islandora_text_extraction_defaults/config/{install => optional}/field.storage.media.field_edited_text.yml (100%) rename modules/islandora_text_extraction_defaults/config/{install => optional}/language.content_settings.media.extracted_text.yml (100%) rename modules/islandora_text_extraction_defaults/config/{install => optional}/media.type.extracted_text.yml (100%) rename modules/islandora_text_extraction_defaults/config/{install => optional}/rdf.mapping.media.extracted_text.yml (100%) rename modules/islandora_text_extraction_defaults/config/{install => optional}/system.action.get_ocr_from_image.yml (100%) delete mode 100644 modules/islandora_text_extraction_defaults/islandora_text_extraction_defaults.features.yml diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index 8e4e19bed..2ab3a539e 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -109,7 +109,6 @@ jobs: run: | cd $DRUPAL_DIR/web drush --uri=127.0.0.1:8282 en -y islandora_audio islandora_breadcrumbs islandora_iiif islandora_image islandora_video islandora_text_extraction_defaults - drush --uri=127.0.0.1:8282 fim -y islandora_core_feature,islandora_text_extraction_defaults - name: Copy PHPunit file run: cp $PHPUNIT_FILE $DRUPAL_DIR/web/core/phpunit.xml diff --git a/composer.json b/composer.json index 34107d37b..cb95bbc6e 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,6 @@ "drupal/context": "^4 || ^5@RC", "drupal/ctools": "^3.8 || ^4", "drupal/eva" : "^3.0", - "drupal/features" : "^3.13", "drupal/file_replace": "^1.1", "drupal/filehash": "^2", "drupal/flysystem" : "^2.0@alpha", diff --git a/islandora.info.yml b/islandora.info.yml index 34e8118ac..6dd0597f2 100644 --- a/islandora.info.yml +++ b/islandora.info.yml @@ -22,7 +22,6 @@ dependencies: - drupal:text - drupal:views_ui - eva:eva - - features:features_ui - file_replace:file_replace - filehash:filehash - flysystem:flysystem diff --git a/modules/islandora_core_feature/config/install/features.bundle.islandora.yml b/modules/islandora_core_feature/config/install/features.bundle.islandora.yml deleted file mode 100644 index 9c3587314..000000000 --- a/modules/islandora_core_feature/config/install/features.bundle.islandora.yml +++ /dev/null @@ -1,100 +0,0 @@ -langcode: en -status: true -dependencies: - enforced: - module: - - islandora_core_feature -name: Islandora -machine_name: islandora -description: 'Features for islandora' -assignments: - alter: - core: true - uuid: true - user_permissions: true - enabled: true - weight: 0 - base: - types: - config: - comment_type: comment_type - node_type: node_type - content: - user: user - enabled: true - weight: -2 - core: - types: - config: - date_format: date_format - field_storage_config: field_storage_config - entity_form_mode: entity_form_mode - image_style: image_style - menu: menu - responsive_image_style: responsive_image_style - user_role: user_role - entity_view_mode: entity_view_mode - enabled: true - weight: 5 - dependency: - enabled: true - weight: 15 - exclude: - types: - config: - features_bundle: features_bundle - curated: true - module: - installed: true - profile: true - namespace: true - namespace_any: false - enabled: true - weight: -5 - existing: - enabled: true - weight: 12 - forward_dependency: - enabled: true - weight: 4 - namespace: - enabled: true - weight: 0 - optional: - types: - config: { } - enabled: true - weight: 0 - packages: - enabled: true - weight: -20 - profile: - curated: true - standard: - files: true - dependencies: true - types: - config: - block: block - language_content_settings: language_content_settings - configurable_language: configurable_language - migration: migration - shortcut_set: shortcut_set - tour: tour - enabled: true - weight: 10 - site: - types: - config: - action: action - contact_form: contact_form - block_content_type: block_content_type - rdf_mapping: rdf_mapping - search_page: search_page - taxonomy_vocabulary: taxonomy_vocabulary - editor: editor - filter_format: filter_format - enabled: true - weight: 7 -profile_name: '' -is_profile: false diff --git a/modules/islandora_core_feature/config/install/core.entity_view_mode.media.source.yml b/modules/islandora_core_feature/config/optional/core.entity_view_mode.media.source.yml similarity index 100% rename from modules/islandora_core_feature/config/install/core.entity_view_mode.media.source.yml rename to modules/islandora_core_feature/config/optional/core.entity_view_mode.media.source.yml diff --git a/modules/islandora_core_feature/config/install/field.field.taxonomy_term.islandora_media_use.field_external_uri.yml b/modules/islandora_core_feature/config/optional/field.field.taxonomy_term.islandora_media_use.field_external_uri.yml similarity index 100% rename from modules/islandora_core_feature/config/install/field.field.taxonomy_term.islandora_media_use.field_external_uri.yml rename to modules/islandora_core_feature/config/optional/field.field.taxonomy_term.islandora_media_use.field_external_uri.yml diff --git a/modules/islandora_core_feature/config/install/field.field.taxonomy_term.islandora_models.field_external_uri.yml b/modules/islandora_core_feature/config/optional/field.field.taxonomy_term.islandora_models.field_external_uri.yml similarity index 100% rename from modules/islandora_core_feature/config/install/field.field.taxonomy_term.islandora_models.field_external_uri.yml rename to modules/islandora_core_feature/config/optional/field.field.taxonomy_term.islandora_models.field_external_uri.yml diff --git a/modules/islandora_core_feature/config/install/field.storage.media.field_file_size.yml b/modules/islandora_core_feature/config/optional/field.storage.media.field_file_size.yml similarity index 100% rename from modules/islandora_core_feature/config/install/field.storage.media.field_file_size.yml rename to modules/islandora_core_feature/config/optional/field.storage.media.field_file_size.yml diff --git a/modules/islandora_core_feature/config/install/field.storage.media.field_height.yml b/modules/islandora_core_feature/config/optional/field.storage.media.field_height.yml similarity index 100% rename from modules/islandora_core_feature/config/install/field.storage.media.field_height.yml rename to modules/islandora_core_feature/config/optional/field.storage.media.field_height.yml diff --git a/modules/islandora_core_feature/config/install/field.storage.media.field_media_audio_file.yml b/modules/islandora_core_feature/config/optional/field.storage.media.field_media_audio_file.yml similarity index 100% rename from modules/islandora_core_feature/config/install/field.storage.media.field_media_audio_file.yml rename to modules/islandora_core_feature/config/optional/field.storage.media.field_media_audio_file.yml diff --git a/modules/islandora_core_feature/config/install/field.storage.media.field_media_document.yml b/modules/islandora_core_feature/config/optional/field.storage.media.field_media_document.yml similarity index 100% rename from modules/islandora_core_feature/config/install/field.storage.media.field_media_document.yml rename to modules/islandora_core_feature/config/optional/field.storage.media.field_media_document.yml diff --git a/modules/islandora_core_feature/config/install/field.storage.media.field_media_file.yml b/modules/islandora_core_feature/config/optional/field.storage.media.field_media_file.yml similarity index 100% rename from modules/islandora_core_feature/config/install/field.storage.media.field_media_file.yml rename to modules/islandora_core_feature/config/optional/field.storage.media.field_media_file.yml diff --git a/modules/islandora_core_feature/config/install/field.storage.media.field_media_image.yml b/modules/islandora_core_feature/config/optional/field.storage.media.field_media_image.yml similarity index 100% rename from modules/islandora_core_feature/config/install/field.storage.media.field_media_image.yml rename to modules/islandora_core_feature/config/optional/field.storage.media.field_media_image.yml diff --git a/modules/islandora_core_feature/config/install/field.storage.media.field_media_of.yml b/modules/islandora_core_feature/config/optional/field.storage.media.field_media_of.yml similarity index 100% rename from modules/islandora_core_feature/config/install/field.storage.media.field_media_of.yml rename to modules/islandora_core_feature/config/optional/field.storage.media.field_media_of.yml diff --git a/modules/islandora_core_feature/config/install/field.storage.media.field_media_use.yml b/modules/islandora_core_feature/config/optional/field.storage.media.field_media_use.yml similarity index 100% rename from modules/islandora_core_feature/config/install/field.storage.media.field_media_use.yml rename to modules/islandora_core_feature/config/optional/field.storage.media.field_media_use.yml diff --git a/modules/islandora_core_feature/config/install/field.storage.media.field_media_video_file.yml b/modules/islandora_core_feature/config/optional/field.storage.media.field_media_video_file.yml similarity index 100% rename from modules/islandora_core_feature/config/install/field.storage.media.field_media_video_file.yml rename to modules/islandora_core_feature/config/optional/field.storage.media.field_media_video_file.yml diff --git a/modules/islandora_core_feature/config/install/field.storage.media.field_mime_type.yml b/modules/islandora_core_feature/config/optional/field.storage.media.field_mime_type.yml similarity index 100% rename from modules/islandora_core_feature/config/install/field.storage.media.field_mime_type.yml rename to modules/islandora_core_feature/config/optional/field.storage.media.field_mime_type.yml diff --git a/modules/islandora_core_feature/config/install/field.storage.media.field_original_name.yml b/modules/islandora_core_feature/config/optional/field.storage.media.field_original_name.yml similarity index 100% rename from modules/islandora_core_feature/config/install/field.storage.media.field_original_name.yml rename to modules/islandora_core_feature/config/optional/field.storage.media.field_original_name.yml diff --git a/modules/islandora_core_feature/config/install/field.storage.media.field_width.yml b/modules/islandora_core_feature/config/optional/field.storage.media.field_width.yml similarity index 100% rename from modules/islandora_core_feature/config/install/field.storage.media.field_width.yml rename to modules/islandora_core_feature/config/optional/field.storage.media.field_width.yml diff --git a/modules/islandora_core_feature/config/install/field.storage.node.field_member_of.yml b/modules/islandora_core_feature/config/optional/field.storage.node.field_member_of.yml similarity index 100% rename from modules/islandora_core_feature/config/install/field.storage.node.field_member_of.yml rename to modules/islandora_core_feature/config/optional/field.storage.node.field_member_of.yml diff --git a/modules/islandora_core_feature/config/install/field.storage.node.field_model.yml b/modules/islandora_core_feature/config/optional/field.storage.node.field_model.yml similarity index 100% rename from modules/islandora_core_feature/config/install/field.storage.node.field_model.yml rename to modules/islandora_core_feature/config/optional/field.storage.node.field_model.yml diff --git a/modules/islandora_core_feature/config/install/field.storage.node.field_weight.yml b/modules/islandora_core_feature/config/optional/field.storage.node.field_weight.yml similarity index 100% rename from modules/islandora_core_feature/config/install/field.storage.node.field_weight.yml rename to modules/islandora_core_feature/config/optional/field.storage.node.field_weight.yml diff --git a/modules/islandora_core_feature/config/install/field.storage.taxonomy_term.field_external_uri.yml b/modules/islandora_core_feature/config/optional/field.storage.taxonomy_term.field_external_uri.yml similarity index 100% rename from modules/islandora_core_feature/config/install/field.storage.taxonomy_term.field_external_uri.yml rename to modules/islandora_core_feature/config/optional/field.storage.taxonomy_term.field_external_uri.yml diff --git a/modules/islandora_core_feature/config/install/filehash.settings.yml b/modules/islandora_core_feature/config/optional/filehash.settings.yml similarity index 100% rename from modules/islandora_core_feature/config/install/filehash.settings.yml rename to modules/islandora_core_feature/config/optional/filehash.settings.yml diff --git a/modules/islandora_core_feature/config/install/migrate_plus.migration.islandora_tags.yml b/modules/islandora_core_feature/config/optional/migrate_plus.migration.islandora_tags.yml similarity index 100% rename from modules/islandora_core_feature/config/install/migrate_plus.migration.islandora_tags.yml rename to modules/islandora_core_feature/config/optional/migrate_plus.migration.islandora_tags.yml diff --git a/modules/islandora_core_feature/config/install/migrate_plus.migration_group.islandora.yml b/modules/islandora_core_feature/config/optional/migrate_plus.migration_group.islandora.yml similarity index 100% rename from modules/islandora_core_feature/config/install/migrate_plus.migration_group.islandora.yml rename to modules/islandora_core_feature/config/optional/migrate_plus.migration_group.islandora.yml diff --git a/modules/islandora_core_feature/config/install/rest.resource.entity.file.yml b/modules/islandora_core_feature/config/optional/rest.resource.entity.file.yml similarity index 100% rename from modules/islandora_core_feature/config/install/rest.resource.entity.file.yml rename to modules/islandora_core_feature/config/optional/rest.resource.entity.file.yml diff --git a/modules/islandora_core_feature/config/install/rest.resource.entity.media.yml b/modules/islandora_core_feature/config/optional/rest.resource.entity.media.yml similarity index 100% rename from modules/islandora_core_feature/config/install/rest.resource.entity.media.yml rename to modules/islandora_core_feature/config/optional/rest.resource.entity.media.yml diff --git a/modules/islandora_core_feature/config/install/rest.resource.entity.node.yml b/modules/islandora_core_feature/config/optional/rest.resource.entity.node.yml similarity index 100% rename from modules/islandora_core_feature/config/install/rest.resource.entity.node.yml rename to modules/islandora_core_feature/config/optional/rest.resource.entity.node.yml diff --git a/modules/islandora_core_feature/config/install/rest.resource.entity.taxonomy_term.yml b/modules/islandora_core_feature/config/optional/rest.resource.entity.taxonomy_term.yml similarity index 100% rename from modules/islandora_core_feature/config/install/rest.resource.entity.taxonomy_term.yml rename to modules/islandora_core_feature/config/optional/rest.resource.entity.taxonomy_term.yml diff --git a/modules/islandora_core_feature/config/install/system.action.delete_file_as_fedora_external_content.yml b/modules/islandora_core_feature/config/optional/system.action.delete_file_as_fedora_external_content.yml similarity index 100% rename from modules/islandora_core_feature/config/install/system.action.delete_file_as_fedora_external_content.yml rename to modules/islandora_core_feature/config/optional/system.action.delete_file_as_fedora_external_content.yml diff --git a/modules/islandora_core_feature/config/install/system.action.delete_media_from_triplestore.yml b/modules/islandora_core_feature/config/optional/system.action.delete_media_from_triplestore.yml similarity index 100% rename from modules/islandora_core_feature/config/install/system.action.delete_media_from_triplestore.yml rename to modules/islandora_core_feature/config/optional/system.action.delete_media_from_triplestore.yml diff --git a/modules/islandora_core_feature/config/install/system.action.delete_node_from_fedora.yml b/modules/islandora_core_feature/config/optional/system.action.delete_node_from_fedora.yml similarity index 100% rename from modules/islandora_core_feature/config/install/system.action.delete_node_from_fedora.yml rename to modules/islandora_core_feature/config/optional/system.action.delete_node_from_fedora.yml diff --git a/modules/islandora_core_feature/config/install/system.action.delete_node_from_triplestore.yml b/modules/islandora_core_feature/config/optional/system.action.delete_node_from_triplestore.yml similarity index 100% rename from modules/islandora_core_feature/config/install/system.action.delete_node_from_triplestore.yml rename to modules/islandora_core_feature/config/optional/system.action.delete_node_from_triplestore.yml diff --git a/modules/islandora_core_feature/config/install/system.action.delete_taxonomy_term_in_fedora.yml b/modules/islandora_core_feature/config/optional/system.action.delete_taxonomy_term_in_fedora.yml similarity index 100% rename from modules/islandora_core_feature/config/install/system.action.delete_taxonomy_term_in_fedora.yml rename to modules/islandora_core_feature/config/optional/system.action.delete_taxonomy_term_in_fedora.yml diff --git a/modules/islandora_core_feature/config/install/system.action.delete_taxonomy_term_in_triplestore.yml b/modules/islandora_core_feature/config/optional/system.action.delete_taxonomy_term_in_triplestore.yml similarity index 100% rename from modules/islandora_core_feature/config/install/system.action.delete_taxonomy_term_in_triplestore.yml rename to modules/islandora_core_feature/config/optional/system.action.delete_taxonomy_term_in_triplestore.yml diff --git a/modules/islandora_core_feature/config/install/system.action.index_file_as_fedora_external_content.yml b/modules/islandora_core_feature/config/optional/system.action.index_file_as_fedora_external_content.yml similarity index 100% rename from modules/islandora_core_feature/config/install/system.action.index_file_as_fedora_external_content.yml rename to modules/islandora_core_feature/config/optional/system.action.index_file_as_fedora_external_content.yml diff --git a/modules/islandora_core_feature/config/install/system.action.index_media_in_fedora.yml b/modules/islandora_core_feature/config/optional/system.action.index_media_in_fedora.yml similarity index 100% rename from modules/islandora_core_feature/config/install/system.action.index_media_in_fedora.yml rename to modules/islandora_core_feature/config/optional/system.action.index_media_in_fedora.yml diff --git a/modules/islandora_core_feature/config/install/system.action.index_media_in_triplestore.yml b/modules/islandora_core_feature/config/optional/system.action.index_media_in_triplestore.yml similarity index 100% rename from modules/islandora_core_feature/config/install/system.action.index_media_in_triplestore.yml rename to modules/islandora_core_feature/config/optional/system.action.index_media_in_triplestore.yml diff --git a/modules/islandora_core_feature/config/install/system.action.index_node_in_fedora.yml b/modules/islandora_core_feature/config/optional/system.action.index_node_in_fedora.yml similarity index 100% rename from modules/islandora_core_feature/config/install/system.action.index_node_in_fedora.yml rename to modules/islandora_core_feature/config/optional/system.action.index_node_in_fedora.yml diff --git a/modules/islandora_core_feature/config/install/system.action.index_node_in_triplestore.yml b/modules/islandora_core_feature/config/optional/system.action.index_node_in_triplestore.yml similarity index 100% rename from modules/islandora_core_feature/config/install/system.action.index_node_in_triplestore.yml rename to modules/islandora_core_feature/config/optional/system.action.index_node_in_triplestore.yml diff --git a/modules/islandora_core_feature/config/install/system.action.index_taxonomy_term_in_fedora.yml b/modules/islandora_core_feature/config/optional/system.action.index_taxonomy_term_in_fedora.yml similarity index 100% rename from modules/islandora_core_feature/config/install/system.action.index_taxonomy_term_in_fedora.yml rename to modules/islandora_core_feature/config/optional/system.action.index_taxonomy_term_in_fedora.yml diff --git a/modules/islandora_core_feature/config/install/system.action.index_taxonomy_term_in_the_triplestore.yml b/modules/islandora_core_feature/config/optional/system.action.index_taxonomy_term_in_the_triplestore.yml similarity index 100% rename from modules/islandora_core_feature/config/install/system.action.index_taxonomy_term_in_the_triplestore.yml rename to modules/islandora_core_feature/config/optional/system.action.index_taxonomy_term_in_the_triplestore.yml diff --git a/modules/islandora_core_feature/config/install/taxonomy.vocabulary.islandora_media_use.yml b/modules/islandora_core_feature/config/optional/taxonomy.vocabulary.islandora_media_use.yml similarity index 100% rename from modules/islandora_core_feature/config/install/taxonomy.vocabulary.islandora_media_use.yml rename to modules/islandora_core_feature/config/optional/taxonomy.vocabulary.islandora_media_use.yml diff --git a/modules/islandora_core_feature/config/install/taxonomy.vocabulary.islandora_models.yml b/modules/islandora_core_feature/config/optional/taxonomy.vocabulary.islandora_models.yml similarity index 100% rename from modules/islandora_core_feature/config/install/taxonomy.vocabulary.islandora_models.yml rename to modules/islandora_core_feature/config/optional/taxonomy.vocabulary.islandora_models.yml diff --git a/modules/islandora_core_feature/config/install/views.view.all_taxonomy_terms.yml b/modules/islandora_core_feature/config/optional/views.view.all_taxonomy_terms.yml similarity index 100% rename from modules/islandora_core_feature/config/install/views.view.all_taxonomy_terms.yml rename to modules/islandora_core_feature/config/optional/views.view.all_taxonomy_terms.yml diff --git a/modules/islandora_core_feature/config/install/views.view.display_media.yml b/modules/islandora_core_feature/config/optional/views.view.display_media.yml similarity index 100% rename from modules/islandora_core_feature/config/install/views.view.display_media.yml rename to modules/islandora_core_feature/config/optional/views.view.display_media.yml diff --git a/modules/islandora_core_feature/config/install/views.view.file_checksum.yml b/modules/islandora_core_feature/config/optional/views.view.file_checksum.yml similarity index 100% rename from modules/islandora_core_feature/config/install/views.view.file_checksum.yml rename to modules/islandora_core_feature/config/optional/views.view.file_checksum.yml diff --git a/modules/islandora_core_feature/config/install/views.view.manage_members.yml b/modules/islandora_core_feature/config/optional/views.view.manage_members.yml similarity index 100% rename from modules/islandora_core_feature/config/install/views.view.manage_members.yml rename to modules/islandora_core_feature/config/optional/views.view.manage_members.yml diff --git a/modules/islandora_core_feature/config/install/views.view.media_of.yml b/modules/islandora_core_feature/config/optional/views.view.media_of.yml similarity index 100% rename from modules/islandora_core_feature/config/install/views.view.media_of.yml rename to modules/islandora_core_feature/config/optional/views.view.media_of.yml diff --git a/modules/islandora_core_feature/config/install/views.view.non_fedora_files.yml b/modules/islandora_core_feature/config/optional/views.view.non_fedora_files.yml similarity index 100% rename from modules/islandora_core_feature/config/install/views.view.non_fedora_files.yml rename to modules/islandora_core_feature/config/optional/views.view.non_fedora_files.yml diff --git a/modules/islandora_core_feature/config/install/views.view.reorder_children.yml b/modules/islandora_core_feature/config/optional/views.view.reorder_children.yml similarity index 100% rename from modules/islandora_core_feature/config/install/views.view.reorder_children.yml rename to modules/islandora_core_feature/config/optional/views.view.reorder_children.yml diff --git a/modules/islandora_core_feature/islandora_core_feature.features.yml b/modules/islandora_core_feature/islandora_core_feature.features.yml deleted file mode 100755 index 5af003a72..000000000 --- a/modules/islandora_core_feature/islandora_core_feature.features.yml +++ /dev/null @@ -1,16 +0,0 @@ -bundle: islandora -excluded: - - language.content_settings.taxonomy_term.islandora_media_use - - language.content_settings.taxonomy_term.islandora_models -required: - - features.bundle.islandora - - field.storage.media.field_file_size - - field.storage.media.field_height - - field.storage.media.field_media_of - - field.storage.media.field_media_use - - field.storage.media.field_mime_type - - field.storage.media.field_width - - field.storage.node.field_member_of - - field.storage.node.field_model - - field.storage.node.field_weight - - field.storage.taxonomy_term.field_external_uri diff --git a/modules/islandora_core_feature/islandora_core_feature.info.yml b/modules/islandora_core_feature/islandora_core_feature.info.yml index 6976eb8ca..38992ea7b 100755 --- a/modules/islandora_core_feature/islandora_core_feature.info.yml +++ b/modules/islandora_core_feature/islandora_core_feature.info.yml @@ -6,7 +6,6 @@ dependencies: - drupal:basic_auth - drupal:content_translation - drupal:eva - - drupal:features - drupal:field - drupal:file - drupal:filehash diff --git a/modules/islandora_text_extraction_defaults/config/install/core.entity_form_display.media.extracted_text.default.yml b/modules/islandora_text_extraction_defaults/config/optional/core.entity_form_display.media.extracted_text.default.yml similarity index 100% rename from modules/islandora_text_extraction_defaults/config/install/core.entity_form_display.media.extracted_text.default.yml rename to modules/islandora_text_extraction_defaults/config/optional/core.entity_form_display.media.extracted_text.default.yml diff --git a/modules/islandora_text_extraction_defaults/config/install/core.entity_view_display.media.extracted_text.default.yml b/modules/islandora_text_extraction_defaults/config/optional/core.entity_view_display.media.extracted_text.default.yml similarity index 100% rename from modules/islandora_text_extraction_defaults/config/install/core.entity_view_display.media.extracted_text.default.yml rename to modules/islandora_text_extraction_defaults/config/optional/core.entity_view_display.media.extracted_text.default.yml diff --git a/modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_edited_text.yml b/modules/islandora_text_extraction_defaults/config/optional/field.field.media.extracted_text.field_edited_text.yml similarity index 100% rename from modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_edited_text.yml rename to modules/islandora_text_extraction_defaults/config/optional/field.field.media.extracted_text.field_edited_text.yml diff --git a/modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_media_file.yml b/modules/islandora_text_extraction_defaults/config/optional/field.field.media.extracted_text.field_media_file.yml similarity index 100% rename from modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_media_file.yml rename to modules/islandora_text_extraction_defaults/config/optional/field.field.media.extracted_text.field_media_file.yml diff --git a/modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_media_of.yml b/modules/islandora_text_extraction_defaults/config/optional/field.field.media.extracted_text.field_media_of.yml similarity index 100% rename from modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_media_of.yml rename to modules/islandora_text_extraction_defaults/config/optional/field.field.media.extracted_text.field_media_of.yml diff --git a/modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_media_use.yml b/modules/islandora_text_extraction_defaults/config/optional/field.field.media.extracted_text.field_media_use.yml similarity index 100% rename from modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_media_use.yml rename to modules/islandora_text_extraction_defaults/config/optional/field.field.media.extracted_text.field_media_use.yml diff --git a/modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_mime_type.yml b/modules/islandora_text_extraction_defaults/config/optional/field.field.media.extracted_text.field_mime_type.yml similarity index 100% rename from modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_mime_type.yml rename to modules/islandora_text_extraction_defaults/config/optional/field.field.media.extracted_text.field_mime_type.yml diff --git a/modules/islandora_text_extraction_defaults/config/install/field.storage.media.field_edited_text.yml b/modules/islandora_text_extraction_defaults/config/optional/field.storage.media.field_edited_text.yml similarity index 100% rename from modules/islandora_text_extraction_defaults/config/install/field.storage.media.field_edited_text.yml rename to modules/islandora_text_extraction_defaults/config/optional/field.storage.media.field_edited_text.yml diff --git a/modules/islandora_text_extraction_defaults/config/install/language.content_settings.media.extracted_text.yml b/modules/islandora_text_extraction_defaults/config/optional/language.content_settings.media.extracted_text.yml similarity index 100% rename from modules/islandora_text_extraction_defaults/config/install/language.content_settings.media.extracted_text.yml rename to modules/islandora_text_extraction_defaults/config/optional/language.content_settings.media.extracted_text.yml diff --git a/modules/islandora_text_extraction_defaults/config/install/media.type.extracted_text.yml b/modules/islandora_text_extraction_defaults/config/optional/media.type.extracted_text.yml similarity index 100% rename from modules/islandora_text_extraction_defaults/config/install/media.type.extracted_text.yml rename to modules/islandora_text_extraction_defaults/config/optional/media.type.extracted_text.yml diff --git a/modules/islandora_text_extraction_defaults/config/install/rdf.mapping.media.extracted_text.yml b/modules/islandora_text_extraction_defaults/config/optional/rdf.mapping.media.extracted_text.yml similarity index 100% rename from modules/islandora_text_extraction_defaults/config/install/rdf.mapping.media.extracted_text.yml rename to modules/islandora_text_extraction_defaults/config/optional/rdf.mapping.media.extracted_text.yml diff --git a/modules/islandora_text_extraction_defaults/config/install/system.action.get_ocr_from_image.yml b/modules/islandora_text_extraction_defaults/config/optional/system.action.get_ocr_from_image.yml similarity index 100% rename from modules/islandora_text_extraction_defaults/config/install/system.action.get_ocr_from_image.yml rename to modules/islandora_text_extraction_defaults/config/optional/system.action.get_ocr_from_image.yml diff --git a/modules/islandora_text_extraction_defaults/islandora_text_extraction_defaults.features.yml b/modules/islandora_text_extraction_defaults/islandora_text_extraction_defaults.features.yml deleted file mode 100644 index 9e48e9fd5..000000000 --- a/modules/islandora_text_extraction_defaults/islandora_text_extraction_defaults.features.yml +++ /dev/null @@ -1,2 +0,0 @@ -bundle: islandora -required: true From e30cdbf6812febe2b38e8d22020c2fc352f28638 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Fri, 8 Mar 2024 09:44:50 -0400 Subject: [PATCH 219/252] Update testing drupal and php versions --- .github/workflows/build-2.x.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index 2ab3a539e..4750ba4de 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -23,10 +23,10 @@ jobs: strategy: fail-fast: false matrix: - php-versions: ["8.1", "8.2"] + php-versions: ["8.1", "8.2", "8.3"] # test-suite functional-javascript will appear to pass but will skip tests; missing chromedriver. test-suite: ["kernel", "functional", "functional-javascript"] - drupal-version: ["10.0.x", "10.1.x", "10.2.x-dev"] + drupal-version: ["10.1.x", "10.2.x", "10.3.x-dev"] mysql: ["8.0"] allowed_failure: [false] From 3784def28765a08f6df616aa9fb91731000dccd5 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Fri, 8 Mar 2024 11:03:10 -0400 Subject: [PATCH 220/252] Tests use strings not translateable markup to select interface buttons. --- .../src/Functional/GenerateAudioDerivativeTest.php | 6 +++--- .../src/Functional/GenerateImageDerivativeTest.php | 6 +++--- .../src/Functional/GenerateVideoDerivativeTest.php | 6 +++--- tests/src/Functional/ContentEntityTypeTest.php | 2 +- tests/src/Functional/DerivativeReactionTest.php | 2 +- tests/src/Functional/EmitNodeEventTest.php | 2 +- tests/src/Functional/EntityBundleTest.php | 2 +- .../src/Functional/FormDisplayAlterReactionTest.php | 2 +- tests/src/Functional/IndexingTest.php | 2 +- tests/src/Functional/IslandoraSettingsFormTest.php | 10 +++++----- .../Functional/JsonldSelfReferenceReactionTest.php | 2 +- tests/src/Functional/JsonldTypeAlterReactionTest.php | 12 ++++++------ 12 files changed, 27 insertions(+), 27 deletions(-) diff --git a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php index 6b85cd1b5..094a7856a 100644 --- a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php +++ b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php @@ -40,7 +40,7 @@ public function testGenerateAudioDerivativeFromScratch() { // Create an action to generate a audio derivative. $this->drupalGet('admin/config/system/actions'); $this->getSession()->getPage()->findById("edit-action")->selectOption("Generate a audio derivative"); - $this->getSession()->getPage()->pressButton($this->t('Create')); + $this->getSession()->getPage()->pressButton('Create'); $this->assertSession()->statusCodeEquals(200); $this->getSession()->getPage()->fillField('edit-label', "Generate audio test derivative"); @@ -53,7 +53,7 @@ public function testGenerateAudioDerivativeFromScratch() { $this->getSession()->getPage()->fillField('edit-args', "-f mp3"); $this->getSession()->getPage()->fillField('edit-scheme', "public"); $this->getSession()->getPage()->fillField('edit-path', "derp.mov"); - $this->getSession()->getPage()->pressButton($this->t('Save')); + $this->getSession()->getPage()->pressButton('Save'); $this->assertSession()->statusCodeEquals(200); // Create a context and add the action as a derivative reaction. @@ -69,7 +69,7 @@ public function testGenerateAudioDerivativeFromScratch() { 'field_media_use[0][target_id]' => $this->preservationMasterTerm->label(), ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); - $this->submitForm($values, $this->t('Save')); + $this->submitForm($values, 'Save'); $expected = [ 'source_uri' => 'test_file.txt', diff --git a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php index 44cdda589..17c1beae0 100644 --- a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php +++ b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php @@ -42,7 +42,7 @@ public function testGenerateImageDerivativeFromScratch() { // Create an action to generate a jpeg thumbnail. $this->drupalGet('admin/config/system/actions'); $this->getSession()->getPage()->findById("edit-action")->selectOption("Generate an image derivative"); - $this->getSession()->getPage()->pressButton($this->t('Create')); + $this->getSession()->getPage()->pressButton('Create'); $this->assertSession()->statusCodeEquals(200); $this->getSession()->getPage()->fillField('edit-label', "Generate image test derivative"); @@ -55,7 +55,7 @@ public function testGenerateImageDerivativeFromScratch() { $this->getSession()->getPage()->fillField('edit-args', "-thumbnail 20x20"); $this->getSession()->getPage()->fillField('edit-scheme', "public"); $this->getSession()->getPage()->fillField('edit-path', "derp.jpeg"); - $this->getSession()->getPage()->pressButton($this->t('Save')); + $this->getSession()->getPage()->pressButton('Save'); $this->assertSession()->statusCodeEquals(200); // Create a context and add the action as a derivative reaction. @@ -71,7 +71,7 @@ public function testGenerateImageDerivativeFromScratch() { 'field_media_use[0][target_id]' => $this->preservationMasterTerm->label(), ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); - $this->submitForm($values, $this->t('Save')); + $this->submitForm($values, 'Save'); $expected = [ 'source_uri' => 'test_file.txt', diff --git a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php index de06ba2f7..2f79e18e9 100644 --- a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php +++ b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php @@ -37,7 +37,7 @@ public function testGenerateVideoDerivativeFromScratch() { // Create an action to generate a jpeg thumbnail. $this->drupalGet('admin/config/system/actions'); $this->getSession()->getPage()->findById("edit-action")->selectOption("Generate a video derivative"); - $this->getSession()->getPage()->pressButton($this->t('Create')); + $this->getSession()->getPage()->pressButton('Create'); $this->assertSession()->statusCodeEquals(200); $this->getSession()->getPage()->fillField('edit-label', "Generate video test derivative"); @@ -50,7 +50,7 @@ public function testGenerateVideoDerivativeFromScratch() { $this->getSession()->getPage()->fillField('edit-args', "-f mp4"); $this->getSession()->getPage()->fillField('edit-scheme', "public"); $this->getSession()->getPage()->fillField('edit-path', "derp.mov"); - $this->getSession()->getPage()->pressButton($this->t('Save')); + $this->getSession()->getPage()->pressButton('Save'); $this->assertSession()->statusCodeEquals(200); // Create a context and add the action as a derivative reaction. @@ -66,7 +66,7 @@ public function testGenerateVideoDerivativeFromScratch() { 'field_media_use[0][target_id]' => $this->preservationMasterTerm->label(), ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); - $this->submitForm($values, $this->t('Save')); + $this->submitForm($values, 'Save'); $expected = [ 'source_uri' => 'test_file.txt', diff --git a/tests/src/Functional/ContentEntityTypeTest.php b/tests/src/Functional/ContentEntityTypeTest.php index 5ed229486..b753852ac 100644 --- a/tests/src/Functional/ContentEntityTypeTest.php +++ b/tests/src/Functional/ContentEntityTypeTest.php @@ -39,7 +39,7 @@ public function testContentEntityType() { $this->addCondition('test', 'content_entity_type'); $this->getSession()->getPage()->checkField("edit-conditions-content-entity-type-types-node"); $this->getSession()->getPage()->findById("edit-conditions-content-entity-type-context-mapping-node")->selectOption("@node.node_route_context:node"); - $this->getSession()->getPage()->pressButton($this->t('Save and continue')); + $this->getSession()->getPage()->pressButton('Save and continue'); $this->addPresetReaction('test', 'index', 'hello_world'); // Create a new node confirm Hello World! is printed to the screen. diff --git a/tests/src/Functional/DerivativeReactionTest.php b/tests/src/Functional/DerivativeReactionTest.php index 00e0e5ae5..7c0cedb35 100644 --- a/tests/src/Functional/DerivativeReactionTest.php +++ b/tests/src/Functional/DerivativeReactionTest.php @@ -53,7 +53,7 @@ public function testExecuteDerivativeReaction() { 'field_media_of[0][target_id]' => 'Test Node', ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); - $this->submitForm($values, $this->t('Save')); + $this->submitForm($values, 'Save'); // field_media_of is set and there's a file, so derivatives should fire. $this->assertSession()->pageTextContains("Hello World!"); diff --git a/tests/src/Functional/EmitNodeEventTest.php b/tests/src/Functional/EmitNodeEventTest.php index 83f062ae7..3ebcc6ddd 100644 --- a/tests/src/Functional/EmitNodeEventTest.php +++ b/tests/src/Functional/EmitNodeEventTest.php @@ -44,7 +44,7 @@ public function testEmitEvent() { $this->addCondition('test', 'content_entity_type'); $this->getSession()->getPage()->checkField("edit-conditions-content-entity-type-types-node"); $this->getSession()->getPage()->findById("edit-conditions-content-entity-type-context-mapping-node")->selectOption("@node.node_route_context:node"); - $this->getSession()->getPage()->pressButton($this->t('Save and continue')); + $this->getSession()->getPage()->pressButton('Save and continue'); $this->addPresetReaction('test', 'index', $action_id); $this->assertSession()->statusCodeEquals(200); diff --git a/tests/src/Functional/EntityBundleTest.php b/tests/src/Functional/EntityBundleTest.php index bde1ee40e..27183826f 100644 --- a/tests/src/Functional/EntityBundleTest.php +++ b/tests/src/Functional/EntityBundleTest.php @@ -27,7 +27,7 @@ public function testEntityBundleType() { $this->addCondition('test', 'islandora_entity_bundle'); $this->getSession()->getPage()->checkField("edit-conditions-islandora-entity-bundle-bundles-test-type"); $this->getSession()->getPage()->findById("edit-conditions-islandora-entity-bundle-context-mapping-node")->selectOption("@node.node_route_context:node"); - $this->getSession()->getPage()->pressButton($this->t('Save and continue')); + $this->getSession()->getPage()->pressButton('Save and continue'); $this->addPresetReaction('test', 'index', 'hello_world'); // Create a new test_type confirm Hello World! is printed to the screen. diff --git a/tests/src/Functional/FormDisplayAlterReactionTest.php b/tests/src/Functional/FormDisplayAlterReactionTest.php index d394b7288..fe70aa645 100644 --- a/tests/src/Functional/FormDisplayAlterReactionTest.php +++ b/tests/src/Functional/FormDisplayAlterReactionTest.php @@ -49,7 +49,7 @@ public function testViewModeAlter() { $this->drupalGet("admin/structure/context/test/reaction/add/form_display_alter"); $this->getSession()->getPage()->findById("edit-reactions-form-display-alter-mode")->selectOption('node.secondary'); - $this->getSession()->getPage()->pressButton($this->t('Save and continue')); + $this->getSession()->getPage()->pressButton('Save and continue'); $this->assertSession()->statusCodeEquals(200); drupal_flush_all_caches(); diff --git a/tests/src/Functional/IndexingTest.php b/tests/src/Functional/IndexingTest.php index ff2152817..cf2dbb667 100644 --- a/tests/src/Functional/IndexingTest.php +++ b/tests/src/Functional/IndexingTest.php @@ -66,7 +66,7 @@ public function testIndexing() { $this->drupalGet("$url/delete"); // Delete the node. - $this->submitForm([], $this->t('Delete')); + $this->submitForm([], 'Delete'); $this->assertSession()->statusCodeEquals(200); // Confirm Goodbye, Cruel World! is printed to the screen. diff --git a/tests/src/Functional/IslandoraSettingsFormTest.php b/tests/src/Functional/IslandoraSettingsFormTest.php index 80a327af1..18bfcafb4 100644 --- a/tests/src/Functional/IslandoraSettingsFormTest.php +++ b/tests/src/Functional/IslandoraSettingsFormTest.php @@ -38,23 +38,23 @@ public function testJwtExpiry() { $this->assertSession()->fieldValueEquals('edit-jwt-expiry', '+2 hour'); $this->drupalGet('/admin/config/islandora/core'); // Blank is not allowed. - $this->submitForm(['edit-jwt-expiry' => ""], $this->t('Save configuration')); + $this->submitForm(['edit-jwt-expiry' => ""], 'Save configuration'); $this->assertSession()->pageTextContainsOnce('"" is not a valid time or interval expression.'); $this->drupalGet('/admin/config/islandora/core'); // Negative is not allowed. - $this->submitForm(['edit-jwt-expiry' => "-2 hours"], $this->t('Save configuration')); + $this->submitForm(['edit-jwt-expiry' => "-2 hours"], 'Save configuration'); $this->assertSession()->pageTextContainsOnce('Time or interval expression cannot be negative'); $this->drupalGet('/admin/config/islandora/core'); // Must include an integer value. - $this->submitForm(['edit-jwt-expiry' => "last hour"], $this->t('Save configuration')); + $this->submitForm(['edit-jwt-expiry' => "last hour"], 'Save configuration'); $this->assertSession()->pageTextContainsOnce('No numeric interval specified, for example "1 day"'); $this->drupalGet('/admin/config/islandora/core'); // Must have an accepted interval. - $this->submitForm(['edit-jwt-expiry' => "1 fortnight"], $this->t('Save configuration')); + $this->submitForm(['edit-jwt-expiry' => "1 fortnight"], 'Save configuration'); $this->assertSession()->pageTextContainsOnce('No time interval found, please include one of'); $this->drupalGet('/admin/config/islandora/core'); // Test a valid setting. - $this->submitForm(['edit-jwt-expiry' => "2 weeks"], $this->t('Save configuration')); + $this->submitForm(['edit-jwt-expiry' => "2 weeks"], 'Save configuration'); $this->assertSession()->pageTextContainsOnce('The configuration options have been saved.'); } diff --git a/tests/src/Functional/JsonldSelfReferenceReactionTest.php b/tests/src/Functional/JsonldSelfReferenceReactionTest.php index 1b4e24ec7..c8acfcc96 100644 --- a/tests/src/Functional/JsonldSelfReferenceReactionTest.php +++ b/tests/src/Functional/JsonldSelfReferenceReactionTest.php @@ -60,7 +60,7 @@ public function testMappingReaction() { $this->postNodeAddForm('test_type', ['title[0][value]' => 'Test Node'], - $this->t('Save')); + 'Save'); $this->assertSession()->pageTextContains("Test Node"); $url = $this->getUrl(); diff --git a/tests/src/Functional/JsonldTypeAlterReactionTest.php b/tests/src/Functional/JsonldTypeAlterReactionTest.php index 75ae41dd3..5ab9037cb 100644 --- a/tests/src/Functional/JsonldTypeAlterReactionTest.php +++ b/tests/src/Functional/JsonldTypeAlterReactionTest.php @@ -32,7 +32,7 @@ public function testMappingReaction() { 'label' => 'Typed Predicate', 'field_name' => 'type_predicate', ], 'Save and continue'); - $this->submitForm([], $this->t('Save field settings')); + $this->submitForm([], 'Save field settings'); } else { $this->getSession()->getPage()->selectFieldOption('new_storage_type', 'plain_text'); @@ -46,7 +46,7 @@ public function testMappingReaction() { 'new_storage_type' => 'plain_text', 'label' => 'Typed Predicate', 'field_name' => 'type_predicate', - ], $this->t('Continue')); + ], 'Continue'); // Now we can proceed, selecting the plain text (i.e. string) // for the second element now that the element is displayed after @@ -57,16 +57,16 @@ public function testMappingReaction() { 'label' => 'Typed Predicate', 'field_name' => 'type_predicate', 'group_field_options_wrapper' => 'string', - ], $this->t('Continue')); + ], 'Continue'); } - $this->submitForm([], $this->t('Save settings')); + $this->submitForm([], 'Save settings'); $this->assertSession()->responseContains('field_type_predicate'); // Add the test node. $this->postNodeAddForm('test_type', [ 'title[0][value]' => 'Test Node', 'field_type_predicate[0][value]' => 'schema:Organization', - ], $this->t('Save')); + ], 'Save'); $this->assertSession()->pageTextContains("Test Node"); $url = $this->getUrl(); @@ -103,7 +103,7 @@ public function testMappingReaction() { $this->addCondition('test', 'islandora_entity_bundle'); $this->getSession()->getPage()->checkField("edit-conditions-islandora-entity-bundle-bundles-test-type"); $this->getSession()->getPage()->findById("edit-conditions-islandora-entity-bundle-context-mapping-node")->selectOption("@node.node_route_context:node"); - $this->getSession()->getPage()->pressButton($this->t('Save and continue')); + $this->getSession()->getPage()->pressButton('Save and continue'); // The first time a Context is saved, you need to clear the cache. // Subsequent changes to the context don't need a cache rebuild, though. From 89261c17aefa7c2b6110de57c4f0814e0c572cfc Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Fri, 8 Mar 2024 11:06:22 -0400 Subject: [PATCH 221/252] Add some forgotten translateable markup. --- tests/src/Functional/ContentEntityTypeTest.php | 2 +- tests/src/Functional/DerivativeReactionTest.php | 4 ++-- tests/src/Functional/EmitNodeEventTest.php | 4 ++-- tests/src/Functional/IslandoraFunctionalTestBase.php | 2 +- tests/src/Functional/ViewModeAlterReactionTest.php | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/src/Functional/ContentEntityTypeTest.php b/tests/src/Functional/ContentEntityTypeTest.php index b753852ac..2fa9b5746 100644 --- a/tests/src/Functional/ContentEntityTypeTest.php +++ b/tests/src/Functional/ContentEntityTypeTest.php @@ -53,7 +53,7 @@ public function testContentEntityType() { 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt', ]; $this->drupalGet('media/add/' . $this->testMediaType->id()); - $this->submitForm($values, $this->t('Save')); + $this->submitForm($values, 'Save'); $this->assertSession()->pageTextNotContains("Hello World!"); } diff --git a/tests/src/Functional/DerivativeReactionTest.php b/tests/src/Functional/DerivativeReactionTest.php index 7c0cedb35..720b8a45b 100644 --- a/tests/src/Functional/DerivativeReactionTest.php +++ b/tests/src/Functional/DerivativeReactionTest.php @@ -71,9 +71,9 @@ public function testExecuteDerivativeReaction() { 'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file2.txt', ]; $this->drupalGet($media_url . '/edit'); - $this->getSession()->getPage()->pressButton($this->t('Remove')); + $this->getSession()->getPage()->pressButton('Remove'); $this->getSession()->getPage()->fillField('files[field_media_file_0]', __DIR__ . '/../../fixtures/test_file2.txt'); - $this->getSession()->getPage()->pressButton($this->t('Save')); + $this->getSession()->getPage()->pressButton('Save'); $this->assertSession()->pageTextContains("Hello World!"); } diff --git a/tests/src/Functional/EmitNodeEventTest.php b/tests/src/Functional/EmitNodeEventTest.php index 3ebcc6ddd..a18ffbc8f 100644 --- a/tests/src/Functional/EmitNodeEventTest.php +++ b/tests/src/Functional/EmitNodeEventTest.php @@ -68,7 +68,7 @@ public function testEmitEvent() { protected function createEmitAction($entity_type, $event_type) { $this->drupalGet('admin/config/system/actions'); $this->getSession()->getPage()->findById("edit-action")->selectOption("Emit a $entity_type event to a queue/topic"); - $this->getSession()->getPage()->pressButton($this->t('Create')); + $this->getSession()->getPage()->pressButton('Create'); $this->assertSession()->statusCodeEquals(200); $action_id = "emit_" . $entity_type . "_" . lcfirst($event_type); @@ -76,7 +76,7 @@ protected function createEmitAction($entity_type, $event_type) { $this->getSession()->getPage()->fillField('edit-id', $action_id); $this->getSession()->getPage()->fillField('edit-queue', "emit-$entity_type-" . lcfirst($event_type)); $this->getSession()->getPage()->findById("edit-event")->selectOption($event_type); - $this->getSession()->getPage()->pressButton($this->t('Save')); + $this->getSession()->getPage()->pressButton('Save'); $this->assertSession()->statusCodeEquals(200); return $action_id; diff --git a/tests/src/Functional/IslandoraFunctionalTestBase.php b/tests/src/Functional/IslandoraFunctionalTestBase.php index 016788d05..b4c0bc959 100644 --- a/tests/src/Functional/IslandoraFunctionalTestBase.php +++ b/tests/src/Functional/IslandoraFunctionalTestBase.php @@ -306,7 +306,7 @@ protected function addPresetReaction($context_id, $reaction_type, $action_id) { ->getPage() ->findById("edit-reactions-$reaction_type-actions") ->selectOption($action_id); - $this->getSession()->getPage()->pressButton($this->t('Save and continue')); + $this->getSession()->getPage()->pressButton('Save and continue'); $this->assertSession()->statusCodeEquals(200); } diff --git a/tests/src/Functional/ViewModeAlterReactionTest.php b/tests/src/Functional/ViewModeAlterReactionTest.php index 19660bda1..904414027 100644 --- a/tests/src/Functional/ViewModeAlterReactionTest.php +++ b/tests/src/Functional/ViewModeAlterReactionTest.php @@ -75,7 +75,7 @@ public function testViewModeAlter() { $this->drupalGet("admin/structure/context/test/reaction/add/view_mode_alter"); $this->getSession()->getPage()->findById("edit-reactions-view-mode-alter-mode")->selectOption('node.teaser'); - $this->getSession()->getPage()->pressButton($this->t('Save and continue')); + $this->getSession()->getPage()->pressButton('Save and continue'); $this->assertSession()->statusCodeEquals(200); drupal_flush_all_caches(); From 9f2277fc51c5e29bea3730e2bef3a0432f20b800 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Fri, 8 Mar 2024 11:22:03 -0400 Subject: [PATCH 222/252] Exclude PHP 8.3 with Drupal 10.1. --- .github/workflows/build-2.x.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index 4750ba4de..c5d9d66b0 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -29,6 +29,9 @@ jobs: drupal-version: ["10.1.x", "10.2.x", "10.3.x-dev"] mysql: ["8.0"] allowed_failure: [false] + exclude: + - php-versions: "8.3" + drupal-version: "10.1.x" name: PHP ${{ matrix.php-versions }} | drupal ${{ matrix.drupal-version }} | mysql ${{ matrix.mysql }} | test-suite ${{ matrix.test-suite }} From 13bc15ea43659824f2397a43914efe462a8dd546 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Fri, 8 Mar 2024 16:50:50 -0400 Subject: [PATCH 223/252] Last attempt to not pass translatables as button labels. --- tests/src/Functional/IslandoraFunctionalTestBase.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/src/Functional/IslandoraFunctionalTestBase.php b/tests/src/Functional/IslandoraFunctionalTestBase.php index b4c0bc959..1ad8081d1 100644 --- a/tests/src/Functional/IslandoraFunctionalTestBase.php +++ b/tests/src/Functional/IslandoraFunctionalTestBase.php @@ -315,7 +315,7 @@ protected function addPresetReaction($context_id, $reaction_type, $action_id) { */ protected function postNodeAddForm($bundle_id, $values, $button_text) { $this->drupalGet("node/add/$bundle_id"); - $this->submitForm($values, $this->t('@text', ['@text' => $button_text])); + $this->submitForm($values, $button_text); $this->assertSession()->statusCodeEquals(200); } @@ -324,7 +324,7 @@ protected function postNodeAddForm($bundle_id, $values, $button_text) { */ protected function postTermAddForm($taxomony_id, $values, $button_text) { $this->drupalGet("admin/structure/taxonomy/manage/$taxomony_id/add"); - $this->submitForm($values, $this->t('@text', ['@text' => $button_text])); + $this->submitForm($values, $button_text); $this->assertSession()->statusCodeEquals(200); } @@ -333,7 +333,7 @@ protected function postTermAddForm($taxomony_id, $values, $button_text) { */ protected function postEntityEditForm($entity_url, $values, $button_text) { $this->drupalGet("$entity_url/edit"); - $this->submitForm($values, $this->t('@text', ['@text' => $button_text])); + $this->submitForm($values, $button_text); $this->assertSession()->statusCodeEquals(200); } From 9ed3637339d4aaf1723f775cc9d009d12a3c2e2d Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 3 Apr 2024 14:16:19 -0300 Subject: [PATCH 224/252] Update islandora.module (#1008) --- islandora.module | 1 + 1 file changed, 1 insertion(+) diff --git a/islandora.module b/islandora.module index d3dfa01d9..d715db52d 100644 --- a/islandora.module +++ b/islandora.module @@ -615,6 +615,7 @@ function islandora_form_block_form_alter(&$form, FormStateInterface $form_state, unset($form['visibility']['media_is_islandora_media']); unset($form['visibility']['media_uses_filesystem']); unset($form['visibility']['node_had_namespace']); + unset($form['visibility']['node_has_ancestor']); unset($form['visibility']['node_has_parent']); unset($form['visibility']['node_has_term']); unset($form['visibility']['node_is_islandora_object']); From a2c31fcaad87d753ca6725fef47fde39579c3342 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 3 Apr 2024 14:47:01 -0300 Subject: [PATCH 225/252] @adam-vessey's fix for drupalGet headers. --- tests/src/Functional/LinkHeaderTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/src/Functional/LinkHeaderTest.php b/tests/src/Functional/LinkHeaderTest.php index 98b36c68b..78dd6c994 100644 --- a/tests/src/Functional/LinkHeaderTest.php +++ b/tests/src/Functional/LinkHeaderTest.php @@ -142,7 +142,7 @@ public function testMediaLinkHeaders() { $media_url = $this->media->toUrl('canonical', ['absolute' => TRUE])->toString(); // Perform a GET request as anonymous. - $this->drupalGet($media_url, [], ['Cache-Control: no-cache']); + $this->drupalGet($media_url, [], ['Cache-Control' => 'no-cache']); // Check link headers. $this->assertTrue( $this->validateLinkHeaderWithUrl('describes', $file_url, '', 'text/plain') == 1, @@ -174,7 +174,7 @@ public function testMediaLinkHeaders() { $this->drupalLogin($account); // Perform a GET request with update media permissions. - $this->drupalGet($media_url, [], ['Cache-Control: no-cache']); + $this->drupalGet($media_url, [], ['Cache-Control' => 'no-cache']); // Check link headers again, the edit-media link header should be present. $this->assertTrue( From cde2c133e1b06f90f5f9cce949e32d4ab0bffb2a Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 4 Apr 2024 09:56:45 -0300 Subject: [PATCH 226/252] Update tests for D10.3's new field selector form. --- .../JsonldTypeAlterReactionTest.php | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/tests/src/Functional/JsonldTypeAlterReactionTest.php b/tests/src/Functional/JsonldTypeAlterReactionTest.php index 5ab9037cb..900360483 100644 --- a/tests/src/Functional/JsonldTypeAlterReactionTest.php +++ b/tests/src/Functional/JsonldTypeAlterReactionTest.php @@ -34,11 +34,11 @@ public function testMappingReaction() { ], 'Save and continue'); $this->submitForm([], 'Save field settings'); } - else { + elseif (version_compare(\Drupal::VERSION, '10.3.x-dev', 'lt'){ $this->getSession()->getPage()->selectFieldOption('new_storage_type', 'plain_text'); - // First need to submit the form with the elements displayed - // on initial page load. The form is using AJAX to send a second element - // after we selected the radio button above + // For Drupal 10.2, we first need to submit the form with the elements + // displayed on initial page load. The form is using AJAX to send a + // second element after we selected the radio button above // we can instead get the second element by submitting the form // and having it throw an error since the required field is missing. // @todo refactor this as a functional javascript test. @@ -59,6 +59,25 @@ public function testMappingReaction() { 'group_field_options_wrapper' => 'string', ], 'Continue'); } + else { + $this->getSession()->getPage()->selectFieldOption('new_storage_type', 'plain_text'); + // For Drupal 10.3 the label is not visible at first. + // @todo refactor this as a functional javascript test. + $this->submitForm([ + 'new_storage_type' => 'plain_text', + ], 'Continue'); + + // Now we can proceed, entering a label and selecting Text (plain) + // for the second element now that the elements are displayed after + // the initial form submission. + $this->getSession()->getPage()->selectFieldOption('group_field_options_wrapper', 'string'); + $this->submitForm([ + 'new_storage_type' => 'plain_text', + 'label' => 'Typed Predicate', + 'field_name' => 'type_predicate', + 'group_field_options_wrapper' => 'string', + ], 'Continue'); + } $this->submitForm([], 'Save settings'); $this->assertSession()->responseContains('field_type_predicate'); From 95c2d6c0c9970f48f44b579d19f76a3f87ed8767 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 4 Apr 2024 10:04:05 -0300 Subject: [PATCH 227/252] Syntax. --- tests/src/Functional/JsonldTypeAlterReactionTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/Functional/JsonldTypeAlterReactionTest.php b/tests/src/Functional/JsonldTypeAlterReactionTest.php index 900360483..edefd77aa 100644 --- a/tests/src/Functional/JsonldTypeAlterReactionTest.php +++ b/tests/src/Functional/JsonldTypeAlterReactionTest.php @@ -34,7 +34,7 @@ public function testMappingReaction() { ], 'Save and continue'); $this->submitForm([], 'Save field settings'); } - elseif (version_compare(\Drupal::VERSION, '10.3.x-dev', 'lt'){ + elseif (version_compare(\Drupal::VERSION, '10.3.x-dev', 'lt')) { $this->getSession()->getPage()->selectFieldOption('new_storage_type', 'plain_text'); // For Drupal 10.2, we first need to submit the form with the elements // displayed on initial page load. The form is using AJAX to send a From 263666f5fcf305e0fe8ee86fda03959e4db4bde7 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 4 Apr 2024 14:51:20 -0300 Subject: [PATCH 228/252] Remove new_storage_type from form part 2. --- tests/src/Functional/JsonldTypeAlterReactionTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/src/Functional/JsonldTypeAlterReactionTest.php b/tests/src/Functional/JsonldTypeAlterReactionTest.php index edefd77aa..6ac70d7da 100644 --- a/tests/src/Functional/JsonldTypeAlterReactionTest.php +++ b/tests/src/Functional/JsonldTypeAlterReactionTest.php @@ -72,7 +72,6 @@ public function testMappingReaction() { // the initial form submission. $this->getSession()->getPage()->selectFieldOption('group_field_options_wrapper', 'string'); $this->submitForm([ - 'new_storage_type' => 'plain_text', 'label' => 'Typed Predicate', 'field_name' => 'type_predicate', 'group_field_options_wrapper' => 'string', From 9b2661696db027867061f237639167ed3684c6b5 Mon Sep 17 00:00:00 2001 From: Joe Corall Date: Fri, 19 Apr 2024 11:13:21 -0400 Subject: [PATCH 229/252] Add hOCR functionality (#1006) * Add hOCR functionality * Fix wording in Islandora IIIF View Style config form. * Islandora IIIF: Attempt to fix broken config schema. * Islandora IIIF: Remove labels from config schema. * Islandora IIIF: Add labels to config schema items. * Update IIIFManifest.php * Move to memorized term lookup, instead of polluting method call. * Deal explicitly with URIs, instead of attempting to put the entity in config. * hocr Islandora IIIF: Add missing null check. --------- Co-authored-by: Alexander O'Neill Co-authored-by: Alexander O'Neill Co-authored-by: Rosie Le Faive Co-authored-by: Adam Vessey --- .../config/schema/islandora_iiif.schema.yml | 12 ++ .../src/Plugin/views/style/IIIFManifest.php | 135 ++++++++++++++++-- 2 files changed, 136 insertions(+), 11 deletions(-) diff --git a/modules/islandora_iiif/config/schema/islandora_iiif.schema.yml b/modules/islandora_iiif/config/schema/islandora_iiif.schema.yml index 1f91450fa..11fff4c71 100644 --- a/modules/islandora_iiif/config/schema/islandora_iiif.schema.yml +++ b/modules/islandora_iiif/config/schema/islandora_iiif.schema.yml @@ -17,5 +17,17 @@ views.style.iiif_manifest: mapping: iiif_tile_field: type: sequence + label: "Tile source field(s)" sequence: type: string + iiif_ocr_file_field: + type: sequence + label: "Structured OCR data file field" + sequence: + type: string + structured_text_term_uri: + type: string + label: "Structured text term" + search_endpoint: + type: string + label: "Search endpoint path" diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 2fc8a431a..f0aca47da 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -11,6 +11,8 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\Url; +use Drupal\islandora\IslandoraUtils; +use Drupal\taxonomy\TermInterface; use Drupal\views\Plugin\views\style\StylePluginBase; use Drupal\views\ResultRow; use GuzzleHttp\Client; @@ -35,6 +37,13 @@ */ class IIIFManifest extends StylePluginBase { + /** + * Islandora utility functions. + * + * @var \Drupal\islandora\IslandoraUtils + */ + protected $utils; + /** * {@inheritdoc} */ @@ -108,10 +117,24 @@ class IIIFManifest extends StylePluginBase { */ protected $moduleHandler; + /** + * Memoized structured text term. + * + * @var \Drupal\taxonomy\TermInterface|null + */ + protected ?TermInterface $structuredTextTerm; + + /** + * Flag to track if we _have_ attempted a lookup, as the value is nullable. + * + * @var bool + */ + protected bool $structuredTextTermMemoized = FALSE; + /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system, Client $http_client, MessengerInterface $messenger, ModuleHandlerInterface $moduleHandler) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system, Client $http_client, MessengerInterface $messenger, ModuleHandlerInterface $moduleHandler, IslandoraUtils $utils) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->serializer = $serializer; @@ -121,6 +144,7 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition $this->fileSystem = $file_system; $this->httpClient = $http_client; $this->messenger = $messenger; + $this->utils = $utils; $this->moduleHandler = $moduleHandler; } @@ -139,7 +163,8 @@ public static function create(ContainerInterface $container, array $configuratio $container->get('file_system'), $container->get('http_client'), $container->get('messenger'), - $container->get('module_handler') + $container->get('module_handler'), + $container->get('islandora.utils') ); } @@ -217,6 +242,9 @@ public function render() { $content_type = 'json'; + // Add a search endpoint if one is defined. + $this->addSearchEndpoint($json, $url_components); + // Give other modules a chance to alter the manifest. $this->moduleHandler->alter('islandora_iiif_manifest', $json, $this); @@ -300,7 +328,7 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas ], ]; - if ($ocr_url = $this->getOcrUrl($entity, $row, $i)) { + if ($ocr_url = $this->getOcrUrl($entity)) { $tmp_canvas['seeAlso'] = [ '@id' => $ocr_url, 'format' => 'text/vnd.hocr+html', @@ -380,30 +408,38 @@ protected function getCanvasDimensions(string $iiif_url, FieldItemInterface $ima * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity at the current row. - * @param \Drupal\views\ResultRow $row - * Result row. - * @param int $delta - * The delta in case there are multiple canvases on one media. * * @return string|false * The absolute URL of the current row's structured text, * or FALSE if none. */ - protected function getOcrUrl(EntityInterface $entity, ResultRow $row, $delta) { + protected function getOcrUrl(EntityInterface $entity) { $ocr_url = FALSE; $iiif_ocr_file_field = !empty($this->options['iiif_ocr_file_field']) ? array_filter(array_values($this->options['iiif_ocr_file_field'])) : []; $ocrField = count($iiif_ocr_file_field) > 0 ? $this->view->field[$iiif_ocr_file_field[0]] : NULL; if ($ocrField) { - $ocr_entity = $ocrField->getEntity($row); + $ocr_entity = $entity; $ocr_field_name = $ocrField->definition['field_name']; if (!is_null($ocr_field_name)) { $ocrs = $ocr_entity->{$ocr_field_name}; - $ocr = isset($ocrs[$delta]) ? $ocrs[$delta] : FALSE; + $ocr = $ocrs[0] ?? FALSE; if ($ocr) { $ocr_url = $ocr->entity->createFileUrl(FALSE); } } } + elseif ($structured_text_term = $this->getStructuredTextTerm()) { + $parent_node = $this->utils->getParentNode($entity); + $ocr_entity_array = $this->utils->getMediaReferencingNodeAndTerm($parent_node, $structured_text_term); + $ocr_entity_id = is_array($ocr_entity_array) ? array_shift($ocr_entity_array) : NULL; + $ocr_entity = $ocr_entity_id ? $this->entityTypeManager->getStorage('media')->load($ocr_entity_id) : NULL; + if ($ocr_entity) { + $ocr_file_source = $ocr_entity->getSource(); + $ocr_fid = $ocr_file_source->getSourceFieldValue($ocr_entity); + $ocr_file = $this->entityTypeManager->getStorage('file')->load($ocr_fid); + $ocr_url = $ocr_file->createFileUrl(FALSE); + } + } return $ocr_url; } @@ -448,6 +484,29 @@ protected function defineOptions() { return $options; } + /** + * Add the configured search endpoint to the manifest. + * + * @param array $json + * The IIIF manifest. + * @param array $url_components + * The search endpoint URL as array. + */ + protected function addSearchEndpoint(array &$json, array $url_components) { + $url_base = $this->getRequest()->getSchemeAndHttpHost(); + $hocr_search_path = $this->options['search_endpoint']; + $hocr_search_url = $url_base . '/' . ltrim($hocr_search_path, '/'); + + $hocr_search_url = str_replace('%node', $url_components[1], $hocr_search_url); + + $json['service'][] = [ + "@context" => "http://iiif.io/api/search/0/context.json", + "@id" => $hocr_search_url, + "profile" => "http://iiif.io/api/search/0/search", + "label" => t("Search inside this work"), + ]; + } + /** * {@inheritdoc} */ @@ -504,10 +563,27 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { '#title' => $this->t('Structured OCR data file field'), '#type' => 'checkboxes', '#default_value' => $this->options['iiif_ocr_file_field'], - '#description' => $this->t('The source of structured OCR text for each entity.'), + '#description' => $this->t("If the hOCR is a field on the same entity as the image source field above, select it here. If it's found in a related entity via the term below, leave this blank."), '#options' => $field_options, '#required' => FALSE, ]; + + $form['structured_text_term'] = [ + '#type' => 'entity_autocomplete', + '#target_type' => 'taxonomy_term', + '#title' => $this->t('Structured OCR text term'), + '#default_value' => $this->getStructuredTextTerm(), + '#required' => FALSE, + '#description' => $this->t('Term indicating the media that holds structured text, such as hOCR, for the given object. Use this if the text is on a separate media from the tile source.'), + ]; + + $form['search_endpoint'] = [ + '#type' => 'textfield', + '#title' => $this->t("Search endpoint path."), + '#description' => $this->t("If there is a search endpoint to search within the book that returns IIIF annotations, put it here. Use %node substitution where needed.
    E.g., paged-content-search/%node"), + '#default_value' => $this->options['search_endpoint'], + '#required' => FALSE, + ]; } /** @@ -520,4 +596,41 @@ public function getFormats() { return ['json' => 'json']; } + /** + * Submit handler for options form. + * + * Used to store the structured text media term by URL instead of Ttid. + * + * @param array $form + * The form. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The form state object. + */ + // @codingStandardsIgnoreStart + public function submitOptionsForm(&$form, FormStateInterface $form_state) { + // @codingStandardsIgnoreEnd + $style_options = $form_state->getValue('style_options'); + $tid = $style_options['structured_text_term']; + unset($style_options['structured_text_term']); + $term = $this->entityTypeManager->getStorage('taxonomy_term')->load($tid); + $style_options['structured_text_term_uri'] = $this->utils->getUriForTerm($term); + $form_state->setValue('style_options', $style_options); + parent::submitOptionsForm($form, $form_state); + } + + /** + * Get the structured text term. + * + * @return \Drupal\taxonomy\TermInterface|null + * The term if it could be found; otherwise, NULL. + */ + protected function getStructuredTextTerm() : ?TermInterface { + if (!$this->structuredTextTermMemoized) { + $this->structuredTextTermMemoized = TRUE; + $this->structuredTextTerm = $this->utils->getTermForUri($this->options['structured_text_term_uri']); + } + + return $this->structuredTextTerm; + } + } From 54206de71204691ef67a28b1036a8d5f7df0ad0a Mon Sep 17 00:00:00 2001 From: Adam <607975+adam-vessey@users.noreply.github.com> Date: Wed, 24 Apr 2024 14:13:41 -0300 Subject: [PATCH 230/252] Fix Functional Javascript CI tests (#1004) * Fixup js tests * Move MINK env var into phpunit for easier local testing * Fix xpath for 10.3 --------- Co-authored-by: Joe Corall --- .github/workflows/build-2.x.yml | 42 ++-- phpunit.xml | 2 +- .../views.view.test_integer_weight.yml | 221 ++++++++++-------- .../IntegerWeightTest.php | 39 ++-- 4 files changed, 165 insertions(+), 139 deletions(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index c5d9d66b0..8cd9f1d1e 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -1,30 +1,26 @@ -# This is a basic workflow to help you get started with Actions - name: CI -# Controls when the action will run. on: - # Triggers the workflow on push or pull request events but only for the 2.x branch push: branches: [ 2.x ] pull_request: branches: [ 2.x ] - - # Allows you to run this workflow manually from the Actions tab workflow_dispatch: -# A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: - # This workflow contains a single job called "build" build: - # The type of runner that the job will run on + env: + DRUPAL_VERSION: ${{ matrix.drupal-version }} + SCRIPT_DIR: ${{ github.workspace }}/islandora_ci + DRUPAL_DIR: /opt/drupal + PHPUNIT_FILE: ${{ github.workspace }}/build_dir/phpunit.xml + runs-on: ubuntu-latest continue-on-error: ${{ matrix.allowed_failure }} strategy: fail-fast: false matrix: php-versions: ["8.1", "8.2", "8.3"] - # test-suite functional-javascript will appear to pass but will skip tests; missing chromedriver. test-suite: ["kernel", "functional", "functional-javascript"] drupal-version: ["10.1.x", "10.2.x", "10.3.x-dev"] mysql: ["8.0"] @@ -51,17 +47,15 @@ jobs: - 61616:61616 - 61613:61613 - # Steps represent a sequence of tasks that will be executed as part of the job steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: path: build_dir - name: Checkout islandora_ci - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: islandora/islandora_ci ref: github-actions @@ -79,13 +73,6 @@ jobs: sudo apt-get remove -y mysql-client mysql-common sudo apt-get install -y mysql-client - - name: Set environment variables - run: | - echo "DRUPAL_VERSION=${{ matrix.drupal-version }}" >> $GITHUB_ENV - echo "SCRIPT_DIR=$GITHUB_WORKSPACE/islandora_ci" >> $GITHUB_ENV - echo "DRUPAL_DIR=/opt/drupal" >> $GITHUB_ENV - echo "PHPUNIT_FILE=$GITHUB_WORKSPACE/build_dir/phpunit.xml" >> $GITHUB_ENV - - name: Cache Composer dependencies uses: actions/cache@v3 with: @@ -118,8 +105,21 @@ jobs: - name: Test scripts run: $SCRIPT_DIR/travis_scripts.sh + + - name: Start chromedriver + if: matrix.test-suite == 'functional-javascript' + run: |- + /usr/local/share/chromedriver-linux64/chromedriver \ + --log-path=/tmp/chromedriver.log \ + --verbose \ + --allowed-ips= \ + --allowed-origins=* & - name: PHPUNIT tests run: | cd $DRUPAL_DIR/web/core $DRUPAL_DIR/vendor/bin/phpunit --verbose --testsuite "${{ matrix.test-suite }}" + + - name: Print chromedriver logs + if: matrix.test-suite == 'functional-javascript' + run: cat /tmp/chromedriver.log diff --git a/phpunit.xml b/phpunit.xml index 46e82e78d..bc0609fba 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -47,7 +47,7 @@ - + diff --git a/tests/modules/integer_weight_test_views/test_views/views.view.test_integer_weight.yml b/tests/modules/integer_weight_test_views/test_views/views.view.test_integer_weight.yml index 08dc4912a..9ccb76a81 100644 --- a/tests/modules/integer_weight_test_views/test_views/views.view.test_integer_weight.yml +++ b/tests/modules/integer_weight_test_views/test_views/views.view.test_integer_weight.yml @@ -4,6 +4,7 @@ dependencies: config: - node.type.repo_item module: + - islandora - node - user id: test_integer_weight @@ -13,87 +14,36 @@ description: '' tag: '' base_table: node_field_data base_field: nid -core: 8.x display: default: - display_plugin: default id: default display_title: Master + display_plugin: default position: 0 display_options: - access: - type: perm - options: - perm: 'access content' - cache: - type: tag - options: { } - query: - type: views_query - options: - disable_sql_rewrite: false - distinct: false - replica: false - query_comment: '' - query_tags: { } - exposed_form: - type: basic - options: - submit_button: Apply - reset_button: false - reset_button_label: Reset - exposed_sorts_label: 'Sort by' - expose_sort_order: true - sort_asc_label: Asc - sort_desc_label: Desc - pager: - type: mini - options: - items_per_page: 10 - offset: 0 - id: 0 - total_pages: null - expose: - items_per_page: false - items_per_page_label: 'Items per page' - items_per_page_options: '5, 10, 25, 50' - items_per_page_options_all: false - items_per_page_options_all_label: '- All -' - offset: false - offset_label: Offset - tags: - previous: ‹‹ - next: ›› - style: - type: table - row: - type: fields + title: 'test weight' fields: title: id: title table: node_field_data field: title + relationship: none + group_type: group + admin_label: '' entity_type: node entity_field: title + plugin_id: field + label: Title + exclude: false alter: alter_text: false make_link: false absolute: false - trim: false word_boundary: false ellipsis: false strip_tags: false + trim: false html: false - hide_empty: false - empty_zero: false - settings: - link_to_entity: true - plugin_id: field - relationship: none - group_type: group - admin_label: '' - label: Title - exclude: false element_type: '' element_class: '' element_label_type: '' @@ -103,9 +53,13 @@ display: element_wrapper_class: '' element_default_classes: true empty: '' + hide_empty: false + empty_zero: false hide_alter_empty: true click_sort_column: value type: string + settings: + link_to_entity: true group_column: value group_columns: { } group_rows: true @@ -123,7 +77,8 @@ display: relationship: none group_type: group admin_label: '' - label: 'Integer weight selector (field_integer_weight)' + plugin_id: integer_weight_selector + label: 'Integer Weight Selector (field_integer_weight)' exclude: false alter: alter_text: false @@ -164,44 +119,57 @@ display: hide_empty: false empty_zero: false hide_alter_empty: true - range: '20' - plugin_id: integer_weight_selector - filters: - status: - value: '1' - table: node_field_data - field: status - plugin_id: boolean - entity_type: node - entity_field: status - id: status + pager: + type: mini + options: + offset: 0 + items_per_page: 10 + total_pages: null + id: 0 + tags: + next: ›› + previous: ‹‹ expose: - operator: '' - group: 1 - type: - id: type - table: node_field_data - field: type - value: - repo_item:repo_item - entity_type: node - entity_field: type - plugin_id: bundle + items_per_page: false + items_per_page_label: 'Items per page' + items_per_page_options: '5, 10, 25, 50' + items_per_page_options_all: false + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + access: + type: perm + options: + perm: 'access content' + cache: + type: tag + options: { } + empty: { } sorts: created: id: created table: node_field_data field: created - order: DESC - entity_type: node - entity_field: created - plugin_id: date relationship: none group_type: group admin_label: '' - exposed: false + entity_type: node + entity_field: created + plugin_id: date + order: DESC expose: label: '' + exposed: false granularity: second field_integer_weight_value: id: field_integer_weight_value @@ -210,17 +178,82 @@ display: relationship: none group_type: group admin_label: '' + plugin_id: standard order: ASC + expose: + label: '' + field_identifier: '' + exposed: false + arguments: { } + filters: + status: + id: status + table: node_field_data + field: status + entity_type: node + entity_field: status + plugin_id: boolean + value: '1' + group: 1 + expose: + operator: '' + type: + id: type + table: node_field_data + field: type + relationship: none + group_type: group + admin_label: '' + entity_type: node + entity_field: type + plugin_id: bundle + operator: in + value: + repo_item: repo_item + group: 1 exposed: false expose: + operator_id: '' label: '' - plugin_id: standard - title: 'test weight' + description: '' + use_operator: false + operator: '' + operator_limit_selection: false + operator_list: { } + identifier: '' + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + reduce: false + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + style: + type: table + row: + type: fields + query: + type: views_query + options: + query_comment: '' + disable_sql_rewrite: false + distinct: false + replica: false + query_tags: { } + relationships: { } header: { } footer: { } - empty: { } - relationships: { } - arguments: { } display_extenders: { } cache_metadata: max-age: -1 @@ -232,9 +265,9 @@ display: - user.permissions tags: { } page_1: - display_plugin: page id: page_1 display_title: Page + display_plugin: page position: 1 display_options: display_extenders: { } diff --git a/tests/src/FunctionalJavascript/IntegerWeightTest.php b/tests/src/FunctionalJavascript/IntegerWeightTest.php index 2572c191e..5e10133c4 100644 --- a/tests/src/FunctionalJavascript/IntegerWeightTest.php +++ b/tests/src/FunctionalJavascript/IntegerWeightTest.php @@ -8,6 +8,7 @@ use Drupal\field\Entity\FieldStorageConfig; use Drupal\field\Entity\FieldConfig; use Drupal\node\Entity\Node; +use Drupal\views\Tests\ViewTestData; /** * Test integer weight selector. @@ -30,6 +31,7 @@ class IntegerWeightTest extends WebDriverTestBase { 'views', 'field_ui', 'integer_weight_test_views', + 'islandora', ]; /** @@ -82,27 +84,16 @@ class IntegerWeightTest extends WebDriverTestBase { */ public function setUp(): void { parent::setUp(); + $this->drupalCreateContentType([ + 'type' => 'repo_item', + 'name' => 'Repository Item', + ]); - $this->adminUser = $this->drupalCreateUser( - [ - 'administer content types', - 'administer node fields', - 'administer node display', - ] - ); - - // Create dummy repo_item type to sort (since we don't have - // repository_object without islandora_defaults). - $type = $this->container->get('entity_type.manager')->getStorage('node_type') - ->create([ - 'type' => 'repo_item', - 'name' => 'Repository Item', - ]); - $type->save(); - $this->container->get('router.builder')->rebuild(); + $account = $this->createUser(['edit any repo_item content'], 'test', TRUE); + $this->drupalLogin($account); $fieldStorage = FieldStorageConfig::create([ - 'fieldName' => static::$fieldName, + 'field_name' => static::$fieldName, 'entity_type' => 'node', 'type' => static::$fieldType, ]); @@ -124,16 +115,18 @@ public function setUp(): void { $this->nodes[] = $node; } - ViewsTestData::createTestViews(get_class($this), ['integer_weight_test_views']); + ViewTestData::createTestViews(get_class($this), ['integer_weight_test_views']); } /** * Test integer weight selector. */ public function testIntegerWeightSelector() { - $this->drupalGet('test-integer-weight'); - $page = $this->getSession()->getPage(); + $web_assert = $this->assertSession(); + $this->drupalGet('/test-integer-weight'); + $web_assert->pageTextContains('Item 1'); + $page = $this->getSession()->getPage(); $weight_select1 = $page->findField("field_integer_weight[0][weight]"); $weight_select2 = $page->findField("field_integer_weight[1][weight]"); $weight_select3 = $page->findField("field_integer_weight[2][weight]"); @@ -153,8 +146,8 @@ public function testIntegerWeightSelector() { $this->assertSession()->pageTextNotContains('You have unsaved changes.'); // Drag and drop 'Item 1' over 'Item 2'. - $dragged = $this->xpath("//tr[@class='draggable'][1]//a[@class='tabledrag-handle']")[0]; - $target = $this->xpath("//tr[@class='draggable'][2]//a[@class='tabledrag-handle']")[0]; + $dragged = $this->xpath("//tr[contains(@class, 'draggable')][1]//a[contains(@class, 'tabledrag-handle')]")[0]; + $target = $this->xpath("//tr[contains(@class, 'draggable')][2]//a[contains(@class, 'tabledrag-handle')]")[0]; $dragged->dragTo($target); // Pause for javascript to do it's thing. From c80769580cdc8e722b9d28be0b87beef4f803d70 Mon Sep 17 00:00:00 2001 From: Aron Novak Date: Wed, 24 Apr 2024 18:46:01 +0000 Subject: [PATCH 231/252] Do not have a fatal error on a missing action (#1014) --- src/PresetReaction/PresetReaction.php | 29 ++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/PresetReaction/PresetReaction.php b/src/PresetReaction/PresetReaction.php index 98aa69462..4ebd68235 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -7,6 +7,7 @@ use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Psr\Log\LoggerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -21,12 +22,20 @@ class PresetReaction extends ContextReactionPluginBase implements ContainerFacto */ protected $actionStorage; + /** + * The logger. + * + * @var \Psr\Log\LoggerInterface + */ + protected $logger; + /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityStorageInterface $action_storage) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityStorageInterface $action_storage, LoggerInterface $logger) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->actionStorage = $action_storage; + $this->logger = $logger; } /** @@ -37,7 +46,8 @@ public static function create(ContainerInterface $container, array $configuratio $configuration, $plugin_id, $plugin_definition, - $container->get('entity_type.manager')->getStorage('action') + $container->get('entity_type.manager')->getStorage('action'), + $container->get('logger.factory')->get('islandora') ); } @@ -56,7 +66,20 @@ public function execute(EntityInterface $entity = NULL) { $action_ids = $config['actions']; foreach ($action_ids as $action_id) { $action = $this->actionStorage->load($action_id); - $action->execute([$entity]); + if (empty($action)) { + $this->logger->warning('Action "@action" not found.', ['@action' => $action_id]); + continue; + } + try { + $action->execute([$entity]); + } + catch (\Exception $e) { + $this->logger->error('Error executing action "@action" on entity "@entity": @message', [ + '@action' => $action->label(), + '@entity' => $entity->label(), + '@message' => $e->getMessage(), + ]); + } } } From 3902cce0ac7525aa209e56f198d5059f4c42e09a Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 1 May 2024 14:41:48 -0300 Subject: [PATCH 232/252] Allow filehash 3 (#1016) --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index cb95bbc6e..79d5ef5a4 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "drupal/ctools": "^3.8 || ^4", "drupal/eva" : "^3.0", "drupal/file_replace": "^1.1", - "drupal/filehash": "^2", + "drupal/filehash": "^2 || ^3", "drupal/flysystem" : "^2.0@alpha", "drupal/jwt": "^1.1 || ^2", "drupal/migrate_plus" : "^5.1 || ^6", From 5e958a5e10715f67e5c6341efabaeaee5a66149f Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Sat, 11 May 2024 08:29:03 -0700 Subject: [PATCH 233/252] Allow application/xml in OCR Action. --- .../src/Plugin/Action/GenerateOCRDerivative.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php b/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php index 272e9f01b..e60931a85 100644 --- a/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php +++ b/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php @@ -48,8 +48,9 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta */ public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { parent::validateConfigurationForm($form, $form_state); - $exploded_mime = explode('/', $form_state->getValue('mimetype')); - if ($exploded_mime[0] != 'text') { + $mime = $form_state->getValue('mimetype'); + $exploded_mime = explode('/', $mime); + if ($exploded_mime[0] != 'text' && $mime != 'application/xml') { $form_state->setErrorByName( 'mimetype', $this->t('Please enter file mimetype (e.g. text/plain.)') From da47bcfb081fc9f42fa547de124431c375a3f76c Mon Sep 17 00:00:00 2001 From: Akanksha Singh Date: Thu, 16 May 2024 12:46:26 -0300 Subject: [PATCH 234/252] Node has Parent context does not explicitly check if the field exists. (#1019) * Check that the field exists on node * Early exit with disabled check --- src/IslandoraContextManager.php | 2 +- src/Plugin/Condition/NodeHasParent.php | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/IslandoraContextManager.php b/src/IslandoraContextManager.php index 9fd93fbc2..ed6f74af9 100644 --- a/src/IslandoraContextManager.php +++ b/src/IslandoraContextManager.php @@ -37,7 +37,7 @@ public function evaluateContexts(array $provided = []) { } /** @var \Drupal\context\ContextInterface $context */ foreach ($this->getContexts() as $context) { - if ($this->evaluateContextConditions($context, $provided) && !$context->disabled()) { + if (!$context->disabled() && $this->evaluateContextConditions($context, $provided)) { $this->activeContexts[$context->id()] = $context; } } diff --git a/src/Plugin/Condition/NodeHasParent.php b/src/Plugin/Condition/NodeHasParent.php index f9ef0cbf5..813fd00b1 100644 --- a/src/Plugin/Condition/NodeHasParent.php +++ b/src/Plugin/Condition/NodeHasParent.php @@ -137,9 +137,11 @@ public function evaluate() { * TRUE if entity references the specified parent. */ protected function evaluateEntity(EntityInterface $entity) { + $parent_reference_field = $this->configuration['parent_reference_field']; foreach ($entity->referencedEntities() as $referenced_entity) { - if ($entity->getEntityTypeID() == 'node' && $referenced_entity->getEntityTypeId() == 'node') { - $parent_reference_field = $this->configuration['parent_reference_field']; + // Check whether the entity and the referenced entity are nodes. + // Also make sure that the field exists. + if ($entity->getEntityTypeID() == 'node' && $entity->hasField($parent_reference_field) && $referenced_entity->getEntityTypeId() == 'node') { $field = $entity->get($parent_reference_field); if (!$field->isEmpty()) { $nids = $field->getValue(); From b8f0b9c96601d952d69a7e067ac614568d78154c Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 16 May 2024 17:12:26 -0300 Subject: [PATCH 235/252] Allow NodeHasMediaUse view filter to work on views with node relationships. (#1010) * Adjust addition of where clause. * Bit of other paranoia with aliases. * Dependency injection in NodeHasMediaUse views filter. --------- Co-authored-by: Adam Vessey --- src/Plugin/views/filter/NodeHasMediaUse.php | 74 +++++++++++++++++---- 1 file changed, 62 insertions(+), 12 deletions(-) diff --git a/src/Plugin/views/filter/NodeHasMediaUse.php b/src/Plugin/views/filter/NodeHasMediaUse.php index 3c69bddd5..1686c4217 100644 --- a/src/Plugin/views/filter/NodeHasMediaUse.php +++ b/src/Plugin/views/filter/NodeHasMediaUse.php @@ -2,8 +2,13 @@ namespace Drupal\islandora\Plugin\views\filter; +use Drupal\Core\Database\Connection; +use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\islandora\IslandoraUtils; use Drupal\views\Plugin\views\filter\FilterPluginBase; +use Psr\Log\LoggerInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Views Filter on Having Media of a Type. @@ -14,6 +19,48 @@ */ class NodeHasMediaUse extends FilterPluginBase { + /** + * Islandora's utility service. + * + * @var \Drupal\islandora\IslandoraUtils + */ + protected IslandoraUtils $utils; + + /** + * Drupal's entity type manager service. + * + * @var \Drupal\Core\Entity\EntityTypeManagerInterface + */ + protected EntityTypeManagerInterface $entityTypeManager; + + /** + * Drupal's database connection service. + * + * @var \Drupal\Core\Database\Connection + */ + protected Connection $connection; + + /** + * Logger service. + * + * @var \Psr\Log\LoggerInterface + */ + protected LoggerInterface $logger; + + /** + * {@inheritDoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition); + + $instance->utils = $container->get('islandora.utils'); + $instance->entityTypeManager = $container->get('entity_type.manager'); + $instance->connection = $container->get('database'); + $instance->logger = $container->get('logger.factory')->get('islanodra'); + + return $instance; + } + /** * {@inheritdoc} */ @@ -29,7 +76,7 @@ protected function defineOptions() { */ public function validateOptionsForm(&$form, FormStateInterface $form_state) { $uri = $form_state->getValues()['options']['use_uri']; - $term = \Drupal::service('islandora.utils')->getTermForUri($uri); + $term = $this->utils->getTermForUri($uri); if (empty($term)) { $form_state->setError($form['use_uri'], $this->t('Could not find term with URI: "%uri"', ['%uri' => $uri])); } @@ -39,7 +86,7 @@ public function validateOptionsForm(&$form, FormStateInterface $form_state) { * {@inheritdoc} */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { - $terms = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadByProperties(['vid' => 'islandora_media_use']); + $terms = $this->entityTypeManager->getStorage('taxonomy_term')->loadByProperties(['vid' => 'islandora_media_use']); $uris = []; foreach ($terms as $term) { foreach ($term->get('field_external_uri')->getValue() as $uri) { @@ -67,7 +114,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { */ public function adminSummary() { $operator = ($this->options['negated']) ? "does not have" : "has"; - $term = \Drupal::service('islandora.utils')->getTermForUri($this->options['use_uri']); + $term = $this->utils->getTermForUri($this->options['use_uri']); $label = (empty($term)) ? 'BROKEN TERM URI' : $term->label(); return "Node {$operator} a '{$label}' media"; } @@ -77,18 +124,21 @@ public function adminSummary() { */ public function query() { $condition = ($this->options['negated']) ? 'NOT IN' : 'IN'; - $utils = \Drupal::service('islandora.utils'); - $term = $utils->getTermForUri($this->options['use_uri']); + $term = $this->utils->getTermForUri($this->options['use_uri']); if (empty($term)) { - \Drupal::logger('islandora')->warning('Node Has Media Filter could not find term with URI: "%uri"', ['%uri' => $this->options['use_uri']]); + $this->logger->warning('Node Has Media Filter could not find term with URI: "%uri"', ['%uri' => $this->options['use_uri']]); return; } - $sub_query = \Drupal::database()->select('media', 'm'); - $sub_query->join('media__field_media_use', 'use', 'm.mid = use.entity_id'); - $sub_query->join('media__field_media_of', 'of', 'm.mid = of.entity_id'); - $sub_query->fields('of', ['field_media_of_target_id']) - ->condition('use.field_media_use_target_id', $term->id()); - $this->query->addWhere(0, 'nid', $sub_query, $condition); + $sub_query = $this->connection->select('media', 'm'); + $use_alias = $sub_query->join('media__field_media_use', 'use', 'm.mid = %alias.entity_id'); + $of_alias = $sub_query->join('media__field_media_of', 'of', 'm.mid = %alias.entity_id'); + $sub_query->fields($of_alias, ['field_media_of_target_id']) + ->condition("{$use_alias}.field_media_use_target_id", $term->id()); + + /** @var \Drupal\views\Plugin\views\query\Sql $query */ + $query = $this->query; + $alias = $query->ensureTable('node_field_data', $this->relationship); + $query->addWhere(0, "{$alias}.nid", $sub_query, $condition); } } From 71d131a2ee9acbc0191669ba12abc6f81d6adde6 Mon Sep 17 00:00:00 2001 From: Alan Stanley Date: Thu, 30 May 2024 11:39:57 -0300 Subject: [PATCH 236/252] Deletion abstraction (#1017) * Change to Boolean logic * remove accidental newline * abstracted media and file deletion * abstracted media and file deletion * codered * fixed test * Update IslandoraUtils.php Fixed PHPDoc * Update IslandoraUtils.php Tweaked PHPDocs * Type hint * More complete parameter description --------- Co-authored-by: Rosie Le Faive --- islandora.module | 130 ++--------------------- islandora.services.yml | 2 +- src/Form/ConfirmDeleteMediaAndFile.php | 118 +++----------------- src/IslandoraUtils.php | 94 ++++++++++++++-- tests/src/Functional/DeleteMediaTest.php | 2 +- 5 files changed, 117 insertions(+), 229 deletions(-) diff --git a/islandora.module b/islandora.module index d715db52d..8fa478a7f 100644 --- a/islandora.module +++ b/islandora.module @@ -16,19 +16,18 @@ use Drupal\Component\Plugin\Exception\PluginNotFoundException; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; +use Drupal\Core\Entity\EntityForm; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Site\Settings; use Drupal\Core\Url; +use Drupal\file\FileInterface; use Drupal\islandora\Form\IslandoraSettingsForm; -use Drupal\node\NodeInterface; use Drupal\media\MediaInterface; -use Drupal\file\FileInterface; -use Drupal\taxonomy\TermInterface; -use Drupal\Core\Routing\RouteMatchInterface; +use Drupal\node\NodeInterface; use Drupal\serialization\Normalizer\CacheableNormalizerInterface; -use Drupal\Core\Entity\EntityForm; -use Drupal\file\Entity\File; +use Drupal\taxonomy\TermInterface; /** * Implements hook_help(). @@ -408,132 +407,25 @@ function islandora_media_custom_form_submit(&$form, FormStateInterface $form_sta * Implements a submit handler for the delete form. */ function islandora_object_delete_form_submit($form, FormStateInterface $form_state) { - $result = $form_state->getValues('delete_associated_content'); - $utils = \Drupal::service('islandora.utils'); - if ($result['delete_associated_content'] == 1) { - + $utils = \Drupal::service('islandora.utils'); $node = $form_state->getFormObject()->getEntity(); $medias = $utils->getMedia($node); - $media_list = []; - - $entity_field_manager = \Drupal::service('entity_field.manager'); - $current_user = \Drupal::currentUser(); + $results = $utils->deleteMediaAndFiles($medias); $logger = \Drupal::logger('logger.channel.islandora'); $messenger = \Drupal::messenger(); - - $delete_media = []; - $media_translations = []; - $media_files = []; - $entity_protected_medias = []; - $inaccessible_entities = []; - - foreach ($medias as $id => $media) { - $lang = $media->language()->getId(); - $selected_langcodes[$lang] = $lang; - - if (!$media->access('delete', $current_user)) { - $inaccessible_entities[] = $media; - continue; - } - // Check for files. - $fields = $entity_field_manager->getFieldDefinitions('media', $media->bundle()); - foreach ($fields as $field) { - $type = $field->getType(); - if ($type == 'file' || $type == 'image') { - $target_id = $media->get($field->getName())->target_id; - $file = File::load($target_id); - if ($file) { - if (!$file->access('delete', $current_user)) { - $inaccessible_entities[] = $file; - continue; - } - $media_files[$id][$file->id()] = $file; - } - } - } - - foreach ($selected_langcodes as $langcode) { - // We're only working with media, which are translatable. - $entity = $media->getTranslation($langcode); - if ($entity->isDefaultTranslation()) { - $delete_media[$id] = $entity; - unset($media_translations[$id]); - } - elseif (!isset($delete_media[$id])) { - $media_translations[$id][] = $entity; - } - } + if (isset($results['inaccessible'])) { + $messenger->addWarning($results['inaccessible']); } - - if ($delete_media) { - foreach ($delete_media as $id => $media) { - try { - $media->delete(); - $media_list[] = $id; - $logger->notice('The media %label has been deleted.', [ - '%label' => $media->label(), - ]); - } - catch (Exception $e) { - $entity_protected_medias[] = $id; - } - } - } - - $delete_files = array_filter($media_files, function ($media) use ($entity_protected_medias) { - return !in_array($media, $entity_protected_medias); - }, ARRAY_FILTER_USE_KEY); - - if ($delete_files) { - foreach ($delete_files as $files_array) { - foreach ($files_array as $file) { - $file->delete(); - $logger->notice('The file %label has been deleted.', [ - '%label' => $file->label(), - ]); - } - } - } - - $delete_media_translations = array_filter($media_translations, function ($media) use ($entity_protected_medias) { - return !in_array($media, $entity_protected_medias); - }, ARRAY_FILTER_USE_KEY); - - if ($delete_media_translations) { - foreach ($delete_media_translations as $id => $translations) { - $media = $medias[$id]; - foreach ($translations as $translation) { - $media->removeTranslation($translation->language()->getId()); - } - $media->save(); - foreach ($translations as $translation) { - $logger->notice('The media %label @language translation has been deleted', [ - '%label' => $media->label(), - '@language' => $translation->language()->getName(), - ]); - } - } - } - - if ($inaccessible_entities) { - $messenger->addWarning("@count items have not been deleted because you do not have the necessary permissions.", [ - '@count' => count($inaccessible_entities), - ]); - } - + $logger->notice($results['deleted']); $build = [ 'heading' => [ '#type' => 'html_tag', '#tag' => 'div', '#value' => t("The repository item @node and @media", [ '@node' => $node->getTitle(), - '@media' => \Drupal::translation()->formatPlural( - count($media_list), 'the media with the id @media has been deleted.', - 'the medias with the ids @media have been deleted.', - ['@media' => implode(", ", $media_list)], - ), + '@media' => $results['deleted'], ]), ], ]; diff --git a/islandora.services.yml b/islandora.services.yml index 74725d803..36ef7dac3 100644 --- a/islandora.services.yml +++ b/islandora.services.yml @@ -54,7 +54,7 @@ services: arguments: ['@entity_type.manager', '@current_user', '@language_manager', '@file_system', '@islandora.utils'] islandora.utils: class: Drupal\islandora\IslandoraUtils - arguments: ['@entity_type.manager', '@entity_field.manager', '@context.manager', '@flysystem_factory', '@language_manager'] + arguments: ['@entity_type.manager', '@entity_field.manager', '@context.manager', '@flysystem_factory', '@language_manager', '@current_user'] islandora.entity_mapper: class: Islandora\EntityMapper\EntityMapper islandora.stomp.auth_header_listener: diff --git a/src/Form/ConfirmDeleteMediaAndFile.php b/src/Form/ConfirmDeleteMediaAndFile.php index a9613871f..90e61878a 100644 --- a/src/Form/ConfirmDeleteMediaAndFile.php +++ b/src/Form/ConfirmDeleteMediaAndFile.php @@ -2,7 +2,6 @@ namespace Drupal\islandora\Form; -use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Entity\Form\DeleteMultipleForm; use Drupal\Core\Form\FormStateInterface; @@ -10,8 +9,7 @@ use Drupal\Core\Session\AccountInterface; use Drupal\Core\TempStore\PrivateTempStoreFactory; use Drupal\Core\Url; -use Drupal\file\Entity\File; -use Drupal\islandora\MediaSource\MediaSourceService; +use Drupal\islandora\IslandoraUtils; use Psr\Log\LoggerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -21,11 +19,11 @@ class ConfirmDeleteMediaAndFile extends DeleteMultipleForm { /** - * Media source service. + * The current user. * - * @var \Drupal\islandora\MediaSource\MediaSourceService + * @var \Drupal\Core\Session\AccountInterface */ - protected $mediaSourceService; + protected $currentUser; /** * Logger. @@ -42,23 +40,22 @@ class ConfirmDeleteMediaAndFile extends DeleteMultipleForm { protected $selection = []; /** - * Entity field manager. + * The Islandora Utils service. * - * @var \Drupal\Core\Entity\EntityFieldManagerInterface + * @var \Drupal\islandora\IslandoraUtils */ - protected $entityFieldManager; + protected IslandoraUtils $utils; /** * {@inheritdoc} */ - public function __construct(AccountInterface $current_user, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, PrivateTempStoreFactory $temp_store_factory, MessengerInterface $messenger, MediaSourceService $media_source_service, LoggerInterface $logger) { + public function __construct(AccountInterface $current_user, EntityTypeManagerInterface $entity_type_manager, PrivateTempStoreFactory $temp_store_factory, MessengerInterface $messenger, LoggerInterface $logger, IslandoraUtils $utils) { $this->currentUser = $current_user; $this->entityTypeManager = $entity_type_manager; - $this->entityFieldManager = $entity_field_manager; $this->tempStore = $temp_store_factory->get('media_and_file_delete_confirm'); $this->messenger = $messenger; - $this->mediaSourceService = $media_source_service; $this->logger = $logger; + $this->utils = $utils; } /** @@ -68,11 +65,11 @@ public static function create(ContainerInterface $container) { return new static( $container->get('current_user'), $container->get('entity_type.manager'), - $container->get('entity_field.manager'), $container->get('tempstore.private'), $container->get('messenger'), - $container->get('islandora.media_source_service'), - $container->get('logger.channel.islandora')); + $container->get('logger.channel.islandora'), + $container->get('islandora.utils') + ); } /** @@ -111,94 +108,13 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t public function submitForm(array &$form, FormStateInterface $form_state) { // Similar to parent::submitForm(), but let's blend in the related files and // optimize based on the fact that we know we're working with media. - $total_count = 0; - $delete_media = []; - $delete_media_translations = []; - $delete_files = []; - $inaccessible_entities = []; $media_storage = $this->entityTypeManager->getStorage('media'); - $file_storage = $this->entityTypeManager->getStorage('file'); $media = $media_storage->loadMultiple(array_keys($this->selection)); - foreach ($this->selection as $id => $selected_langcodes) { - $entity = $media[$id]; - if (!$entity->access('delete', $this->currentUser)) { - $inaccessible_entities[] = $entity; - continue; - } - // Check for files. - $fields = $this->entityFieldManager->getFieldDefinitions('media', $entity->bundle()); - foreach ($fields as $field) { - if ($field->getName() == 'thumbnail') { - continue; - } - $type = $field->getType(); - if ($type == 'file' || $type == 'image') { - $target_id = $entity->get($field->getName())->target_id; - $file = File::load($target_id); - if ($file) { - if (!$file->access('delete', $this->currentUser)) { - $inaccessible_entities[] = $file; - continue; - } - if (!array_key_exists($file->id(), $delete_files)) { - $delete_files[$file->id()] = $file; - $total_count++; - } - - } - } - } - - foreach ($selected_langcodes as $langcode) { - // We're only working with media, which are translatable. - $entity = $entity->getTranslation($langcode); - if ($entity->isDefaultTranslation()) { - $delete_media[$id] = $entity; - unset($delete_media_translations[$id]); - $total_count += count($entity->getTranslationLanguages()); - } - elseif (!isset($delete_media[$id])) { - $delete_media_translations[$id][] = $entity; - } - } - } - if ($delete_media) { - $media_storage->delete($delete_media); - foreach ($delete_media as $entity) { - $this->logger->notice('The media %label has been deleted.', [ - '%label' => $entity->label(), - ]); - } - } - if ($delete_files) { - $file_storage->delete($delete_files); - foreach ($delete_files as $entity) { - $this->logger->notice('The file %label has been deleted.', [ - '%label' => $entity->label(), - ]); - } - } - if ($delete_media_translations) { - foreach ($delete_media_translations as $id => $translations) { - $entity = $media[$id]; - foreach ($translations as $translation) { - $entity->removeTranslation($translation->language()->getId()); - } - $entity->save(); - foreach ($translations as $translation) { - $this->logger->notice('The media %label @language translation has been deleted', [ - '%label' => $entity->label(), - '@language' => $translation->language()->getName(), - ]); - } - $total_count += count($translations); - } - } - if ($total_count) { - $this->messenger->addStatus($this->getDeletedMessage($total_count)); - } - if ($inaccessible_entities) { - $this->messenger->addWarning($this->getInaccessibleMessage(count($inaccessible_entities))); + $results = $this->utils->deleteMediaAndFiles($media); + $this->logger->notice($results['deleted']); + $this->messenger->addStatus($results['deleted']); + if (isset($results['inaccessible'])) { + $this->messenger->addWarning($results['inaccessible']); } $this->tempStore->delete($this->currentUser->id()); $form_state->setRedirectUrl($this->getCancelUrl()); diff --git a/src/IslandoraUtils.php b/src/IslandoraUtils.php index a2df75896..5d667fc42 100644 --- a/src/IslandoraUtils.php +++ b/src/IslandoraUtils.php @@ -10,7 +10,9 @@ use Drupal\Core\Entity\Query\QueryException; use Drupal\Core\Entity\Query\QueryInterface; use Drupal\Core\Language\LanguageManagerInterface; +use Drupal\Core\Session\AccountInterface; use Drupal\Core\Site\Settings; +use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\Url; use Drupal\file\FileInterface; use Drupal\flysystem\FlysystemFactory; @@ -26,13 +28,15 @@ * Utility functions for figuring out when to fire derivative reactions. */ class IslandoraUtils { - + use StringTranslationTrait; const EXTERNAL_URI_FIELD = 'field_external_uri'; const MEDIA_OF_FIELD = 'field_media_of'; const MEDIA_USAGE_FIELD = 'field_media_use'; + const MEMBER_OF_FIELD = 'field_member_of'; + const MODEL_FIELD = 'field_model'; /** @@ -68,7 +72,14 @@ class IslandoraUtils { * * @var \Drupal\Core\Language\LanguageManagerInterface */ - protected $languageManager; + protected LanguageManagerInterface $languageManager; + + /** + * The current user. + * + * @var \Drupal\Core\Session\AccountInterface + */ + protected AccountInterface $currentUser; /** * Constructor. @@ -83,19 +94,23 @@ class IslandoraUtils { * Flysystem factory. * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager * Language manager. + * @param \Drupal\Core\Session\AccountInterface $current_user + * The current user. */ public function __construct( EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, ContextManager $context_manager, FlysystemFactory $flysystem_factory, - LanguageManagerInterface $language_manager + LanguageManagerInterface $language_manager, + AccountInterface $current_user ) { $this->entityTypeManager = $entity_type_manager; $this->entityFieldManager = $entity_field_manager; $this->contextManager = $context_manager; $this->flysystemFactory = $flysystem_factory; $this->languageManager = $language_manager; + $this->currentUser = $current_user; } /** @@ -423,7 +438,6 @@ public function executeDerivativeReactions($reaction_type, NodeInterface $node, * TRUE if the fields have changed. */ public function haveFieldsChanged(ContentEntityInterface $entity, ContentEntityInterface $original) { - $field_definitions = $this->entityFieldManager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle()); $ignore_list = ['vid' => 1, 'changed' => 1, 'path' => 1]; @@ -528,7 +542,8 @@ public function getMediaReferencingNodeAndTerm(NodeInterface $node, TermInterfac * Array of fields. */ public function getReferencingFields($entity_type, $target_type) { - $fields = $this->entityTypeManager->getStorage('field_storage_config')->getQuery() + $fields = $this->entityTypeManager->getStorage('field_storage_config') + ->getQuery() ->condition('entity_type', $entity_type) ->condition('settings.target_type', $target_type) ->execute(); @@ -657,8 +672,6 @@ public function isIslandoraType($entity_type, $bundle) { public function canCreateIslandoraEntity($entity_type, $bundle_type) { $bundles = $this->entityTypeManager->getStorage($bundle_type)->loadMultiple(); $access_control_handler = $this->entityTypeManager->getAccessControlHandler($entity_type); - - $allowed = []; foreach (array_keys($bundles) as $bundle) { // Skip bundles that aren't 'Islandora' types. if (!$this->isIslandoraType($entity_type, $bundle)) { @@ -755,4 +768,71 @@ protected function getParentsByEntityReference(ContentEntityInterface $entity, a return $parents; } + /** + * Deletes Media and all associated files. + * + * @param \Drupal\media\MediaInterface[] $media + * Array of media objects to be deleted along with their files. + * + * @return array + * Associative array keyed 'deleted' and 'inaccessible'. + * + * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException + * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException + * @throws \Drupal\Core\Entity\EntityStorageException + */ + public function deleteMediaAndFiles(array $media) { + $results = []; + $delete_media = []; + $delete_files = []; + $inaccessible_entities = []; + $media_storage = $this->entityTypeManager->getStorage('media'); + $file_storage = $this->entityTypeManager->getStorage('file'); + foreach ($media as $entity) { + if (!$entity->access('delete', $this->currentUser)) { + $inaccessible_entities[] = $entity; + continue; + } + else { + $delete_media[$entity->id()] = $entity; + } + // Check for source and additional files. + $fields = $this->entityFieldManager->getFieldDefinitions('media', $entity->bundle()); + foreach ($fields as $field) { + if ($field->getName() == 'thumbnail') { + continue; + } + $type = $field->getType(); + if ($type == 'file' || $type == 'image') { + $target_id = $entity->get($field->getName())->target_id; + $file = $file_storage->load($target_id); + if ($file) { + if (!$file->access('delete', $this->currentUser)) { + $inaccessible_entities[] = $file; + continue; + } + if (!array_key_exists($file->id(), $delete_files)) { + $delete_files[$file->id()] = $file; + } + } + } + } + } + if ($delete_media) { + $media_storage->delete($delete_media); + } + if ($delete_files) { + $file_storage->delete($delete_files); + } + $results['deleted'] = $this->formatPlural( + count($delete_media), 'The media with the id @media has been deleted.', + 'The medias with the ids @media have been deleted.', + ['@media' => implode(", ", array_keys($delete_media))], + ); + if ($inaccessible_entities) { + $results['inaccessible'] = $this->formatPlural($inaccessible_entities, "@count item has not been deleted because you do not have the necessary permissions.", "@count items have not been deleted because you do not have the necessary permissions."); + } + return $results; + } + } diff --git a/tests/src/Functional/DeleteMediaTest.php b/tests/src/Functional/DeleteMediaTest.php index c52eca31f..957146fdc 100644 --- a/tests/src/Functional/DeleteMediaTest.php +++ b/tests/src/Functional/DeleteMediaTest.php @@ -93,7 +93,7 @@ public function testDeleteMediaAndFile() { $this->assertSession()->pageTextContains('Are you sure you want to delete this media and associated files?'); $page->pressButton('Delete'); // Should assert that a media and file were deleted. - $this->assertSession()->pageTextContains('Deleted 2 items.'); + $this->assertSession()->pageTextContains("The media with the id $mid has been deleted"); // Attempt to reload the entities. // Both media and file should be gone. From 780cf6efb93aa8e1c4257a4d921f5303795b19e9 Mon Sep 17 00:00:00 2001 From: Adam <607975+adam-vessey@users.noreply.github.com> Date: Mon, 3 Jun 2024 17:38:10 -0300 Subject: [PATCH 237/252] Only generate tokens for our Islandora-esque nodes. (#1025) --- islandora.tokens.inc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/islandora.tokens.inc b/islandora.tokens.inc index f528dee3d..d2c424c53 100644 --- a/islandora.tokens.inc +++ b/islandora.tokens.inc @@ -80,6 +80,9 @@ function islandora_tokens($type, $tokens, array $data, array $options, Bubbleabl return; } $islandoraUtils = \Drupal::service('islandora.utils'); + if (!$islandoraUtils->isIslandoraType('node', $data['node']->bundle())) { + return; + } foreach ($tokens as $name => $original) { switch ($name) { case 'media-original-file:basename': From 3f42453cd478e572473b37c0634e022bec4c0b3c Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 6 Jun 2024 08:48:33 -0300 Subject: [PATCH 238/252] Require Jsonld at the drupal namespace. (#1023) --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 79d5ef5a4..9a3c693e8 100644 --- a/composer.json +++ b/composer.json @@ -20,6 +20,7 @@ "drupal/file_replace": "^1.1", "drupal/filehash": "^2 || ^3", "drupal/flysystem" : "^2.0@alpha", + "drupal/jsonld": "^2 || ^3", "drupal/jwt": "^1.1 || ^2", "drupal/migrate_plus" : "^5.1 || ^6", "drupal/migrate_source_csv" : "^3.4", @@ -28,7 +29,6 @@ "drupal/token" : "^1.3", "islandora/chullo": "^2.0", "islandora/fedora-entity-mapper": "^1.0", - "islandora/jsonld": "^2 || ^3", "stomp-php/stomp-php": "4.* || ^5" }, "require-dev": { From e36ad1701cb5742d4b17e26de2bea957e1579728 Mon Sep 17 00:00:00 2001 From: Adam <607975+adam-vessey@users.noreply.github.com> Date: Tue, 18 Jun 2024 18:43:02 -0300 Subject: [PATCH 239/252] Fix use of batch methods from decorated services. (#1027) --- .../AbstractFileSelectionForm.php | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/Form/AddChildrenWizard/AbstractFileSelectionForm.php b/src/Form/AddChildrenWizard/AbstractFileSelectionForm.php index 6aeed8795..445c251e9 100644 --- a/src/Form/AddChildrenWizard/AbstractFileSelectionForm.php +++ b/src/Form/AddChildrenWizard/AbstractFileSelectionForm.php @@ -142,16 +142,46 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $builder = (new BatchBuilder()) ->setTitle($this->t('Bulk creating...')) ->setInitMessage($this->t('Initializing...')) - ->setFinishCallback([$this->batchProcessor, 'batchProcessFinished']); + ->setFinishCallback([$this, 'batchProcessFinished']); $values = $form_state->getValue($this->getField($cached_values)->getName()); $massaged_values = $widget->massageFormValues($values, $form, $form_state); foreach ($massaged_values as $delta => $info) { $builder->addOperation( - [$this->batchProcessor, 'batchOperation'], + [$this, 'batchOperation'], [$delta, $info, $cached_values] ); } batch_set($builder->toArray()); } + /** + * Wrap batch processor operation call to side-step serialization issues. + * + * Previously, we referred to the method on the processors directly; however, + * this can lead to issues regarding the (un)serialization of the services as + * which the processors are implemented. For example, if decorating one of the + * processors to extend it, it loses the reference back to be able to load the + * "inner"/decorated processor. + * + * @see \Drupal\islandora\Form\AddChildrenWizard\AbstractBatchProcessor::batchOperation() + */ + public function batchOperation($delta, $info, $cached_values, &$context) : void { + $this->batchProcessor->batchOperation($delta, $info, $cached_values, $context); + } + + /** + * Wrap batch processor finished call to side-step serialization issues. + * + * Previously, we referred to the method on the processors directly; however, + * this can lead to issues regarding the (un)serialization of the services as + * which the processors are implemented. For example, if decorating one of the + * processors to extend it, it loses the reference back to be able to load the + * "inner"/decorated processor. + * + * @see \Drupal\islandora\Form\AddChildrenWizard\AbstractBatchProcessor::batchProcessFinished() + */ + public function batchProcessFinished($success, $results, $operations) : void { + $this->batchProcessor->batchProcessFinished($success, $results, $operations); + } + } From 849b12af4f6025db33860da3af2583fc625bb0b3 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 26 Jun 2024 18:24:54 -0300 Subject: [PATCH 240/252] D10.3 (#1032) * Deprecate 10.1, add 10.4.x-dev. * Correct permission list. --- .github/workflows/build-2.x.yml | 6 +----- islandora.info.yml | 2 +- tests/src/Functional/DeleteMediaTest.php | 7 +------ tests/src/Functional/JsonldTypeAlterReactionTest.php | 10 +--------- 4 files changed, 4 insertions(+), 21 deletions(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index 8cd9f1d1e..8677ddf4e 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -22,13 +22,9 @@ jobs: matrix: php-versions: ["8.1", "8.2", "8.3"] test-suite: ["kernel", "functional", "functional-javascript"] - drupal-version: ["10.1.x", "10.2.x", "10.3.x-dev"] + drupal-version: ["10.2.x", "10.3.x", "10.4.x-dev"] mysql: ["8.0"] allowed_failure: [false] - exclude: - - php-versions: "8.3" - drupal-version: "10.1.x" - name: PHP ${{ matrix.php-versions }} | drupal ${{ matrix.drupal-version }} | mysql ${{ matrix.mysql }} | test-suite ${{ matrix.test-suite }} diff --git a/islandora.info.yml b/islandora.info.yml index 6dd0597f2..a43196a42 100644 --- a/islandora.info.yml +++ b/islandora.info.yml @@ -4,7 +4,7 @@ name: 'islandora' description: "Islandora Core" type: module package: Islandora -core_version_requirement: ^9 || ^10 +core_version_requirement: ^10.2 dependencies: - context:context_ui - ctools:ctools diff --git a/tests/src/Functional/DeleteMediaTest.php b/tests/src/Functional/DeleteMediaTest.php index 957146fdc..76298501a 100644 --- a/tests/src/Functional/DeleteMediaTest.php +++ b/tests/src/Functional/DeleteMediaTest.php @@ -50,12 +50,7 @@ class DeleteMediaTest extends IslandoraFunctionalTestBase { public function setUp(): void { parent::setUp(); - if (version_compare(\Drupal::VERSION, '10.1', '>=')) { - $permissions = ['create media', 'delete any media', 'delete any file']; - } - else { - $permissions = ['create media', 'delete any media']; - } + $permissions = ['create media', 'delete any media', 'delete any file']; // Create a test user. $this->account = $this->createUser($permissions); diff --git a/tests/src/Functional/JsonldTypeAlterReactionTest.php b/tests/src/Functional/JsonldTypeAlterReactionTest.php index 6ac70d7da..7e2005842 100644 --- a/tests/src/Functional/JsonldTypeAlterReactionTest.php +++ b/tests/src/Functional/JsonldTypeAlterReactionTest.php @@ -26,15 +26,7 @@ public function testMappingReaction() { // Add the typed predicate we will select in the reaction config. // Taken from FieldUiTestTrait->fieldUIAddNewField. - if (version_compare(\Drupal::VERSION, '10.2.x-dev', 'lt')) { - $this->submitForm([ - 'new_storage_type' => 'string', - 'label' => 'Typed Predicate', - 'field_name' => 'type_predicate', - ], 'Save and continue'); - $this->submitForm([], 'Save field settings'); - } - elseif (version_compare(\Drupal::VERSION, '10.3.x-dev', 'lt')) { + if (version_compare(\Drupal::VERSION, '10.3.x-dev', 'lt')) { $this->getSession()->getPage()->selectFieldOption('new_storage_type', 'plain_text'); // For Drupal 10.2, we first need to submit the form with the elements // displayed on initial page load. The form is using AJAX to send a From 010534349c0b4c2d72762f3268cccaa75e9ea0ca Mon Sep 17 00:00:00 2001 From: Alan Stanley Date: Thu, 27 Jun 2024 16:13:00 -0300 Subject: [PATCH 241/252] added check (#1031) * added check * blank line * cleaner implementation * check added * tidied up --- islandora.module | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/islandora.module b/islandora.module index 8fa478a7f..153eb1679 100644 --- a/islandora.module +++ b/islandora.module @@ -545,12 +545,11 @@ function islandora_entity_view(array &$build, EntityInterface $entity, EntityVie $route_match_item = \Drupal::routeMatch()->getParameters()->get($entity->getEntityTypeId()); // Ensure the entity matches the route. if ($entity === $route_match_item) { - if ($display->getComponent('field_gemini_uri')) { - $mapper = \Drupal::service('islandora.entity_mapper'); - $flysystem_config = Settings::get('flysystem'); - $fedora_root = $flysystem_config['fedora']['config']['root']; + $flysystem_config = Settings::get('flysystem'); + $fedora_root = $flysystem_config['fedora']['config']['root'] ?? NULL; + if ($display->getComponent('field_gemini_uri') && $fedora_root) { $fedora_root = rtrim($fedora_root, '/'); - + $mapper = \Drupal::service('islandora.entity_mapper'); if ($entity->getEntityTypeId() == 'media') { // Check if the source file is in Fedora or not. $media_source_service = \Drupal::service('islandora.media_source_service'); From 14c4e423237de41e982c27fbec28e5293476b726 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 3 Jul 2024 21:02:24 -0300 Subject: [PATCH 242/252] Option to get alt text from Original File. (#1024) * Option to get alt text from Original File. * Add schema. * Logic re-work and fixing a undefined method. --------- Co-authored-by: Jordan Dukart --- config/schema/islandora.schema.yml | 4 + .../IslandoraImageFormatter.php | 111 +++++++++++++++--- 2 files changed, 101 insertions(+), 14 deletions(-) diff --git a/config/schema/islandora.schema.yml b/config/schema/islandora.schema.yml index 49de998b3..282f7b3c5 100644 --- a/config/schema/islandora.schema.yml +++ b/config/schema/islandora.schema.yml @@ -173,6 +173,10 @@ condition.plugin.node_had_namespace: field.formatter.settings.islandora_image: type: field.formatter.settings.image label: 'Islandora image field display format settings' + mapping: + image_alt_text: + type: string + label: "Alt text source" condition.plugin.islandora_entity_bundle: type: condition.plugin diff --git a/src/Plugin/Field/FieldFormatter/IslandoraImageFormatter.php b/src/Plugin/Field/FieldFormatter/IslandoraImageFormatter.php index deb6c7690..ffe6d47a2 100644 --- a/src/Plugin/Field/FieldFormatter/IslandoraImageFormatter.php +++ b/src/Plugin/Field/FieldFormatter/IslandoraImageFormatter.php @@ -6,9 +6,11 @@ use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\File\FileUrlGeneratorInterface; +use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Session\AccountInterface; use Drupal\image\Plugin\Field\FieldFormatter\ImageFormatter; use Drupal\islandora\IslandoraUtils; +use Drupal\islandora\MediaSource\MediaSourceService; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -34,6 +36,13 @@ class IslandoraImageFormatter extends ImageFormatter { */ protected $utils; + /** + * Islandora media source service. + * + * @var \Drupal\islandora\MediaSource\MediaSourceService + */ + protected $mediaSourceService; + /** * Constructs an IslandoraImageFormatter object. * @@ -59,6 +68,8 @@ class IslandoraImageFormatter extends ImageFormatter { * Islandora utils. * @param \Drupal\Core\File\FileUrlGeneratorInterface $file_url_generator * The File URL Generator. + * @param \Drupal\islandora\MediaSource\MediaSourceService $media_source_service + * Utils to get the source file from media. */ public function __construct( $plugin_id, @@ -71,7 +82,8 @@ public function __construct( AccountInterface $current_user, EntityStorageInterface $image_style_storage, IslandoraUtils $utils, - FileUrlGeneratorInterface $file_url_generator + FileUrlGeneratorInterface $file_url_generator, + MediaSourceService $media_source_service ) { parent::__construct( $plugin_id, @@ -86,6 +98,7 @@ public function __construct( $file_url_generator ); $this->utils = $utils; + $this->mediaSourceService = $media_source_service; } /** @@ -103,10 +116,40 @@ public static function create(ContainerInterface $container, array $configuratio $container->get('current_user'), $container->get('entity_type.manager')->getStorage('image_style'), $container->get('islandora.utils'), - $container->get('file_url_generator') + $container->get('file_url_generator'), + $container->get('islandora.media_source_service') ); } + /** + * {@inheritdoc} + */ + public static function defaultSettings() { + return [ + 'image_alt_text' => 'local', + ] + parent::defaultSettings(); + } + + /** + * {@inheritdoc} + */ + public function settingsForm(array $form, FormStateInterface $form_state) { + $element = parent::settingsForm($form, $form_state); + $alt_text_options = [ + 'local' => $this->t('Local'), + 'original_file_fallback' => $this->t('Local, with fallback to Original File'), + 'original_file' => $this->t('Original File'), + ]; + $element['image_alt_text'] = [ + '#title' => $this->t('Alt text source'), + '#type' => 'select', + '#default_value' => $this->getSetting('image_alt_text'), + '#empty_option' => $this->t('None'), + '#options' => $alt_text_options, + ]; + return $element; + } + /** * {@inheritdoc} */ @@ -114,28 +157,68 @@ public function viewElements(FieldItemListInterface $items, $langcode) { $elements = parent::viewElements($items, $langcode); $image_link_setting = $this->getSetting('image_link'); - // Check if the formatter involves a link. - if ($image_link_setting != 'content') { + $alt_text_setting = $this->getsetting('image_alt_text'); + + // Check if we can leave the image as-is: + if ($image_link_setting !== 'content' && $alt_text_setting === 'local') { return $elements; } - $entity = $items->getEntity(); - if ($entity->isNew() || $entity->getEntityTypeId() != 'media') { + if ($entity->isNew() || $entity->getEntityTypeId() !== 'media') { return $elements; } - $node = $this->utils->getParentNode($entity); - - if ($node === NULL) { - return $elements; + if ($alt_text_setting === 'none') { + foreach ($elements as $element) { + $element['#item']->set('alt', ''); + } } - $url = $node->toUrl(); + if ($image_link_setting === 'content' || $alt_text_setting === 'original_file' || $alt_text_setting === 'original_file_fallback') { + $node = $this->utils->getParentNode($entity); + if ($node === NULL) { + return $elements; + } - foreach ($elements as &$element) { - $element['#url'] = $url; - } + if ($image_link_setting === 'content') { + // Set image link. + $url = $node->toUrl(); + foreach ($elements as &$element) { + $element['#url'] = $url; + } + unset($element); + } + + if ($alt_text_setting === 'original_file' || $alt_text_setting === 'original_file_fallback') { + $original_file_term = $this->utils->getTermForUri("http://pcdm.org/use#OriginalFile"); + if ($original_file_term !== NULL) { + $original_file_media = $this->utils->getMediaWithTerm($node, $original_file_term); + + if ($original_file_media !== NULL) { + $source_field_name = $this->mediaSourceService->getSourceFieldName($original_file_media->bundle()); + if ($original_file_media->hasField($source_field_name)) { + $original_file_files = $original_file_media->get($source_field_name); + // XXX: Support the multifile media use case where there could + // be multiple files in the source field. + $i = 0; + foreach ($original_file_files as $file) { + if (isset($file->alt)) { + $alt_text = $file->get('alt')->getValue(); + if (isset($elements[$i])) { + $element = $elements[$i]; + if ($alt_text_setting === 'original_file' || $element['#item']->get('alt')->getValue() === '') { + $elements[$i]['#item']->set('alt', $alt_text); + } + $i++; + } + } + } + } + } + } + } + } return $elements; } From 60a1678cac4a3a01987b67fc0f1bfcc7849d55c5 Mon Sep 17 00:00:00 2001 From: Noel Chiasson <53783039+nchiasson-dgi@users.noreply.github.com> Date: Sun, 7 Jul 2024 19:48:53 -0300 Subject: [PATCH 243/252] Shortcircuiting if search_endpoint isn't set (#1035) --- .../src/Plugin/views/style/IIIFManifest.php | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index f0aca47da..42984eba8 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -494,17 +494,20 @@ protected function defineOptions() { */ protected function addSearchEndpoint(array &$json, array $url_components) { $url_base = $this->getRequest()->getSchemeAndHttpHost(); - $hocr_search_path = $this->options['search_endpoint']; - $hocr_search_url = $url_base . '/' . ltrim($hocr_search_path, '/'); + $hocr_search_path = $this->options['search_endpoint'] ?? null; - $hocr_search_url = str_replace('%node', $url_components[1], $hocr_search_url); + if ($hocr_search_path) { + $hocr_search_url = $url_base . '/' . ltrim($hocr_search_path, '/'); - $json['service'][] = [ - "@context" => "http://iiif.io/api/search/0/context.json", - "@id" => $hocr_search_url, - "profile" => "http://iiif.io/api/search/0/search", - "label" => t("Search inside this work"), - ]; + $hocr_search_url = str_replace('%node', $url_components[1], $hocr_search_url); + + $json['service'][] = [ + "@context" => "http://iiif.io/api/search/0/context.json", + "@id" => $hocr_search_url, + "profile" => "http://iiif.io/api/search/0/search", + "label" => t("Search inside this work"), + ]; + } } /** From 60f49255d82006e781adce6c031b28e63df24fff Mon Sep 17 00:00:00 2001 From: Adam <607975+adam-vessey@users.noreply.github.com> Date: Wed, 10 Jul 2024 15:05:17 -0300 Subject: [PATCH 244/252] Fix for coding standards. (#1040) --- modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 42984eba8..28077aee6 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -494,7 +494,7 @@ protected function defineOptions() { */ protected function addSearchEndpoint(array &$json, array $url_components) { $url_base = $this->getRequest()->getSchemeAndHttpHost(); - $hocr_search_path = $this->options['search_endpoint'] ?? null; + $hocr_search_path = $this->options['search_endpoint'] ?? NULL; if ($hocr_search_path) { $hocr_search_url = $url_base . '/' . ltrim($hocr_search_path, '/'); From 7bae08f1160e34b26dab82502039c443282a1076 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Thu, 11 Jul 2024 19:12:23 -0300 Subject: [PATCH 245/252] 959 configurable width height caching (#1029) * Refactor IIIF, create IIIF Info Service. * Islandora IIIF: Add action to retrieve image attributes from IIIF server. * Islandora IIIF: Add auth headers to IIIF Info request. * Islandora IIIF: Change media action to node. * Islandora IIIF: Update README. * Finish rebase. * Islandora IIIF: Address PHPCS errors. * Islandora IIIF: Address PHPCS errors. * islandora_iiif: Fix Authorization header syntax. * 959-iiif-width-height-caching Islandora IIIF: Add search endpoint config to manifest. * 959-iiif-width-height-caching Add handler for ServerException in Islandora IIIF manifest generator. * 959-iiif-width-height-caching Add option to skip retrieveing TIFF and JP2 dimensions from IIIF server. * Checking for width/height on media first when generating IIIF manifest * 959-iiif-width-height-caching Add IIIF service function to get downlaod link with given dimensions. * Fix redundant function from rebase. * Rebase resolve conflict. * WIP: Make Get dimensions from File image action target fields configurable. * WIP * WIP use configured height and width fields. * Extract TIFF and JP2 dimensions action: Make width and height field configurable. * Islandora IIIF: Make media height and width fields configurable. * Islandora IIIF: Make media width and height fields configurable in manifest plugin. * Islandora IIIF: Add config schema update hook. * Islandora IIIF: Fix warning on Views display plugin page. * Remove outdated action. * Islandora IIIF: Update the README. * Islandora IIIF: Update PHPDoc description of IIIF Dimensions complex action. * Islandora IIIF: Add instructions for setting up a context reaction for the IIIF Dimensions actions. * Update modules/islandora_iiif/config/schema/islandora_iiif.schema.yml Co-authored-by: Adam <607975+adam-vessey@users.noreply.github.com> * Islandora IIIF: Address PHPCS errors. * Islandora IIIF: Remove unused schema entry. * Islandora IIIF: Address PHPCS errors. * Islandora IIIF: Address PHPCS errors. * Islandora IIIF: Fix PHPCS errors. * Islandora IIIF: Fix PHPCS warnings. * Islandora IIIF: Address code review comment. * Update modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php Co-authored-by: Adam <607975+adam-vessey@users.noreply.github.com> * Update modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php Co-authored-by: Adam <607975+adam-vessey@users.noreply.github.com> * Islandora IIIF: Address PHPCS errors. --------- Co-authored-by: dannylamb Co-authored-by: Adam <607975+adam-vessey@users.noreply.github.com> --- modules/islandora_iiif/README.md | 45 ++- modules/islandora_iiif/islandora_iiif.install | 41 +++ .../islandora_iiif.services.yml | 4 + modules/islandora_iiif/src/IiifInfo.php | 151 +++++++++ .../Plugin/Action/MediaAttributesFromIiif.php | 302 ++++++++++++++++++ .../src/Plugin/views/style/IIIFManifest.php | 195 ++++++++--- 6 files changed, 691 insertions(+), 47 deletions(-) create mode 100644 modules/islandora_iiif/islandora_iiif.install create mode 100644 modules/islandora_iiif/islandora_iiif.services.yml create mode 100644 modules/islandora_iiif/src/IiifInfo.php create mode 100644 modules/islandora_iiif/src/Plugin/Action/MediaAttributesFromIiif.php diff --git a/modules/islandora_iiif/README.md b/modules/islandora_iiif/README.md index c1f89872c..676723e9e 100644 --- a/modules/islandora_iiif/README.md +++ b/modules/islandora_iiif/README.md @@ -6,7 +6,7 @@ ## Introduction -Provides IIIF manifests using views. +Provides [IIIF manifests](https://iiif.io) using views. ## Requirements @@ -20,7 +20,7 @@ For a full digital repository solution, see our [installation documentation](htt To download/enable just this module, use the following from the command line: ```bash -$ composer require islandora/islandora +$ composer require drupal/islandora $ drush en islandora_core_feature $ drush mim islandora_tags $ drush en islandora_iiif @@ -38,9 +38,46 @@ This module implements a Views Style plugin. It provides the following settings: 1. Tile Source: A field that was added to the views list of fields with the image to be served. This should be a File or Image type field on a Media. 2. Structured Text field: This lets you specify a file field where OCR text with positional data, e.g., hOCR can be found. +3. Structured Text Term: If your Islandora Object has a separate media with hOCR, point to it with this setting. +4. File Width and Height fields: If you want to use TIFF or JP2 files directly, set the fields where the files' width and height can be found with these settings. + +### Media Attributes from IIIF Action + +The module also provides an action that lets a site owner populate a TIFF or JP2 image's width and +height attributes into fields so the IIIF server is not bogged down trying to generate a manifest if +it doesn't have them. + +It is a complex action that must be configured. Go to +Admin -> Actions UI -> Actions, choose +"Add image dimensions retrieved from the IIIF server" from the Create Action drop-down +And on the next screen, choose the width +and height fields that the action should +populate. + +To use it, either: +- Add it as a derivative reaction to a node with an Original FIle as its child, or +- Use it as a batch action, such as on a Paged Content object's list of child pages. + +### Setting up the action as a Context Reaction + +These instructions assume a standard Islandora Starter Site, so if you have different field names or Contexts, adjust accordingly. + +1. Go to admin/config/system/actions +2. Choose "Add image dimensions retrieved from the IIIF server" from the Create Complex Action drop-down and then click Create. +3. Enter Original File for the Source Media Use term. +4. Choose media -- file -- Width and Media -- File -- Height for the corresponding configuration values and click Save. +5. Go to admin/structure/context, and click Duplicate oon the Page Derivatives row. +6. Name the new context something like "Retrieve Page Dimensionss". and edit it. +7. This is the tricky bit, delete 'Original File' from the 'Media has term with URI' field and replace it with Service File. The explanation for this is that to retrieve a file from the IIIF server, it must be part of an Islandora Media that has been fully created and saved and given a URL. This hasn't happened yet when Original File derivatives are being created, so we need to hang our action onto a derivative that is created after the original one. +8. Under Reactions, deselect the existing actions and select "Add i mage dimensions from IIIF sserver" and click Save and continue. +9. Go back to your Paged Content object and add another child with a File media, to which you should upload another TIFF or JP2 file. +10. Without going to the Original File Book Manifestt, make sure that a service file has been generated, then click Edit on the Original File media. +11. Ensure that the Width and Height fields are populated with thee correct values from the file. + + ## Documentation -Official documentation is available on the [Islandora 8 documentation site](https://islandora.github.io/documentation/). +Official documentation is available on the [Islandora 2 documentation site](https://islandora.github.io/documentation/). ## Development @@ -48,8 +85,6 @@ If you would like to contribute, please get involved by attending our weekly [Te If you would like to contribute code to the project, you need to be covered by an Islandora Foundation [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). Please see the [Contributors](http://islandora.ca/resources/contributors) pages on Islandora.ca for more information. -We recommend using the [islandora-playbook](https://github.com/Islandora-Devops/islandora-playbook) to get started. - ## License [GPLv2](http://www.gnu.org/licenses/gpl-2.0.txt) diff --git a/modules/islandora_iiif/islandora_iiif.install b/modules/islandora_iiif/islandora_iiif.install new file mode 100644 index 000000000..dc9af68bf --- /dev/null +++ b/modules/islandora_iiif/islandora_iiif.install @@ -0,0 +1,41 @@ +listAll(); + $views_configs = array_values(array_filter($all_configs, function ($config) { + return str_starts_with($config, 'views.view.'); + })); + + foreach ($views_configs as $views_config_name) { + $needs_save = FALSE; + $view_config = $config_factory->getEditable($views_config_name); + $displays = $view_config->get('display'); + foreach ($displays as $display_name => $display) { + if ($display['display_plugin'] == 'rest_export' + && $display['display_options']['style']['type'] == 'iiif_manifest' + &&!empty($display['display_options']['style']['options']['iiif_ocr_file_field'])) { + + $display['display_options']['style']['options']['advanced']['iiif_ocr_file_field'] = $display['display_options']['style']['options']['iiif_ocr_file_field']; + unset($display['display_options']['style']['options']['iiif_ocr_file_field']); + $view_config->set('display.' . $display_name . '.display_options.style.options', $display['display_options']['style']['options']); + $needs_save = TRUE; + } + } + if ($needs_save) { + $view_config->save(); + } + } +} diff --git a/modules/islandora_iiif/islandora_iiif.services.yml b/modules/islandora_iiif/islandora_iiif.services.yml new file mode 100644 index 000000000..fd39211cd --- /dev/null +++ b/modules/islandora_iiif/islandora_iiif.services.yml @@ -0,0 +1,4 @@ +services: + islandora_iiif: + class: Drupal\islandora_iiif\IiifInfo + arguments: ['@config.factory', '@http_client', '@logger.channel.islandora', '@jwt.authentication.jwt'] diff --git a/modules/islandora_iiif/src/IiifInfo.php b/modules/islandora_iiif/src/IiifInfo.php new file mode 100644 index 000000000..f2b1138ad --- /dev/null +++ b/modules/islandora_iiif/src/IiifInfo.php @@ -0,0 +1,151 @@ +configFactory = $config_factory; + + $this->iiifConfig = $this->configFactory->get('islandora_iiif.settings'); + $this->httpClient = $http_client; + $this->logger = $channel; + $this->jwtAuth = $jwt_auth; + } + + /** + * The IIIF base URL for an image. + * + * Visiting this URL will resolve to the info.json for the image. + * + * @return string + * The absolute URL on the IIIF server. + */ + public function baseUrl($image) { + + if ($this->iiifConfig->get('use_relative_paths')) { + $file_url = ltrim($image->createFileUrl(TRUE), '/'); + } + else { + $file_url = $image->createFileUrl(FALSE); + } + + $iiif_address = $this->iiifConfig->get('iiif_server'); + $iiif_url = rtrim($iiif_address, '/') . '/' . urlencode($file_url); + + return $iiif_url; + } + + /** + * Retrieve an image's original dimensions via the IIIF server. + * + * @param \Drupal\File\FileInterface $file + * The image file. + * + * @return array|false + * The image dimensions in an array as [$width, $height] + */ + public function getImageDimensions(FileInterface $file) { + $iiif_url = $this->baseUrl($file); + try { + $info_json = $this->httpClient->request('get', $iiif_url, [ + 'headers' => [ + 'Authorization' => 'Bearer ' . $this->jwtAuth->generateToken(), + ], + ])->getBody(); + $resource = json_decode($info_json, TRUE); + $width = $resource['width']; + $height = $resource['height']; + if (is_numeric($width) && is_numeric($height)) { + return [intval($width), intval($height)]; + } + } + catch (ClientException | ConnectException | RequestException | ServerException $e) { + $this->logger->info("Error getting image file dimensions from IIIF server: " . $e->getMessage()); + } + return FALSE; + } + + /** + * The IIIF base URL for an image. + * + * Visiting this URL resolves to the image resized to the maximum dimensions. + * + * @param \Drupal\file\FileInterface $image + * The image entity. + * @param int $width + * The maximum width of the image to be returned. 0 for no constraint. + * @param int $height + * The maxim um height of the image to be returned. 0 for no contraint. + * + * @return string + * The IIIF URl to retrieve the full image with the given max dimensions. + */ + public function getImageWithMaxDimensions(FileInterface $image, $width = 0, $height = 0) { + $base_url = $this->baseUrl($image); + return $base_url . "/full/!$width,$height/0/default.jpg"; + + } + +} diff --git a/modules/islandora_iiif/src/Plugin/Action/MediaAttributesFromIiif.php b/modules/islandora_iiif/src/Plugin/Action/MediaAttributesFromIiif.php new file mode 100644 index 000000000..cfe41f17c --- /dev/null +++ b/modules/islandora_iiif/src/Plugin/Action/MediaAttributesFromIiif.php @@ -0,0 +1,302 @@ +configFactory = $config_factory; + $this->entityTypeManager = $entity_type_manager; + $this->httpClient = $http_client; + $this->iiifInfo = $iiif_info; + $this->utils = $islandora_utils; + $this->mediaSource = $media_source; + $this->logger = $channel; + $this->entityFieldManager = $entity_field_manager; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('entity_type.manager'), + $container->get('datetime.time'), + $container->get('http_client'), + $container->get('islandora_iiif'), + $container->get('islandora.utils'), + $container->get('islandora.media_source_service'), + $container->get('logger.channel.islandora'), + $container->get('entity_field.manager'), + $container->get('config.factory') + ); + } + + /** + * {@inheritdoc} + */ + public function execute($entity = NULL) { + $width = $height = FALSE; + + // Get the original File media use term. + $source_term = $this->utils->getTermForUri($this->configuration['source_term_uri']); + + $source_mids = $this->utils->getMediaReferencingNodeAndTerm($entity, $source_term); + if (!empty($source_mids)) { + + foreach ($source_mids as $source_mid) { + + /** + * @var \Drupal\Media\MediaInterface + */ + $source_media = $this->entityTypeManager->getStorage('media')->load($source_mid); + + // Get the media MIME Type. + $source_file = $this->mediaSource->getSourceFile($source_media); + $mime_type = $source_file->getMimeType(); + + if (in_array($mime_type, ['image/tiff', 'image/jp2'])) { + [$width, $height] = $this->iiifInfo->getImageDimensions($source_file); + } + + $width_field = $this->getShortFieldName($this->configuration['width_field']); + $height_field = $this->getShortFieldName($this->configuration['height_field']); + if ($source_media->hasField($width_field) && $source_media->hasField($height_field)) { + $source_media->set($width_field, $width); + $source_media->set($height_field, $height); + $source_media->save(); + } + } + } + } + + /** + * {@inheritdoc} + */ + public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) { + + /** +* @var \Drupal\Core\Entity\EntityInterface $object +*/ + return $object->access('update', $account, $return_as_object); + } + + /** + * {@inheritDoc} + */ + public function buildConfigurationForm(array $form, FormStateInterface $form_state) { + + $integer_fields = $this->getIntegerFields(); + + $form['source_term'] = [ + '#type' => 'entity_autocomplete', + '#target_type' => 'taxonomy_term', + '#title' => $this->t('Source media use term'), + '#default_value' => $this->utils->getTermForUri($this->configuration['source_term_uri']), + '#required' => TRUE, + '#description' => $this->t('Term indicating the source media'), + ]; + + $form['width_field'] = [ + '#type' => 'select', + '#title' => $this->t('Width Field'), + '#description' => $this->t("Field to populate with an image's width."), + '#default_value' => $this->configuration['width_field'], + '#options' => $integer_fields, + ]; + + $form['height_field'] = [ + '#type' => 'select', + '#title' => $this->t('Height Field'), + '#description' => $this->t("Field to populate with an image's height."), + '#default_value' => $this->configuration['height_field'], + '#options' => $integer_fields, + ]; + + return $form; + } + + /** + * {@inheritdoc} + */ + public function defaultConfiguration() { + $config = parent::defaultConfiguration(); + + $config['media_use_term'] = ''; + $config['width_field'] = ''; + $config['height_field'] = ''; + + return $config; + } + + /** + * {@inheritdoc} + */ + public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { + $tid = $form_state->getValue('source_term'); + $term = $this->entityTypeManager->getStorage('taxonomy_term')->load($tid); + $this->configuration['source_term_uri'] = $this->utils->getUriForTerm($term); + + $this->configuration['width_field'] = $form_state->getValue('width_field'); + $this->configuration['height_field'] = $form_state->getValue('height_field'); + + } + + /** + * Get all fields of an entity that are integer types. + * + * @return array + * The integer type fields. + */ + protected function getIntegerFields() { + // Get media types. + $media_types = $this->entityTypeManager->getStorage('media_type')->loadMultiple(); + $all_integer_fields = []; + foreach (array_keys($media_types) as $key => $value) { + $fields = $this->entityFieldManager->getFieldDefinitions("media", $value); + + $integer_fields = array_filter( + $fields, + function ($field_value, $field_key) { + // Only keep fields of type 'integer'. + return (strpos($field_value->getType(), 'integer') > -1) + && is_a($field_value, '\Drupal\Core\Field\FieldConfigInterface'); + }, ARRAY_FILTER_USE_BOTH + ); + foreach ($integer_fields as $integer_field) { + $all_integer_fields[$integer_field->id()] = $integer_field->getTargetEntityTypeId() + . ' -- ' . $integer_field->getTargetBundle() . ' -- ' . $integer_field->getLabel(); + } + + } + return $all_integer_fields; + } + + /** + * Returns the last part of a qualified field name. + * + * @param string $field_id + * The full field id, e.g., 'media.file.field_height'. + * + * @return string + * The short field name, e.g., 'field_height'. + */ + protected function getShortFieldName(string $field_id): string { + [$entity_type, $bundle, $field_name] = explode('.', $field_id); + return $field_name; + } + +} diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 28077aee6..6afae2499 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -6,22 +6,21 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Extension\ModuleHandlerInterface; -use Drupal\Core\File\FileSystemInterface; use Drupal\Core\Field\FieldItemInterface; +use Drupal\Core\File\FileSystemInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\Url; use Drupal\islandora\IslandoraUtils; +use Drupal\islandora_iiif\IiifInfo; +use Drupal\media\MediaInterface; use Drupal\taxonomy\TermInterface; use Drupal\views\Plugin\views\style\StylePluginBase; use Drupal\views\ResultRow; use GuzzleHttp\Client; -use GuzzleHttp\Exception\ClientException; -use GuzzleHttp\Exception\ConnectException; -use GuzzleHttp\Exception\ServerException; use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\Serializer\SerializerInterface; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Serializer\SerializerInterface; /** * Provide serializer format for IIIF Manifest. @@ -68,6 +67,13 @@ class IIIFManifest extends StylePluginBase { */ protected $serializer; + /** + * The IIIF Info service. + * + * @var \Drupal\islandora_iiif\IiifInfo + */ + protected $iiifInfo; + /** * The request service. * @@ -134,7 +140,7 @@ class IIIFManifest extends StylePluginBase { /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system, Client $http_client, MessengerInterface $messenger, ModuleHandlerInterface $moduleHandler, IslandoraUtils $utils) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system, Client $http_client, MessengerInterface $messenger, ModuleHandlerInterface $moduleHandler, IslandoraUtils $utils, IiifInfo $iiif_info) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->serializer = $serializer; @@ -146,6 +152,8 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition $this->messenger = $messenger; $this->utils = $utils; $this->moduleHandler = $moduleHandler; + $this->utils = $utils; + $this->iiifInfo = $iiif_info; } /** @@ -164,7 +172,8 @@ public static function create(ContainerInterface $container, array $configuratio $container->get('http_client'), $container->get('messenger'), $container->get('module_handler'), - $container->get('islandora.utils') + $container->get('islandora.utils'), + $container->get('islandora_iiif') ); } @@ -296,7 +305,11 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas $canvas_id = $iiif_base_id . '/canvas/' . $entity->id(); $annotation_id = $iiif_base_id . '/annotation/' . $entity->id(); - [$width, $height] = $this->getCanvasDimensions($iiif_url, $image, $mime_type); + [$width, $height] = $this->getCanvasDimensions($iiif_url, $entity, $image, $mime_type); + + if ($width == 0) { + continue; + } $tmp_canvas = [ // @see https://iiif.io/api/presentation/2.1/#canvas @@ -357,6 +370,8 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas * * @param string $iiif_url * Base URL of the canvas. + * @param \Drupal\media\MediaInterface $media + * The Media entity. * @param \Drupal\Core\Field\FieldItemInterface $image * The image field. * @param string $mime_type @@ -365,42 +380,73 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas * @return [string] * The width and height of the image. */ - protected function getCanvasDimensions(string $iiif_url, FieldItemInterface $image, string $mime_type) { + protected function getCanvasDimensions(string $iiif_url, MediaInterface $media, FieldItemInterface $image, string $mime_type) { if (isset($image->width) && is_numeric($image->width) && isset($image->height) && is_numeric($image->height)) { - return [intval($image->width), intval($image->height)]; + return [intval($image->width), + intval($image->height), + ]; } - try { - $info_json = $this->httpClient->get($iiif_url)->getBody(); - $resource = json_decode($info_json, TRUE); - $width = $resource['width']; - $height = $resource['height']; + if ($properties = $image->getProperties() + && isset($properties['width']) && is_numeric($properties['width']) + && isset($properties['height']) && is_numeric($properties['width'])) { + return [intval($properties['width']), + intval($properties['height']), + ]; } - catch (ClientException | ServerException | ConnectException $e) { - // If we couldn't get the info.json from IIIF - // try seeing if we can get it from Drupal. - if (empty($width) || empty($height)) { - // Get the image properties so we know the image width/height. - $properties = $image->getProperties(); - $width = isset($properties['width']) ? $properties['width'] : 0; - $height = isset($properties['height']) ? $properties['height'] : 0; - - // If this is a TIFF AND we don't know the width/height - // see if we can get the image size via PHP's core function. - if ($mime_type === 'image/tiff' && (!$width || !$height)) { - $uri = $image->entity->getFileUri(); - $path = $this->fileSystem->realpath($uri); - $image_size = getimagesize($path); - if ($image_size) { - $width = $image_size[0]; - $height = $image_size[1]; - } + + $entity = $image->entity; + + if ($entity->hasField('field_height') && !$entity->get('field_height')->isEmpty() + && $entity->get('field_height')->value > 0 + && $entity->hasField('field_width') + && !$entity->get('field_width')->isEmpty() + && $entity->get('field_width')->value > 0) { + return [$entity->get('field_width')->value, + $entity->get('field_height')->value, + ]; + } + + // If the media has width and height fields, return those values. + $width_field = !empty($this->options['advanced']['custom_width_height']['width_field']) ? $this->options['advanced']['custom_width_height']['height_field'] : 'field_width'; + $height_field = !empty($this->options['advanced']['custom_width_height']['height_field']) ? $this->options['advanced']['custom_width_height']['height_field'] : 'field_height'; + if ($media->hasField($height_field) + && !$media->get($height_field)->isEmpty() + && $media->get($height_field)->value > 0 + && $media->hasField($width_field) + && !$media->get($width_field)->isEmpty() + && $media->get($width_field)->value > 0) { + return [intval($media->get($width_field)->value), + intval($media->get($height_field)->value), + ]; + } + + if ($mime_type === 'image/tiff') { + // If this is a TIFF AND we don't know the width/height + // see if we can get the image size via PHP's core function. + $uri = $image->entity->getFileUri(); + $path = $this->fileSystem->realpath($uri); + if (!empty($path)) { + $image_size = getimagesize($path); + if ($image_size) { + return [intval($image_size[0]), + intval($image_size[1]), + ]; } } } - return [$width, $height]; + + // As a last resort, get it from the IIIF server. + // This can be very slow and will fail if there are too many pages. + $dimensions = $this->iiifInfo->getImageDimensions($image->entity); + if ($dimensions !== FALSE) { + $this->storeImageDimensions($media, $dimensions[0], $dimensions[1]); + return $dimensions; + } + + return [0, 0]; } /** @@ -410,12 +456,11 @@ protected function getCanvasDimensions(string $iiif_url, FieldItemInterface $ima * The entity at the current row. * * @return string|false - * The absolute URL of the current row's structured text, - * or FALSE if none. + * The URL where the OCR text is found. */ protected function getOcrUrl(EntityInterface $entity) { $ocr_url = FALSE; - $iiif_ocr_file_field = !empty($this->options['iiif_ocr_file_field']) ? array_filter(array_values($this->options['iiif_ocr_file_field'])) : []; + $iiif_ocr_file_field = !empty($this->options['advanced']['iiif_ocr_file_field']) ? array_filter(array_values($this->options['advanced']['iiif_ocr_file_field'])) : []; $ocrField = count($iiif_ocr_file_field) > 0 ? $this->view->field[$iiif_ocr_file_field[0]] : NULL; if ($ocrField) { $ocr_entity = $entity; @@ -529,6 +574,8 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { // File formatters. 'file_default', 'file_url_plain', ]; + $dimensions_field_options = []; + /** @var \Drupal\views\Plugin\views\field\FieldPluginBase[] $fields */ foreach ($fields as $field_name => $field) { // If this is a known Islandora file/image field @@ -542,6 +589,10 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { (!empty($field->options['type']) && in_array($field->options['type'], $file_views_field_formatters))) { $field_options[$field_name] = $field->adminLabel(); } + else { + // Put it in the list of fields that may contain the custom value. + $dimensions_field_options[$field_name] = $field->adminLabel(); + } } // If no fields to choose from, add an error message indicating such. @@ -550,6 +601,8 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { You will need to add a field to this View'), 'error'); } + $dimensions_field_options = array_merge(['' => ' - None -- '], $dimensions_field_options); + $form['iiif_tile_field'] = [ '#title' => $this->t('Tile source field(s)'), '#type' => 'checkboxes', @@ -562,10 +615,36 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { '#required' => count($field_options) > 0, ]; - $form['iiif_ocr_file_field'] = [ + $form['advanced'] = [ + '#type' => 'details', + '#title' => $this->t('Advanced'), + '#open' => FALSE, + ]; + + $form['advanced']['custom_width_height'] = [ + '#type' => 'fieldset', + '#title' => $this->t('Custom width and height fields.'), + '#description' => $this->t('Use these if the media type of the image does not have built in Width and height fields, e.g., File. As a fallback, if the media has fields with the name "field_width" and "field_height" this formatter will try and get the width from that.'), + ]; + + $form['advanced']['custom_width_height']['height_field'] = [ + '#type' => 'select', + '#title' => $this->t('Custom Height field'), + '#default_value' => $this->options['advanced']['custom_width_height']['height_field'], + '#options' => $dimensions_field_options, + ]; + + $form['advanced']['custom_width_height']['width_field'] = [ + '#type' => 'select', + '#title' => $this->t('Custom width field'), + '#default_value' => $this->options['advanced']['custom_width_height']['width_field'], + '#options' => $dimensions_field_options, + ]; + + $form['advanced']['iiif_ocr_file_field'] = [ '#title' => $this->t('Structured OCR data file field'), '#type' => 'checkboxes', - '#default_value' => $this->options['iiif_ocr_file_field'], + '#default_value' => $this->options['advanced']['iiif_ocr_file_field'], '#description' => $this->t("If the hOCR is a field on the same entity as the image source field above, select it here. If it's found in a related entity via the term below, leave this blank."), '#options' => $field_options, '#required' => FALSE, @@ -584,7 +663,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { '#type' => 'textfield', '#title' => $this->t("Search endpoint path."), '#description' => $this->t("If there is a search endpoint to search within the book that returns IIIF annotations, put it here. Use %node substitution where needed.
    E.g., paged-content-search/%node"), - '#default_value' => $this->options['search_endpoint'], + '#default_value' => !empty($this->options['search_endpoint']) ? $this->options['search_endpoint'] : '', '#required' => FALSE, ]; } @@ -616,7 +695,9 @@ public function submitOptionsForm(&$form, FormStateInterface $form_state) { $tid = $style_options['structured_text_term']; unset($style_options['structured_text_term']); $term = $this->entityTypeManager->getStorage('taxonomy_term')->load($tid); - $style_options['structured_text_term_uri'] = $this->utils->getUriForTerm($term); + if ($term) { + $style_options['structured_text_term_uri'] = $this->utils->getUriForTerm($term); + } $form_state->setValue('style_options', $style_options); parent::submitOptionsForm($form, $form_state); } @@ -636,4 +717,34 @@ protected function getStructuredTextTerm() : ?TermInterface { return $this->structuredTextTerm; } + /** + * Store the image dimensions back onto the entity. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity to store the dimensions on to. + * @param int $width + * The image's width. + * @param int $height + * The image's height. + */ + protected function storeImageDimensions(EntityInterface $entity, $width, $height) { + $height_field = !empty($this->options['advanced']['custom_width_height']['height_field']) ? $this->view->field[$this->options['advanced']['custom_width_height']['height_field']]->definition['field_name'] : 'field_height'; + $width_field = !empty($this->options['advanced']['custom_width_height']['width_field']) ? $this->view->field[$this->options['advanced']['custom_width_height']['width_field']]->definition['field_name'] : 'field_width'; + + $needs_save = FALSE; + if ($entity->hasField($height_field) && $entity->get($height_field)->getString() !== $height) { + $entity->set($height_field, $height); + $needs_save = TRUE; + } + + if ($entity->hasField($width_field) && $entity->get($width_field)->getString() !== $width) { + $entity->set($width_field, $width); + $needs_save = TRUE; + } + + if ($needs_save) { + $entity->save(); + } + } + } From 4821cca693fd7da5cf3948de20ee6a1181bd348d Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 17 Jul 2024 18:32:47 -0300 Subject: [PATCH 246/252] Term revisions can now go to Fedora (#1043) * Allow revisioning taxonomy terms. --- src/EventGenerator/EventGenerator.php | 30 +++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/EventGenerator/EventGenerator.php b/src/EventGenerator/EventGenerator.php index 4c29e44ba..ab172225d 100644 --- a/src/EventGenerator/EventGenerator.php +++ b/src/EventGenerator/EventGenerator.php @@ -2,13 +2,13 @@ namespace Drupal\islandora\EventGenerator; +use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\EntityStorageInterface; +use Drupal\Core\Site\Settings; use Drupal\islandora\IslandoraUtils; use Drupal\islandora\MediaSource\MediaSourceService; use Drupal\user\UserInterface; -use Drupal\Core\Site\Settings; -use Drupal\media\Entity\Media; -use Drupal\Core\Entity\EntityStorageInterface; /** * The default EventGenerator implementation. @@ -186,26 +186,26 @@ protected function isNewRevision(EntityInterface $entity) { $revision_ids = \Drupal::entityTypeManager()->getStorage($entity->getEntityTypeId())->revisionIds($entity); return count($revision_ids) > 1; } - elseif ($entity->getEntityTypeId() == "media") { - $mediaStorage = \Drupal::entityTypeManager()->getStorage($entity->getEntityTypeId()); - return count($this->getRevisionIds($entity, $mediaStorage)) > 1; + elseif (in_array($entity->getEntityTypeId(), ["media", "taxonomy_term"])) { + $entity_storage = \Drupal::entityTypeManager()->getStorage($entity->getEntityTypeId()); + return count($this->getRevisionIds($entity, $entity_storage)) > 1; } } /** - * Method to get the revisionIds of a media object. + * Method to get the revisionIds of an entity. * - * @param \Drupal\media\Entity\Media $media - * Media object. - * @param \Drupal\Core\Entity\EntityStorageInterface $media_storage - * Media Storage. + * @param \Drupal\entity\Entity\ContentEntityInterface $entity + * Entity instance such as a Media or Taxonomy term. + * @param \Drupal\Core\Entity\EntityStorageInterface $entity_storage + * Entity Storage. */ - protected function getRevisionIds(Media $media, EntityStorageInterface $media_storage) { - $result = $media_storage->getQuery() + protected function getRevisionIds(ContentEntityInterface $entity, EntityStorageInterface $entity_storage) { + $result = $entity_storage->getQuery() ->allRevisions() ->accessCheck(TRUE) - ->condition($media->getEntityType()->getKey('id'), $media->id()) - ->sort($media->getEntityType()->getKey('revision'), 'DESC') + ->condition($entity->getEntityType()->getKey('id'), $entity->id()) + ->sort($entity->getEntityType()->getKey('revision'), 'DESC') ->execute(); return array_keys($result); } From c9d778ea456f3fe8a4b5918ca0983a77a80631da Mon Sep 17 00:00:00 2001 From: Alan Stanley Date: Tue, 30 Jul 2024 15:03:08 -0300 Subject: [PATCH 247/252] Node and media delete action (#1041) * added node and media deletion action * Update islandora.schema.yml * Added config install hook * Codered --- .../system.action.delete_node_and_media.yml | 12 ++ config/schema/islandora.schema.yml | 4 + islandora.install | 15 +- islandora.routing.yml | 7 + src/Form/ConfirmDeleteNodeAndMedia.php | 163 ++++++++++++++++++ src/Plugin/Action/DeleteNodeAndMedia.php | 46 +++++ 6 files changed, 245 insertions(+), 2 deletions(-) create mode 100644 config/install/system.action.delete_node_and_media.yml create mode 100755 src/Form/ConfirmDeleteNodeAndMedia.php create mode 100755 src/Plugin/Action/DeleteNodeAndMedia.php diff --git a/config/install/system.action.delete_node_and_media.yml b/config/install/system.action.delete_node_and_media.yml new file mode 100644 index 000000000..74fee13cd --- /dev/null +++ b/config/install/system.action.delete_node_and_media.yml @@ -0,0 +1,12 @@ +status: true +dependencies: + enforced: + module: + - islandora + module: + - islandora +id: delete_node_and_media +label: 'Delete node(s) and associated media' +type: node +plugin: delete_node_and_media +configuration: { } \ No newline at end of file diff --git a/config/schema/islandora.schema.yml b/config/schema/islandora.schema.yml index 282f7b3c5..41b7338d1 100644 --- a/config/schema/islandora.schema.yml +++ b/config/schema/islandora.schema.yml @@ -81,6 +81,10 @@ action.configuration.delete_media_and_file: type: action_configuration_default label: 'Delete media and file' +action.configuration.delete_node_and_media: + type: action_configuration_default + label: 'Delete node and media' + condition.plugin.node_has_term: type: condition.plugin mapping: diff --git a/islandora.install b/islandora.install index 01e5a467b..fb569eb4a 100644 --- a/islandora.install +++ b/islandora.install @@ -8,6 +8,7 @@ use Drupal\Core\Extension\ExtensionNameLengthException; use Drupal\Core\Extension\MissingDependencyException; use Drupal\Core\Utility\UpdateException; +use Symfony\Component\Yaml\Yaml; /** * Adds common namespaces to jsonld.settings. @@ -221,8 +222,18 @@ function islandora_update_8008() { if ($config) { $config->set('redirect_after_media_save', FALSE); $config->save(TRUE); - return t('A new configuration option, "Redirect after media save" is now available. - It has been turned off to preserve existing behaviour. To enable this setting visit + return t('A new configuration option, "Redirect after media save" is now available. + It has been turned off to preserve existing behaviour. To enable this setting visit Configuration > Islandora > Core Settings.'); } } + +/** + * Add "Delete node and media" action. + */ +function islandora_update_9001(&$sandbox) { + $config_id = 'system.action.delete_node_and_media'; + $config_path = \Drupal::service('extension.list.module')->getPath('islandora') . '/config/install/' . $config_id . '.yml'; + $data = Yaml::parseFile($config_path); + \Drupal::configFactory()->getEditable($config_id)->setData($data)->save(TRUE); +} diff --git a/islandora.routing.yml b/islandora.routing.yml index 86d134828..f72db51c8 100644 --- a/islandora.routing.yml +++ b/islandora.routing.yml @@ -109,3 +109,10 @@ islandora.confirm_delete_media_and_file: _form: 'Drupal\islandora\Form\ConfirmDeleteMediaAndFile' requirements: _permission: 'administer media+delete any media' + +islandora.confirm_delete_node_and_media: + path: '/node/delete_with_media' + defaults: + _form: 'Drupal\islandora\Form\ConfirmDeleteNodeAndMedia' + requirements: + _permission: 'administer media+delete any media' diff --git a/src/Form/ConfirmDeleteNodeAndMedia.php b/src/Form/ConfirmDeleteNodeAndMedia.php new file mode 100755 index 000000000..d39aa702b --- /dev/null +++ b/src/Form/ConfirmDeleteNodeAndMedia.php @@ -0,0 +1,163 @@ +currentUser = $current_user; + $this->entityTypeManager = $entity_type_manager; + $this->entityFieldManager = $entity_field_manager; + $this->tempStore = $temp_store_factory->get('node_and_media_delete_confirm'); + $this->messenger = $messenger; + $this->utils = $utils; + $this->mediaSourceService = $media_source_service; + $this->logger = $logger; + $this->deletedMediaCount = 0; + $this->deletedFileCount = 0; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('current_user'), + $container->get('entity_type.manager'), + $container->get('entity_field.manager'), + $container->get('tempstore.private'), + $container->get('messenger'), + $container->get('islandora.utils'), + $container->get('islandora.media_source_service'), + $container->get('logger.channel.islandora')); + } + + /** + * {@inheritdoc} + */ + public function getFormId() { + return 'node_and_media_delete_confirm_form'; + } + + /** + * {@inheritdoc} + */ + public function getQuestion() { + return $this->formatPlural(count($this->selection), + 'Are you sure you want to delete this node and its associated media and files?', + 'Are you sure you want to delete these nodes and their associated media and files?'); + } + + /** + * {@inheritdoc} + */ + public function getCancelUrl() { + return new Url('entity.media.collection'); + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state, $entity_type_id = NULL) { + return parent::buildForm($form, $form_state, 'node'); + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + $deleted_media = 0; + $node_storage = $this->entityTypeManager->getStorage('node'); + $nodes = $node_storage->loadMultiple(array_keys($this->selection)); + $deleteable_nodes = []; + foreach ($nodes as $node) { + if ($node->access('delete', $this->currentUser)) { + $deleteable_nodes[] = $node; + } + else { + $nondeleteable_nodes = $node; + } + } + foreach ($deleteable_nodes as $candidate) { + $media = $this->utils->getMedia($candidate); + $this->utils->deleteMediaAndFiles($media); + $candidate->delete(); + } + $this->messenger->addStatus($this->getDeletedMessage(count($deleteable_nodes))); + if ($nondeleteable_nodes) { + $failures = count($nondeleteable_nodes); + $this->messenger->addStatus($this->formatPlural($failures, 'Unable to delete 1 node', 'Unable to delete @count nodes')); + } + $this->tempStore->delete($this->currentUser->id()); + $form_state->setRedirectUrl($this->getCancelUrl()); + } + +} diff --git a/src/Plugin/Action/DeleteNodeAndMedia.php b/src/Plugin/Action/DeleteNodeAndMedia.php new file mode 100755 index 000000000..2dd243872 --- /dev/null +++ b/src/Plugin/Action/DeleteNodeAndMedia.php @@ -0,0 +1,46 @@ +currentUser = $current_user; + $this->tempStore = $temp_store_factory->get('node_and_media_delete_confirm'); + $this->entityTypeManager = $entity_type_manager; + $this->configuration = $configuration; + $this->pluginId = $plugin_id; + $this->pluginDefinition = $plugin_definition; + } + + /** + * {@inheritdoc} + */ + public function executeMultiple(array $entities): void { + $selection = []; + foreach ($entities as $entity) { + $langcode = $entity->language()->getId(); + $selection[$entity->id()][$langcode] = $langcode; + } + $this->tempStore->set("{$this->currentUser->id()}:node", $selection); + } + +} From 9fd63e5a8b64b9eeedffb2b87ca85ed3fde45b54 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 31 Jul 2024 14:33:29 -0300 Subject: [PATCH 248/252] Some deprecations in advance of Drupal 11 (#1026) --- .github/workflows/build-2.x.yml | 6 +++--- src/Plugin/Field/FieldType/MediaTrackItem.php | 2 +- tests/src/Functional/AddMediaToNodeTest.php | 4 ++-- tests/src/Functional/IslandoraFunctionalTestBase.php | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index 8677ddf4e..529aeff02 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -44,7 +44,7 @@ jobs: - 61613:61613 steps: - + - name: Checkout code uses: actions/checkout@v4 with: @@ -70,7 +70,7 @@ jobs: sudo apt-get install -y mysql-client - name: Cache Composer dependencies - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: /tmp/composer-cache key: ${{ runner.os }}-${{ hashFiles('**/composer.lock') }} @@ -101,7 +101,7 @@ jobs: - name: Test scripts run: $SCRIPT_DIR/travis_scripts.sh - + - name: Start chromedriver if: matrix.test-suite == 'functional-javascript' run: |- diff --git a/src/Plugin/Field/FieldType/MediaTrackItem.php b/src/Plugin/Field/FieldType/MediaTrackItem.php index d281ed216..68756ae59 100644 --- a/src/Plugin/Field/FieldType/MediaTrackItem.php +++ b/src/Plugin/Field/FieldType/MediaTrackItem.php @@ -16,7 +16,7 @@ * id = "media_track", * label = @Translation("Media track"), * description = @Translation("This field stores the ID of a media track file as an integer value."), - * category = @Translation("Reference"), + * category = "reference", * default_widget = "media_track", * default_formatter = "file_default", * column_groups = { diff --git a/tests/src/Functional/AddMediaToNodeTest.php b/tests/src/Functional/AddMediaToNodeTest.php index 4b0b62c52..ab67a6604 100644 --- a/tests/src/Functional/AddMediaToNodeTest.php +++ b/tests/src/Functional/AddMediaToNodeTest.php @@ -3,7 +3,7 @@ namespace Drupal\Tests\islandora\Functional; use Drupal\Core\Url; -use Drupal\Tests\field\Traits\EntityReferenceTestTrait; +use Drupal\Tests\field\Traits\EntityReferenceFieldCreationTrait; /** * Tests the RelatedLinkHeader view alter. @@ -12,7 +12,7 @@ */ class AddMediaToNodeTest extends IslandoraFunctionalTestBase { - use EntityReferenceTestTrait; + use EntityReferenceFieldCreationTrait; /** * Node to hold the media. diff --git a/tests/src/Functional/IslandoraFunctionalTestBase.php b/tests/src/Functional/IslandoraFunctionalTestBase.php index 1ad8081d1..e58ec0162 100644 --- a/tests/src/Functional/IslandoraFunctionalTestBase.php +++ b/tests/src/Functional/IslandoraFunctionalTestBase.php @@ -8,7 +8,7 @@ use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\link\LinkItemInterface; use Drupal\Tests\BrowserTestBase; -use Drupal\Tests\field\Traits\EntityReferenceTestTrait; +use Drupal\Tests\field\Traits\EntityReferenceFieldCreationTrait; use Drupal\Tests\media\Traits\MediaTypeCreationTrait; use Drupal\Tests\TestFileCreationTrait; @@ -17,7 +17,7 @@ */ class IslandoraFunctionalTestBase extends BrowserTestBase { - use EntityReferenceTestTrait; + use EntityReferenceFieldCreationTrait; use TestFileCreationTrait; use MediaTypeCreationTrait; use StringTranslationTrait; From 54958b311fee4de78a7babf8cfdef321a2002c03 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 7 Aug 2024 14:16:10 -0300 Subject: [PATCH 249/252] Update gitlab-mirror.yml (#1046) --- .github/workflows/gitlab-mirror.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gitlab-mirror.yml b/.github/workflows/gitlab-mirror.yml index f59207e8a..fa3eda50b 100644 --- a/.github/workflows/gitlab-mirror.yml +++ b/.github/workflows/gitlab-mirror.yml @@ -9,7 +9,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Mirror + trigger CI From ea87476b6daca5f3cd6e365ad6eb2f01f5352c8e Mon Sep 17 00:00:00 2001 From: Adam <607975+adam-vessey@users.noreply.github.com> Date: Thu, 8 Aug 2024 14:02:28 -0300 Subject: [PATCH 250/252] Update IIIFManifest.php (#1047) --- modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 6afae2499..86389c0d8 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -711,7 +711,8 @@ public function submitOptionsForm(&$form, FormStateInterface $form_state) { protected function getStructuredTextTerm() : ?TermInterface { if (!$this->structuredTextTermMemoized) { $this->structuredTextTermMemoized = TRUE; - $this->structuredTextTerm = $this->utils->getTermForUri($this->options['structured_text_term_uri']); + $uri = $this->options['structured_text_term_uri'] ?? NULL; + $this->structuredTextTerm = $uri ? $this->utils->getTermForUri($uri) : NULL; } return $this->structuredTextTerm; From 2b9b320c70de6c1a9eb93c5172a573194a306dc6 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 8 Aug 2024 14:42:10 -0300 Subject: [PATCH 251/252] Add config schema for new Action, and alter wording. (#1044) --- modules/islandora_iiif/README.md | 25 ++++++++++--------- .../config/schema/islandora_iiif.schema.yml | 10 ++++++++ .../Plugin/Action/MediaAttributesFromIiif.php | 8 +++--- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/modules/islandora_iiif/README.md b/modules/islandora_iiif/README.md index 676723e9e..3375e4d20 100644 --- a/modules/islandora_iiif/README.md +++ b/modules/islandora_iiif/README.md @@ -41,38 +41,39 @@ This module implements a Views Style plugin. It provides the following settings: 3. Structured Text Term: If your Islandora Object has a separate media with hOCR, point to it with this setting. 4. File Width and Height fields: If you want to use TIFF or JP2 files directly, set the fields where the files' width and height can be found with these settings. -### Media Attributes from IIIF Action +### Action to add image dimensions from the IIIF server The module also provides an action that lets a site owner populate a TIFF or JP2 image's width and -height attributes into fields so the IIIF server is not bogged down trying to generate a manifest if +height attributes into fields on the media so the IIIF server is not bogged down trying to generate a manifest if it doesn't have them. -It is a complex action that must be configured. Go to +It is an advanced action that must be configured. Go to Admin -> Actions UI -> Actions, choose "Add image dimensions retrieved from the IIIF server" from the Create Action drop-down -And on the next screen, choose the width +And on the next screen, choose the Media Use term which this should be applied to (as +it is a node action), as well as the width and height fields that the action should populate. To use it, either: -- Add it as a derivative reaction to a node with an Original FIle as its child, or -- Use it as a batch action, such as on a Paged Content object's list of child pages. +- Add it as a derivative reaction (in Contexts) to a node, or +- Use it as a batch action in a View, such as on a Paged Content object's list of child pages. -### Setting up the action as a Context Reaction +### Setting up the action as a Contexts Derivative Reaction These instructions assume a standard Islandora Starter Site, so if you have different field names or Contexts, adjust accordingly. 1. Go to admin/config/system/actions -2. Choose "Add image dimensions retrieved from the IIIF server" from the Create Complex Action drop-down and then click Create. +2. Choose "Add image dimensions retrieved from the IIIF server" from the Create advanced Action drop-down and then click Create. 3. Enter Original File for the Source Media Use term. 4. Choose media -- file -- Width and Media -- File -- Height for the corresponding configuration values and click Save. -5. Go to admin/structure/context, and click Duplicate oon the Page Derivatives row. -6. Name the new context something like "Retrieve Page Dimensionss". and edit it. +5. Go to admin/structure/context, and click Duplicate on the Page Derivatives row. +6. Name the new context something like "Retrieve Page Dimensions" and edit it. 7. This is the tricky bit, delete 'Original File' from the 'Media has term with URI' field and replace it with Service File. The explanation for this is that to retrieve a file from the IIIF server, it must be part of an Islandora Media that has been fully created and saved and given a URL. This hasn't happened yet when Original File derivatives are being created, so we need to hang our action onto a derivative that is created after the original one. -8. Under Reactions, deselect the existing actions and select "Add i mage dimensions from IIIF sserver" and click Save and continue. +8. Under Reactions, deselect the existing actions and select "Add image dimensions from IIIF server" and click Save and continue. 9. Go back to your Paged Content object and add another child with a File media, to which you should upload another TIFF or JP2 file. 10. Without going to the Original File Book Manifestt, make sure that a service file has been generated, then click Edit on the Original File media. -11. Ensure that the Width and Height fields are populated with thee correct values from the file. +11. Ensure that the Width and Height fields are populated with the correct values based on the file. ## Documentation diff --git a/modules/islandora_iiif/config/schema/islandora_iiif.schema.yml b/modules/islandora_iiif/config/schema/islandora_iiif.schema.yml index 11fff4c71..46a7f569c 100644 --- a/modules/islandora_iiif/config/schema/islandora_iiif.schema.yml +++ b/modules/islandora_iiif/config/schema/islandora_iiif.schema.yml @@ -31,3 +31,13 @@ views.style.iiif_manifest: search_endpoint: type: string label: "Search endpoint path" + +action.configuration.media_attributes_from_iiif_action: + type: mapping + mapping: + source_term_uri: + type: string + width_field: + type: string + height_field: + type: string diff --git a/modules/islandora_iiif/src/Plugin/Action/MediaAttributesFromIiif.php b/modules/islandora_iiif/src/Plugin/Action/MediaAttributesFromIiif.php index cfe41f17c..43813b506 100644 --- a/modules/islandora_iiif/src/Plugin/Action/MediaAttributesFromIiif.php +++ b/modules/islandora_iiif/src/Plugin/Action/MediaAttributesFromIiif.php @@ -151,7 +151,7 @@ public static function create(ContainerInterface $container, array $configuratio public function execute($entity = NULL) { $width = $height = FALSE; - // Get the original File media use term. + // Get the selected media use term. $source_term = $this->utils->getTermForUri($this->configuration['source_term_uri']); $source_mids = $this->utils->getMediaReferencingNodeAndTerm($entity, $source_term); @@ -204,10 +204,10 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta $form['source_term'] = [ '#type' => 'entity_autocomplete', '#target_type' => 'taxonomy_term', - '#title' => $this->t('Source media use term'), + '#title' => $this->t('Media use term of media to process.'), '#default_value' => $this->utils->getTermForUri($this->configuration['source_term_uri']), '#required' => TRUE, - '#description' => $this->t('Term indicating the source media'), + '#description' => $this->t('Term that indicates the child media on which to perform this action.'), ]; $form['width_field'] = [ @@ -235,7 +235,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta public function defaultConfiguration() { $config = parent::defaultConfiguration(); - $config['media_use_term'] = ''; + $config['source_term_uri'] = ''; $config['width_field'] = ''; $config['height_field'] = ''; From b0df472a621d61cd88c82fd1536183a08bf13871 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 15 Aug 2024 17:22:21 -0300 Subject: [PATCH 252/252] Use vocabulary's current name, Media Use (#1052) * Use vocabulary's current name, Media Use * Update MediaSourceController.php --- src/Controller/MediaSourceController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controller/MediaSourceController.php b/src/Controller/MediaSourceController.php index 3d0e79092..02a652131 100644 --- a/src/Controller/MediaSourceController.php +++ b/src/Controller/MediaSourceController.php @@ -136,7 +136,7 @@ public function put(MediaInterface $media, Request $request) { * @param \Drupal\media\MediaTypeInterface $media_type * Media type for new media. * @param \Drupal\taxonomy\TermInterface $taxonomy_term - * Term from the 'Behavior' vocabulary to give to new media. + * Term from the 'Media Use' vocabulary to give to new media. * @param \Symfony\Component\HttpFoundation\Request $request * The request object. *