From 4f45cb8c06df9da096260a6a449bec6f494cc65d Mon Sep 17 00:00:00 2001 From: Alan Stanley Date: Fri, 3 Dec 2021 14:46:52 -0400 Subject: [PATCH 001/281] added additional iiif config exception (#857) --- 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 90d67951727452896b2a281337b8fab6485ff237 Mon Sep 17 00:00:00 2001 From: Seth Shaw Date: Wed, 8 Dec 2021 10:19:17 -0800 Subject: [PATCH 002/281] Purge Migrate Tools (Issue 1994) (#859) * Update composer.json * purge migrate_tools instead --- README.md | 3 ++- composer.json | 2 -- islandora.info.yml | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c085764db..befd4926c 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,6 @@ Installing via composer will download all required libraries and modules. Howev - [eva](http://drupal.org/project/eva) - [features](http://drupal.org/project/features) - [migrate_plus](http://drupal.org/project/migrate_plus) -- [migrate_tools](http://drupal.org/project/migrate_tools) - [migrate_source_csv](http://drupal.org/project/migrate_source_csv) - [flysystem](http://drupal.org/project/flysystem) @@ -49,6 +48,8 @@ It also requires the following PHP libraries: - [Crayfish Commons](https://packagist.org/packages/islandora/crayfish-commons) - [Stomp PHP](http://drupal.org/project/) +If you are using a Drush version less than 10.4 you will also need to install and enable [migrate_tools](http://drupal.org/project/migrate_tools) separately. + ## Installation For a full digital repository solution, see our [installation documentation](https://islandora.github.io/documentation/installation/component_overview/). diff --git a/composer.json b/composer.json index f787f94a7..46bede3f2 100644 --- a/composer.json +++ b/composer.json @@ -24,13 +24,11 @@ "drupal/eva" : "^2.0", "drupal/features" : "^3.7", "drupal/migrate_plus" : "^5.1", - "drupal/migrate_tools" : "^5.0", "drupal/migrate_source_csv" : "^3.4", "drupal/token" : "^1.3", "drupal/flysystem" : "^2.0@alpha", "islandora/crayfish-commons": "^2", "drupal/file_replace": "^1.1" - }, "require-dev": { "phpunit/phpunit": "^6", diff --git a/islandora.info.yml b/islandora.info.yml index c66c1ba8d..9cd89cddc 100644 --- a/islandora.info.yml +++ b/islandora.info.yml @@ -27,7 +27,6 @@ dependencies: - drupal:media - drupal:prepopulate - drupal:features_ui - - drupal:migrate_tools - drupal:migrate_source_csv - drupal:content_translation - drupal:flysystem From c1aa0a5f2f593440b607b73245e103a9b6626371 Mon Sep 17 00:00:00 2001 From: Jared Whiklo Date: Fri, 21 Jan 2022 13:00:12 -0600 Subject: [PATCH 003/281] Update testing (#861) * Update Github Actions to test more --- .github/workflows/build-2.x.yml | 117 ++++++++++++++++++++++++++++++-- 1 file changed, 113 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index 306278ba6..ad11dca8a 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -19,17 +19,124 @@ jobs: build: # The type of runner that the job will run on runs-on: ubuntu-latest + continue-on-error: ${{ matrix.allowed_failure }} strategy: + fail-fast: false matrix: php-versions: ["7.3", "7.4"] test-suite: ["kernel", "functional", "functional-javascript"] - drupal-version: ["8.9.11", "9.1.5"] - - name: PHP ${{ matrix.php-versions }} drupal ${{ matrix.drupal-version }} test-suite ${{ matrix.test-suite }} + drupal-version: ["9.3.x", "9.4.x-dev"] + allowed_failure: [false] + mysql: ["5.7"] + # include experimental parts + include: + # 9.3.x on PHP 8.0 + - drupal-version: '9.3.x' + php-versions: '8.0' + mysql: "8.0" + test-suite: "kernel" + allowed_failure: true + - drupal-version: '9.3.x' + php-versions: '8.0' + mysql: "8.0" + test-suite: "functional" + allowed_failure: true + - drupal-version: '9.3.x' + php-versions: '8.0' + mysql: "8.0" + test-suite: "functional-javascript" + allowed_failure: true + # 9.3.x on PHP 8.1 + - drupal-version: '9.3.x' + php-versions: '8.1' + mysql: "8.0" + test-suite: "kernel" + allowed_failure: true + - drupal-version: '9.3.x' + php-versions: '8.1' + mysql: "8.0" + test-suite: "functional" + allowed_failure: true + - drupal-version: '9.3.x' + php-versions: '8.1' + mysql: "8.0" + test-suite: "functional-javascript" + allowed_failure: true + # 9.4.x-dev on PHP "8.0" + - drupal-version: '9.4.x-dev' + php-versions: '8.0' + mysql: "8.0" + test-suite: "kernel" + allowed_failure: true + - drupal-version: '9.4.x-dev' + php-versions: '8.0' + mysql: "8.0" + test-suite: "functional" + allowed_failure: true + - drupal-version: '9.4.x-dev' + php-versions: '8.0' + mysql: "8.0" + test-suite: "functional-javascript" + allowed_failure: true + - drupal-version: '10.0.x-dev' + php-versions: '8.0' + mysql: "8.0" + test-suite: "kernel" + allowed_failure: true + # 9.4.x-dev on PHP 8.1 + - drupal-version: '9.4.x-dev' + php-versions: '8.1' + mysql: "8.0" + test-suite: "kernel" + allowed_failure: true + - drupal-version: '9.4.x-dev' + php-versions: '8.1' + mysql: "8.0" + test-suite: "functional" + allowed_failure: true + - drupal-version: '9.4.x-dev' + php-versions: '8.1' + mysql: "8.0" + test-suite: "functional-javascript" + allowed_failure: true + # 10.0.x-dev on PHP 8.0 + - drupal-version: '10.0.x-dev' + php-versions: '8.0' + mysql: "8.0" + test-suite: "kernel" + allowed_failure: true + - drupal-version: '10.0.x-dev' + php-versions: '8.0' + mysql: "8.0" + test-suite: "functional" + allowed_failure: true + - drupal-version: '10.0.x-dev' + php-versions: '8.0' + mysql: "8.0" + test-suite: "functional-javascript" + allowed_failure: true + # 10.0.x-dev on PHP 8.1 + - drupal-version: '10.0.x-dev' + php-versions: '8.1' + mysql: "8.0" + test-suite: "kernel" + allowed_failure: true + - drupal-version: '10.0.x-dev' + php-versions: '8.1' + mysql: "8.0" + test-suite: "functional" + allowed_failure: true + - drupal-version: '10.0.x-dev' + php-versions: '8.1' + mysql: "8.0" + test-suite: "functional-javascript" + allowed_failure: true + + name: PHP ${{ matrix.php-versions }} | drupal ${{ matrix.drupal-version }} | mysql ${{ matrix.mysql }} | test-suite ${{ matrix.test-suite }} services: mysql: - image: mysql:5.7 + image: mysql:${{ matrix.mysql }} env: MYSQL_ALLOW_EMPTY_PASSWORD: yes MYSQL_DATABASE: drupal @@ -44,6 +151,7 @@ jobs: # 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@v2 @@ -66,6 +174,7 @@ jobs: - name: Setup Mysql client run: | sudo apt-get update + sudo apt-get remove -y mysql-client mysql-common sudo apt-get install -y mysql-client - name: Set environment variables From 77094253584bde34058fecfa0d838be7b7c9fadb Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Wed, 2 Feb 2022 17:03:22 +0000 Subject: [PATCH 004/281] Add check for cache tags in JSON-LD alter hook. --- islandora.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/islandora.module b/islandora.module index 738be5b43..85abaf0d0 100644 --- a/islandora.module +++ b/islandora.module @@ -251,7 +251,7 @@ function islandora_jsonld_alter_normalized_array(EntityInterface $entity, array $reaction->execute($entity, $normalized, $context); foreach ($context_manager->getActiveContexts() as $context_config) { try { - if ($context_config->getReaction($reaction->getPluginId())) { + if ($context_config->getReaction($reaction->getPluginId()) && isset($context['cacheability'])) { $context['cacheability']->addCacheTags($context_config->getCacheTags()); }; } From 2199336446580ca76f2ba043445c364be81a85d2 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Mon, 28 Feb 2022 17:49:25 +0000 Subject: [PATCH 005/281] Add further check to jsonld context cacheability to avoid white screen. --- islandora.module | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/islandora.module b/islandora.module index 85abaf0d0..dd8f363f2 100644 --- a/islandora.module +++ b/islandora.module @@ -251,7 +251,8 @@ function islandora_jsonld_alter_normalized_array(EntityInterface $entity, array $reaction->execute($entity, $normalized, $context); foreach ($context_manager->getActiveContexts() as $context_config) { try { - if ($context_config->getReaction($reaction->getPluginId()) && isset($context['cacheability'])) { + if ($context_config->getReaction($reaction->getPluginId()) && isset($context['cacheability']) + && method_exists($context['cacheability'], 'addCacheTags')) { $context['cacheability']->addCacheTags($context_config->getCacheTags()); }; } From 1a61b178754e2f44db42e427ebfc4a60add43e06 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Wed, 23 Mar 2022 12:50:09 +0000 Subject: [PATCH 006/281] Update to File Hash 2.x due to failing tests. See https://www.drupal.org/project/filehash/issues/3271137 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 46bede3f2..2993244dd 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ "islandora/jsonld": "^2", "stomp-php/stomp-php": "4.*", "drupal/jwt": "^1.0.0-beta5", - "drupal/filehash": "^1.1", + "drupal/filehash": "^2", "drupal/prepopulate" : "^2.2", "drupal/eva" : "^2.0", "drupal/features" : "^3.7", From 20f7ebb3328c57abc8062a16b027e8e4922fcbb9 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Wed, 23 Mar 2022 18:26:13 +0000 Subject: [PATCH 007/281] Maintain backward compatibility with File Hash v. 1.x Use valid license string per composer validate. --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 2993244dd..c783e12be 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ "islandora/jsonld": "^2", "stomp-php/stomp-php": "4.*", "drupal/jwt": "^1.0.0-beta5", - "drupal/filehash": "^2", + "drupal/filehash": "^1.1 || ^2", "drupal/prepopulate" : "^2.2", "drupal/eva" : "^2.0", "drupal/features" : "^3.7", @@ -39,7 +39,7 @@ "suggest": { "drupal/transliterate_filenames": "Sanitizes filenames when they are uploaded so they don't break your repository." }, - "license": "GPL-2.0+", + "license": "GPL-2.0-or-later", "authors": [ { "name": "Islandora Foundation", From 081183bc7171d563464fbe2e04a6e9762e68300d Mon Sep 17 00:00:00 2001 From: Islandora Foundation Community <92804539+islandora-community@users.noreply.github.com> Date: Wed, 23 Mar 2022 13:10:11 -0600 Subject: [PATCH 008/281] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index befd4926c..83e3f301c 100644 --- a/README.md +++ b/README.md @@ -109,9 +109,9 @@ Current maintainers: ## Development -If you would like to contribute, please get involved by attending our weekly [Tech Call](https://github.com/Islandora/documentation/wiki). We love to hear from you! +If you would like to contribute, please get involved by attending our weekly [Tech Call](https://github.com/Islandora/islandora-community/wiki/Weekly-Open-Tech-Call). We love to hear from you! -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. +If you would like to contribute code to the project, you need to be covered by an Islandora Foundation [Contributor License Agreement](https://github.com/Islandora/islandora-community/wiki/Onboarding-Checklist#contributor-license-agreements) or [Corporate Contributor License Agreement](https://github.com/Islandora/islandora-community/wiki/Onboarding-Checklist#contributor-license-agreements). Please see the [Contributor License Agreements](https://github.com/Islandora/islandora-community/wiki/Contributor-License-Agreements) page on the islandora-community wiki for more information. We recommend using the [islandora-playbook](https://github.com/Islandora-Devops/islandora-playbook) to get started. From 9c8193b75a79e90c59acbc13cfd322635f645fcc Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Thu, 24 Mar 2022 14:26:10 -0300 Subject: [PATCH 009/281] islandora:862 Incorporate PR review suggestion Co-authored-by: Jordan Dukart --- islandora.module | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/islandora.module b/islandora.module index dd8f363f2..f81693d33 100644 --- a/islandora.module +++ b/islandora.module @@ -251,9 +251,9 @@ function islandora_jsonld_alter_normalized_array(EntityInterface $entity, array $reaction->execute($entity, $normalized, $context); foreach ($context_manager->getActiveContexts() as $context_config) { try { - if ($context_config->getReaction($reaction->getPluginId()) && isset($context['cacheability']) - && method_exists($context['cacheability'], 'addCacheTags')) { - $context['cacheability']->addCacheTags($context_config->getCacheTags()); + if ($context_config->getReaction($reaction->getPluginId()) && isset($context[CacheableNormalizerInterface::SERIALIZATION_CONTEXT_CACHEABILITY])) { + $context[CacheableNormalizerInterface::SERIALIZATION_CONTEXT_CACHEABILITY]->addCacheableDependency($context_config); + }; }; } catch (PluginNotFoundException $e) { From f7287be0125e90bf7a5904ebac6a8c7c896e1a63 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Thu, 24 Mar 2022 18:04:31 +0000 Subject: [PATCH 010/281] islandora:862 Add Use statement to go with last commit. --- islandora.module | 1 + 1 file changed, 1 insertion(+) diff --git a/islandora.module b/islandora.module index f81693d33..8cff7884e 100644 --- a/islandora.module +++ b/islandora.module @@ -26,6 +26,7 @@ use Drupal\media\MediaInterface; use Drupal\file\FileInterface; use Drupal\taxonomy\TermInterface; use Drupal\Core\Routing\RouteMatchInterface; +use Drupal\serialization\Normalizer\CacheableNormalizerInterface; /** * Implements hook_help(). From ac749ce3b59526bc26af545c25e0ded423a97991 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Thu, 24 Mar 2022 18:18:48 +0000 Subject: [PATCH 011/281] Fix syntax error. --- islandora.module | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/islandora.module b/islandora.module index 8cff7884e..d7f1ceb64 100644 --- a/islandora.module +++ b/islandora.module @@ -253,8 +253,7 @@ function islandora_jsonld_alter_normalized_array(EntityInterface $entity, array foreach ($context_manager->getActiveContexts() as $context_config) { try { if ($context_config->getReaction($reaction->getPluginId()) && isset($context[CacheableNormalizerInterface::SERIALIZATION_CONTEXT_CACHEABILITY])) { - $context[CacheableNormalizerInterface::SERIALIZATION_CONTEXT_CACHEABILITY]->addCacheableDependency($context_config); - }; + $context[CacheableNormalizerInterface::SERIALIZATION_CONTEXT_CACHEABILITY]->addCacheableDependency($context_config); }; } catch (PluginNotFoundException $e) { From 4c08d5a274b1ac313cc523aa2df67d6f5d640429 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Thu, 24 Mar 2022 19:10:17 +0000 Subject: [PATCH 012/281] islandora:862 Remove white space at end of line causing failing tests. --- islandora.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/islandora.module b/islandora.module index d7f1ceb64..e26888674 100644 --- a/islandora.module +++ b/islandora.module @@ -253,7 +253,7 @@ function islandora_jsonld_alter_normalized_array(EntityInterface $entity, array foreach ($context_manager->getActiveContexts() as $context_config) { try { if ($context_config->getReaction($reaction->getPluginId()) && isset($context[CacheableNormalizerInterface::SERIALIZATION_CONTEXT_CACHEABILITY])) { - $context[CacheableNormalizerInterface::SERIALIZATION_CONTEXT_CACHEABILITY]->addCacheableDependency($context_config); + $context[CacheableNormalizerInterface::SERIALIZATION_CONTEXT_CACHEABILITY]->addCacheableDependency($context_config); }; } catch (PluginNotFoundException $e) { From 4c439d48171220468304ca5e1ade7badf97370f6 Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Fri, 25 Mar 2022 12:47:40 -0300 Subject: [PATCH 013/281] Ensure node exists before using it. (#864) --- src/Controller/ManageMediaController.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Controller/ManageMediaController.php b/src/Controller/ManageMediaController.php index 56e0b5c50..bd670561a 100644 --- a/src/Controller/ManageMediaController.php +++ b/src/Controller/ManageMediaController.php @@ -45,13 +45,19 @@ public function addToNodePage(NodeInterface $node) { * Whether we can or can't show the "thing". */ public function access(RouteMatch $route_match) { + // Route match is being used as opposed to slugs as there are a few + // admin routes being altered. + // @see: \Drupal\islandora\EventSubscriber\AdminViewsRouteSubscriber::alterRoutes(). if ($route_match->getParameters()->has('node')) { $node = $route_match->getParameter('node'); if (!$node instanceof NodeInterface) { $node = Node::load($node); } - if ($this->utils->isIslandoraType($node->getEntityTypeId(), $node->bundle())) { - return AccessResult::allowed(); + // Ensure there's actually a node before referencing it. + if ($node) { + if ($this->utils->isIslandoraType($node->getEntityTypeId(), $node->bundle())) { + return AccessResult::allowed(); + } } } return AccessResult::forbidden(); From bd98028f0026653ac285d3a45602f5c5f697131a Mon Sep 17 00:00:00 2001 From: Ant Brown Date: Sat, 26 Mar 2022 04:56:55 +1300 Subject: [PATCH 014/281] Fill in blanks for IntegerWeightSelector (Islandora#2065) (#863) Authored-by: Ant Brown --- src/Plugin/views/field/IntegerWeightSelector.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Plugin/views/field/IntegerWeightSelector.php b/src/Plugin/views/field/IntegerWeightSelector.php index 141d3567b..60892c960 100644 --- a/src/Plugin/views/field/IntegerWeightSelector.php +++ b/src/Plugin/views/field/IntegerWeightSelector.php @@ -46,12 +46,13 @@ public function viewsForm(array &$form, FormStateInterface $form_state) { $options[$this->getValue($row)] = $this->getValue($row); } - // If we were given some blank values we need to fill + // If we were given some blank values, or less than the + // total_rows for the view, we need to fill // out the option list from 1 through the result count // to make sure we have enough. (Blanks should only appear // at the beginning of the results list.) // Also, blank values will break the selector, remove it. - if (array_key_exists('', $options)) { + if (array_key_exists('', $options) || (count($options) < $this->view->total_rows)) { unset($options['']); for ($i = 1; $i <= $this->view->total_rows; $i++) { $options[$i] = $i; From a7e4c1659e2a7cb1539143158a2e2b1c05b8a23c Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Tue, 5 Apr 2022 14:15:17 -0300 Subject: [PATCH 015/281] Add ancestor helper and condition. (#865) * Add ancestor condition. * Move the ancestors to the utils helper, re-work the builder. * Use the config option as opposed to hard coding. * Handle a looping scenario (a > b > c > a). --- .../islandora_breadcrumbs.services.yml | 2 +- .../src/IslandoraBreadcrumbBuilder.php | 59 +++--- src/IslandoraUtils.php | 79 ++++++++ src/Plugin/Condition/NodeHasAncestor.php | 169 ++++++++++++++++++ 4 files changed, 272 insertions(+), 37 deletions(-) create mode 100644 src/Plugin/Condition/NodeHasAncestor.php diff --git a/modules/islandora_breadcrumbs/islandora_breadcrumbs.services.yml b/modules/islandora_breadcrumbs/islandora_breadcrumbs.services.yml index 58e3c9594..71c723f02 100644 --- a/modules/islandora_breadcrumbs/islandora_breadcrumbs.services.yml +++ b/modules/islandora_breadcrumbs/islandora_breadcrumbs.services.yml @@ -1,6 +1,6 @@ services: islandora_breadcrumbs.breadcrumb: class: Drupal\islandora_breadcrumbs\IslandoraBreadcrumbBuilder - arguments: ['@entity_type.manager', '@config.factory'] + arguments: ['@entity_type.manager', '@config.factory', '@islandora.utils'] tags: - { name: breadcrumb_builder, priority: 100 } diff --git a/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php b/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php index 93ed7097b..620f22895 100644 --- a/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php +++ b/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php @@ -4,12 +4,12 @@ use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Breadcrumb\Breadcrumb; use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface; use Drupal\Core\Link; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; +use Drupal\islandora\IslandoraUtils; /** * Provides breadcrumbs for nodes using a configured entity reference field. @@ -31,6 +31,13 @@ class IslandoraBreadcrumbBuilder implements BreadcrumbBuilderInterface { */ protected $nodeStorage; + /** + * Islandora utils. + * + * @var \Drupal\islandora\IslandoraUtils + */ + protected $utils; + /** * Constructs a breadcrumb builder. * @@ -38,10 +45,13 @@ class IslandoraBreadcrumbBuilder implements BreadcrumbBuilderInterface { * Storage to load nodes. * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * The configuration factory. + * @param \Drupal\islandora\IslandoraUtils $utils + * Islandora utils service. */ - public function __construct(EntityTypeManagerInterface $entity_manager, ConfigFactoryInterface $config_factory) { + public function __construct(EntityTypeManagerInterface $entity_manager, ConfigFactoryInterface $config_factory, IslandoraUtils $utils) { $this->nodeStorage = $entity_manager->getStorage('node'); $this->config = $config_factory->get('islandora_breadcrumbs.breadcrumbs'); + $this->utils = $utils; } /** @@ -68,49 +78,26 @@ public function build(RouteMatchInterface $route_match) { $breadcrumb = new Breadcrumb(); $breadcrumb->addLink(Link::createFromRoute($this->t('Home'), '')); - $chain = []; - $this->walkMembership($node, $chain); + $chain = array_reverse($this->utils->findAncestors($node, [$this->config->get('referenceField')], $this->config->get('maxDepth'))); - if (!$this->config->get('includeSelf')) { - array_pop($chain); + // XXX: Handle a looping breadcrumb scenario by filtering the present + // node out and then optionally re-adding it after if set to do so. + $chain = array_filter($chain, function ($link) use ($nid) { + return $link !== $nid; + }); + if ($this->config->get('includeSelf')) { + array_push($chain, $node); } $breadcrumb->addCacheableDependency($node); // Add membership chain to the breadcrumb. foreach ($chain as $chainlink) { - $breadcrumb->addCacheableDependency($chainlink); - $breadcrumb->addLink($chainlink->toLink()); + $node = $this->nodeStorage->load($chainlink); + $breadcrumb->addCacheableDependency($node); + $breadcrumb->addLink($node->toLink()); } $breadcrumb->addCacheContexts(['route']); return $breadcrumb; } - /** - * Follows chain of field_member_of links. - * - * We pass crumbs by reference to enable checking for looped chains. - */ - protected function walkMembership(EntityInterface $entity, &$crumbs) { - // Avoid infinate loops, return if we've seen this before. - foreach ($crumbs as $crumb) { - if ($crumb->uuid == $entity->uuid) { - return; - } - } - - // Add this item onto the pile. - array_unshift($crumbs, $entity); - - if ($this->config->get('maxDepth') > 0 && count($crumbs) >= $this->config->get('maxDepth')) { - return; - } - - // Find the next in the chain, if there are any. - if ($entity->hasField($this->config->get('referenceField')) && - !$entity->get($this->config->get('referenceField'))->isEmpty() && - $entity->get($this->config->get('referenceField'))->entity instanceof EntityInterface) { - $this->walkMembership($entity->get($this->config->get('referenceField'))->entity, $crumbs); - } - } - } diff --git a/src/IslandoraUtils.php b/src/IslandoraUtils.php index a4dda6c12..e5071a05b 100644 --- a/src/IslandoraUtils.php +++ b/src/IslandoraUtils.php @@ -672,4 +672,83 @@ public function canCreateIslandoraEntity($entity_type, $bundle_type) { return FALSE; } + /** + * Recursively finds ancestors of an entity. + * + * @param \Drupal\Core\Entity\ContentEntityInterface $entity + * The entity being checked. + * @param array $fields + * An optional array where the values are the field names to be used for + * retrieval. + * @param int|bool $max_height + * How many levels of checking should be done when retrieving ancestors. + * + * @return array + * An array where the keys and values are the node IDs of the ancestors. + */ + public function findAncestors(ContentEntityInterface $entity, array $fields = [self::MEMBER_OF_FIELD], $max_height = FALSE): array { + // XXX: If a negative integer is passed assume it's false. + if ($max_height < 0) { + $max_height = FALSE; + } + $context = [ + 'max_height' => $max_height, + 'ancestors' => [], + ]; + $this->findAncestorsByEntityReference($entity, $context, $fields); + return $context['ancestors']; + } + + /** + * Helper that builds up the ancestors. + * + * @param \Drupal\Core\Entity\ContentEntityInterface $entity + * The entity being checked. + * @param array $context + * An array containing: + * -ancestors: The ancestors that have been found. + * -max_height: How far up the chain to go. + * @param array $fields + * An optional array where the values are the field names to be used for + * retrieval. + * @param int $current_height + * The current height of the recursion. + */ + protected function findAncestorsByEntityReference(ContentEntityInterface $entity, array &$context, array $fields = [self::MEMBER_OF_FIELD], int $current_height = 0): void { + $parents = $this->getParentsByEntityReference($entity, $fields); + foreach ($parents as $parent) { + if (isset($context['ancestors'][$parent->id()])) { + continue; + } + $context['ancestors'][$parent->id()] = $parent->id(); + if ($context['max_height'] === FALSE || $current_height < $context['max_height']) { + $this->findAncestorsByEntityReference($parent, $context, $fields, $current_height + 1); + } + } + } + + /** + * Helper that gets the immediate parents of a node. + * + * @param \Drupal\Core\Entity\ContentEntityInterface $entity + * The entity being checked. + * @param array $fields + * An array where the values are the field names to be used. + * + * @return array + * An array of entity objects keyed by field item deltas. + */ + protected function getParentsByEntityReference(ContentEntityInterface $entity, array $fields): array { + $parents = []; + foreach ($fields as $field) { + if ($entity->hasField($field)) { + $reference_field = $entity->get($field); + if (!$reference_field->isEmpty()) { + $parents = array_merge($parents, $reference_field->referencedEntities()); + } + } + } + return $parents; + } + } diff --git a/src/Plugin/Condition/NodeHasAncestor.php b/src/Plugin/Condition/NodeHasAncestor.php new file mode 100644 index 000000000..dd2abc54b --- /dev/null +++ b/src/Plugin/Condition/NodeHasAncestor.php @@ -0,0 +1,169 @@ +entityTypeManager = $entity_type_manager; + $this->utils = $islandora_utils; + } + + /** + * {@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('islandora.utils') + ); + } + + /** + * {@inheritdoc} + */ + public function defaultConfiguration(): array { + return parent::defaultConfiguration() + [ + 'ancestor_nids' => FALSE, + 'parent_reference_field' => IslandoraUtils::MEMBER_OF_FIELD, + ]; + } + + /** + * {@inheritdoc} + */ + public function buildConfigurationForm(array $form, FormStateInterface $form_state) { + $default_nids = FALSE; + if ($this->configuration['ancestor_nids']) { + $default_nids = array_map(function ($nid) { + return $this->entityTypeManager->getStorage('node')->load($nid); + }, $this->configuration['ancestor_nids']); + } + $form['ancestor_nids'] = [ + '#type' => 'entity_autocomplete', + '#title' => $this->t('Parent node(s)'), + '#default_value' => $default_nids, + '#required' => TRUE, + '#description' => $this->t("Can be a collection node, compound object or paged content. Accepts multiple values separated by a comma."), + '#target_type' => 'node', + '#tags' => TRUE, + ]; + + $options = []; + $reference_fields = $this->entityTypeManager->getStorage('field_storage_config')->loadByProperties([ + 'type' => 'entity_reference', + 'settings' => [ + 'target_type' => 'node', + ], + ]); + foreach ($reference_fields as $field) { + $options[$field->get('field_name')] = $field->get('field_name'); + } + $form['parent_reference_field'] = [ + '#type' => 'select', + '#title' => $this->t('Direct parent reference'), + '#options' => $options, + '#default_value' => $this->configuration['parent_reference_field'], + '#required' => TRUE, + '#description' => $this->t('Field that contains the reference to its parent node.'), + ]; + + return parent::buildConfigurationForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { + // Entity autocomplete store things with target IDs, for convenience just + // store the plain nid. + $this->configuration['ancestor_nids'] = array_map(function ($nid) { + return $nid['target_id']; + }, $form_state->getValue('ancestor_nids')); + $this->configuration['parent_reference_field'] = $form_state->getValue('parent_reference_field'); + parent::submitConfigurationForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function evaluate() { + if (empty($this->configuration['ancestor_nids']) && !$this->isNegated()) { + return TRUE; + } + + $node = $this->getContextValue('node'); + if (!$node) { + return FALSE; + } + + $ancestors = $this->utils->findAncestors($node); + return !empty(array_intersect($this->configuration['ancestor_nids'], $ancestors)); + } + + /** + * {@inheritdoc} + */ + public function summary() { + if (!empty($this->configuration['negate'])) { + return $this->t('The node does not have node @nid as one of its ancestors.', ['@nid' => $this->configuration['ancestor_nids']]); + } + else { + return $this->t('The node has node @nid as one of its ancestors.', ['@nid' => $this->configuration['ancestor_nids']]); + } + } + +} From e0152eaa8cf72177bfd24063b53ea775e0af1f1c Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Fri, 8 Apr 2022 14:43:32 -0300 Subject: [PATCH 016/281] Per step not job. (#866) --- .github/workflows/build-2.x.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index ad11dca8a..80c581879 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -19,7 +19,6 @@ jobs: build: # The type of runner that the job will run on runs-on: ubuntu-latest - continue-on-error: ${{ matrix.allowed_failure }} strategy: fail-fast: false matrix: @@ -197,6 +196,7 @@ jobs: cd $DRUPAL_DIR chmod -R u+w web/sites/default mkdir -p web/sites/simpletest/browser_output + continue-on-error: ${{ matrix.allowed_failure }} - name: Setup composer paths run: | @@ -211,15 +211,18 @@ jobs: 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 + continue-on-error: ${{ matrix.allowed_failure }} - name: Copy PHPunit file run: cp $PHPUNIT_FILE $DRUPAL_DIR/web/core/phpunit.xml - name: Test scripts run: $SCRIPT_DIR/travis_scripts.sh + continue-on-error: ${{ matrix.allowed_failure }} - name: PHPUNIT tests run: | cd $DRUPAL_DIR/web/core $DRUPAL_DIR/vendor/bin/phpunit --verbose --testsuite "${{ matrix.test-suite }}" + continue-on-error: ${{ matrix.allowed_failure }} From a04a72c483e38b3e18c93a553d34228ca69f1d40 Mon Sep 17 00:00:00 2001 From: Simon Hieu Mai Date: Tue, 19 Apr 2022 11:54:54 -0500 Subject: [PATCH 017/281] The "Node has ancestor" condition shouldn't be required (#867) --- src/Plugin/Condition/NodeHasAncestor.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Plugin/Condition/NodeHasAncestor.php b/src/Plugin/Condition/NodeHasAncestor.php index dd2abc54b..ad6f1b99e 100644 --- a/src/Plugin/Condition/NodeHasAncestor.php +++ b/src/Plugin/Condition/NodeHasAncestor.php @@ -96,7 +96,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta '#type' => 'entity_autocomplete', '#title' => $this->t('Parent node(s)'), '#default_value' => $default_nids, - '#required' => TRUE, + '#required' => FALSE, '#description' => $this->t("Can be a collection node, compound object or paged content. Accepts multiple values separated by a comma."), '#target_type' => 'node', '#tags' => TRUE, @@ -130,9 +130,11 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta public function submitConfigurationForm(array &$form, FormStateInterface $form_state) { // Entity autocomplete store things with target IDs, for convenience just // store the plain nid. - $this->configuration['ancestor_nids'] = array_map(function ($nid) { - return $nid['target_id']; - }, $form_state->getValue('ancestor_nids')); + if (!empty($form_state->getValue('ancestor_nids'))) { + $this->configuration['ancestor_nids'] = array_map(function ($nid) { + return $nid['target_id']; + }, $form_state->getValue('ancestor_nids')); + } $this->configuration['parent_reference_field'] = $form_state->getValue('parent_reference_field'); parent::submitConfigurationForm($form, $form_state); } From e9f9aad49c78c92c11e46b93289b7c3b44cb6069 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Fri, 29 Apr 2022 19:08:15 +0000 Subject: [PATCH 018/281] Set IIIF Manifest title based on content title. --- .../src/Plugin/views/style/IIIFManifest.php | 29 +++++++++++++++++-- 1 file changed, 26 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 073ca04e8..779451c2b 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -121,18 +121,22 @@ public function render() { $iiif_address = $this->iiifConfig->get('iiif_server'); if (!is_null($iiif_address) && !empty($iiif_address)) { // Get the current URL being requested. - $request_url = $this->request->getSchemeAndHttpHost() . $this->request->getRequestUri(); + $request_host = $this->request->getSchemeAndHttpHost(); + $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); array_pop($url_components); - $iiif_base_id = implode('/', $url_components); + $content_path = implode('/', $url_components); + $iiif_base_id = $request_host . '/' . $content_path; + + // @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() ?: 'IIIF Manifest', + 'label' => $this->view->getTitle() ?: $this->getEntityTitle($content_path), '@context' => 'http://iiif.io/api/presentation/2/context.json', // @see https://iiif.io/api/presentation/2.1/#sequence 'sequences' => [ @@ -260,6 +264,25 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas return $canvases; } + /** + * Pull a title from the node or media passed to this view. + * + * @param string $content_path + * @return string + */ + public function getEntityTitle(string $content_path): string { + $entity_title = $this->t('IIIF Manifest'); + $params = \Drupal\Core\Url::fromUserInput($content_path)->getRouteParameters(); + if (isset($params['node'])) { + $node = \Drupal\node\Entity\Node::load($params['node']); + $entity_title = $node->getTitle(); + } elseif (isset($params['media'])) { + $media = \Drupal\media\Entity\Media::load($params['media']); + $entity_title = $media->getName(); + } + return $entity_title; + } + /** * {@inheritdoc} */ From 71b1cb5d645e2303390f42f1c1b6cc85506f1aa1 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Mon, 2 May 2022 14:25:22 +0000 Subject: [PATCH 019/281] Add try() wrapper to IIIF manifest title generate function. --- .../src/Plugin/views/style/IIIFManifest.php | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 779451c2b..2dfe5011f 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -130,7 +130,6 @@ public function render() { $content_path = implode('/', $url_components); $iiif_base_id = $request_host . '/' . $content_path; - // @see https://iiif.io/api/presentation/2.1/#manifest $json += [ '@type' => 'sc:Manifest', @@ -272,13 +271,17 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas */ public function getEntityTitle(string $content_path): string { $entity_title = $this->t('IIIF Manifest'); - $params = \Drupal\Core\Url::fromUserInput($content_path)->getRouteParameters(); - if (isset($params['node'])) { - $node = \Drupal\node\Entity\Node::load($params['node']); - $entity_title = $node->getTitle(); - } elseif (isset($params['media'])) { - $media = \Drupal\media\Entity\Media::load($params['media']); - $entity_title = $media->getName(); + try { + $params = \Drupal\Core\Url::fromUserInput($content_path)->getRouteParameters(); + if (isset($params['node'])) { + $node = \Drupal\node\Entity\Node::load($params['node']); + $entity_title = $node->getTitle(); + } elseif (isset($params['media'])) { + $media = \Drupal\media\Entity\Media::load($params['media']); + $entity_title = $media->getName(); + } + } catch (\InvalidArgumentException $e) { + } return $entity_title; } From d8d101e5710c42804f06eff0f6c6a4ee3c69adbd Mon Sep 17 00:00:00 2001 From: Jared Whiklo Date: Tue, 3 May 2022 10:55:39 -0500 Subject: [PATCH 020/281] Ensure we can connect to the JMS Broker everytime (#868) --- src/EventGenerator/EmitEvent.php | 50 ++++++++++++++----- .../Action/AbstractGenerateDerivativeBase.php | 12 +++-- 2 files changed, 47 insertions(+), 15 deletions(-) diff --git a/src/EventGenerator/EmitEvent.php b/src/EventGenerator/EmitEvent.php index ebec711f4..683f3e8b6 100644 --- a/src/EventGenerator/EmitEvent.php +++ b/src/EventGenerator/EmitEvent.php @@ -5,6 +5,7 @@ use Drupal\Core\Access\AccessResult; use Drupal\Core\Action\ConfigurableActionBase; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Logger\LoggerChannelInterface; use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormStateInterface; @@ -67,6 +68,13 @@ abstract class EmitEvent extends ConfigurableActionBase implements ContainerFact */ protected $messenger; + /** + * The logger. + * + * @var \Drupal\Core\Logger\LoggerChannelInterface + */ + protected $logger; + /** * Constructs a EmitEvent action. * @@ -88,6 +96,8 @@ abstract class EmitEvent extends ConfigurableActionBase implements ContainerFact * The messenger. * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher * Event dispatcher service. + * @param \Drupal\Core\Logger\LoggerChannelInterface $channel + * Logger channel. */ public function __construct( array $configuration, @@ -98,7 +108,8 @@ public function __construct( EventGeneratorInterface $event_generator, StatefulStomp $stomp, MessengerInterface $messenger, - EventDispatcherInterface $event_dispatcher + EventDispatcherInterface $event_dispatcher, + LoggerChannelInterface $channel ) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->account = $account; @@ -107,6 +118,7 @@ public function __construct( $this->stomp = $stomp; $this->messenger = $messenger; $this->eventDispatcher = $event_dispatcher; + $this->logger = $channel; } /** @@ -122,7 +134,8 @@ public static function create(ContainerInterface $container, array $configuratio $container->get('islandora.eventgenerator'), $container->get('islandora.stomp'), $container->get('messenger'), - $container->get('event_dispatcher') + $container->get('event_dispatcher'), + $container->get('logger.channel.islandora') ); } @@ -132,6 +145,16 @@ public static function create(ContainerInterface $container, array $configuratio public function execute($entity = NULL) { // Generate event as stomp message. try { + if (is_null($this->stomp->getClient()->getProtocol())) { + // getProtocol() can return NULL but that causes a larger problem. + // So attempt to disconnect + connect to re-establish the connection or + // throw a StompException. + // @see https://github.com/stomp-php/stomp-php/issues/167 + // @see https://github.com/stomp-php/stomp-php/blob/3a9347a11743d0b79fd60564f356bc3efe40e615/src/Client.php#L429-L434 + $this->stomp->getClient()->disconnect(); + $this->stomp->getClient()->connect(); + } + $user = $this->entityTypeManager->getStorage('user')->load($this->account->id()); $data = $this->generateData($entity); @@ -146,18 +169,22 @@ public function execute($entity = NULL) { ); } catch (StompHeaderEventException $e) { - \Drupal::logger('islandora')->error($e->getMessage()); - $this->messenger->addMessage($e->getMessage(), 'error'); + $this->logger->error($e->getMessage()); + $this->messenger->addError($e->getMessage()); + return; + } + catch (StompException $e) { + $this->logger->error("Unable to connect to JMS Broker: @msg", ["@msg" => $e->getMessage()]); + $this->messenger->addWarning("Unable to connect to JMS Broker, items might not be synchronized to external services."); return; } catch (\RuntimeException $e) { // Notify the user the event couldn't be generated and abort. - \Drupal::logger('islandora')->error( + $this->logger->error( $this->t('Error generating event: @msg', ['@msg' => $e->getMessage()]) ); - $this->messenger->addMessage( - $this->t('Error generating event: @msg', ['@msg' => $e->getMessage()]), - 'error' + $this->messenger->addError( + $this->t('Error generating event: @msg', ['@msg' => $e->getMessage()]) ); return; } @@ -170,17 +197,16 @@ public function execute($entity = NULL) { } catch (StompException $e) { // Log it. - \Drupal::logger('islandora')->error( + $this->logger->error( 'Error publishing message: @msg', ['@msg' => $e->getMessage()] ); // Notify user. - $this->messenger->addMessage( + $this->messenger->addError( $this->t('Error publishing message: @msg', ['@msg' => $e->getMessage()] - ), - 'error' + ) ); } } diff --git a/src/Plugin/Action/AbstractGenerateDerivativeBase.php b/src/Plugin/Action/AbstractGenerateDerivativeBase.php index 3c7ff5b68..9d0520a32 100644 --- a/src/Plugin/Action/AbstractGenerateDerivativeBase.php +++ b/src/Plugin/Action/AbstractGenerateDerivativeBase.php @@ -5,6 +5,7 @@ use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Logger\LoggerChannelInterface; use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\Session\AccountInterface; use Drupal\islandora\IslandoraUtils; @@ -94,6 +95,8 @@ class AbstractGenerateDerivativeBase extends EmitEvent { * Field Manager service. * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher * Event dispatcher service. + * @param \Drupal\Core\Logger\LoggerChannelInterface $channel + * The logger channel. */ public function __construct( array $configuration, @@ -109,7 +112,8 @@ public function __construct( MessengerInterface $messenger, ConfigFactoryInterface $config, EntityFieldManagerInterface $entity_field_manager, - EventDispatcherInterface $event_dispatcher + EventDispatcherInterface $event_dispatcher, + LoggerChannelInterface $channel ) { $this->utils = $utils; $this->mediaSource = $media_source; @@ -126,7 +130,8 @@ public function __construct( $event_generator, $stomp, $messenger, - $event_dispatcher + $event_dispatcher, + $channel ); } @@ -148,7 +153,8 @@ public static function create(ContainerInterface $container, array $configuratio $container->get('messenger'), $container->get('config.factory'), $container->get('entity_field.manager'), - $container->get('event_dispatcher') + $container->get('event_dispatcher'), + $container->get('logger.channel.islandora') ); } From 92d5a7fbbde578b6ea37b27b819cddd521b998a4 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Thu, 5 May 2022 19:14:54 +0000 Subject: [PATCH 021/281] Fix Coder errors in IIIF views style plugin. --- .../src/Plugin/views/style/IIIFManifest.php | 16 +++++++++++----- 1 file changed, 11 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 2dfe5011f..0ebc213e1 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\views\Plugin\views\style\StylePluginBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\MessengerInterface; +use Drupal\Core\Url; use Drupal\views\ResultRow; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Serializer\SerializerInterface; @@ -267,20 +268,25 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas * Pull a title from the node or media passed to this view. * * @param string $content_path + * The path of the content being requested. + * * @return string + * The entity's title. */ public function getEntityTitle(string $content_path): string { $entity_title = $this->t('IIIF Manifest'); try { - $params = \Drupal\Core\Url::fromUserInput($content_path)->getRouteParameters(); + $params = Url::fromUserInput($content_path)->getRouteParameters(); if (isset($params['node'])) { - $node = \Drupal\node\Entity\Node::load($params['node']); + $node = \Drupal::entityTypeManager()->getStorage('node')->load($params['node']); $entity_title = $node->getTitle(); - } elseif (isset($params['media'])) { - $media = \Drupal\media\Entity\Media::load($params['media']); + } + elseif (isset($params['media'])) { + $media = \Drupal::entityTypeManager()->getStorage('media')->load($params['media']); $entity_title = $media->getName(); } - } catch (\InvalidArgumentException $e) { + } + catch (\InvalidArgumentException $e) { } return $entity_title; From 52d3df1462f7df95b20d51a9e8798b9f188509ee Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Thu, 12 May 2022 19:06:32 +0000 Subject: [PATCH 022/281] Suppress 'Schema incomplete' error in Functional test. --- .../src/Functional/IslandoraImageFormatterTest.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/src/Functional/IslandoraImageFormatterTest.php b/tests/src/Functional/IslandoraImageFormatterTest.php index 2793cf49b..750034638 100644 --- a/tests/src/Functional/IslandoraImageFormatterTest.php +++ b/tests/src/Functional/IslandoraImageFormatterTest.php @@ -10,6 +10,11 @@ */ class IslandoraImageFormatterTest extends IslandoraFunctionalTestBase { + /** + * @var bool Suppresses "Schema incomplete" error. + */ + protected $strictConfigSchema = FALSE; + /** * @covers \Drupal\islandora\Plugin\Field\FieldFormatter\IslandoraImageFormatter::viewElements */ @@ -26,15 +31,16 @@ public function testIslandoraImageFormatter() { // Create an image media type. $testImageMediaType = $this->createMediaType('image', ['id' => 'test_image_media_type']); $testImageMediaType->save(); - $this->createEntityReferenceField('media', $testImageMediaType->id(), 'field_media_of', 'Media Of', 'node', 'default', [], 2); - + $this->createEntityReferenceField('media', $testImageMediaType->id(), 'field_media_of', 'Media Of', 'node', 'default', [], 2);("Got past create media type."); // Set the display mode to use the islandora_image formatter. // Also, only show the image on display to remove clutter. $display_options = [ 'type' => 'islandora_image', - 'settings' => ['image_style' => NULL, 'image_link' => 'content'], + 'settings' => [/*'image_style' => NULL,*/ 'image_link' => 'content'], ]; + $display = $this->container->get('entity_display.repository')->getViewDisplay('media', $testImageMediaType->id(), 'default'); + $display->setComponent('field_media_image', $display_options) ->removeComponent('created') ->removeComponent('uid') @@ -47,7 +53,6 @@ public function testIslandoraImageFormatter() { 'title' => 'Test Node', ]); $node->save(); - // Make a image for the Media. $file = $this->container->get('entity_type.manager')->getStorage('file')->create([ 'uid' => $account->id(), From 11bc7886ea13d6d5b674d8fb16ff7b17f09ee834 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Fri, 13 May 2022 19:20:40 +0000 Subject: [PATCH 023/281] Update islandora_image schema to fix failing test. --- config/schema/islandora.schema.yml | 8 ++++++++ .../Functional/IslandoraImageFormatterTest.php | 16 ++++++++-------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/config/schema/islandora.schema.yml b/config/schema/islandora.schema.yml index de7a3e46e..0ee69fc18 100644 --- a/config/schema/islandora.schema.yml +++ b/config/schema/islandora.schema.yml @@ -169,3 +169,11 @@ field.formatter.settings.islandora_image: image_style: type: string label: 'Image style' + image_loading: + type: mapping + label: 'Image loading settings' + mapping: + attribute: + type: string + label: 'Loading attribute' + diff --git a/tests/src/Functional/IslandoraImageFormatterTest.php b/tests/src/Functional/IslandoraImageFormatterTest.php index 750034638..33f6e1e6b 100644 --- a/tests/src/Functional/IslandoraImageFormatterTest.php +++ b/tests/src/Functional/IslandoraImageFormatterTest.php @@ -10,11 +10,6 @@ */ class IslandoraImageFormatterTest extends IslandoraFunctionalTestBase { - /** - * @var bool Suppresses "Schema incomplete" error. - */ - protected $strictConfigSchema = FALSE; - /** * @covers \Drupal\islandora\Plugin\Field\FieldFormatter\IslandoraImageFormatter::viewElements */ @@ -31,16 +26,21 @@ public function testIslandoraImageFormatter() { // Create an image media type. $testImageMediaType = $this->createMediaType('image', ['id' => 'test_image_media_type']); $testImageMediaType->save(); - $this->createEntityReferenceField('media', $testImageMediaType->id(), 'field_media_of', 'Media Of', 'node', 'default', [], 2);("Got past create media type."); + $this->createEntityReferenceField('media', $testImageMediaType->id(), 'field_media_of', 'Media Of', 'node', 'default', [], 2); // Set the display mode to use the islandora_image formatter. // Also, only show the image on display to remove clutter. $display_options = [ 'type' => 'islandora_image', - 'settings' => [/*'image_style' => NULL,*/ 'image_link' => 'content'], + 'settings' => [ + 'image_style' => '', + 'image_link' => 'content', + 'image_loading' => [ + 'attribute' => 'eager', + ], + ], ]; $display = $this->container->get('entity_display.repository')->getViewDisplay('media', $testImageMediaType->id(), 'default'); - $display->setComponent('field_media_image', $display_options) ->removeComponent('created') ->removeComponent('uid') From f6fa77984b08e78372a50984292fe0b49aa2fce8 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Mon, 16 May 2022 16:29:05 +0000 Subject: [PATCH 024/281] Islandora Image schema inherits from parent. --- config/schema/islandora.schema.yml | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/config/schema/islandora.schema.yml b/config/schema/islandora.schema.yml index 0ee69fc18..c98679eba 100644 --- a/config/schema/islandora.schema.yml +++ b/config/schema/islandora.schema.yml @@ -158,22 +158,6 @@ condition.plugin.node_had_namespace: pid_field: type: ignore label: 'PID field' - field.formatter.settings.islandora_image: - type: mapping - label: 'Image field display format settings' - mapping: - image_link: - type: string - label: 'Link image to' - image_style: - type: string - label: 'Image style' - image_loading: - type: mapping - label: 'Image loading settings' - mapping: - attribute: - type: string - label: 'Loading attribute' - + type: field.formatter.settings.image + label: 'Islandora image field display format settings' From ed0979f97c96d125f1d9822ef428c00cb9371689 Mon Sep 17 00:00:00 2001 From: Seth Shaw Date: Tue, 17 May 2022 11:27:55 -0700 Subject: [PATCH 025/281] make breadcrumbs referenceField an array --- .../islandora_breadcrumbs.breadcrumbs.yml | 3 ++- .../schema/islandora_breadcrumbs.schema.yml | 9 ++++++--- .../islandora_breadcrumbs.install | 18 ++++++++++++++++++ .../src/IslandoraBreadcrumbBuilder.php | 2 +- 4 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 modules/islandora_breadcrumbs/islandora_breadcrumbs.install diff --git a/modules/islandora_breadcrumbs/config/install/islandora_breadcrumbs.breadcrumbs.yml b/modules/islandora_breadcrumbs/config/install/islandora_breadcrumbs.breadcrumbs.yml index ad166b50b..ea34ee2ed 100644 --- a/modules/islandora_breadcrumbs/config/install/islandora_breadcrumbs.breadcrumbs.yml +++ b/modules/islandora_breadcrumbs/config/install/islandora_breadcrumbs.breadcrumbs.yml @@ -1,6 +1,7 @@ maxDepth: -1 includeSelf: FALSE -referenceField: field_member_of +referenceFields: + - field_member_of dependencies: module: - islandora diff --git a/modules/islandora_breadcrumbs/config/schema/islandora_breadcrumbs.schema.yml b/modules/islandora_breadcrumbs/config/schema/islandora_breadcrumbs.schema.yml index 6bc44096d..4175cbf51 100644 --- a/modules/islandora_breadcrumbs/config/schema/islandora_breadcrumbs.schema.yml +++ b/modules/islandora_breadcrumbs/config/schema/islandora_breadcrumbs.schema.yml @@ -7,6 +7,9 @@ islandora_breadcrumbs.breadcrumbs: includeSelf: type: boolean label: 'Include Self' - referenceField: - type: string - label: 'Reference Field' + referenceFields: + type: sequence + label: 'Reference Fields' + sequence: + type: string + label: 'Reference Field' diff --git a/modules/islandora_breadcrumbs/islandora_breadcrumbs.install b/modules/islandora_breadcrumbs/islandora_breadcrumbs.install new file mode 100644 index 000000000..2c2208017 --- /dev/null +++ b/modules/islandora_breadcrumbs/islandora_breadcrumbs.install @@ -0,0 +1,18 @@ +getEditable('islandora_breadcrumbs.breadcrumbs'); + $config->set('referenceFields', [$config->get('referenceField')]); + $config->clear('referenceField'); + $config->save(); + return "Updated referenceFields config."; +} \ No newline at end of file diff --git a/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php b/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php index 620f22895..23d3ff3cd 100644 --- a/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php +++ b/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php @@ -78,7 +78,7 @@ public function build(RouteMatchInterface $route_match) { $breadcrumb = new Breadcrumb(); $breadcrumb->addLink(Link::createFromRoute($this->t('Home'), '')); - $chain = array_reverse($this->utils->findAncestors($node, [$this->config->get('referenceField')], $this->config->get('maxDepth'))); + $chain = array_reverse($this->utils->findAncestors($node, $this->config->get('referenceFields'), $this->config->get('maxDepth'))); // XXX: Handle a looping breadcrumb scenario by filtering the present // node out and then optionally re-adding it after if set to do so. From 9c283ea0c0fdb7a4788976feaa1ba190689f7a12 Mon Sep 17 00:00:00 2001 From: Seth Shaw Date: Tue, 17 May 2022 16:09:57 -0700 Subject: [PATCH 026/281] add breadcrumbs form; fix includeSelf error --- .../islandora_breadcrumbs.install | 2 +- .../islandora_breadcrumbs.links.menu.yml | 5 + .../islandora_breadcrumbs.routing.yml | 7 + .../Form/IslandoraBreadcrumbsSettingsForm.php | 132 ++++++++++++++++++ .../src/IslandoraBreadcrumbBuilder.php | 11 +- 5 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 modules/islandora_breadcrumbs/islandora_breadcrumbs.links.menu.yml create mode 100644 modules/islandora_breadcrumbs/islandora_breadcrumbs.routing.yml create mode 100644 modules/islandora_breadcrumbs/src/Form/IslandoraBreadcrumbsSettingsForm.php diff --git a/modules/islandora_breadcrumbs/islandora_breadcrumbs.install b/modules/islandora_breadcrumbs/islandora_breadcrumbs.install index 2c2208017..2ca9ada68 100644 --- a/modules/islandora_breadcrumbs/islandora_breadcrumbs.install +++ b/modules/islandora_breadcrumbs/islandora_breadcrumbs.install @@ -15,4 +15,4 @@ function islandora_breadcrumbs_update_8001() { $config->clear('referenceField'); $config->save(); return "Updated referenceFields config."; -} \ No newline at end of file +} diff --git a/modules/islandora_breadcrumbs/islandora_breadcrumbs.links.menu.yml b/modules/islandora_breadcrumbs/islandora_breadcrumbs.links.menu.yml new file mode 100644 index 000000000..d198060b6 --- /dev/null +++ b/modules/islandora_breadcrumbs/islandora_breadcrumbs.links.menu.yml @@ -0,0 +1,5 @@ +system.islandora_breadcrumbs_settings: + title: 'Breadcrumbs Settings' + parent: system.admin_config_islandora + route_name: system.islandora_breadcrumbs_settings + description: 'Configure Islandora breadcrumb settings' \ No newline at end of file diff --git a/modules/islandora_breadcrumbs/islandora_breadcrumbs.routing.yml b/modules/islandora_breadcrumbs/islandora_breadcrumbs.routing.yml new file mode 100644 index 000000000..e9fd9ac1b --- /dev/null +++ b/modules/islandora_breadcrumbs/islandora_breadcrumbs.routing.yml @@ -0,0 +1,7 @@ +system.islandora_breadcrumbs_settings: + path: '/admin/config/islandora/breadcrumbs' + defaults: + _form: 'Drupal\islandora_breadcrumbs\Form\IslandoraBreadcrumbsSettingsForm' + _title: 'Islandora Breadcrumbs Settings' + requirements: + _permission: 'administer site configuration' diff --git a/modules/islandora_breadcrumbs/src/Form/IslandoraBreadcrumbsSettingsForm.php b/modules/islandora_breadcrumbs/src/Form/IslandoraBreadcrumbsSettingsForm.php new file mode 100644 index 000000000..bdaa84eff --- /dev/null +++ b/modules/islandora_breadcrumbs/src/Form/IslandoraBreadcrumbsSettingsForm.php @@ -0,0 +1,132 @@ +config(static::SETTINGS); + + $form['maxDepth'] = [ + '#type' => 'number', + '#default_value' => $config->get('maxDepth'), + '#min' => -1, + '#step' => 1, + '#title' => $this->t('Maximum number of breadcrumbs'), + '#description' => $this->t("Stop adding parent references to the breadrumbs at this number of items. The default value, '-1' disables this feature."), + ]; + + $form['includeSelf'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Include the current node in the breadcrumbs?'), + '#default_value' => $config->get('includeSelf'), + ]; + + // Using the textarea instead of a select so the site maintainer can + // provide an ordered list of items rather than simply selecting from a + // list which enforces it's own order. + $form['referenceFields'] = [ + '#type' => 'textarea', + '#title' => $this->t('Entity Reference fields to follow'), + '#default_value' => implode("\n", $config->get('referenceFields')), + '#description' => $this->t("Entity Reference field machine names to follow when building the breadcrumbs.
One per line.
Valid options: @options", + [ + "@options" => implode(", ", static::getNodeEntityReferenceFields()), + ] + ), + '#element_validate' => [[get_class($this), 'validateReferenceFields']], + + ]; + + return parent::buildForm($form, $form_state); + } + + /** + * Returns a list of node entity reference field machine names. + * + * We use this for building the form field description and for + * validating the reference fields value. + */ + protected static function getNodeEntityReferenceFields() { + return array_keys(\Drupal::service('entity_field.manager')->getFieldMapByFieldType('entity_reference')['node']); + } + + /** + * Turns a text area into an array of values. + * + * Used for validating the field reference text area + * and saving the form state. + */ + protected static function textToArray($string) { + return array_filter(array_map('trim', explode("\n", $string)), 'strlen'); + } + + /** + * Callback for settings form. + * + * @param array $element + * An associative array containing the properties and children of the + * generic form element. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The current state of the form for the form this element belongs to. + * + * @see \Drupal\Core\Render\Element\FormElement::processPattern() + */ + public static function validateReferenceFields(array $element, FormStateInterface $form_state) { + + $valid_fields = static::getNodeEntityReferenceFields(); + + foreach (static::textToArray($element['#value']) as $value) { + if (!in_array($value, $valid_fields)) { + $form_state->setError($element, t('"@field" is not a valid entity reference field!', ["@field" => $value])); + } + } + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + $this->configFactory->getEditable(static::SETTINGS) + ->set('referenceFields', static::textToArray($form_state->getValue('referenceFields'))) + ->set('maxDepth', $form_state->getValue('maxDepth')) + ->set('includeSelf', $form_state->getValue('includeSelf')) + ->save(); + + parent::submitForm($form, $form_state); + } + +} diff --git a/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php b/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php index 23d3ff3cd..d84b8c3c4 100644 --- a/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php +++ b/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php @@ -64,7 +64,14 @@ public function applies(RouteMatchInterface $attributes) { $nid = $attributes->getRawParameters()->get('node'); if (!empty($nid)) { $node = $this->nodeStorage->load($nid); - return (!empty($node) && $node->hasField($this->config->get('referenceField'))); + if (empty($node)) { + return FALSE; + } + foreach ($this->config->get('referenceFields') as $field) { + if ($node->hasField($field)) { + return TRUE; + } + } } } @@ -86,7 +93,7 @@ public function build(RouteMatchInterface $route_match) { return $link !== $nid; }); if ($this->config->get('includeSelf')) { - array_push($chain, $node); + array_push($chain, $nid); } $breadcrumb->addCacheableDependency($node); From 73d0d66402662dc3e2560e05123ac9de0fa31cf0 Mon Sep 17 00:00:00 2001 From: Seth Shaw Date: Wed, 18 May 2022 08:42:30 -0700 Subject: [PATCH 027/281] maxDepth counting should start at 1, not zero --- src/IslandoraUtils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/IslandoraUtils.php b/src/IslandoraUtils.php index e5071a05b..f81cb7472 100644 --- a/src/IslandoraUtils.php +++ b/src/IslandoraUtils.php @@ -714,7 +714,7 @@ public function findAncestors(ContentEntityInterface $entity, array $fields = [s * @param int $current_height * The current height of the recursion. */ - protected function findAncestorsByEntityReference(ContentEntityInterface $entity, array &$context, array $fields = [self::MEMBER_OF_FIELD], int $current_height = 0): void { + protected function findAncestorsByEntityReference(ContentEntityInterface $entity, array &$context, array $fields = [self::MEMBER_OF_FIELD], int $current_height = 1): void { $parents = $this->getParentsByEntityReference($entity, $fields); foreach ($parents as $parent) { if (isset($context['ancestors'][$parent->id()])) { From e1428bb13afe7ad5281880e7b9221209969438f6 Mon Sep 17 00:00:00 2001 From: Seth Shaw Date: Wed, 18 May 2022 08:43:12 -0700 Subject: [PATCH 028/281] PR recommendations; clarify max-depth config --- .../islandora_breadcrumbs.links.menu.yml | 2 +- .../src/Form/IslandoraBreadcrumbsSettingsForm.php | 4 ++-- .../islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/islandora_breadcrumbs/islandora_breadcrumbs.links.menu.yml b/modules/islandora_breadcrumbs/islandora_breadcrumbs.links.menu.yml index d198060b6..dcf995346 100644 --- a/modules/islandora_breadcrumbs/islandora_breadcrumbs.links.menu.yml +++ b/modules/islandora_breadcrumbs/islandora_breadcrumbs.links.menu.yml @@ -2,4 +2,4 @@ system.islandora_breadcrumbs_settings: title: 'Breadcrumbs Settings' parent: system.admin_config_islandora route_name: system.islandora_breadcrumbs_settings - description: 'Configure Islandora breadcrumb settings' \ No newline at end of file + description: 'Configure Islandora breadcrumb settings' diff --git a/modules/islandora_breadcrumbs/src/Form/IslandoraBreadcrumbsSettingsForm.php b/modules/islandora_breadcrumbs/src/Form/IslandoraBreadcrumbsSettingsForm.php index bdaa84eff..679a565e6 100644 --- a/modules/islandora_breadcrumbs/src/Form/IslandoraBreadcrumbsSettingsForm.php +++ b/modules/islandora_breadcrumbs/src/Form/IslandoraBreadcrumbsSettingsForm.php @@ -45,8 +45,8 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#default_value' => $config->get('maxDepth'), '#min' => -1, '#step' => 1, - '#title' => $this->t('Maximum number of breadcrumbs'), - '#description' => $this->t("Stop adding parent references to the breadrumbs at this number of items. The default value, '-1' disables this feature."), + '#title' => $this->t('Maximum number of ancestor breadcrumbs'), + '#description' => $this->t("Stops adding ancestor references when the chain reaches this number. The count does not include the current node when enabled. The default value, '-1' disables this feature."), ]; $form['includeSelf'] = [ diff --git a/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php b/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php index d84b8c3c4..5ed7f6d06 100644 --- a/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php +++ b/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php @@ -83,6 +83,7 @@ public function build(RouteMatchInterface $route_match) { $nid = $route_match->getRawParameters()->get('node'); $node = $this->nodeStorage->load($nid); $breadcrumb = new Breadcrumb(); + $breadcrumb->addCacheableDependency($this->config); $breadcrumb->addLink(Link::createFromRoute($this->t('Home'), '')); $chain = array_reverse($this->utils->findAncestors($node, $this->config->get('referenceFields'), $this->config->get('maxDepth'))); From 032280827f0f5822179a6121eed17872f6fb189c Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 18 May 2022 17:31:56 -0300 Subject: [PATCH 029/281] Support multiple tracks. (#871) --- .../islandora_video/templates/islandora-file-video.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/islandora_video/templates/islandora-file-video.html.twig b/modules/islandora_video/templates/islandora-file-video.html.twig index 7c62badea..e1b8730c3 100644 --- a/modules/islandora_video/templates/islandora-file-video.html.twig +++ b/modules/islandora_video/templates/islandora-file-video.html.twig @@ -21,7 +21,7 @@ {% endfor %} {% if tracks %} {% for track in tracks %} - {% endfor %} {% endif %} From e5a1f99c5710b051bb22f23a36d04b9110bf3787 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Thu, 19 May 2022 13:58:29 +0000 Subject: [PATCH 030/281] IIIF Manifest: Use dependency injection for EntityTypeManager service. --- .../src/Plugin/views/style/IIIFManifest.php | 16 +++++++++++++--- 1 file changed, 13 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 0ebc213e1..13f83e7d9 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -3,6 +3,7 @@ namespace Drupal\islandora_iiif\Plugin\views\style; use Drupal\views\Plugin\views\style\StylePluginBase; +use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\Url; @@ -69,6 +70,13 @@ class IIIFManifest extends StylePluginBase { */ protected $iiifConfig; + /** + * The Drupal Entity Type Manager service. + * + * @var \Drupal\Core\Entity\EntityTypeManagerInterface + */ + protected $entityTypeManager; + /** * The Drupal Filesystem. * @@ -86,12 +94,13 @@ class IIIFManifest extends StylePluginBase { /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, 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) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->serializer = $serializer; $this->request = $request; $this->iiifConfig = $iiif_config; + $this->entityTypeManager = $entity_type_manager; $this->fileSystem = $file_system; $this->httpClient = $http_client; $this->messenger = $messenger; @@ -108,6 +117,7 @@ public static function create(ContainerInterface $container, array $configuratio $container->get('serializer'), $container->get('request_stack')->getCurrentRequest(), $container->get('config.factory')->get('islandora_iiif.settings'), + $container->get('entity_type.manager'), $container->get('file_system'), $container->get('http_client'), $container->get('messenger') @@ -278,11 +288,11 @@ public function getEntityTitle(string $content_path): string { try { $params = Url::fromUserInput($content_path)->getRouteParameters(); if (isset($params['node'])) { - $node = \Drupal::entityTypeManager()->getStorage('node')->load($params['node']); + $node = $this->entityTypeManager->getStorage('node')->load($params['node']); $entity_title = $node->getTitle(); } elseif (isset($params['media'])) { - $media = \Drupal::entityTypeManager()->getStorage('media')->load($params['media']); + $media = $this->entityTypeManager->getStorage('media')->load($params['media']); $entity_title = $media->getName(); } } From b38f195a50745fc89b15d9d5b462f850403e04f9 Mon Sep 17 00:00:00 2001 From: Seth Shaw Date: Thu, 19 May 2022 09:01:23 -0700 Subject: [PATCH 031/281] Produce error if viewing a media without a source file --- islandora.module | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/islandora.module b/islandora.module index e26888674..e29fdb565 100644 --- a/islandora.module +++ b/islandora.module @@ -422,7 +422,7 @@ function islandora_entity_extra_field_info() { if (!empty($pseudo_bundles)) { foreach ($pseudo_bundles as $key) { - list($bundle, $content_entity) = explode(":", $key); + [$bundle, $content_entity] = explode(":", $key); $extra_field[$content_entity][$bundle]['display']['field_gemini_uri'] = [ 'label' => t('Fedora URI'), 'description' => t('The URI to the persistent'), @@ -451,6 +451,17 @@ function islandora_entity_view(array &$build, EntityInterface $entity, EntityVie // Check if the source file is in Fedora or not. $media_source_service = \Drupal::service('islandora.media_source_service'); $source_file = $media_source_service->getSourceFile($entity); + if (!$source_file) { + \Drupal::logger('islandora')->error( + \Drupal::service('string_translation')->translate( + "Can't get source file for @label (@id)", [ + '@label' => $entity->label(), + "@id" => $entity->id(), + ] + ) + ); + return; + } $uri = $source_file->getFileUri(); $scheme = \Drupal::service('stream_wrapper_manager')->getScheme($uri); $flysystem_config = Settings::get('flysystem'); From 222c9601c13d24e7f89922260cd8c4f89a554e97 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 1 Jun 2022 14:38:00 -0300 Subject: [PATCH 032/281] Rename multifile media ocr derivative type. (#875) * Rename multifile media ocr derivative type. * Remove errant 10.0.x/php 8.0 test --- .github/workflows/build-2.x.yml | 21 ------------------- .../Action/GenerateOCRDerivativeFile.php | 2 +- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index 80c581879..f5bce5101 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -77,11 +77,6 @@ jobs: mysql: "8.0" test-suite: "functional-javascript" allowed_failure: true - - drupal-version: '10.0.x-dev' - php-versions: '8.0' - mysql: "8.0" - test-suite: "kernel" - allowed_failure: true # 9.4.x-dev on PHP 8.1 - drupal-version: '9.4.x-dev' php-versions: '8.1' @@ -98,22 +93,6 @@ jobs: mysql: "8.0" test-suite: "functional-javascript" allowed_failure: true - # 10.0.x-dev on PHP 8.0 - - drupal-version: '10.0.x-dev' - php-versions: '8.0' - mysql: "8.0" - test-suite: "kernel" - allowed_failure: true - - drupal-version: '10.0.x-dev' - php-versions: '8.0' - mysql: "8.0" - test-suite: "functional" - allowed_failure: true - - drupal-version: '10.0.x-dev' - php-versions: '8.0' - mysql: "8.0" - test-suite: "functional-javascript" - allowed_failure: true # 10.0.x-dev on PHP 8.1 - drupal-version: '10.0.x-dev' php-versions: '8.1' diff --git a/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivativeFile.php b/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivativeFile.php index 3b5e84980..f6b8034a9 100644 --- a/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivativeFile.php +++ b/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivativeFile.php @@ -12,7 +12,7 @@ * * @Action( * id = "generate_extracted_text_file", - * label = @Translation("Generate an Extracted Text derivative file"), + * label = @Translation("Generate Extracted Text for Media Attachment"), * type = "media" * ) */ From 63a77bd8345f816c35cadeb170765b9dfc9cdf1e Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Fri, 3 Jun 2022 12:35:34 -0300 Subject: [PATCH 033/281] Move to int for config. --- .../islandora_core_feature/config/install/filehash.settings.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/islandora_core_feature/config/install/filehash.settings.yml b/modules/islandora_core_feature/config/install/filehash.settings.yml index aa9c188d1..ce88d0dce 100644 --- a/modules/islandora_core_feature/config/install/filehash.settings.yml +++ b/modules/islandora_core_feature/config/install/filehash.settings.yml @@ -2,4 +2,4 @@ algos: sha1: sha1 md5: '0' sha256: '0' -dedupe: false +dedupe: '0' From 61f9ec9106bd970bc46d009d5d4bda8fed7f8c53 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Fri, 3 Jun 2022 13:58:52 -0300 Subject: [PATCH 034/281] That was a string, whoops... ... was thinking it was the same kind of thing above, but I guess not. --- .../islandora_core_feature/config/install/filehash.settings.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/islandora_core_feature/config/install/filehash.settings.yml b/modules/islandora_core_feature/config/install/filehash.settings.yml index ce88d0dce..7deecc696 100644 --- a/modules/islandora_core_feature/config/install/filehash.settings.yml +++ b/modules/islandora_core_feature/config/install/filehash.settings.yml @@ -2,4 +2,4 @@ algos: sha1: sha1 md5: '0' sha256: '0' -dedupe: '0' +dedupe: 0 From 3d122af5d66cd31219f3fc2b949130d7202316f3 Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 7 Jun 2022 13:34:40 -0300 Subject: [PATCH 035/281] Avoid attempting to refer to an unknown index. (#876) When running in a bare site (without any content... like, in a unit testing rig), this ends up trying to refer to a non-existent offset. ... add an `isset()` test to avoid doing so. --- islandora.views.inc | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/islandora.views.inc b/islandora.views.inc index cd826d081..ad2b141ab 100644 --- a/islandora.views.inc +++ b/islandora.views.inc @@ -13,13 +13,16 @@ function islandora_views_data_alter(&$data) { $fields = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions('node'); foreach ($fields as $field => $field_storage_definition) { if ($field_storage_definition->getType() == 'integer' && strpos($field, "field_") === 0) { - $data['node__' . $field][$field . '_value']['field'] = $data['node__' . $field][$field]['field']; - $data['node__' . $field][$field]['title'] = t('Integer Weight Selector (@field)', [ - '@field' => $field, - ]); - $data['node__' . $field][$field]['help'] = t('Provides a drag-n-drop reordering of integer-based weight fields.'); - $data['node__' . $field][$field]['title short'] = t('Integer weight selector'); - $data['node__' . $field][$field]['field']['id'] = 'integer_weight_selector'; + $prefixed_field = 'node__' . $field; + if (isset($data[$prefixed_field])) { + $data[$prefixed_field][$field . '_value']['field'] = $data[$prefixed_field][$field]['field']; + $data[$prefixed_field][$field]['title'] = t('Integer Weight Selector (@field)', [ + '@field' => $field, + ]); + $data[$prefixed_field][$field]['help'] = t('Provides a drag-n-drop reordering of integer-based weight fields.'); + $data[$prefixed_field][$field]['title short'] = t('Integer weight selector'); + $data[$prefixed_field][$field]['field']['id'] = 'integer_weight_selector'; + } } } } From 019572a778fc20cc6142f550a437a814f6d6409c Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Tue, 7 Jun 2022 17:16:10 -0300 Subject: [PATCH 036/281] Use the interface not the class. (#879) --- src/Commands/IslandoraCommands.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Commands/IslandoraCommands.php b/src/Commands/IslandoraCommands.php index 5209546ca..bd47500a5 100644 --- a/src/Commands/IslandoraCommands.php +++ b/src/Commands/IslandoraCommands.php @@ -4,7 +4,7 @@ use Consolidation\AnnotatedCommand\CommandData; use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\Session\AccountProxy; +use Drupal\Core\Session\AccountProxyInterface; use Drupal\Core\Session\AccountSwitcherInterface; use Drupal\Core\Session\UserSession; use Drush\Commands\DrushCommands; @@ -39,7 +39,7 @@ class IslandoraCommands extends DrushCommands { /** * {@inheritdoc} */ - public function __construct(EntityTypeManagerInterface $entity_type_manager, AccountProxy $current_user, AccountSwitcherInterface $account_switcher) { + public function __construct(EntityTypeManagerInterface $entity_type_manager, AccountProxyInterface $current_user, AccountSwitcherInterface $account_switcher) { $this->entityTypeManager = $entity_type_manager; $this->currentUser = $current_user; $this->accountSwitcher = $account_switcher; From 62211ff90980f02706ca5131a411149d595c4fed Mon Sep 17 00:00:00 2001 From: Seth Shaw Date: Wed, 8 Jun 2022 16:43:39 -0700 Subject: [PATCH 037/281] add NodeHasMediaUse views filter --- islandora.views.inc | 12 +++ src/Plugin/views/filter/NodeHasMediaUse.php | 88 +++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 src/Plugin/views/filter/NodeHasMediaUse.php diff --git a/islandora.views.inc b/islandora.views.inc index cd826d081..de176f158 100644 --- a/islandora.views.inc +++ b/islandora.views.inc @@ -22,4 +22,16 @@ function islandora_views_data_alter(&$data) { $data['node__' . $field][$field]['field']['id'] = 'integer_weight_selector'; } } + + // Add Has Media filter. + $data['node_field_data']['islandora_has_media'] = [ + 'title' => t('Node has Media Use'), + 'group' => t('Content'), + 'filter' => [ + 'title' => t('Node has media use filter'), + 'help' => t('Provides a custom filter for nodes that do or do not have media with a given use.'), + 'field' => 'nid', + 'id' => 'islandora_node_has_media_use', + ], + ]; } diff --git a/src/Plugin/views/filter/NodeHasMediaUse.php b/src/Plugin/views/filter/NodeHasMediaUse.php new file mode 100644 index 000000000..e83c6306e --- /dev/null +++ b/src/Plugin/views/filter/NodeHasMediaUse.php @@ -0,0 +1,88 @@ + NULL]; + $options['negated'] = ['default' => FALSE]; + + return $options; + } + + /** + * {@inheritdoc} + */ + public function validateOptionsForm(&$form, FormStateInterface $form_state) { + parent::validateOptionsForm($form, $form_state); + + $uri = $form_state->getValues()['options']['use_uri']; + $term = \Drupal::service('islandora.utils')->getTermForUri($uri); + if (empty($term)) { + $form_state->setError($form['use_uri'], $this->t('Could not find term with URI: "%uri"', ['%uri' => $uri])); + } + } + + /** + * {@inheritdoc} + */ + protected function valueForm(&$form, FormStateInterface $form_state) { + $form['use_uri'] = [ + '#type' => 'textfield', + '#title' => "Media Use URI", + '#default_value' => $this->options['use_uri'], + '#required' => TRUE, + ]; + $form['negated'] = [ + '#type' => 'checkbox', + '#title' => 'Negated', + '#description' => $this->t("Return nodes that don't have this use URI"), + '#default_value' => $this->options['negated'], + ]; + } + + /** + * {@inheritdoc} + */ + public function adminSummary() { + $operator = ($this->options['negated']) ? "does not have" : "has"; + return "Node {$operator} media with use: '{$this->options['use_uri']}'"; + } + + /** + * {@inheritdoc} + */ + public function query() { + $condition = ($this->options['negated']) ? 'NOT IN' : 'IN'; + $utils = \Drupal::service('islandora.utils'); + $term = $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']]); + 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); + + } + +} From a90630d9760c4daf5c9951e6bc2302c251f96d3b Mon Sep 17 00:00:00 2001 From: Seth Shaw Date: Thu, 9 Jun 2022 12:34:44 -0700 Subject: [PATCH 038/281] turn textfield into a select --- src/Plugin/views/filter/NodeHasMediaUse.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Plugin/views/filter/NodeHasMediaUse.php b/src/Plugin/views/filter/NodeHasMediaUse.php index e83c6306e..bb84ba6ba 100644 --- a/src/Plugin/views/filter/NodeHasMediaUse.php +++ b/src/Plugin/views/filter/NodeHasMediaUse.php @@ -43,9 +43,17 @@ public function validateOptionsForm(&$form, FormStateInterface $form_state) { * {@inheritdoc} */ protected function valueForm(&$form, FormStateInterface $form_state) { + $terms = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadByProperties(['vid' => 'islandora_media_use']); + $uris = []; + foreach ($terms as $term) { + $uri = reset($term->get('field_external_uri')->getValue()); + $uris[$uri['uri']] = $term->label(); + } + $form['use_uri'] = [ - '#type' => 'textfield', - '#title' => "Media Use URI", + '#type' => 'select', + '#title' => "Media Use Term", + '#options' => $uris, '#default_value' => $this->options['use_uri'], '#required' => TRUE, ]; From f6a66fe082bf61806f2bf3b031bdf3879be4e09d Mon Sep 17 00:00:00 2001 From: Seth Shaw Date: Thu, 9 Jun 2022 12:45:37 -0700 Subject: [PATCH 039/281] use term label for filter summary --- src/Plugin/views/filter/NodeHasMediaUse.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Plugin/views/filter/NodeHasMediaUse.php b/src/Plugin/views/filter/NodeHasMediaUse.php index bb84ba6ba..a13bdad4e 100644 --- a/src/Plugin/views/filter/NodeHasMediaUse.php +++ b/src/Plugin/views/filter/NodeHasMediaUse.php @@ -70,7 +70,8 @@ protected function valueForm(&$form, FormStateInterface $form_state) { */ public function adminSummary() { $operator = ($this->options['negated']) ? "does not have" : "has"; - return "Node {$operator} media with use: '{$this->options['use_uri']}'"; + $term = \Drupal::service('islandora.utils')->getTermForUri($this->options['use_uri']); + return "Node {$operator} a '{$term->label()}' media"; } /** From 352631099e98510eac9180ddf08de2a912555e7d Mon Sep 17 00:00:00 2001 From: Seth Shaw Date: Thu, 9 Jun 2022 12:49:35 -0700 Subject: [PATCH 040/281] paranoid checking --- src/Plugin/views/filter/NodeHasMediaUse.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Plugin/views/filter/NodeHasMediaUse.php b/src/Plugin/views/filter/NodeHasMediaUse.php index a13bdad4e..e17cdf3a4 100644 --- a/src/Plugin/views/filter/NodeHasMediaUse.php +++ b/src/Plugin/views/filter/NodeHasMediaUse.php @@ -71,7 +71,8 @@ protected function valueForm(&$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']); - return "Node {$operator} a '{$term->label()}' media"; + $label = (empty($term)) ? 'BROKEN TERM URI' : $term->label(); + return "Node {$operator} a '{$label}' media"; } /** From 39c7b3180a3acfad0583a7747794f77543d0069a Mon Sep 17 00:00:00 2001 From: Seth Shaw Date: Fri, 10 Jun 2022 08:58:13 -0700 Subject: [PATCH 041/281] remove ability to expose form; todo: bring back some day --- src/Plugin/views/filter/NodeHasMediaUse.php | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/Plugin/views/filter/NodeHasMediaUse.php b/src/Plugin/views/filter/NodeHasMediaUse.php index e17cdf3a4..0209505d6 100644 --- a/src/Plugin/views/filter/NodeHasMediaUse.php +++ b/src/Plugin/views/filter/NodeHasMediaUse.php @@ -18,20 +18,16 @@ class NodeHasMediaUse extends FilterPluginBase { * {@inheritdoc} */ protected function defineOptions() { - $options = parent::defineOptions(); - - $options['use_uri'] = ['default' => NULL]; - $options['negated'] = ['default' => FALSE]; - - return $options; + return [ + 'use_uri' => ['default' => NULL], + 'negated' => ['default' => FALSE], + ]; } /** * {@inheritdoc} */ public function validateOptionsForm(&$form, FormStateInterface $form_state) { - parent::validateOptionsForm($form, $form_state); - $uri = $form_state->getValues()['options']['use_uri']; $term = \Drupal::service('islandora.utils')->getTermForUri($uri); if (empty($term)) { @@ -42,12 +38,13 @@ public function validateOptionsForm(&$form, FormStateInterface $form_state) { /** * {@inheritdoc} */ - protected function valueForm(&$form, FormStateInterface $form_state) { + public function buildOptionsForm(&$form, FormStateInterface $form_state) { $terms = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadByProperties(['vid' => 'islandora_media_use']); $uris = []; foreach ($terms as $term) { - $uri = reset($term->get('field_external_uri')->getValue()); - $uris[$uri['uri']] = $term->label(); + foreach ($term->get('field_external_uri')->getValue() as $uri) { + $uris[$uri['uri']] = $term->label(); + } } $form['use_uri'] = [ @@ -92,7 +89,6 @@ public function query() { $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); - } } From 19db152531d0d5fed162e1ff0e252d641eab5ecd Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Tue, 19 Jul 2022 11:21:26 -0300 Subject: [PATCH 042/281] Test matrix: remove php7.3, mysql5.7. --- .github/workflows/build-2.x.yml | 88 ++------------------------------- 1 file changed, 3 insertions(+), 85 deletions(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index f5bce5101..52f107100 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -22,93 +22,11 @@ jobs: strategy: fail-fast: false matrix: - php-versions: ["7.3", "7.4"] + php-versions: ["7.4", "8.0", "8.1"] test-suite: ["kernel", "functional", "functional-javascript"] - drupal-version: ["9.3.x", "9.4.x-dev"] + drupal-version: ["9.4.x", "9.5.x-dev"] + mysql: ["8.0"] allowed_failure: [false] - mysql: ["5.7"] - # include experimental parts - include: - # 9.3.x on PHP 8.0 - - drupal-version: '9.3.x' - php-versions: '8.0' - mysql: "8.0" - test-suite: "kernel" - allowed_failure: true - - drupal-version: '9.3.x' - php-versions: '8.0' - mysql: "8.0" - test-suite: "functional" - allowed_failure: true - - drupal-version: '9.3.x' - php-versions: '8.0' - mysql: "8.0" - test-suite: "functional-javascript" - allowed_failure: true - # 9.3.x on PHP 8.1 - - drupal-version: '9.3.x' - php-versions: '8.1' - mysql: "8.0" - test-suite: "kernel" - allowed_failure: true - - drupal-version: '9.3.x' - php-versions: '8.1' - mysql: "8.0" - test-suite: "functional" - allowed_failure: true - - drupal-version: '9.3.x' - php-versions: '8.1' - mysql: "8.0" - test-suite: "functional-javascript" - allowed_failure: true - # 9.4.x-dev on PHP "8.0" - - drupal-version: '9.4.x-dev' - php-versions: '8.0' - mysql: "8.0" - test-suite: "kernel" - allowed_failure: true - - drupal-version: '9.4.x-dev' - php-versions: '8.0' - mysql: "8.0" - test-suite: "functional" - allowed_failure: true - - drupal-version: '9.4.x-dev' - php-versions: '8.0' - mysql: "8.0" - test-suite: "functional-javascript" - allowed_failure: true - # 9.4.x-dev on PHP 8.1 - - drupal-version: '9.4.x-dev' - php-versions: '8.1' - mysql: "8.0" - test-suite: "kernel" - allowed_failure: true - - drupal-version: '9.4.x-dev' - php-versions: '8.1' - mysql: "8.0" - test-suite: "functional" - allowed_failure: true - - drupal-version: '9.4.x-dev' - php-versions: '8.1' - mysql: "8.0" - test-suite: "functional-javascript" - allowed_failure: true - # 10.0.x-dev on PHP 8.1 - - drupal-version: '10.0.x-dev' - php-versions: '8.1' - mysql: "8.0" - test-suite: "kernel" - allowed_failure: true - - drupal-version: '10.0.x-dev' - php-versions: '8.1' - mysql: "8.0" - test-suite: "functional" - allowed_failure: true - - drupal-version: '10.0.x-dev' - php-versions: '8.1' - mysql: "8.0" - test-suite: "functional-javascript" - allowed_failure: true name: PHP ${{ matrix.php-versions }} | drupal ${{ matrix.drupal-version }} | mysql ${{ matrix.mysql }} | test-suite ${{ matrix.test-suite }} From 887cd8791e00ef2bc1aa3f112a3e6ad12d8fad9f Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Tue, 19 Jul 2022 11:33:34 -0300 Subject: [PATCH 043/281] Update php version in README. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 83e3f301c..d891c0e6f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ![Islandora](https://cloud.githubusercontent.com/assets/2371345/25624809/f95b0972-2f30-11e7-8992-a8f135402cdc.png) Islandora -[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.2-8892BF.svg?style=flat-square)](https://php.net/) +[![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) [![Contribution Guidelines](http://img.shields.io/badge/CONTRIBUTING-Guidelines-blue.svg)](./CONTRIBUTING.md) [![LICENSE](https://img.shields.io/badge/license-GPLv2-blue.svg?style=flat-square)](./LICENSE) From 4d565164d7980b52c9cbeee09ec9a9df4690ed59 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Tue, 19 Jul 2022 14:51:58 -0300 Subject: [PATCH 044/281] Update stomp. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index c783e12be..24eb9e5ba 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ "drupal/context": "^4.0@beta", "drupal/search_api": "~1.8", "islandora/jsonld": "^2", - "stomp-php/stomp-php": "4.*", + "stomp-php/stomp-php": "4.* || ^5", "drupal/jwt": "^1.0.0-beta5", "drupal/filehash": "^1.1 || ^2", "drupal/prepopulate" : "^2.2", From 85cf0822f5282f3ba121ef35a445b809cfa0ff2a Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 20 Jul 2022 07:57:53 -0300 Subject: [PATCH 045/281] Allow failure on php 8.1 and add back drupal 10. --- .github/workflows/build-2.x.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index 52f107100..23a1b4441 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -22,11 +22,21 @@ jobs: strategy: fail-fast: false matrix: - php-versions: ["7.4", "8.0", "8.1"] + php-versions: ["7.4", "8.0"] test-suite: ["kernel", "functional", "functional-javascript"] drupal-version: ["9.4.x", "9.5.x-dev"] mysql: ["8.0"] allowed_failure: [false] + include: + - php-versions: "8.1" + drupal-version: "9.4.x" + allowed_failure: true + - php-versions: "8.1" + drupal-version: "9.5.x-dev" + allowed_failure: true + - php-versions: "8.1" + drupal-version: "10.0.x-dev" + allowed_failure: true name: PHP ${{ matrix.php-versions }} | drupal ${{ matrix.drupal-version }} | mysql ${{ matrix.mysql }} | test-suite ${{ matrix.test-suite }} From 98c9ba4c636e0102df50bceab2f7ab3a63c211dd Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 20 Jul 2022 08:24:30 -0300 Subject: [PATCH 046/281] simplify matrix. --- .github/workflows/build-2.x.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index 23a1b4441..618e7f66c 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -29,14 +29,15 @@ jobs: allowed_failure: [false] include: - php-versions: "8.1" - drupal-version: "9.4.x" allowed_failure: true - - php-versions: "8.1" - drupal-version: "9.5.x-dev" + - drupal-version: "10.0.x-dev" allowed_failure: true - - php-versions: "8.1" + exclude: + - php-versions: "7.4" drupal-version: "10.0.x-dev" - allowed_failure: true + - php-versions: "8.0" + drupal-version: "10.0.x-dev" + name: PHP ${{ matrix.php-versions }} | drupal ${{ matrix.drupal-version }} | mysql ${{ matrix.mysql }} | test-suite ${{ matrix.test-suite }} From 5644a68a0692d737148468ad90c1d6665335483f Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 20 Jul 2022 08:41:37 -0300 Subject: [PATCH 047/281] Try again to use matrix overrides. --- .github/workflows/build-2.x.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index 618e7f66c..a40e19e33 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -22,16 +22,14 @@ jobs: strategy: fail-fast: false matrix: - php-versions: ["7.4", "8.0"] + php-versions: ["7.4", "8.0", "8.1"] test-suite: ["kernel", "functional", "functional-javascript"] - drupal-version: ["9.4.x", "9.5.x-dev"] + drupal-version: ["9.4.x", "9.5.x-dev", "10.0.x-dev"] mysql: ["8.0"] allowed_failure: [false] include: - php-versions: "8.1" allowed_failure: true - - drupal-version: "10.0.x-dev" - allowed_failure: true exclude: - php-versions: "7.4" drupal-version: "10.0.x-dev" From 551a6673bfd8810d3540d4b8a90a9dc760b94170 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 20 Jul 2022 15:34:54 -0300 Subject: [PATCH 048/281] Add back drupal 9.3. --- .github/workflows/build-2.x.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index a40e19e33..ac6b0ca68 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -24,7 +24,7 @@ jobs: matrix: php-versions: ["7.4", "8.0", "8.1"] test-suite: ["kernel", "functional", "functional-javascript"] - drupal-version: ["9.4.x", "9.5.x-dev", "10.0.x-dev"] + drupal-version: ["9.3.x", "9.4.x", "9.5.x-dev", "10.0.x-dev"] mysql: ["8.0"] allowed_failure: [false] include: From f4e91b20a33cce96248079e27cb50fbdf6a8adfb Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 20 Jul 2022 16:03:00 -0300 Subject: [PATCH 049/281] Fix matrix. --- .github/workflows/build-2.x.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index ac6b0ca68..a8e49ba52 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -26,8 +26,8 @@ jobs: test-suite: ["kernel", "functional", "functional-javascript"] drupal-version: ["9.3.x", "9.4.x", "9.5.x-dev", "10.0.x-dev"] mysql: ["8.0"] - allowed_failure: [false] include: + - allowed_failure: false - php-versions: "8.1" allowed_failure: true exclude: From cdb83ece9251ca59a47e5de8106efee91676686b Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 20 Jul 2022 16:42:12 -0300 Subject: [PATCH 050/281] Update matrix. --- .github/workflows/build-2.x.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index a8e49ba52..1bd91b998 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -19,6 +19,7 @@ jobs: build: # The type of runner that the job will run on runs-on: ubuntu-latest + continue-on-error: ${{ matrix.allowed_failure }} strategy: fail-fast: false matrix: @@ -102,7 +103,6 @@ jobs: cd $DRUPAL_DIR chmod -R u+w web/sites/default mkdir -p web/sites/simpletest/browser_output - continue-on-error: ${{ matrix.allowed_failure }} - name: Setup composer paths run: | @@ -117,18 +117,15 @@ jobs: 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 - continue-on-error: ${{ matrix.allowed_failure }} - name: Copy PHPunit file run: cp $PHPUNIT_FILE $DRUPAL_DIR/web/core/phpunit.xml - name: Test scripts run: $SCRIPT_DIR/travis_scripts.sh - continue-on-error: ${{ matrix.allowed_failure }} - name: PHPUNIT tests run: | cd $DRUPAL_DIR/web/core $DRUPAL_DIR/vendor/bin/phpunit --verbose --testsuite "${{ matrix.test-suite }}" - continue-on-error: ${{ matrix.allowed_failure }} From 2d8df5a226c240f1595f9e6fdf769461394f0c14 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 21 Jul 2022 09:21:16 -0300 Subject: [PATCH 051/281] Remove future versions we're not ready for. --- .github/workflows/build-2.x.yml | 16 +++++----------- .../Functional/IslandoraFunctionalTestBase.php | 9 ++++++--- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index 1bd91b998..fad82be8d 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -23,19 +23,13 @@ jobs: strategy: fail-fast: false matrix: - php-versions: ["7.4", "8.0", "8.1"] + php-versions: ["7.4", "8.0"] + # PHP 8.1 fails - see https://github.com/Islandora/islandora/issues/887 test-suite: ["kernel", "functional", "functional-javascript"] - drupal-version: ["9.3.x", "9.4.x", "9.5.x-dev", "10.0.x-dev"] + drupal-version: ["9.3.x", "9.4.x", "9.5.x-dev"] + # Not yet Drupal 10 ready - see https://github.com/Islandora/islandora/issues/888 mysql: ["8.0"] - include: - - allowed_failure: false - - php-versions: "8.1" - allowed_failure: true - exclude: - - php-versions: "7.4" - drupal-version: "10.0.x-dev" - - php-versions: "8.0" - drupal-version: "10.0.x-dev" + allowed_failure: [false] name: PHP ${{ matrix.php-versions }} | drupal ${{ matrix.drupal-version }} | mysql ${{ matrix.mysql }} | test-suite ${{ matrix.test-suite }} diff --git a/tests/src/Functional/IslandoraFunctionalTestBase.php b/tests/src/Functional/IslandoraFunctionalTestBase.php index c154c5c23..1d970b5ab 100644 --- a/tests/src/Functional/IslandoraFunctionalTestBase.php +++ b/tests/src/Functional/IslandoraFunctionalTestBase.php @@ -278,11 +278,13 @@ protected function createPreservationMasterTag() { * Creates a test context. */ protected function createContext($label, $name) { - $this->drupalPostForm('admin/structure/context/add', [ + $this->drupalGet('admin/structure/context/add'); + $values = [ 'label' => $label, 'name' => $name, - ], - $this->t('Save')); + ]; + $this->submitForm($values, 'Save'); + $this->assertSession()->statusCodeEquals(200); } @@ -455,3 +457,4 @@ protected function makeMediaAndFile(AccountInterface $account) { } } + From 704405e3daeb1320d925c2758c209ac3c0f14a66 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 21 Jul 2022 09:49:00 -0300 Subject: [PATCH 052/281] no newline is one newline. --- tests/src/Functional/IslandoraFunctionalTestBase.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/src/Functional/IslandoraFunctionalTestBase.php b/tests/src/Functional/IslandoraFunctionalTestBase.php index 1d970b5ab..2e4c88e89 100644 --- a/tests/src/Functional/IslandoraFunctionalTestBase.php +++ b/tests/src/Functional/IslandoraFunctionalTestBase.php @@ -457,4 +457,3 @@ protected function makeMediaAndFile(AccountInterface $account) { } } - From 573d6878edf057987f1e41e5068de0074573e4c7 Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Thu, 21 Jul 2022 12:09:03 -0300 Subject: [PATCH 053/281] Merge pull request from GHSA-m58q-qq5h-mgqq --- islandora.routing.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/islandora.routing.yml b/islandora.routing.yml index 6fea02e98..5387e9a47 100644 --- a/islandora.routing.yml +++ b/islandora.routing.yml @@ -44,8 +44,7 @@ islandora.upload_children: options: _admin_route: 'TRUE' requirements: - _access: 'TRUE' - #_permssion: 'create node,create media' + _custom_access: '\Drupal\islandora\Form\AddChildrenForm::access' islandora.add_media_to_node_page: path: '/node/{node}/media/add' From dd58302b9889d3d6e9b94e1e0d17cc5eec942a7d Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 21 Jul 2022 20:07:00 -0300 Subject: [PATCH 054/281] Try to get FunctionalJavascript working. --- .github/workflows/build-2.x.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index fad82be8d..13b2e56a6 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -118,6 +118,15 @@ jobs: - name: Test scripts run: $SCRIPT_DIR/travis_scripts.sh + # needed for FunctionalJavascript + - name: Set up chromedriver + uses: actions/checkout@v2 + uses: nanasess/setup-chromedriver@v1 + run: | + export DISPLAY=:99 + chromedriver --url-base=/wd/hub & + sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 & # optional + - name: PHPUNIT tests run: | cd $DRUPAL_DIR/web/core From 724d0845f454ef058cc5d9baf19a983d44c90a23 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 21 Jul 2022 20:12:10 -0300 Subject: [PATCH 055/281] typo. --- .github/workflows/build-2.x.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index 13b2e56a6..3ca7cc50d 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -120,7 +120,6 @@ jobs: # needed for FunctionalJavascript - name: Set up chromedriver - uses: actions/checkout@v2 uses: nanasess/setup-chromedriver@v1 run: | export DISPLAY=:99 From cebeeaec5cc5e7889921151641f353527eb25e7a Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 21 Jul 2022 20:13:40 -0300 Subject: [PATCH 056/281] typo. --- .github/workflows/build-2.x.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index 3ca7cc50d..cd48c5e70 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -119,8 +119,10 @@ jobs: run: $SCRIPT_DIR/travis_scripts.sh # needed for FunctionalJavascript - - name: Set up chromedriver + - name: Setup chromedriver uses: nanasess/setup-chromedriver@v1 + + - name: Start chromedriver run: | export DISPLAY=:99 chromedriver --url-base=/wd/hub & From 1415bd509bb4c1b38c5cc649cc51cf8ea13943b5 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 21 Jul 2022 20:35:05 -0300 Subject: [PATCH 057/281] chromedriver. --- .github/workflows/build-2.x.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index cd48c5e70..d95b1d6bf 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -125,8 +125,7 @@ jobs: - name: Start chromedriver run: | export DISPLAY=:99 - chromedriver --url-base=/wd/hub & - sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 & # optional + chromedriver --port=4444 - name: PHPUNIT tests run: | From 705f623fdb303a0f1a86382ff097bf971440591a Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 21 Jul 2022 20:44:25 -0300 Subject: [PATCH 058/281] chromedriver. --- .github/workflows/build-2.x.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index d95b1d6bf..beb1b6f87 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -125,7 +125,7 @@ jobs: - name: Start chromedriver run: | export DISPLAY=:99 - chromedriver --port=4444 + chromedriver --port=4444 & - name: PHPUNIT tests run: | From 87231dc5c032eb91bb95160e9300e86fa598b6a7 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 21 Jul 2022 22:14:09 -0300 Subject: [PATCH 059/281] try now --- .github/workflows/build-2.x.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index beb1b6f87..a6b29565e 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -125,7 +125,7 @@ jobs: - name: Start chromedriver run: | export DISPLAY=:99 - chromedriver --port=4444 & + chromedriver --port=4444 --no-sandbox & - name: PHPUNIT tests run: | From 07e3c49ecc967824658cb910c82c45d45d746f44 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Fri, 22 Jul 2022 09:08:17 -0300 Subject: [PATCH 060/281] Add webdriver setting in phpunit.xml. --- .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 a6b29565e..ab6a4b071 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -125,7 +125,7 @@ jobs: - name: Start chromedriver run: | export DISPLAY=:99 - chromedriver --port=4444 --no-sandbox & + chromedriver --port=4444 --no-sandbox --url-base=/wd/hub & - name: PHPUNIT tests run: | diff --git a/phpunit.xml b/phpunit.xml index a40917813..3e6e1562b 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -47,7 +47,7 @@ - + From eb53ff474eaf374cfc143aa7925ec1c9ee7388ba Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Fri, 22 Jul 2022 10:35:23 -0300 Subject: [PATCH 061/281] revert setting up chromedriver. --- .github/workflows/build-2.x.yml | 14 +++----------- phpunit.xml | 2 +- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build-2.x.yml b/.github/workflows/build-2.x.yml index ab6a4b071..439395b0a 100644 --- a/.github/workflows/build-2.x.yml +++ b/.github/workflows/build-2.x.yml @@ -23,11 +23,12 @@ jobs: strategy: fail-fast: false matrix: - php-versions: ["7.4", "8.0"] # PHP 8.1 fails - see https://github.com/Islandora/islandora/issues/887 + php-versions: ["7.4", "8.0"] + # test-suite functional-javascript will appear to pass but will skip tests; missing chromedriver. test-suite: ["kernel", "functional", "functional-javascript"] - drupal-version: ["9.3.x", "9.4.x", "9.5.x-dev"] # 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"] mysql: ["8.0"] allowed_failure: [false] @@ -118,15 +119,6 @@ jobs: - name: Test scripts run: $SCRIPT_DIR/travis_scripts.sh - # needed for FunctionalJavascript - - name: Setup chromedriver - uses: nanasess/setup-chromedriver@v1 - - - name: Start chromedriver - run: | - export DISPLAY=:99 - chromedriver --port=4444 --no-sandbox --url-base=/wd/hub & - - name: PHPUNIT tests run: | cd $DRUPAL_DIR/web/core diff --git a/phpunit.xml b/phpunit.xml index 3e6e1562b..a40917813 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -47,7 +47,7 @@ - + From a297796f47b23b9f5a778d65fe6bee110a70d6ef Mon Sep 17 00:00:00 2001 From: dannylamb Date: Sun, 24 Jul 2022 15:52:38 -0300 Subject: [PATCH 062/281] Allowing Image fields for multi-file media (#860) --- src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php b/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php index 84c064e92..f484fdc33 100644 --- a/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php +++ b/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php @@ -88,10 +88,16 @@ 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); $form['event']['#disabled'] = 'disabled'; $form['destination_field_name'] = [ From 7bca3d56751a86a0320a0b018498355a558d16f9 Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Wed, 3 Aug 2022 12:23:57 -0300 Subject: [PATCH 063/281] IsIslandora views filter and context condition use Islandora Utils. (#881) * IsIslandora views filter and context condition use Islandora Utils. --- islandora.views.inc | 12 ++ .../Condition/NodeIsIslandoraObject.php | 38 ++++- src/Plugin/views/filter/NodeIsIslandora.php | 144 ++++++++++++++++++ 3 files changed, 188 insertions(+), 6 deletions(-) create mode 100644 src/Plugin/views/filter/NodeIsIslandora.php diff --git a/islandora.views.inc b/islandora.views.inc index 574fa4155..97dbf08c1 100644 --- a/islandora.views.inc +++ b/islandora.views.inc @@ -37,4 +37,16 @@ function islandora_views_data_alter(&$data) { 'id' => 'islandora_node_has_media_use', ], ]; + + // Add Is Islandora filter. + $data['node_field_data']['islandora_node_is_islandora'] = [ + 'title' => t('Node is Islandora'), + 'group' => t('Content'), + 'filter' => [ + 'title' => t('Node is Islandora'), + 'help' => t('Node has a content type that possesses the mandatory Islandora fields.'), + 'field' => 'nid', + 'id' => 'islandora_node_is_islandora', + ], + ]; } diff --git a/src/Plugin/Condition/NodeIsIslandoraObject.php b/src/Plugin/Condition/NodeIsIslandoraObject.php index 6448cfdcb..06ff62596 100644 --- a/src/Plugin/Condition/NodeIsIslandoraObject.php +++ b/src/Plugin/Condition/NodeIsIslandoraObject.php @@ -5,13 +5,14 @@ use Drupal\Core\Condition\ConditionPluginBase; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Symfony\Component\DependencyInjection\ContainerInterface; +use Drupal\Islandora\IslandoraUtils; /** * Checks whether node has fields that qualify it as an "Islandora" node. * * @Condition( * id = "node_is_islandora_object", - * label = @Translation("Node is an Islandora object"), + * label = @Translation("Node is an Islandora node"), * context_definitions = { * "node" = @ContextDefinition("entity:node", required = TRUE , label = @Translation("node")) * } @@ -19,6 +20,30 @@ */ class NodeIsIslandoraObject extends ConditionPluginBase implements ContainerFactoryPluginInterface { + /** + * Islandora Utils. + * + * @var \Drupal\islandora\IslandoraUtils + */ + protected $utils; + + /** + * Constructs a Node is Islandora Condition plugin. + * + * @param array $configuration + * A configuration array containing information about the plugin instance. + * @param string $plugin_id + * The plugin_id for the plugin instance. + * @param mixed $plugin_definition + * The plugin implementation definition. + * @param \Drupal\islandora\IslandoraUtils $islandora_utils + * Islandora utilities. + */ + public function __construct(array $configuration, $plugin_id, $plugin_definition, IslandoraUtils $islandora_utils) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + $this->utils = $islandora_utils; + } + /** * {@inheritdoc} */ @@ -26,7 +51,8 @@ public static function create(ContainerInterface $container, array $configuratio return new static( $configuration, $plugin_id, - $plugin_definition + $plugin_definition, + $container->get('islandora.utils') ); } @@ -38,8 +64,8 @@ public function evaluate() { if (!$node) { return FALSE; } - // Islandora objects have these two fields. - if ($node->hasField('field_model') && $node->hasField('field_member_of')) { + // Determine if node is Islandora. + if ($this->utils->isIslandoraType('node', $node->bundle())) { return TRUE; } } @@ -49,10 +75,10 @@ public function evaluate() { */ public function summary() { if (!empty($this->configuration['negate'])) { - return $this->t('The node is not an Islandora object.'); + return $this->t('The node is not an Islandora node.'); } else { - return $this->t('The node is an Islandora object.'); + return $this->t('The node is an Islandora node.'); } } diff --git a/src/Plugin/views/filter/NodeIsIslandora.php b/src/Plugin/views/filter/NodeIsIslandora.php new file mode 100644 index 000000000..2065c46b9 --- /dev/null +++ b/src/Plugin/views/filter/NodeIsIslandora.php @@ -0,0 +1,144 @@ +joinHandler = $join_handler; + $this->utils = $islandora_utils; + $this->entityTypeBundleInfo = $entity_type_bundle_info; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, $plugin_id, $plugin_definition, + $container->get('plugin.manager.views.join'), + $container->get('islandora.utils'), + $container->get('entity_type.bundle.info') + ); + } + + /** + * {@inheritdoc} + */ + protected function defineOptions() { + return [ + 'negated' => ['default' => FALSE], + ]; + } + + /** + * {@inheritdoc} + */ + public function buildOptionsForm(&$form, FormStateInterface $form_state) { + $types = []; + foreach ($this->entityTypeBundleInfo->getBundleInfo('node') as $bundle_id => $bundle) { + if ($this->utils->isIslandoraType('node', $bundle_id)) { + $types[] = "{$bundle['label']} ($bundle_id)"; + } + } + $types_list = implode(', ', $types); + $form['info'] = [ + '#type' => 'item', + '#title' => 'Information', + '#description' => t("Configured Islandora bundles: @types", ['@types' => $types_list]), + ]; + $form['negated'] = [ + '#type' => 'checkbox', + '#title' => 'Negated', + '#description' => $this->t("Return nodes that don't have islandora fields"), + '#default_value' => $this->options['negated'], + ]; + } + + /** + * {@inheritdoc} + */ + public function adminSummary() { + $operator = ($this->options['negated']) ? "is not" : "is"; + return "Node {$operator} an islandora node"; + } + + /** + * {@inheritdoc} + */ + public function query() { + $types = []; + foreach (array_keys($this->entityTypeBundleInfo->getBundleInfo('node')) as $bundle_id) { + if ($this->utils->isIslandoraType('node', $bundle_id)) { + $types[] = $bundle_id; + } + } + $condition = ($this->options['negated']) ? 'NOT IN' : 'IN'; + $query_base_table = $this->relationship ?: $this->view->storage->get('base_table'); + + $definition = [ + 'table' => 'node', + 'type' => 'LEFT', + 'field' => 'nid', + 'left_table' => $query_base_table, + 'left_field' => 'nid', + ]; + $join = $this->joinHandler->createInstance('standard', $definition); + $node_table_alias = $this->query->addTable('node', $this->relationship, $join); + $this->query->addWhere($this->options['group'], "$node_table_alias.type", $types, $condition); + } + +} From d405a2f14fd5cf1ce8cd95497643b2201458fb65 Mon Sep 17 00:00:00 2001 From: Seth Shaw <108362375+seth-shaw-asu@users.noreply.github.com> Date: Tue, 9 Aug 2022 13:09:23 -0700 Subject: [PATCH 064/281] throw error instead of returning null data Avoids WSOD when EmitEvent creates a StompHeaderEvent --- src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php b/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php index f484fdc33..be9eca80b 100644 --- a/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php +++ b/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php @@ -40,7 +40,7 @@ public function defaultConfiguration() { protected function generateData(EntityInterface $entity) { $data = parent::generateData($entity); if (get_class($entity) != 'Drupal\media\Entity\Media') { - return; + throw new \RuntimeException("Entity {$entity->getEntityTypeId()} {$entity->id()} is not a media", 500); } $source_file = $this->mediaSource->getSourceFile($entity); if (!$source_file) { From 3048594a8b95194707c095c2d30e9d9acc93e89b Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Mon, 15 Aug 2022 15:27:07 -0300 Subject: [PATCH 065/281] Allow media to use integer weight selector. (#894) --- islandora.views.inc | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/islandora.views.inc b/islandora.views.inc index 97dbf08c1..f249c633f 100644 --- a/islandora.views.inc +++ b/islandora.views.inc @@ -9,19 +9,21 @@ * Implements hook_views_data_alter(). */ function islandora_views_data_alter(&$data) { - // For now only support Nodes. - $fields = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions('node'); - foreach ($fields as $field => $field_storage_definition) { - if ($field_storage_definition->getType() == 'integer' && strpos($field, "field_") === 0) { - $prefixed_field = 'node__' . $field; - if (isset($data[$prefixed_field])) { - $data[$prefixed_field][$field . '_value']['field'] = $data[$prefixed_field][$field]['field']; - $data[$prefixed_field][$field]['title'] = t('Integer Weight Selector (@field)', [ - '@field' => $field, - ]); - $data[$prefixed_field][$field]['help'] = t('Provides a drag-n-drop reordering of integer-based weight fields.'); - $data[$prefixed_field][$field]['title short'] = t('Integer weight selector'); - $data[$prefixed_field][$field]['field']['id'] = 'integer_weight_selector'; + // For now only support Nodes and Media. + foreach (['node', 'media'] as $entity_type) { + $fields = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions($entity_type); + foreach ($fields as $field => $field_storage_definition) { + if ($field_storage_definition->getType() == 'integer' && strpos($field, "field_") === 0) { + $prefixed_field = $entity_type . '__' . $field; + if (isset($data[$prefixed_field])) { + $data[$prefixed_field][$field . '_value']['field'] = $data[$prefixed_field][$field]['field']; + $data[$prefixed_field][$field]['title'] = t('Integer Weight Selector (@field)', [ + '@field' => $field, + ]); + $data[$prefixed_field][$field]['help'] = t('Provides a drag-n-drop reordering of integer-based weight fields.'); + $data[$prefixed_field][$field]['title short'] = t('Integer weight selector'); + $data[$prefixed_field][$field]['field']['id'] = 'integer_weight_selector'; + } } } } From 725b5592803564c9727e920b780247e45ecbc9a4 Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 31 Aug 2022 19:14:12 -0300 Subject: [PATCH 066/281] Add file access check to IIIF manifest generation. (#884) --- .../islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 13f83e7d9..194670016 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -198,6 +198,10 @@ protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_bas /** @var \Drupal\Core\Field\FieldItemListInterface $images */ $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; + } // 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); From 0bea8da572110f8910bd1e14542edf7bfcccf018 Mon Sep 17 00:00:00 2001 From: Alexander O'Neill Date: Tue, 12 Jul 2022 16:23:33 -0300 Subject: [PATCH 067/281] 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 068/281] 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 069/281] 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 070/281] 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 071/281] 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 072/281] 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 073/281] 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 074/281] 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 075/281] 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 076/281] 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 0e8c05cc7bfcb90cfcba640b48d5ad21af7a0d16 Mon Sep 17 00:00:00 2001 From: Islandora Foundation Community <92804539+islandora-community@users.noreply.github.com> Date: Thu, 8 Sep 2022 11:16:28 -0600 Subject: [PATCH 077/281] Update PULL_REQUEST_TEMPLATE.md --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index df4255eea..a9417abed 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -40,4 +40,4 @@ Any additional information that you think would be helpful when reviewing this PR. # Interested parties -Tag (@ mention) interested parties or, if unsure, @Islandora/8-x-committers +Tag (@ mention) interested parties or, if unsure, @Islandora/committers From a250c2ac7883d7ba235b0e43b2e978e51e18dae9 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 15 Sep 2022 12:52:51 -0300 Subject: [PATCH 078/281] Fix/schemas (#898) * Define schemas that should be defined. Came out of the starter site project, running "config_inspector" flagged a number of things. * Avoid the deprecated sequence specification. * Bad assumption on my part... ... Seeing the name and the module, figured this schema was just misplaced... Appears that the `islandora_image` thing is indeed in `islandora` proper. --- config/schema/islandora.schema.yml | 78 +++++++++++++++++++ .../config/schema/islandora_audio.schema.yml | 3 + .../config/schema/islandora_iiif.schema.yml | 8 ++ .../config/schema/islandora_video.schema.yml | 3 + 4 files changed, 92 insertions(+) diff --git a/config/schema/islandora.schema.yml b/config/schema/islandora.schema.yml index c98679eba..e85d57396 100644 --- a/config/schema/islandora.schema.yml +++ b/config/schema/islandora.schema.yml @@ -87,6 +87,14 @@ condition.plugin.node_has_term: logic: type: string label: 'Logic (AND or OR)' + tids: + type: sequence + sequence: + type: mapping + mapping: + target_id: + type: integer + label: The target taxonomy term IDs condition.plugin.node_has_parent: type: condition.plugin @@ -158,6 +166,76 @@ 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' + +condition.plugin.islandora_entity_bundle: + type: condition.plugin + mapping: + bundles: + type: sequence + sequence: + type: string + +condition.plugin.media_source_mimetype: + type: condition.plugin + mapping: + mimetype: + type: string + +reaction.plugin.alter_jsonld_type: + type: islandora.reaction_plugin_with_saved + mapping: + source_field: + type: string + +islandora.reaction_plugin_with_saved: + type: reaction.plugin + mapping: + saved: + type: boolean + label: Default config upstream; however, left undefined in the schema. + +reaction.plugin.islandora_map_uri_predicate: + type: islandora.reaction_plugin_with_saved + mapping: + drupal_uri_predicate: + type: string + +reaction.plugin.view_mode_alter: + type: islandora.reaction_plugin_with_saved + mapping: + mode: + type: string + label: The view mode to which to switch + +islandora.reaction.actions: + type: islandora.reaction_plugin_with_saved + mapping: + actions: + type: sequence + sequence: + type: string + +reaction.plugin.index: + type: islandora.reaction.actions + +reaction.plugin.delete: + type: islandora.reaction.actions + +reaction.plugin.derivative: + type: islandora.reaction.actions + +field.widget.settings.media_track: + type: field.widget.settings.file_generic + +field.field_settings.media_track: + type: field.field_settings.file + mapping: + languages: + type: string + +field.storage_settings.media_track: + type: field.storage_settings.file diff --git a/modules/islandora_audio/config/schema/islandora_audio.schema.yml b/modules/islandora_audio/config/schema/islandora_audio.schema.yml index 5f09740a3..82b080887 100644 --- a/modules/islandora_audio/config/schema/islandora_audio.schema.yml +++ b/modules/islandora_audio/config/schema/islandora_audio.schema.yml @@ -29,3 +29,6 @@ action.configuration.generate_audio_derivative: path: type: text label: 'File path with extension' + +field.formatter.settings.islandora_file_audio: + type: field.formatter.settings.file_audio diff --git a/modules/islandora_iiif/config/schema/islandora_iiif.schema.yml b/modules/islandora_iiif/config/schema/islandora_iiif.schema.yml index 6ef42bc4c..fc62c5c4c 100644 --- a/modules/islandora_iiif/config/schema/islandora_iiif.schema.yml +++ b/modules/islandora_iiif/config/schema/islandora_iiif.schema.yml @@ -5,3 +5,11 @@ islandora_iiif.settings: iiif_server: type: string label: 'IIIF Server Url' + +views.style.iiif_manifest: + type: views_style + mapping: + iiif_tile_field: + type: sequence + sequence: + type: string diff --git a/modules/islandora_video/config/schema/islandora_video.schema.yml b/modules/islandora_video/config/schema/islandora_video.schema.yml index b1d72d7ff..01d284814 100644 --- a/modules/islandora_video/config/schema/islandora_video.schema.yml +++ b/modules/islandora_video/config/schema/islandora_video.schema.yml @@ -29,3 +29,6 @@ action.configuration.generate_video_derivative: path: type: text label: 'File path with extension' + +field.formatter.settings.islandora_file_video: + type: field.formatter.settings.file_video From ca1d9f6f6073e2260271c7907b7afafa7f677472 Mon Sep 17 00:00:00 2001 From: Mark Jordan Date: Wed, 21 Sep 2022 11:07:05 -0700 Subject: [PATCH 079/281] Issue #2170: Sort "manage members" View results by field_weight (#900) --- .../install/views.view.manage_members.yml | 182 ++++++++++-------- 1 file changed, 98 insertions(+), 84 deletions(-) diff --git a/modules/islandora_core_feature/config/install/views.view.manage_members.yml b/modules/islandora_core_feature/config/install/views.view.manage_members.yml index a978f1d22..4a2429249 100644 --- a/modules/islandora_core_feature/config/install/views.view.manage_members.yml +++ b/modules/islandora_core_feature/config/install/views.view.manage_members.yml @@ -1,15 +1,17 @@ langcode: en status: true dependencies: - enforced: - module: - - islandora_core_feature module: - jsonld - node - rest - serialization - user + enforced: + module: + - islandora_core_feature +_core: + default_config_hash: Zwu8JUsBiYaxPko_9DbJJhA-ZZSGOm81I9XtT9NH3M4 id: manage_members label: 'Manage members' module: views @@ -17,61 +19,14 @@ description: 'Manage members belonging to a piece of content' 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: 'manage members' - 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: 'Manage members' fields: node_bulk_form: id: node_bulk_form @@ -80,6 +35,8 @@ display: relationship: none group_type: group admin_label: '' + entity_type: node + plugin_id: node_bulk_form label: 'Node operations bulk form' exclude: false alter: @@ -124,33 +81,27 @@ display: action_title: Action include_exclude: exclude selected_actions: { } - entity_type: node - plugin_id: node_bulk_form 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: '' @@ -160,9 +111,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 @@ -180,6 +135,8 @@ display: relationship: none group_type: group admin_label: '' + entity_type: node + plugin_id: entity_operations label: 'Operations links' exclude: false alter: @@ -222,15 +179,56 @@ display: empty_zero: false hide_alter_empty: true destination: false - entity_type: node - plugin_id: entity_operations - filters: { } - sorts: { } - title: 'Manage members' - header: { } - footer: { } + 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: perm + options: + perm: 'manage members' + cache: + type: tag + options: { } empty: { } - relationships: { } + sorts: + field_weight_value: + id: field_weight_value + table: node__field_weight + field: field_weight_value + relationship: none + group_type: group + admin_label: '' + plugin_id: standard + order: ASC + expose: + label: '' + field_identifier: '' + exposed: false arguments: field_member_of_target_id: id: field_member_of_target_id @@ -239,6 +237,7 @@ display: relationship: none group_type: group admin_label: '' + plugin_id: numeric default_action: default exception: value: all @@ -252,8 +251,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 @@ -263,17 +262,32 @@ display: type: 'entity:node' fail: 'not found' validate_options: - operation: view - multiple: 0 bundles: { } access: false + operation: view + multiple: 0 break_phrase: false not: false - plugin_id: numeric - display_extenders: { } + filters: { } filter_groups: operator: AND groups: { } + 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: { } + display_extenders: { } cache_metadata: max-age: 0 contexts: @@ -285,9 +299,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: { } @@ -296,11 +310,11 @@ display: type: tab title: Children description: '' + weight: 0 expanded: false + menu_name: main parent: '' - weight: 0 context: '0' - menu_name: main cache_metadata: max-age: 0 contexts: @@ -312,13 +326,11 @@ display: - user.permissions 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: node/%node/members style: type: serializer options: @@ -326,6 +338,8 @@ display: formats: jsonld: jsonld json: json + display_extenders: { } + path: node/%node/members auth: - basic_auth - jwt_auth From 09484363955a46c8673dd84fb1658f8bd86f4b86 Mon Sep 17 00:00:00 2001 From: Jared Whiklo Date: Wed, 21 Sep 2022 14:27:29 -0500 Subject: [PATCH 080/281] Unset pseudo field in display modes automatically (#899) * Unset pseudo field in display modes automatically * Clear the correct cache and fix coder issues --- islandora.module | 2 +- src/Form/IslandoraSettingsForm.php | 63 ++++++++++++++++++++++++++++-- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/islandora.module b/islandora.module index e29fdb565..5b5446d13 100644 --- a/islandora.module +++ b/islandora.module @@ -423,7 +423,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, diff --git a/src/Form/IslandoraSettingsForm.php b/src/Form/IslandoraSettingsForm.php index 0ebc0b3cf..5049ef161 100644 --- a/src/Form/IslandoraSettingsForm.php +++ b/src/Form/IslandoraSettingsForm.php @@ -2,8 +2,10 @@ namespace Drupal\islandora\Form; +use Drupal\Core\Cache\Cache; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Entity\EntityTypeBundleInfoInterface; +use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\ConfigFormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Site\Settings; @@ -39,6 +41,7 @@ class IslandoraSettingsForm extends ConfigFormBase { 'month', 'year', ]; + const GEMINI_PSEUDO_FIELD = 'field_gemini_uri'; /** * To list the available bundle types. @@ -54,6 +57,13 @@ class IslandoraSettingsForm extends ConfigFormBase { */ private $brokerPassword; + /** + * The entity type manager service. + * + * @var \Drupal\Core\Entity\EntityTypeManagerInterface + */ + private $entityTypeManager; + /** * Constructs a \Drupal\system\ConfigFormBase object. * @@ -61,14 +71,18 @@ class IslandoraSettingsForm extends ConfigFormBase { * The factory for configuration objects. * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info * The EntityTypeBundleInfo service. + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager + * The EntityTypeManager service. */ public function __construct( ConfigFactoryInterface $config_factory, - EntityTypeBundleInfoInterface $entity_type_bundle_info + EntityTypeBundleInfoInterface $entity_type_bundle_info, + EntityTypeManagerInterface $entity_type_manager ) { $this->setConfigFactory($config_factory); $this->entityTypeBundleInfo = $entity_type_bundle_info; $this->brokerPassword = $this->config(self::CONFIG_NAME)->get(self::BROKER_PASSWORD); + $this->entityTypeManager = $entity_type_manager; } /** @@ -78,6 +92,7 @@ public static function create(ContainerInterface $container) { return new static( $container->get('config.factory'), $container->get('entity_type.bundle.info'), + $container->get('entity_type.manager') ); } @@ -308,7 +323,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) { public function submitForm(array &$form, FormStateInterface $form_state) { $config = $this->configFactory->getEditable(self::CONFIG_NAME); - $pseudo_types = array_filter($form_state->getValue(self::GEMINI_PSEUDO)); + $new_pseudo_types = array_filter($form_state->getValue(self::GEMINI_PSEUDO)); $broker_password = $form_state->getValue(self::BROKER_PASSWORD); @@ -326,15 +341,57 @@ public function submitForm(array &$form, FormStateInterface $form_state) { } } + // Check for types being unset and remove the field from them first. + $current_pseudo_types = $config->get(self::GEMINI_PSEUDO); + $this->updateEntityViewConfiguration($current_pseudo_types, $new_pseudo_types); + $config ->set(self::BROKER_URL, $form_state->getValue(self::BROKER_URL)) ->set(self::JWT_EXPIRY, $form_state->getValue(self::JWT_EXPIRY)) ->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, $pseudo_types) + ->set(self::GEMINI_PSEUDO, $new_pseudo_types) ->save(); parent::submitForm($form, $form_state); } + /** + * Removes the Fedora URI field from entity bundles that have be unselected. + * + * @param array $current_config + * The current set of entity types & bundles to have the pseudo field, + * format {bundle}:{entity_type}. + * @param array $new_config + * The new set of entity types & bundles to have the pseudo field, format + * {bundle}:{entity_type}. + * + * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException + * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException + * @throws \Drupal\Core\Entity\EntityStorageException + */ + private function updateEntityViewConfiguration(array $current_config, array $new_config) { + $removed = array_diff($current_config, $new_config); + $added = array_diff($new_config, $current_config); + $entity_view_display = $this->entityTypeManager->getStorage('entity_view_display'); + foreach ($removed as $bundle_type) { + [$bundle, $type_id] = explode(":", $bundle_type); + $results = $entity_view_display->getQuery() + ->condition('bundle', $bundle) + ->condition('targetEntityType', $type_id) + ->exists('content.' . self::GEMINI_PSEUDO_FIELD . '.region') + ->execute(); + $entities = $entity_view_display->loadMultiple($results); + foreach ($entities as $entity) { + $entity->removeComponent(self::GEMINI_PSEUDO_FIELD); + $entity->save(); + } + } + if (count($removed) > 0 || count($added) > 0) { + // If we added or cleared a type then clear the extra_fields cache. + // @see Drupal/Core/Entity/EntityFieldManager::getExtraFields + Cache::invalidateTags(["entity_field_info"]); + } + } + } From aa3c71893e7aea98dff67e660df5f3b7832fafb0 Mon Sep 17 00:00:00 2001 From: shriram Date: Tue, 18 Oct 2022 16:10:19 -0300 Subject: [PATCH 081/281] 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 082/281] 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 083/281] 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 084/281] 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 085/281] 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 086/281] 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 087/281] 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 088/281] 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 089/281] 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 090/281] 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 091/281] 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 092/281] 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 093/281] 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 094/281] 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 095/281] 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 096/281] 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 097/281] 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 098/281] 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 099/281] 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 100/281] 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 101/281] 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 102/281] 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 103/281] 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 104/281] 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 105/281] 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 106/281] 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 107/281] 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 108/281] 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 109/281] 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 110/281] 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 111/281] 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 112/281] 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 113/281] 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 114/281] 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 115/281] 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 116/281] 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 117/281] 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 118/281] 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 119/281] 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 120/281] 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 121/281] 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 122/281] 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 123/281] 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 124/281] 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 125/281] 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 126/281] 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 127/281] 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 128/281] 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 129/281] 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 130/281] 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 131/281] 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 132/281] 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 133/281] 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 134/281] 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 135/281] 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 136/281] 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 137/281] 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 138/281] 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 139/281] 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 140/281] 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 141/281] 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 142/281] 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 143/281] 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 144/281] 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 145/281] 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 146/281] 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 147/281] 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 148/281] 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 149/281] 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 150/281] 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 151/281] 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 152/281] 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 153/281] 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 154/281] 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 155/281] 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 156/281] 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 157/281] 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 158/281] 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 159/281] 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 160/281] 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 161/281] 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 162/281] 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 163/281] 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 164/281] 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 165/281] 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 166/281] 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 167/281] 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 168/281] 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 169/281] 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 170/281] 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 171/281] 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 172/281] 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 173/281] 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 174/281] 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 175/281] 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 176/281] 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 177/281] 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 178/281] 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 179/281] 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 180/281] 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 181/281] 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 182/281] 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 183/281] 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 184/281] 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 185/281] 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 186/281] 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 187/281] 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 188/281] 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 189/281] 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 190/281] 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 191/281] 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 192/281] 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 193/281] 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 194/281] 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 195/281] 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 196/281] 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 197/281] 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 198/281] 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 199/281] 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 200/281] 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 201/281] 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 202/281] 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 203/281] 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 204/281] 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 205/281] 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 206/281] 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 207/281] 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 208/281] 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 209/281] 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 210/281] 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 211/281] 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 212/281] 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 213/281] 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 214/281] 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 215/281] 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 216/281] 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 217/281] 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 218/281] 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 219/281] 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 220/281] 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 221/281] 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 222/281] 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 223/281] 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 224/281] 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 225/281] 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 226/281] 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 227/281] 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 228/281] 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 229/281] 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 230/281] 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 231/281] 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 232/281] 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 233/281] 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 234/281] 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 235/281] 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 236/281] 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 237/281] 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 238/281] 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 239/281] 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 240/281] 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 241/281] 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 242/281] 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 243/281] 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 244/281] 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 245/281] 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 246/281] 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 247/281] 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 248/281] 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 249/281] 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 250/281] 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 251/281] 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 252/281] 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 253/281] 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 254/281] 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 255/281] 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 256/281] 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 257/281] 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 258/281] 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 259/281] =?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 260/281] 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 261/281] 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 262/281] 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 263/281] =?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 264/281] 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 265/281] 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 266/281] 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 267/281] 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 268/281] 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 269/281] 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 270/281] 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 271/281] 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 272/281] 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 273/281] 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 274/281] 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 275/281] 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 276/281] 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 277/281] 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 278/281] 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 279/281] 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 280/281] 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 281/281] 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,