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 aecb7706..dc750a5a 100644 --- a/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php +++ b/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php @@ -8,6 +8,7 @@ use Drupal\Core\Form\FormStateInterface; 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 @@ class IslandoraIIIFConfigForm extends ConfigFormBase { 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 c085764d..befd4926 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 f787f94a..46bede3f 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 c66c1ba8..9cd89cdd 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 306278ba..ad11dca8 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 738be5b4..85abaf0d 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 85abaf0d..dd8f363f 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 46bede3f..2993244d 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 2993244d..c783e12b 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 befd4926..83e3f301 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 dd8f363f..f81693d3 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 f81693d3..8cff7884 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 8cff7884..d7f1ceb6 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 d7f1ceb6..e2688867 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 56e0b5c5..bd670561 100644 --- a/src/Controller/ManageMediaController.php +++ b/src/Controller/ManageMediaController.php @@ -45,13 +45,19 @@ class ManageMediaController extends ManageMembersController { * 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 141d3567..60892c96 100644 --- a/src/Plugin/views/field/IntegerWeightSelector.php +++ b/src/Plugin/views/field/IntegerWeightSelector.php @@ -46,12 +46,13 @@ class IntegerWeightSelector extends FieldPluginBase { $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 58e3c959..71c723f0 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 93ed7097..620f2289 100644 --- a/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php +++ b/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php @@ -4,12 +4,12 @@ namespace Drupal\islandora_breadcrumbs; 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 @@ class IslandoraBreadcrumbBuilder implements BreadcrumbBuilderInterface { $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 a4dda6c1..e5071a05 100644 --- a/src/IslandoraUtils.php +++ b/src/IslandoraUtils.php @@ -672,4 +672,83 @@ class IslandoraUtils { 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 00000000..dd2abc54 --- /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 ad11dca8..80c58187 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 dd2abc54..ad6f1b99 100644 --- a/src/Plugin/Condition/NodeHasAncestor.php +++ b/src/Plugin/Condition/NodeHasAncestor.php @@ -96,7 +96,7 @@ class NodeHasAncestor extends ConditionPluginBase implements ContainerFactoryPlu '#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 @@ class NodeHasAncestor extends ConditionPluginBase implements ContainerFactoryPlu 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 073ca04e..779451c2 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 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { 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 779451c2..2dfe5011 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 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { */ 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 ebec711f..683f3e8b 100644 --- a/src/EventGenerator/EmitEvent.php +++ b/src/EventGenerator/EmitEvent.php @@ -5,6 +5,7 @@ namespace Drupal\islandora\EventGenerator; 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 @@ abstract class EmitEvent extends ConfigurableActionBase implements ContainerFact 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 @@ abstract class EmitEvent extends ConfigurableActionBase implements ContainerFact $this->stomp = $stomp; $this->messenger = $messenger; $this->eventDispatcher = $event_dispatcher; + $this->logger = $channel; } /** @@ -122,7 +134,8 @@ abstract class EmitEvent extends ConfigurableActionBase implements ContainerFact $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 @@ abstract class EmitEvent extends ConfigurableActionBase implements ContainerFact 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 @@ abstract class EmitEvent extends ConfigurableActionBase implements ContainerFact ); } 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 @@ abstract class EmitEvent extends ConfigurableActionBase implements ContainerFact } 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 3c7ff5b6..9d0520a3 100644 --- a/src/Plugin/Action/AbstractGenerateDerivativeBase.php +++ b/src/Plugin/Action/AbstractGenerateDerivativeBase.php @@ -5,6 +5,7 @@ namespace Drupal\islandora\Plugin\Action; 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 @@ class AbstractGenerateDerivativeBase extends EmitEvent { 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 @@ class AbstractGenerateDerivativeBase extends EmitEvent { $event_generator, $stomp, $messenger, - $event_dispatcher + $event_dispatcher, + $channel ); } @@ -148,7 +153,8 @@ class AbstractGenerateDerivativeBase extends EmitEvent { $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 2dfe5011..0ebc213e 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 @@ namespace Drupal\islandora_iiif\Plugin\views\style; 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 @@ class IIIFManifest extends StylePluginBase { * 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 2793cf49..75003463 100644 --- a/tests/src/Functional/IslandoraImageFormatterTest.php +++ b/tests/src/Functional/IslandoraImageFormatterTest.php @@ -10,6 +10,11 @@ namespace Drupal\Tests\islandora\Functional; */ 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 @@ class IslandoraImageFormatterTest extends IslandoraFunctionalTestBase { // 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 @@ class IslandoraImageFormatterTest extends IslandoraFunctionalTestBase { '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 de7a3e46..0ee69fc1 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 75003463..33f6e1e6 100644 --- a/tests/src/Functional/IslandoraImageFormatterTest.php +++ b/tests/src/Functional/IslandoraImageFormatterTest.php @@ -10,11 +10,6 @@ namespace Drupal\Tests\islandora\Functional; */ 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 @@ class IslandoraImageFormatterTest extends IslandoraFunctionalTestBase { // 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 0ee69fc1..c98679eb 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 ad166b50..ea34ee2e 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 6bc44096..4175cbf5 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 00000000..2c220801 --- /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 620f2289..23d3ff3c 100644 --- a/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php +++ b/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php @@ -78,7 +78,7 @@ class IslandoraBreadcrumbBuilder implements BreadcrumbBuilderInterface { $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 2c220801..2ca9ada6 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 00000000..d198060b --- /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 00000000..e9fd9ac1 --- /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 00000000..bdaa84ef --- /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 23d3ff3c..d84b8c3c 100644 --- a/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php +++ b/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php @@ -64,7 +64,14 @@ class IslandoraBreadcrumbBuilder implements BreadcrumbBuilderInterface { $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 @@ class IslandoraBreadcrumbBuilder implements BreadcrumbBuilderInterface { 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 e5071a05..f81cb747 100644 --- a/src/IslandoraUtils.php +++ b/src/IslandoraUtils.php @@ -714,7 +714,7 @@ class IslandoraUtils { * @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 d198060b..dcf99534 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 bdaa84ef..679a565e 100644 --- a/modules/islandora_breadcrumbs/src/Form/IslandoraBreadcrumbsSettingsForm.php +++ b/modules/islandora_breadcrumbs/src/Form/IslandoraBreadcrumbsSettingsForm.php @@ -45,8 +45,8 @@ class IslandoraBreadcrumbsSettingsForm extends ConfigFormBase { '#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 d84b8c3c..5ed7f6d0 100644 --- a/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php +++ b/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php @@ -83,6 +83,7 @@ class IslandoraBreadcrumbBuilder implements BreadcrumbBuilderInterface { $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 7c62bade..e1b8730c 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 0ebc213e..13f83e7d 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 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { 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 e2688867..e29fdb56 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 80c58187..f5bce510 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 3b5e8498..f6b8034a 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 @@ use Drupal\islandora\Plugin\Action\AbstractGenerateDerivativeMediaFile; * * @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 aa9c188d..ce88d0dc 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 ce88d0dc..7deecc69 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 cd826d08..ad2b141a 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 5209546c..bd47500a 100644 --- a/src/Commands/IslandoraCommands.php +++ b/src/Commands/IslandoraCommands.php @@ -4,7 +4,7 @@ namespace Drupal\islandora\Commands; 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 cd826d08..de176f15 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 00000000..e83c6306 --- /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 e83c6306..bb84ba6b 100644 --- a/src/Plugin/views/filter/NodeHasMediaUse.php +++ b/src/Plugin/views/filter/NodeHasMediaUse.php @@ -43,9 +43,17 @@ class NodeHasMediaUse extends FilterPluginBase { * {@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 bb84ba6b..a13bdad4 100644 --- a/src/Plugin/views/filter/NodeHasMediaUse.php +++ b/src/Plugin/views/filter/NodeHasMediaUse.php @@ -70,7 +70,8 @@ class NodeHasMediaUse extends FilterPluginBase { */ 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 a13bdad4..e17cdf3a 100644 --- a/src/Plugin/views/filter/NodeHasMediaUse.php +++ b/src/Plugin/views/filter/NodeHasMediaUse.php @@ -71,7 +71,8 @@ class NodeHasMediaUse extends FilterPluginBase { 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 e17cdf3a..0209505d 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 @@ class NodeHasMediaUse extends FilterPluginBase { /** * {@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 @@ class NodeHasMediaUse extends FilterPluginBase { $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 f5bce510..52f10710 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 83e3f301..d891c0e6 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 c783e12b..24eb9e5b 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 52f10710..23a1b444 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 23a1b444..618e7f66 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 618e7f66..a40e19e3 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 a40e19e3..ac6b0ca6 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 ac6b0ca6..a8e49ba5 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 a8e49ba5..1bd91b99 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 1bd91b99..fad82be8 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 c154c5c2..1d970b5a 100644 --- a/tests/src/Functional/IslandoraFunctionalTestBase.php +++ b/tests/src/Functional/IslandoraFunctionalTestBase.php @@ -278,11 +278,13 @@ EOD; * 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 @@ EOD; } } + 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 1d970b5a..2e4c88e8 100644 --- a/tests/src/Functional/IslandoraFunctionalTestBase.php +++ b/tests/src/Functional/IslandoraFunctionalTestBase.php @@ -457,4 +457,3 @@ EOD; } } - 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 6fea02e9..5387e9a4 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 fad82be8..13b2e56a 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 13b2e56a..3ca7cc50 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 3ca7cc50..cd48c5e7 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 cd48c5e7..d95b1d6b 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 d95b1d6b..beb1b6f8 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 beb1b6f8..a6b29565 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 a6b29565..ab6a4b07 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 a4091781..3e6e1562 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 ab6a4b07..439395b0 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 3e6e1562..a4091781 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 84c064e9..f484fdc3 100644 --- a/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php +++ b/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php @@ -88,10 +88,16 @@ class AbstractGenerateDerivativeMediaFile extends AbstractGenerateDerivativeBase */ 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 574fa415..97dbf08c 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 6448cfdc..06ff6259 100644 --- a/src/Plugin/Condition/NodeIsIslandoraObject.php +++ b/src/Plugin/Condition/NodeIsIslandoraObject.php @@ -5,13 +5,14 @@ namespace Drupal\islandora\Plugin\Condition; 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 @@ use Symfony\Component\DependencyInjection\ContainerInterface; */ 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 @@ class NodeIsIslandoraObject extends ConditionPluginBase implements ContainerFact return new static( $configuration, $plugin_id, - $plugin_definition + $plugin_definition, + $container->get('islandora.utils') ); } @@ -38,8 +64,8 @@ class NodeIsIslandoraObject extends ConditionPluginBase implements ContainerFact 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 @@ class NodeIsIslandoraObject extends ConditionPluginBase implements ContainerFact */ 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 00000000..2065c46b --- /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 f484fdc3..be9eca80 100644 --- a/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php +++ b/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php @@ -40,7 +40,7 @@ class AbstractGenerateDerivativeMediaFile extends AbstractGenerateDerivativeBase 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 97dbf08c..f249c633 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 13f83e7d..19467001 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 @@ class IIIFManifest extends StylePluginBase { /** @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 f6b8034a..73318e35 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\Core\Url; 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 @@ class GenerateOCRDerivativeFile extends AbstractGenerateDerivativeMediaFile { $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 @@ class GenerateOCRDerivativeFile extends AbstractGenerateDerivativeMediaFile { 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 @@ class GenerateOCRDerivativeFile extends AbstractGenerateDerivativeMediaFile { $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 @@ class GenerateOCRDerivativeFile extends AbstractGenerateDerivativeMediaFile { 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 19467001..446358d0 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 @@ class IIIFManifest extends StylePluginBase { $options = parent::defineOptions(); $options['iiif_tile_field'] = ['default' => '']; + $options['iiif_ocr_file_field'] = ['default' => '']; return $options; } @@ -368,6 +369,15 @@ class IIIFManifest extends StylePluginBase { // 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 be9eca80..2c4e9224 100644 --- a/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php +++ b/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php @@ -5,7 +5,6 @@ namespace Drupal\islandora\Plugin\Action; 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 @@ class AbstractGenerateDerivativeMediaFile extends AbstractGenerateDerivativeBase */ 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 446358d0..ba971b47 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 @@ class IIIFManifest extends StylePluginBase { */ 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 ba971b47..b06b0f5d 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 @@ class IIIFManifest extends StylePluginBase { $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 b06b0f5d..ad5ea178 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 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { } } } - - $canvases[] = [ + $tmp_canvas = [ // @see https://iiif.io/api/presentation/2.1/#canvas '@id' => $canvas_id, '@type' => 'sc:Canvas', @@ -272,6 +276,17 @@ class IIIFManifest extends StylePluginBase { ], ], ]; + + 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 ad5ea178..561b216d 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 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { // 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 561b216d..594e75d8 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 @@ class IIIFManifest extends StylePluginBase { 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 594e75d8..a0915242 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 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { 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 2c4e9224..be9eca80 100644 --- a/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php +++ b/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php @@ -5,6 +5,7 @@ namespace Drupal\islandora\Plugin\Action; 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 @@ class AbstractGenerateDerivativeMediaFile extends AbstractGenerateDerivativeBase */ 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 73318e35..4ff0d93f 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 @@ class GenerateOCRDerivativeFile extends AbstractGenerateDerivativeMediaFile { 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 df4255ee..a9417abe 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 c98679eb..e85d5739 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 5f09740a..82b08088 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 6ef42bc4..fc62c5c4 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 b1d72d7f..01d28481 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 a978f1d2..4a242924 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 e29fdb56..5b5446d1 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 0ebc0b3c..5049ef16 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 @@ class IslandoraSettingsForm extends ConfigFormBase { return new static( $container->get('config.factory'), $container->get('entity_type.bundle.info'), + $container->get('entity_type.manager') ); } @@ -308,7 +323,7 @@ class IslandoraSettingsForm extends ConfigFormBase { 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 @@ class IslandoraSettingsForm extends ConfigFormBase { } } + // 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 5b5446d1..708f8ec1 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 a0915242..cc4b5e94 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 @@ class IIIFManifest extends StylePluginBase { ], ]; - 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 708f8ec1..ab9eab18 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 ab9eab18..63018266 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 63018266..e8aeb232 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 00000000..b9cc8f99 --- /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 24eb9e5b..c02d7c16 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 9cd89cdd..0336d89d 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 f9eb1225..ad2eb8e1 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 5387e9a4..86d13482 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 4b3a9d16..4108e244 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 0ff72496..528b4283 100644 --- a/src/Form/AddChildrenForm.php +++ b/src/Form/AddChildrenForm.php @@ -229,7 +229,7 @@ class AddChildrenForm extends AddMediaForm { * @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 00000000..6193c0c3 --- /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 00000000..6aeed879 --- /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 00000000..e9fac387 --- /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 00000000..0adafde5 --- /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 00000000..084e7816 --- /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 00000000..9783d082 --- /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 00000000..0b9a197f --- /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 00000000..f5795997 --- /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 00000000..830f95cd --- /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 00000000..9a54f03b --- /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 00000000..534c7309 --- /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 00000000..2e6fa217 --- /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 00000000..b06d004d --- /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 00000000..36cf6ff2 --- /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 00000000..dd56450f --- /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 bd670561..a58d9860 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 @@ class ManageMediaController extends ManageMembersController { $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 7f480fb3..e07ec5df 100644 --- a/src/Controller/ManageMembersController.php +++ b/src/Controller/ManageMembersController.php @@ -88,7 +88,8 @@ class ManageMembersController extends EntityController { */ 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 @@ class ManageMembersController extends EntityController { $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 a58d9860..d15175f9 100644 --- a/src/Controller/ManageMediaController.php +++ b/src/Controller/ManageMediaController.php @@ -36,8 +36,11 @@ class ManageMediaController extends ManageMembersController { 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 e07ec5df..bfd2cf74 100644 --- a/src/Controller/ManageMembersController.php +++ b/src/Controller/ManageMembersController.php @@ -100,8 +100,11 @@ class ManageMembersController extends EntityController { 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 d15175f9..025d1d9d 100644 --- a/src/Controller/ManageMediaController.php +++ b/src/Controller/ManageMediaController.php @@ -6,6 +6,7 @@ use Drupal\islandora\IslandoraUtils; 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 @@ class ManageMediaController extends ManageMembersController { ['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 bfd2cf74..9827ff35 100644 --- a/src/Controller/ManageMembersController.php +++ b/src/Controller/ManageMembersController.php @@ -7,6 +7,7 @@ use Drupal\Core\Render\RendererInterface; 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 @@ class ManageMembersController extends EntityController { ['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 e8aeb232..9130caeb 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 9130caeb..44dc35a7 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 b9cc8f99..ff793f0d 100644 --- a/tests/src/Functional/DeleteNodeWithMedia.php +++ b/tests/src/Functional/DeleteNodeWithMediaAndFile.php @@ -7,17 +7,18 @@ namespace Drupal\Tests\islandora\Functional; * * @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 @@ class DeleteNodeWithMedia extends IslandoraFunctionalTestBase { $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 00000000..696587ac --- /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 00000000..047006bf --- /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 44dc35a7..66c74ad5 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 66c74ad5..5cab2cce 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 5049ef16..a65ab82f 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 @@ class IslandoraSettingsForm extends ConfigFormBase { $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 @@ class IslandoraSettingsForm extends ConfigFormBase { ->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 c02d7c16..eebdd9ab 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 be9eca80..54e7bde0 100644 --- a/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php +++ b/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php @@ -88,16 +88,10 @@ class AbstractGenerateDerivativeMediaFile extends AbstractGenerateDerivativeBase */ 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 d6f99b58..54b215f3 100644 --- a/modules/islandora_image/src/Plugin/Action/GenerateImageDerivativeFile.php +++ b/modules/islandora_image/src/Plugin/Action/GenerateImageDerivativeFile.php @@ -34,7 +34,23 @@ class GenerateImageDerivativeFile extends AbstractGenerateDerivativeMediaFile { */ 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 54b215f3..e0420fe8 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\Core\Form\FormStateInterface; 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 @@ class GenerateImageDerivativeFile extends AbstractGenerateDerivativeMediaFile { $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 @@ class GenerateImageDerivativeFile extends AbstractGenerateDerivativeMediaFile { '#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 bab43fcf..3d0e7909 100644 --- a/src/Controller/MediaSourceController.php +++ b/src/Controller/MediaSourceController.php @@ -280,8 +280,7 @@ class MediaSourceController extends ControllerBase { */ 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 9399e334..60e41672 100644 --- a/src/MediaSource/MediaSourceService.php +++ b/src/MediaSource/MediaSourceService.php @@ -268,8 +268,8 @@ class MediaSourceService { '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 @@ class MediaSourceService { '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 54e7bde0..f0974b0c 100644 --- a/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php +++ b/src/Plugin/Action/AbstractGenerateDerivativeMediaFile.php @@ -7,7 +7,10 @@ use Drupal\Core\Form\FormStateInterface; 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 @@ class AbstractGenerateDerivativeMediaFile extends AbstractGenerateDerivativeBase */ 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 8fb25fb8..179d4213 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 e85d5739..86b65fd0 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 5cab2cce..b651f291 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 ff793f0d..40e469c5 100644 --- a/tests/src/Functional/DeleteNodeWithMediaAndFile.php +++ b/tests/src/Functional/DeleteNodeWithMediaAndFile.php @@ -19,6 +19,7 @@ class DeleteNodeWithMediaAndFile extends IslandoraFunctionalTestBase { 'view media', 'bypass node access', 'access files overview', + 'administer site configuration', ]); $this->drupalLogin($account); @@ -75,6 +76,10 @@ class DeleteNodeWithMediaAndFile extends IslandoraFunctionalTestBase { ]); $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 b651f291..05e18c4a 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 c02d7c16..8fe708ed 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 7deecc69..1ac77eec 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 b498ba66..a9fd4584 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 1ac77eec..3dcae297 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 a9fd4584..2c819101 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 0209505d..3c69bddd 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 5b5446d1..9814820e 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 eebdd9ab..29b40894 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 047006bf..840dc294 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 05e18c4a..64b65ca8 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 00000000..0a29e56e --- /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 a65ab82f..90e0b420 100644 --- a/src/Form/IslandoraSettingsForm.php +++ b/src/Form/IslandoraSettingsForm.php @@ -205,7 +205,7 @@ class IslandoraSettingsForm extends ConfigFormBase { $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 cc4b5e94..c2a2fbc3 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 @@ class IIIFManifest extends StylePluginBase { 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 683f3e8b..2e0d226e 100644 --- a/src/EventGenerator/EmitEvent.php +++ b/src/EventGenerator/EmitEvent.php @@ -157,6 +157,10 @@ abstract class EmitEvent extends ConfigurableActionBase implements ContainerFact $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 b22201e1..129af994 100644 --- a/src/Plugin/Action/AbstractGenerateDerivative.php +++ b/src/Plugin/Action/AbstractGenerateDerivative.php @@ -60,6 +60,13 @@ class AbstractGenerateDerivative extends AbstractGenerateDerivativeBase { 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 745c5772..63a714a8 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 2e0d226e..fd33fd99 100644 --- a/src/EventGenerator/EmitEvent.php +++ b/src/EventGenerator/EmitEvent.php @@ -14,6 +14,7 @@ use Drupal\Core\Session\AccountInterface; 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 @@ abstract class EmitEvent extends ConfigurableActionBase implements ContainerFact $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 @@ abstract class EmitEvent extends ConfigurableActionBase implements ContainerFact $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 00000000..66f63606 --- /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 66f63606..7efe4773 100644 --- a/src/Exception/IslandoraDerivativeException.php +++ b/src/Exception/IslandoraDerivativeException.php @@ -7,6 +7,5 @@ namespace Drupal\islandora\Exception; * * @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 339d1d87..b44db477 100644 --- a/src/Plugin/Action/AbstractGenerateDerivative.php +++ b/src/Plugin/Action/AbstractGenerateDerivative.php @@ -65,7 +65,7 @@ class AbstractGenerateDerivative extends AbstractGenerateDerivativeBase { // 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 5b5446d1..faf24fdc 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 43533a69..c1bfaa2d 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 c1bfaa2d..0b443c02 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 e0420fe8..a6e06774 100644 --- a/modules/islandora_image/src/Plugin/Action/GenerateImageDerivativeFile.php +++ b/modules/islandora_image/src/Plugin/Action/GenerateImageDerivativeFile.php @@ -51,7 +51,7 @@ class GenerateImageDerivativeFile extends AbstractGenerateDerivativeMediaFile { '#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 60e41672..53378985 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 @@ class MediaSourceService { * @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 @@ class MediaSourceService { } // 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 97619cd2..4976d1d6 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 00000000..10547231 --- /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 cbf52667..a389a29d 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 0b04ea33..00000000 --- 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 a81a267c..00000000 --- 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 a2abac80..c5611a3e 100644 --- a/src/Plugin/Condition/NodeReferencedByNode.php +++ b/src/Plugin/Condition/NodeReferencedByNode.php @@ -16,7 +16,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; * @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 a389a29d..ad70d2f9 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 ad70d2f9..f08dd346 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 8d1c4b6b..abbe6474 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 0b443c02..f4956d3d 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 d6d93c22..1381a920 100644 --- a/src/Event/StompHeaderEvent.php +++ b/src/Event/StompHeaderEvent.php @@ -6,7 +6,7 @@ use Drupal\Core\Entity\EntityInterface; 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 fd33fd99..12700d73 100644 --- a/src/EventGenerator/EmitEvent.php +++ b/src/EventGenerator/EmitEvent.php @@ -160,8 +160,8 @@ abstract class EmitEvent extends ConfigurableActionBase implements ContainerFact $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 801e3253..9a318a5b 100644 --- a/src/IslandoraContextManager.php +++ b/src/IslandoraContextManager.php @@ -48,7 +48,11 @@ class IslandoraContextManager extends ContextManager { $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 @@ class IslandoraContextManager extends ContextManager { * 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 @@ class IslandoraContextManager extends ContextManager { $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 98aa6946..e516eb24 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -56,7 +56,10 @@ class PresetReaction extends ContextReactionPluginBase implements ContainerFacto $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 9a318a5b..b3aec19c 100644 --- a/src/IslandoraContextManager.php +++ b/src/IslandoraContextManager.php @@ -50,7 +50,7 @@ class IslandoraContextManager extends ContextManager { // 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 e516eb24..532606fc 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -56,8 +56,8 @@ class PresetReaction extends ContextReactionPluginBase implements ContainerFacto $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 532606fc..18a771dc 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -56,7 +56,8 @@ class PresetReaction extends ContextReactionPluginBase implements ContainerFacto $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 b3aec19c..11de1fde 100644 --- a/src/IslandoraContextManager.php +++ b/src/IslandoraContextManager.php @@ -50,7 +50,7 @@ class IslandoraContextManager extends ContextManager { // 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 @@ class IslandoraContextManager extends ContextManager { * 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 801e3253..c7228195 100644 --- a/src/IslandoraContextManager.php +++ b/src/IslandoraContextManager.php @@ -13,6 +13,14 @@ use Drupal\Component\Plugin\Exception\ContextException; */ 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 f4956d3d..96f3e886 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 18a771dc..532606fc 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -56,8 +56,7 @@ class PresetReaction extends ContextReactionPluginBase implements ContainerFacto $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 532606fc..e516eb24 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -56,8 +56,8 @@ class PresetReaction extends ContextReactionPluginBase implements ContainerFacto $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 e516eb24..98aa6946 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -56,10 +56,7 @@ class PresetReaction extends ContextReactionPluginBase implements ContainerFacto $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 d891c0e6..839a14e3 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 839a14e3..32e69ea9 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 c2a2fbc3..e30b1d63 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 @@ namespace Drupal\islandora_iiif\Plugin\views\style; 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 @@ class IIIFManifest extends StylePluginBase { $this->fileSystem = $file_system; $this->httpClient = $http_client; $this->messenger = $messenger; + $this->moduleHandler = $moduleHandler; } /** @@ -120,10 +127,21 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { ]; } + // 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 e30b1d63..b31d3e39 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 @@ namespace Drupal\islandora_iiif\Plugin\views\style; 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 @@ class IIIFManifest extends StylePluginBase { /** * Return the request property. - * + * * @return \Symfony\Component\HttpFoundation\Request * The Symfony request object */ @@ -309,15 +311,18 @@ class IIIFManifest extends StylePluginBase { ]; } - // 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 b31d3e39..cacb5245 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 @@ class IIIFManifest extends StylePluginBase { // 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 96f3e886..a92aff53 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 4108e244..465e8d93 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 58be909c..eb79220d 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\Adapter\Polyfill\StreamedCopyTrait; 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 @@ class FedoraAdapter implements AdapterInterface { */ 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 @@ class FedoraAdapter implements AdapterInterface { $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 fe7af7ba..a2ae81e3 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\IFedoraApi; 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 @@ class Fedora implements FlysystemPluginInterface, ContainerFactoryPluginInterfac 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 @@ class Fedora implements FlysystemPluginInterface, ContainerFactoryPluginInterfac * {@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 a92aff53..a2693862 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 465e8d93..74725d80 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 a2693862..0db75d4a 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 a2ae81e3..5a3a68d8 100644 --- a/src/Flysystem/Fedora.php +++ b/src/Flysystem/Fedora.php @@ -88,11 +88,7 @@ class Fedora implements FlysystemPluginInterface, ContainerFactoryPluginInterfac // 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 eb79220d..4ebc61c5 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 5a3a68d8..0cbf1a12 100644 --- a/src/Flysystem/Fedora.php +++ b/src/Flysystem/Fedora.php @@ -13,9 +13,8 @@ use Drupal\islandora\Flysystem\Adapter\FedoraAdapter; 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 10c5beb1..a3b577e4 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 @@ use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface; */ 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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 67491507..cd1c8325 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 @@ class FedoraPluginTest extends IslandoraKernelTestBase { $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 a3b577e4..e5161063 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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 0db75d4a..3ceed0e1 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 c2a2fbc3..90945664 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 @@ class IIIFManifest extends StylePluginBase { $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 5d6f6437..ca330dd4 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 14c36ebd..f15e42d5 100644 --- a/modules/islandora_text_extraction/src/Controller/MediaSourceController.php +++ b/modules/islandora_text_extraction/src/Controller/MediaSourceController.php @@ -108,7 +108,11 @@ class MediaSourceController extends ControllerBase { $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 32e69ea9..546d2192 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 cbf52667..7bae23cd 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 fc1c6188..766ceac0 100644 --- a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php +++ b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php @@ -68,7 +68,8 @@ class GenerateAudioDerivativeTest extends GenerateDerivativeTestBase { '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 80f5dbee..ee35a1ed 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 55fe3634..90945664 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 @@ namespace Drupal\islandora_iiif\Plugin\views\style; 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 @@ class IIIFManifest extends StylePluginBase { $this->fileSystem = $file_system; $this->httpClient = $http_client; $this->messenger = $messenger; - $this->moduleHandler = $moduleHandler; } /** @@ -129,21 +120,10 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { ]; } - // 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 b6e016fc..295eae91 100644 --- a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php +++ b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php @@ -70,7 +70,8 @@ class GenerateImageDerivativeTest extends GenerateDerivativeTestBase { '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 f15e42d5..5518220d 100644 --- a/modules/islandora_text_extraction/src/Controller/MediaSourceController.php +++ b/modules/islandora_text_extraction/src/Controller/MediaSourceController.php @@ -98,7 +98,7 @@ class MediaSourceController extends ControllerBase { 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 31dca62c..172ae73a 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 8714a2f1..17e8bd5b 100644 --- a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php +++ b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php @@ -65,7 +65,8 @@ class GenerateVideoDerivativeTest extends GenerateDerivativeTestBase { '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 ce33ce2e..f7e5725b 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 Drupal\Core\Entity\Exception\UndefinedLinkTemplateException; 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 @@ abstract class LinkHeaderSubscriber implements EventSubscriberInterface { /** * 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 3cebbbaa..0f406cf5 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 e00533f7..c4cdaea8 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 4ebc61c5..55f8b11d 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 @@ class FedoraAdapter implements AdapterInterface { // 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 @@ class FedoraAdapter implements AdapterInterface { 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 6aeed879..cf6ef305 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 @@ abstract class AbstractFileSelectionForm extends FormBase { $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 9fc2f9e2..f27f9db9 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 32909775..4b0b62c5 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 362ff7fb..5ed22948 100644 --- a/tests/src/Functional/ContentEntityTypeTest.php +++ b/tests/src/Functional/ContentEntityTypeTest.php @@ -52,7 +52,8 @@ class ContentEntityTypeTest extends IslandoraFunctionalTestBase { '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 f112c700..86895dbb 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 e1b1c827..00e0e5ae 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 @@ class DerivativeReactionTest extends IslandoraFunctionalTestBase { '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 0f67d591..c5ec9701 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 e995329d..ff215281 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 @@ class IndexingTest extends IslandoraFunctionalTestBase { // 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 2e4c88e8..2e723561 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 @@ EOD; * 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 @@ EOD; * 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 @@ EOD; * 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 33f6e1e6..84ea5517 100644 --- a/tests/src/Functional/IslandoraImageFormatterTest.php +++ b/tests/src/Functional/IslandoraImageFormatterTest.php @@ -92,7 +92,7 @@ class IslandoraImageFormatterTest extends IslandoraFunctionalTestBase { ':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 92cfc6a2..80a327af 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 @@ class IslandoraSettingsFormTest extends IslandoraFunctionalTestBase { $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 f3c88271..7ad8f018 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 @@ class JsonldSelfReferenceReactionTest extends IslandoraFunctionalTestBase { $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 @@ class JsonldSelfReferenceReactionTest extends IslandoraFunctionalTestBase { 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 @@ class JsonldSelfReferenceReactionTest extends IslandoraFunctionalTestBase { $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 @@ class JsonldSelfReferenceReactionTest extends IslandoraFunctionalTestBase { $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 @@ class JsonldSelfReferenceReactionTest extends IslandoraFunctionalTestBase { 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 e5d21abc..58e8bf61 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 @@ class JsonldTypeAlterReactionTest extends JsonldSelfReferenceReactionTest { '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 @@ class JsonldTypeAlterReactionTest extends JsonldSelfReferenceReactionTest { $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 @@ class JsonldTypeAlterReactionTest extends JsonldSelfReferenceReactionTest { // 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 7cb741d5..98b36c68 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 fdea6aef..3c97c695 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 eff5b5c3..2b4ee16f 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 72cdfe44..19660bda 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 ba289aa4..2572c191 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 c423cda3..a9c1f082 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 e5161063..d6adecbb 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 @@ use Symfony\Component\Mime\MimeTypeGuesserInterface; */ 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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 5a95cb68..1c98db3e 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 f97eab9f..9493ab78 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 @@ use Drupal\islandora\EventSubscriber\JwtEventSubscriber; */ 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 63a714a8..9d171622 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 @@ class GenerateOCRDerivative extends AbstractGenerateDerivative { */ 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 9d171622..272e9f01 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 @@ class GenerateOCRDerivative extends AbstractGenerateDerivative { */ 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 abbe6474..f69418af 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 439395b0..d05222d9 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 56b45066..8c3cb0f3 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 2c819101..e529f21e 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 88b0f308..b90494f5 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 90945664..55fe3634 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 @@ namespace Drupal\islandora_iiif\Plugin\views\style; 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 @@ class IIIFManifest extends StylePluginBase { $this->fileSystem = $file_system; $this->httpClient = $http_client; $this->messenger = $messenger; + $this->moduleHandler = $moduleHandler; } /** @@ -120,10 +129,21 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { ]; } + // 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 5518220d..6b886308 100644 --- a/modules/islandora_text_extraction/src/Controller/MediaSourceController.php +++ b/modules/islandora_text_extraction/src/Controller/MediaSourceController.php @@ -5,6 +5,7 @@ namespace Drupal\islandora_text_extraction\Controller; 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 @@ class MediaSourceController extends ControllerBase { */ 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 @@ class MediaSourceController extends ControllerBase { 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 cf6ef305..6aeed879 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 @@ abstract class AbstractFileSelectionForm extends FormBase { $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 7ad8f018..92eca07a 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 58e8bf61..80a6039c 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 f69418af..ab7bb073 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 55fe3634..49c35208 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 @@ use GuzzleHttp\Exception\ServerException; */ 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 @@ class IIIFManifest extends StylePluginBase { $this->fileSystem = $file_system; $this->httpClient = $http_client; $this->messenger = $messenger; - $this->moduleHandler = $moduleHandler; + $this->utils = $utils; + } /** @@ -130,20 +132,10 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { // 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 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { * @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 @@ class IIIFManifest extends StylePluginBase { 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 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { ], ]; - 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 @@ class IIIFManifest extends StylePluginBase { 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 @@ class IIIFManifest extends StylePluginBase { '#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 @@ class IIIFManifest extends StylePluginBase { */ 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 49c35208..9fde1ed7 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 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { ], ]; - 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 @@ class IIIFManifest extends StylePluginBase { 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 ab06524b..a5cfc3b0 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 9fde1ed7..7bbe03dd 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 @@ use Symfony\Component\HttpFoundation\Request; */ class IIIFManifest extends StylePluginBase { -/** + /** * Islandora utility functions. * * @var \Drupal\islandora\IslandoraUtils @@ -233,7 +233,7 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { /** * 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 @@ class IIIFManifest extends StylePluginBase { } /** - * 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 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { */ 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 a5cfc3b0..c1f89872 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 7bbe03dd..a745e1f7 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 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { // 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 @@ class IIIFManifest extends StylePluginBase { * @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 @@ class IIIFManifest extends StylePluginBase { ], ]; - 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 @@ class IIIFManifest extends StylePluginBase { * * @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 @@ class IIIFManifest extends StylePluginBase { '#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 @@ class IIIFManifest extends StylePluginBase { 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 a745e1f7..8527067d 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 @@ class IIIFManifest extends StylePluginBase { * * @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 @@ class IIIFManifest extends StylePluginBase { 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 8527067d..2dfce979 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 @@ class IIIFManifest extends StylePluginBase { * * @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 2dfce979..e52f59f9 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 @@ class IIIFManifest extends StylePluginBase { * * @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 e52f59f9..63f015d1 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\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 GuzzleHttp\Client; @@ -35,13 +34,6 @@ use Symfony\Component\HttpFoundation\Request; */ 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 @@ class IIIFManifest extends StylePluginBase { $this->fileSystem = $file_system; $this->httpClient = $http_client; $this->messenger = $messenger; - $this->utils = $utils; - } /** @@ -132,8 +122,7 @@ class IIIFManifest extends StylePluginBase { $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 3ceed0e1..bf274cd1 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 d05222d9..261ab1de 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 a4091781..46e82e78 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 ea34ee2e..aabb5891 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 56a10bc1..c76020cb 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 6c6e87da..6667f4f4 100644 --- a/src/Plugin/Field/FieldFormatter/IslandoraImageFormatter.php +++ b/src/Plugin/Field/FieldFormatter/IslandoraImageFormatter.php @@ -5,6 +5,7 @@ namespace Drupal\islandora\Plugin\Field\FieldFormatter; 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 @@ class IslandoraImageFormatter extends ImageFormatter { 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 @@ class IslandoraImageFormatter extends ImageFormatter { $view_mode, $third_party_settings, $current_user, - $image_style_storage + $image_style_storage, + $file_url_generator ); $this->utils = $utils; } @@ -97,7 +102,8 @@ class IslandoraImageFormatter extends ImageFormatter { $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 766ceac0..b528e8ba 100644 --- a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php +++ b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php @@ -66,7 +66,7 @@ class GenerateAudioDerivativeTest extends GenerateDerivativeTestBase { '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 295eae91..69672e0b 100644 --- a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php +++ b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php @@ -68,7 +68,7 @@ class GenerateImageDerivativeTest extends GenerateDerivativeTestBase { '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 17e8bd5b..f712e349 100644 --- a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php +++ b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php @@ -63,7 +63,7 @@ class GenerateVideoDerivativeTest extends GenerateDerivativeTestBase { '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 b528e8ba..a7425917 100644 --- a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php +++ b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php @@ -66,7 +66,7 @@ class GenerateAudioDerivativeTest extends GenerateDerivativeTestBase { '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 69672e0b..2e1f5591 100644 --- a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php +++ b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php @@ -68,7 +68,7 @@ class GenerateImageDerivativeTest extends GenerateDerivativeTestBase { '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 f712e349..3a556987 100644 --- a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php +++ b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php @@ -63,7 +63,7 @@ class GenerateVideoDerivativeTest extends GenerateDerivativeTestBase { '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 a7425917..5c1b616e 100644 --- a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php +++ b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php @@ -66,7 +66,7 @@ class GenerateAudioDerivativeTest extends GenerateDerivativeTestBase { '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 2e1f5591..7544cb65 100644 --- a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php +++ b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php @@ -68,7 +68,7 @@ class GenerateImageDerivativeTest extends GenerateDerivativeTestBase { '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 3a556987..264cebb7 100644 --- a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php +++ b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php @@ -63,7 +63,7 @@ class GenerateVideoDerivativeTest extends GenerateDerivativeTestBase { '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 5c1b616e..6b85cd1b 100644 --- a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php +++ b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php @@ -66,7 +66,7 @@ class GenerateAudioDerivativeTest extends GenerateDerivativeTestBase { '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 7544cb65..44cdda58 100644 --- a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php +++ b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php @@ -68,7 +68,7 @@ class GenerateImageDerivativeTest extends GenerateDerivativeTestBase { '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 264cebb7..de06ba2f 100644 --- a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php +++ b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php @@ -63,7 +63,7 @@ class GenerateVideoDerivativeTest extends GenerateDerivativeTestBase { '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 19fe419b..d261542d 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 f81cb747..41f84cbe 100644 --- a/src/IslandoraUtils.php +++ b/src/IslandoraUtils.php @@ -148,6 +148,7 @@ class IslandoraUtils { return []; } $mids = $this->entityTypeManager->getStorage('media')->getQuery() + ->accessCheck(FALSE) ->condition(self::MEDIA_OF_FIELD, $node->id()) ->execute(); if (empty($mids)) { @@ -208,6 +209,7 @@ class IslandoraUtils { // 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 @@ class IslandoraUtils { } $results = $query + ->accessCheck(FALSE) ->condition($orGroup) ->execute(); @@ -498,6 +501,7 @@ class IslandoraUtils { 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 41f84cbe..a2df7589 100644 --- a/src/IslandoraUtils.php +++ b/src/IslandoraUtils.php @@ -148,7 +148,7 @@ class IslandoraUtils { 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 @@ class IslandoraUtils { // 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 @@ class IslandoraUtils { } $results = $query - ->accessCheck(FALSE) + ->accessCheck(TRUE) ->condition($orGroup) ->execute(); @@ -501,7 +501,7 @@ class IslandoraUtils { 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 261ab1de..27506495 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 d261542d..ea8eac00 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 2560ec6e..68724265 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 b1fdb88e..f8f05beb 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 07f45bbe..e1fc7634 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 cf798265..e4414e61 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 d67060f7..f7295428 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 6a136c3c..dbd6bb62 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 3ed0286e..cd89243d 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 e7d4c7cc..a3e253e2 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 25b6fbb2..16d96c3e 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 40e469c5..5ee19b7c 100644 --- a/tests/src/Functional/DeleteNodeWithMediaAndFile.php +++ b/tests/src/Functional/DeleteNodeWithMediaAndFile.php @@ -42,8 +42,8 @@ class DeleteNodeWithMediaAndFile extends IslandoraFunctionalTestBase { '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 2e723561..016788d0 100644 --- a/tests/src/Functional/IslandoraFunctionalTestBase.php +++ b/tests/src/Functional/IslandoraFunctionalTestBase.php @@ -438,8 +438,8 @@ EOD; '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 84ea5517..1b40f7a8 100644 --- a/tests/src/Functional/IslandoraImageFormatterTest.php +++ b/tests/src/Functional/IslandoraImageFormatterTest.php @@ -59,8 +59,8 @@ class IslandoraImageFormatterTest extends IslandoraFunctionalTestBase { '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 80a6039c..658244ae 100644 --- a/tests/src/Functional/JsonldTypeAlterReactionTest.php +++ b/tests/src/Functional/JsonldTypeAlterReactionTest.php @@ -30,7 +30,7 @@ class JsonldTypeAlterReactionTest extends JsonldSelfReferenceReactionTest { '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 3c97c695..3938e9b4 100644 --- a/tests/src/Functional/MediaSourceUpdateTest.php +++ b/tests/src/Functional/MediaSourceUpdateTest.php @@ -52,8 +52,8 @@ class MediaSourceUpdateTest extends IslandoraFunctionalTestBase { '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 4ff0d93f..565d7564 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 @@ class GenerateOCRDerivativeFile extends AbstractGenerateDerivativeMediaFile { 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 a9c1f082..28a4ec03 100644 --- a/tests/src/Kernel/EventGeneratorTest.php +++ b/tests/src/Kernel/EventGeneratorTest.php @@ -116,7 +116,6 @@ class EventGeneratorTest extends IslandoraKernelTestBase { ['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 27506495..6c78bcf9 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 0336d89d..34e8118a 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 524e9dc7..19fae53a 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 c00ce566..09dd1646 100644 --- a/modules/islandora_advanced_search/src/Form/AdvancedSearchForm.php +++ b/modules/islandora_advanced_search/src/Form/AdvancedSearchForm.php @@ -71,7 +71,7 @@ class AdvancedSearchForm extends FormBase { */ 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 c5f5adb8..2aa77f12 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 @@ class AdvancedSearchBlock extends BlockBase implements ContainerFactoryPluginInt $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 f2e4a170..e1e477d8 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 @@ class SearchResultsPagerBlock extends BlockBase implements ContainerFactoryPlugi $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 998590f5..5e6beb5a 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 c76020cb..661ec70a 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 bf4f8d7a..6976eb8c 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 0492158a..39b835c0 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 87076462..277966f3 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 67687f90..fb768e2a 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 5b9aa14f..8596dbd3 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 48eb82f2..aa51af11 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 6b3a4c5c..b975f608 100644 --- a/src/EventGenerator/EventGenerator.php +++ b/src/EventGenerator/EventGenerator.php @@ -192,6 +192,7 @@ class EventGenerator implements EventGeneratorInterface { 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 55f8b11d..cf24cb77 100644 --- a/src/Flysystem/Adapter/FedoraAdapter.php +++ b/src/Flysystem/Adapter/FedoraAdapter.php @@ -160,14 +160,8 @@ class FedoraAdapter implements AdapterInterface { // 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 @@ class FedoraAdapter implements AdapterInterface { $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 c5611a3e..d6db01ea 100644 --- a/src/Plugin/Condition/NodeReferencedByNode.php +++ b/src/Plugin/Condition/NodeReferencedByNode.php @@ -128,6 +128,7 @@ class NodeReferencedByNode extends ConditionPluginBase implements ContainerFacto $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 d6adecbb..4a9d45b5 100644 --- a/tests/src/Kernel/FedoraAdapterTest.php +++ b/tests/src/Kernel/FedoraAdapterTest.php @@ -61,13 +61,8 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { ]); $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 cd1c8325..92a8137c 100644 --- a/tests/src/Kernel/FedoraPluginTest.php +++ b/tests/src/Kernel/FedoraPluginTest.php @@ -6,6 +6,7 @@ use Drupal\Core\Logger\LoggerChannelInterface; 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 @@ use Symfony\Component\Mime\MimeTypeGuesserInterface; */ 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 bf274cd1..48ee9a4a 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 cf24cb77..0871827e 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 4a9d45b5..08db253c 100644 --- a/tests/src/Kernel/FedoraAdapterTest.php +++ b/tests/src/Kernel/FedoraAdapterTest.php @@ -4,7 +4,6 @@ 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; 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 48ee9a4a..1cc5f74d 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 7e298142..77b12ec3 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 77b12ec3..013c7dd8 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 013c7dd8..77b12ec3 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 08db253c..9067d369 100644 --- a/tests/src/Kernel/FedoraAdapterTest.php +++ b/tests/src/Kernel/FedoraAdapterTest.php @@ -235,7 +235,7 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 64c1bff3..d5dc9750 100644 --- a/src/Form/ConfirmDeleteMediaAndFile.php +++ b/src/Form/ConfirmDeleteMediaAndFile.php @@ -137,8 +137,11 @@ class ConfirmDeleteMediaAndFile extends DeleteMultipleForm { $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 a2abac80..c5611a3e 100644 --- a/src/Plugin/Condition/NodeReferencedByNode.php +++ b/src/Plugin/Condition/NodeReferencedByNode.php @@ -16,7 +16,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; * @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 8d1c4b6b..abbe6474 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 0b443c02..f4956d3d 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 d6d93c22..1381a920 100644 --- a/src/Event/StompHeaderEvent.php +++ b/src/Event/StompHeaderEvent.php @@ -6,7 +6,7 @@ use Drupal\Core\Entity\EntityInterface; 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 fd33fd99..12700d73 100644 --- a/src/EventGenerator/EmitEvent.php +++ b/src/EventGenerator/EmitEvent.php @@ -160,8 +160,8 @@ abstract class EmitEvent extends ConfigurableActionBase implements ContainerFact $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 801e3253..c7228195 100644 --- a/src/IslandoraContextManager.php +++ b/src/IslandoraContextManager.php @@ -13,6 +13,14 @@ use Drupal\Component\Plugin\Exception\ContextException; */ 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 f4956d3d..96f3e886 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 c7228195..a8f18772 100644 --- a/src/IslandoraContextManager.php +++ b/src/IslandoraContextManager.php @@ -60,7 +60,11 @@ class IslandoraContextManager extends ContextManager { $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 @@ class IslandoraContextManager extends ContextManager { * 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 @@ class IslandoraContextManager extends ContextManager { $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 98aa6946..e516eb24 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -56,7 +56,10 @@ class PresetReaction extends ContextReactionPluginBase implements ContainerFacto $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 a8f18772..15fac41f 100644 --- a/src/IslandoraContextManager.php +++ b/src/IslandoraContextManager.php @@ -62,7 +62,7 @@ class IslandoraContextManager extends ContextManager { // 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 e516eb24..532606fc 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -56,8 +56,8 @@ class PresetReaction extends ContextReactionPluginBase implements ContainerFacto $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 532606fc..18a771dc 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -56,7 +56,8 @@ class PresetReaction extends ContextReactionPluginBase implements ContainerFacto $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 15fac41f..9fd93fbc 100644 --- a/src/IslandoraContextManager.php +++ b/src/IslandoraContextManager.php @@ -62,7 +62,7 @@ class IslandoraContextManager extends ContextManager { // 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 @@ class IslandoraContextManager extends ContextManager { * 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 18a771dc..532606fc 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -56,8 +56,7 @@ class PresetReaction extends ContextReactionPluginBase implements ContainerFacto $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 532606fc..e516eb24 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -56,8 +56,8 @@ class PresetReaction extends ContextReactionPluginBase implements ContainerFacto $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 e516eb24..98aa6946 100644 --- a/src/PresetReaction/PresetReaction.php +++ b/src/PresetReaction/PresetReaction.php @@ -56,10 +56,7 @@ class PresetReaction extends ContextReactionPluginBase implements ContainerFacto $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 d891c0e6..839a14e3 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 839a14e3..32e69ea9 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 96f3e886..a92aff53 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 4108e244..465e8d93 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 58be909c..eb79220d 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\Adapter\Polyfill\StreamedCopyTrait; 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 @@ class FedoraAdapter implements AdapterInterface { */ 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 @@ class FedoraAdapter implements AdapterInterface { $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 fe7af7ba..a2ae81e3 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\IFedoraApi; 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 @@ class Fedora implements FlysystemPluginInterface, ContainerFactoryPluginInterfac 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 @@ class Fedora implements FlysystemPluginInterface, ContainerFactoryPluginInterfac * {@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 a92aff53..a2693862 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 465e8d93..74725d80 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 a2693862..0db75d4a 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 a2ae81e3..5a3a68d8 100644 --- a/src/Flysystem/Fedora.php +++ b/src/Flysystem/Fedora.php @@ -88,11 +88,7 @@ class Fedora implements FlysystemPluginInterface, ContainerFactoryPluginInterfac // 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 eb79220d..4ebc61c5 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 5a3a68d8..0cbf1a12 100644 --- a/src/Flysystem/Fedora.php +++ b/src/Flysystem/Fedora.php @@ -13,9 +13,8 @@ use Drupal\islandora\Flysystem\Adapter\FedoraAdapter; 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 10c5beb1..a3b577e4 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 @@ use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface; */ 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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 67491507..cd1c8325 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 @@ class FedoraPluginTest extends IslandoraKernelTestBase { $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 a3b577e4..e5161063 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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 0db75d4a..3ceed0e1 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 5d6f6437..ca330dd4 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 14c36ebd..f15e42d5 100644 --- a/modules/islandora_text_extraction/src/Controller/MediaSourceController.php +++ b/modules/islandora_text_extraction/src/Controller/MediaSourceController.php @@ -108,7 +108,11 @@ class MediaSourceController extends ControllerBase { $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 c2a2fbc3..90945664 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 @@ class IIIFManifest extends StylePluginBase { $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 32e69ea9..546d2192 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 90945664..ed054176 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 @@ namespace Drupal\islandora_iiif\Plugin\views\style; 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 @@ class IIIFManifest extends StylePluginBase { $this->fileSystem = $file_system; $this->httpClient = $http_client; $this->messenger = $messenger; + $this->moduleHandler = $moduleHandler; } /** @@ -120,10 +127,21 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { ]; } + // 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 ed054176..3501ada5 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 @@ namespace Drupal\islandora_iiif\Plugin\views\style; 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 @@ class IIIFManifest extends StylePluginBase { /** * Return the request property. - * + * * @return \Symfony\Component\HttpFoundation\Request * The Symfony request object */ @@ -309,15 +311,18 @@ class IIIFManifest extends StylePluginBase { ]; } - // 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 3501ada5..55fe3634 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 @@ class IIIFManifest extends StylePluginBase { // 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 63a714a8..9d171622 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 @@ class GenerateOCRDerivative extends AbstractGenerateDerivative { */ 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 9d171622..272e9f01 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 @@ class GenerateOCRDerivative extends AbstractGenerateDerivative { */ 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 abbe6474..f69418af 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 f69418af..ab7bb073 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 55fe3634..49c35208 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 @@ use GuzzleHttp\Exception\ServerException; */ 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 @@ class IIIFManifest extends StylePluginBase { $this->fileSystem = $file_system; $this->httpClient = $http_client; $this->messenger = $messenger; - $this->moduleHandler = $moduleHandler; + $this->utils = $utils; + } /** @@ -130,20 +132,10 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { // 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 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { * @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 @@ class IIIFManifest extends StylePluginBase { 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 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { ], ]; - 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 @@ class IIIFManifest extends StylePluginBase { 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 @@ class IIIFManifest extends StylePluginBase { '#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 @@ class IIIFManifest extends StylePluginBase { */ 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 49c35208..9fde1ed7 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 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { ], ]; - 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 @@ class IIIFManifest extends StylePluginBase { 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 ab06524b..a5cfc3b0 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 9fde1ed7..7bbe03dd 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 @@ use Symfony\Component\HttpFoundation\Request; */ class IIIFManifest extends StylePluginBase { -/** + /** * Islandora utility functions. * * @var \Drupal\islandora\IslandoraUtils @@ -233,7 +233,7 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { /** * 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 @@ class IIIFManifest extends StylePluginBase { } /** - * 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 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { */ 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 a5cfc3b0..c1f89872 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 7bbe03dd..a745e1f7 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 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { // 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 @@ class IIIFManifest extends StylePluginBase { * @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 @@ class IIIFManifest extends StylePluginBase { ], ]; - 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 @@ class IIIFManifest extends StylePluginBase { * * @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 @@ class IIIFManifest extends StylePluginBase { '#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 @@ class IIIFManifest extends StylePluginBase { 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 a745e1f7..8527067d 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 @@ class IIIFManifest extends StylePluginBase { * * @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 @@ class IIIFManifest extends StylePluginBase { 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 8527067d..2dfce979 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 @@ class IIIFManifest extends StylePluginBase { * * @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 2dfce979..e52f59f9 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 @@ class IIIFManifest extends StylePluginBase { * * @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 e52f59f9..63f015d1 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\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 GuzzleHttp\Client; @@ -35,13 +34,6 @@ use Symfony\Component\HttpFoundation\Request; */ 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 @@ class IIIFManifest extends StylePluginBase { $this->fileSystem = $file_system; $this->httpClient = $http_client; $this->messenger = $messenger; - $this->utils = $utils; - } /** @@ -132,8 +122,7 @@ class IIIFManifest extends StylePluginBase { $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 3ceed0e1..bf274cd1 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 fc1c6188..766ceac0 100644 --- a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php +++ b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php @@ -68,7 +68,8 @@ class GenerateAudioDerivativeTest extends GenerateDerivativeTestBase { '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 80f5dbee..ee35a1ed 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 b6e016fc..295eae91 100644 --- a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php +++ b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php @@ -70,7 +70,8 @@ class GenerateImageDerivativeTest extends GenerateDerivativeTestBase { '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 f15e42d5..5518220d 100644 --- a/modules/islandora_text_extraction/src/Controller/MediaSourceController.php +++ b/modules/islandora_text_extraction/src/Controller/MediaSourceController.php @@ -98,7 +98,7 @@ class MediaSourceController extends ControllerBase { 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 31dca62c..172ae73a 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 8714a2f1..17e8bd5b 100644 --- a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php +++ b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php @@ -65,7 +65,8 @@ class GenerateVideoDerivativeTest extends GenerateDerivativeTestBase { '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 ce33ce2e..f7e5725b 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 Drupal\Core\Entity\Exception\UndefinedLinkTemplateException; 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 @@ abstract class LinkHeaderSubscriber implements EventSubscriberInterface { /** * 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 3cebbbaa..0f406cf5 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 e00533f7..c4cdaea8 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 4ebc61c5..55f8b11d 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 @@ class FedoraAdapter implements AdapterInterface { // 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 @@ class FedoraAdapter implements AdapterInterface { 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 6aeed879..cf6ef305 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 @@ abstract class AbstractFileSelectionForm extends FormBase { $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 9fc2f9e2..f27f9db9 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 32909775..4b0b62c5 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 362ff7fb..5ed22948 100644 --- a/tests/src/Functional/ContentEntityTypeTest.php +++ b/tests/src/Functional/ContentEntityTypeTest.php @@ -52,7 +52,8 @@ class ContentEntityTypeTest extends IslandoraFunctionalTestBase { '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 f112c700..86895dbb 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 e1b1c827..00e0e5ae 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 @@ class DerivativeReactionTest extends IslandoraFunctionalTestBase { '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 0f67d591..c5ec9701 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 e995329d..ff215281 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 @@ class IndexingTest extends IslandoraFunctionalTestBase { // 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 2e4c88e8..2e723561 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 @@ EOD; * 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 @@ EOD; * 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 @@ EOD; * 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 33f6e1e6..84ea5517 100644 --- a/tests/src/Functional/IslandoraImageFormatterTest.php +++ b/tests/src/Functional/IslandoraImageFormatterTest.php @@ -92,7 +92,7 @@ class IslandoraImageFormatterTest extends IslandoraFunctionalTestBase { ':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 92cfc6a2..80a327af 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 @@ class IslandoraSettingsFormTest extends IslandoraFunctionalTestBase { $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 f3c88271..7ad8f018 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 @@ class JsonldSelfReferenceReactionTest extends IslandoraFunctionalTestBase { $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 @@ class JsonldSelfReferenceReactionTest extends IslandoraFunctionalTestBase { 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 @@ class JsonldSelfReferenceReactionTest extends IslandoraFunctionalTestBase { $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 @@ class JsonldSelfReferenceReactionTest extends IslandoraFunctionalTestBase { $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 @@ class JsonldSelfReferenceReactionTest extends IslandoraFunctionalTestBase { 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 e5d21abc..58e8bf61 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 @@ class JsonldTypeAlterReactionTest extends JsonldSelfReferenceReactionTest { '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 @@ class JsonldTypeAlterReactionTest extends JsonldSelfReferenceReactionTest { $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 @@ class JsonldTypeAlterReactionTest extends JsonldSelfReferenceReactionTest { // 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 7cb741d5..98b36c68 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 fdea6aef..3c97c695 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 eff5b5c3..2b4ee16f 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 72cdfe44..19660bda 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 ba289aa4..2572c191 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 c423cda3..a9c1f082 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 e5161063..d6adecbb 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 @@ use Symfony\Component\Mime\MimeTypeGuesserInterface; */ 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 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 5a95cb68..1c98db3e 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 f97eab9f..9493ab78 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 @@ use Drupal\islandora\EventSubscriber\JwtEventSubscriber; */ 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 439395b0..d05222d9 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 56b45066..8c3cb0f3 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 2c819101..e529f21e 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 88b0f308..b90494f5 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 63f015d1..b76628d7 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 @@ class IIIFManifest extends StylePluginBase { $this->fileSystem = $file_system; $this->httpClient = $http_client; $this->messenger = $messenger; + $this->moduleHandler = $moduleHandler; } /** @@ -122,10 +130,21 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { $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 @@ class IIIFManifest extends StylePluginBase { ]; } + // 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 5518220d..6b886308 100644 --- a/modules/islandora_text_extraction/src/Controller/MediaSourceController.php +++ b/modules/islandora_text_extraction/src/Controller/MediaSourceController.php @@ -5,6 +5,7 @@ namespace Drupal\islandora_text_extraction\Controller; 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 @@ class MediaSourceController extends ControllerBase { */ 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 @@ class MediaSourceController extends ControllerBase { 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 cf6ef305..6aeed879 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 @@ abstract class AbstractFileSelectionForm extends FormBase { $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 7ad8f018..92eca07a 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 58e8bf61..80a6039c 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 d05222d9..261ab1de 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 a4091781..46e82e78 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 4ff0d93f..565d7564 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 @@ class GenerateOCRDerivativeFile extends AbstractGenerateDerivativeMediaFile { 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 ea34ee2e..aabb5891 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 56a10bc1..c76020cb 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 6c6e87da..6667f4f4 100644 --- a/src/Plugin/Field/FieldFormatter/IslandoraImageFormatter.php +++ b/src/Plugin/Field/FieldFormatter/IslandoraImageFormatter.php @@ -5,6 +5,7 @@ namespace Drupal\islandora\Plugin\Field\FieldFormatter; 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 @@ class IslandoraImageFormatter extends ImageFormatter { 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 @@ class IslandoraImageFormatter extends ImageFormatter { $view_mode, $third_party_settings, $current_user, - $image_style_storage + $image_style_storage, + $file_url_generator ); $this->utils = $utils; } @@ -97,7 +102,8 @@ class IslandoraImageFormatter extends ImageFormatter { $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 766ceac0..b528e8ba 100644 --- a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php +++ b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php @@ -66,7 +66,7 @@ class GenerateAudioDerivativeTest extends GenerateDerivativeTestBase { '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 295eae91..69672e0b 100644 --- a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php +++ b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php @@ -68,7 +68,7 @@ class GenerateImageDerivativeTest extends GenerateDerivativeTestBase { '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 17e8bd5b..f712e349 100644 --- a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php +++ b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php @@ -63,7 +63,7 @@ class GenerateVideoDerivativeTest extends GenerateDerivativeTestBase { '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 b528e8ba..a7425917 100644 --- a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php +++ b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php @@ -66,7 +66,7 @@ class GenerateAudioDerivativeTest extends GenerateDerivativeTestBase { '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 69672e0b..2e1f5591 100644 --- a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php +++ b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php @@ -68,7 +68,7 @@ class GenerateImageDerivativeTest extends GenerateDerivativeTestBase { '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 f712e349..3a556987 100644 --- a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php +++ b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php @@ -63,7 +63,7 @@ class GenerateVideoDerivativeTest extends GenerateDerivativeTestBase { '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 a7425917..5c1b616e 100644 --- a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php +++ b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php @@ -66,7 +66,7 @@ class GenerateAudioDerivativeTest extends GenerateDerivativeTestBase { '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 2e1f5591..7544cb65 100644 --- a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php +++ b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php @@ -68,7 +68,7 @@ class GenerateImageDerivativeTest extends GenerateDerivativeTestBase { '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 3a556987..264cebb7 100644 --- a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php +++ b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php @@ -63,7 +63,7 @@ class GenerateVideoDerivativeTest extends GenerateDerivativeTestBase { '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 5c1b616e..6b85cd1b 100644 --- a/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php +++ b/modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php @@ -66,7 +66,7 @@ class GenerateAudioDerivativeTest extends GenerateDerivativeTestBase { '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 7544cb65..44cdda58 100644 --- a/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php +++ b/modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php @@ -68,7 +68,7 @@ class GenerateImageDerivativeTest extends GenerateDerivativeTestBase { '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 264cebb7..de06ba2f 100644 --- a/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php +++ b/modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php @@ -63,7 +63,7 @@ class GenerateVideoDerivativeTest extends GenerateDerivativeTestBase { '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 19fe419b..d261542d 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 f81cb747..41f84cbe 100644 --- a/src/IslandoraUtils.php +++ b/src/IslandoraUtils.php @@ -148,6 +148,7 @@ class IslandoraUtils { return []; } $mids = $this->entityTypeManager->getStorage('media')->getQuery() + ->accessCheck(FALSE) ->condition(self::MEDIA_OF_FIELD, $node->id()) ->execute(); if (empty($mids)) { @@ -208,6 +209,7 @@ class IslandoraUtils { // 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 @@ class IslandoraUtils { } $results = $query + ->accessCheck(FALSE) ->condition($orGroup) ->execute(); @@ -498,6 +501,7 @@ class IslandoraUtils { 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 41f84cbe..a2df7589 100644 --- a/src/IslandoraUtils.php +++ b/src/IslandoraUtils.php @@ -148,7 +148,7 @@ class IslandoraUtils { 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 @@ class IslandoraUtils { // 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 @@ class IslandoraUtils { } $results = $query - ->accessCheck(FALSE) + ->accessCheck(TRUE) ->condition($orGroup) ->execute(); @@ -501,7 +501,7 @@ class IslandoraUtils { 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 261ab1de..27506495 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 d261542d..ea8eac00 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 2560ec6e..68724265 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 b1fdb88e..f8f05beb 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 07f45bbe..e1fc7634 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 cf798265..e4414e61 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 d67060f7..f7295428 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 6a136c3c..dbd6bb62 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 3ed0286e..cd89243d 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 e7d4c7cc..a3e253e2 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 25b6fbb2..16d96c3e 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 40e469c5..5ee19b7c 100644 --- a/tests/src/Functional/DeleteNodeWithMediaAndFile.php +++ b/tests/src/Functional/DeleteNodeWithMediaAndFile.php @@ -42,8 +42,8 @@ class DeleteNodeWithMediaAndFile extends IslandoraFunctionalTestBase { '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 2e723561..016788d0 100644 --- a/tests/src/Functional/IslandoraFunctionalTestBase.php +++ b/tests/src/Functional/IslandoraFunctionalTestBase.php @@ -438,8 +438,8 @@ EOD; '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 84ea5517..1b40f7a8 100644 --- a/tests/src/Functional/IslandoraImageFormatterTest.php +++ b/tests/src/Functional/IslandoraImageFormatterTest.php @@ -59,8 +59,8 @@ class IslandoraImageFormatterTest extends IslandoraFunctionalTestBase { '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 80a6039c..658244ae 100644 --- a/tests/src/Functional/JsonldTypeAlterReactionTest.php +++ b/tests/src/Functional/JsonldTypeAlterReactionTest.php @@ -30,7 +30,7 @@ class JsonldTypeAlterReactionTest extends JsonldSelfReferenceReactionTest { '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 3c97c695..3938e9b4 100644 --- a/tests/src/Functional/MediaSourceUpdateTest.php +++ b/tests/src/Functional/MediaSourceUpdateTest.php @@ -52,8 +52,8 @@ class MediaSourceUpdateTest extends IslandoraFunctionalTestBase { '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 a9c1f082..28a4ec03 100644 --- a/tests/src/Kernel/EventGeneratorTest.php +++ b/tests/src/Kernel/EventGeneratorTest.php @@ -116,7 +116,6 @@ class EventGeneratorTest extends IslandoraKernelTestBase { ['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 d5dc9750..a9613871 100644 --- a/src/Form/ConfirmDeleteMediaAndFile.php +++ b/src/Form/ConfirmDeleteMediaAndFile.php @@ -128,6 +128,9 @@ class ConfirmDeleteMediaAndFile extends DeleteMultipleForm { // 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 86895dbb..4328d92d 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 4328d92d..586250cc 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 586250cc..7ca80922 100644 --- a/tests/src/Functional/DeleteMediaTest.php +++ b/tests/src/Functional/DeleteMediaTest.php @@ -51,7 +51,7 @@ class DeleteMediaTest extends IslandoraFunctionalTestBase { 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 7ca80922..c52eca31 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 b76628d7..b5175ed9 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 @@ namespace Drupal\islandora_iiif\Plugin\views\style; 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 1cc5f74d..7706ec74 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 00000000..9e3629fd --- /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 19fae53a..a5ad90ef 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 fc62c5c4..f9e870ef 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 dc750a5a..f09a0143 100644 --- a/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php +++ b/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php @@ -73,6 +73,14 @@ class IslandoraIIIFConfigForm extends ConfigFormBase { '#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 @@ class IslandoraIIIFConfigForm extends ConfigFormBase { $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 b5175ed9..9d31d760 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 @@ class IIIFManifest extends StylePluginBase { // 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 9d31d760..5a2fb63b 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 @@ class IIIFManifest extends StylePluginBase { * 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 6c78bcf9..041eca7a 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 9e3629fd..726d8e9c 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 726d8e9c..f2af6e78 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 f2af6e78..726d8e9c 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 b975f608..4c29e44b 100644 --- a/src/EventGenerator/EventGenerator.php +++ b/src/EventGenerator/EventGenerator.php @@ -147,8 +147,19 @@ class EventGenerator implements EventGeneratorInterface { } } - 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 5a2fb63b..804153ab 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 00000000..5b26cadf --- /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 5b26cadf..00000000 --- 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 69176714..8d4bc905 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 86b65fd0..89c1b58a 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 ad2eb8e1..01e5a467 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 8d4bc905..8d443e1c 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 90e0b420..77d8aa27 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 @@ class IslandoraSettingsForm extends ConfigFormBase { '#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 @@ class IslandoraSettingsForm extends ConfigFormBase { ->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 77d8aa27..6a2662f9 100644 --- a/src/Form/IslandoraSettingsForm.php +++ b/src/Form/IslandoraSettingsForm.php @@ -214,7 +214,7 @@ class IslandoraSettingsForm extends ConfigFormBase { $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 726d8e9c..f59207e8 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 9827ff35..c7b2df6a 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 6a2662f9..33b1a87c 100644 --- a/src/Form/IslandoraSettingsForm.php +++ b/src/Form/IslandoraSettingsForm.php @@ -129,6 +129,9 @@ class IslandoraSettingsForm extends ConfigFormBase { '#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 @@ class IslandoraSettingsForm extends ConfigFormBase { $state_selector => ['checked' => TRUE], ], ], + '#config' => [ + 'key' => 'islandora.settings:' . self::BROKER_USER, + ], ]; $form['broker_info'][self::BROKER_PASSWORD] = [ '#type' => 'password', @@ -159,6 +165,9 @@ class IslandoraSettingsForm extends ConfigFormBase { $state_selector => ['checked' => TRUE], ], ], + '#config' => [ + 'key' => 'islandora.settings:' . self::BROKER_PASSWORD, + ], ]; $form[self::JWT_EXPIRY] = [ '#type' => 'textfield', @@ -221,7 +230,11 @@ class IslandoraSettingsForm extends ConfigFormBase { $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 33b1a87c..ad4c83b3 100644 --- a/src/Form/IslandoraSettingsForm.php +++ b/src/Form/IslandoraSettingsForm.php @@ -167,6 +167,7 @@ class IslandoraSettingsForm extends ConfigFormBase { ], '#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 f09a0143..a99539a3 100644 --- a/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php +++ b/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php @@ -72,6 +72,9 @@ class IslandoraIIIFConfigForm extends ConfigFormBase { '#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 7706ec74..1c649667 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 1c649667..34107d37 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 041eca7a..396b9a0b 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 179d4213..1497c291 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 89c1b58a..49de998b 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 2e066943..055e76d9 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 @@ class OcrTextFormatter extends FormatterBase implements ContainerFactoryPluginIn $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 28a4ec03..34a5ae92 100644 --- a/tests/src/Kernel/EventGeneratorTest.php +++ b/tests/src/Kernel/EventGeneratorTest.php @@ -49,7 +49,7 @@ class EventGeneratorTest extends IslandoraKernelTestBase { $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 8d443e1c..d3dfa01d 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 ab7bb073..f528dee3 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 396b9a0b..8e4e19be 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 658244ae..75ae41dd 100644 --- a/tests/src/Functional/JsonldTypeAlterReactionTest.php +++ b/tests/src/Functional/JsonldTypeAlterReactionTest.php @@ -26,12 +26,39 @@ class JsonldTypeAlterReactionTest extends JsonldSelfReferenceReactionTest { // 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 f27f9db9..ed5282c7 100644 --- a/tests/src/Functional/AddChildTest.php +++ b/tests/src/Functional/AddChildTest.php @@ -9,13 +9,19 @@ namespace Drupal\Tests\islandora\Functional; */ 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 92eca07a..1b4e24ec 100644 --- a/tests/src/Functional/JsonldSelfReferenceReactionTest.php +++ b/tests/src/Functional/JsonldSelfReferenceReactionTest.php @@ -12,6 +12,13 @@ use function GuzzleHttp\json_decode; */ 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 9067d369..6d8fee28 100644 --- a/tests/src/Kernel/FedoraAdapterTest.php +++ b/tests/src/Kernel/FedoraAdapterTest.php @@ -354,7 +354,7 @@ class FedoraAdapterTest extends IslandoraKernelTestBase { $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 6667f4f4..deb6c769 100644 --- a/src/Plugin/Field/FieldFormatter/IslandoraImageFormatter.php +++ b/src/Plugin/Field/FieldFormatter/IslandoraImageFormatter.php @@ -5,7 +5,7 @@ namespace Drupal\islandora\Plugin\Field\FieldFormatter; 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 @@ class IslandoraImageFormatter extends ImageFormatter { AccountInterface $current_user, EntityStorageInterface $image_style_storage, IslandoraUtils $utils, - FileUrlGenerator $file_url_generator + FileUrlGeneratorInterface $file_url_generator ) { parent::__construct( $plugin_id,