From 2a1024c19a4b495c64fb88d4260e8d7ebea1f9b5 Mon Sep 17 00:00:00 2001 From: Jared Whiklo Date: Mon, 2 Mar 2020 09:37:21 -0600 Subject: [PATCH 01/23] Catch Flysystem exceptions and report (#762) --- src/Flysystem/Fedora.php | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/Flysystem/Fedora.php b/src/Flysystem/Fedora.php index b90fc529..fe7af7ba 100644 --- a/src/Flysystem/Fedora.php +++ b/src/Flysystem/Fedora.php @@ -10,6 +10,7 @@ use Drupal\flysystem\Plugin\FlysystemPluginInterface; use Drupal\flysystem\Plugin\FlysystemUrlTrait; 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; @@ -123,20 +124,28 @@ class Fedora implements FlysystemPluginInterface, ContainerFactoryPluginInterfac */ public function ensure($force = FALSE) { // Check fedora root for sanity. - $response = $this->fedora->getResourceHeaders(''); - - if ($response->getStatusCode() != 200) { - return [[ - 'severity' => RfcLogLevel::ERROR, - 'message' => '%url returned %status', - 'context' => [ - '%url' => $this->fedora->getBaseUri(), - '%status' => $response->getStatusCode(), + try { + $response = $this->fedora->getResourceHeaders(''); + $statusCode = $response->getStatusCode(); + $message = '%url returned %status'; + } + catch (ConnectException $e) { + // Fedora is unavailable. + $message = '%url is unavailable, cannot connect.'; + $statusCode = 500; + } + if ($statusCode != 200) { + return [ + [ + 'severity' => RfcLogLevel::ERROR, + 'message' => $message, + 'context' => [ + '%url' => $this->fedora->getBaseUri(), + '%status' => $statusCode, + ], ], - ], ]; } - return []; } From c89ff9f16db4ae677abf5e77593fc606ccfce662 Mon Sep 17 00:00:00 2001 From: dannylamb Date: Thu, 12 Mar 2020 11:32:14 -0600 Subject: [PATCH 02/23] No longer double negating conditions (#763) --- src/Plugin/Condition/EntityBundle.php | 4 ++-- src/Plugin/Condition/MediaHasMimetype.php | 2 +- src/Plugin/Condition/NodeHadNamespace.php | 4 ++-- src/Plugin/Condition/NodeHasParent.php | 3 ++- src/Plugin/Condition/NodeIsPublished.php | 9 +++++---- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/Plugin/Condition/EntityBundle.php b/src/Plugin/Condition/EntityBundle.php index 77cf2826..13500f68 100644 --- a/src/Plugin/Condition/EntityBundle.php +++ b/src/Plugin/Condition/EntityBundle.php @@ -61,11 +61,11 @@ class EntityBundle extends ConditionPluginBase { if ($context->hasContextValue()) { $entity = $context->getContextValue(); if (!empty($this->configuration['bundles'][$entity->bundle()])) { - return !$this->isNegated(); + return TRUE; } } } - return $this->isNegated(); + return FALSE; } /** diff --git a/src/Plugin/Condition/MediaHasMimetype.php b/src/Plugin/Condition/MediaHasMimetype.php index 3b5e0822..291c0da6 100644 --- a/src/Plugin/Condition/MediaHasMimetype.php +++ b/src/Plugin/Condition/MediaHasMimetype.php @@ -152,7 +152,7 @@ class MediaHasMimetype extends ConditionPluginBase implements ContainerFactoryPl foreach ($media as $medium) { $file = $this->mediaSource->getSourceFile($medium); if (in_array($file->getMimeType(), $mimetypes)) { - return $this->isNegated() ? FALSE : TRUE; + return TRUE; } } } diff --git a/src/Plugin/Condition/NodeHadNamespace.php b/src/Plugin/Condition/NodeHadNamespace.php index 2e8042c8..b1d1efe0 100644 --- a/src/Plugin/Condition/NodeHadNamespace.php +++ b/src/Plugin/Condition/NodeHadNamespace.php @@ -154,12 +154,12 @@ class NodeHadNamespace extends ConditionPluginBase implements ContainerFactoryPl foreach ($registered_namespaces as &$registered_namespace) { $registered_namespace = trim($registered_namespace); if (in_array($namespace, $registered_namespaces)) { - return $this->isNegated() ? FALSE : TRUE; + return TRUE; } } } - return $this->isNegated() ? TRUE : FALSE; + return FALSE; } /** diff --git a/src/Plugin/Condition/NodeHasParent.php b/src/Plugin/Condition/NodeHasParent.php index 8455b233..ca5703ec 100644 --- a/src/Plugin/Condition/NodeHasParent.php +++ b/src/Plugin/Condition/NodeHasParent.php @@ -145,12 +145,13 @@ class NodeHasParent extends ConditionPluginBase implements ContainerFactoryPlugi $nids = $field->getValue(); foreach ($nids as $nid) { if ($nid['target_id'] == $this->configuration['parent_nid']) { - return $this->isNegated() ? FALSE : TRUE; + return TRUE; } } } } } + return FALSE; } /** diff --git a/src/Plugin/Condition/NodeIsPublished.php b/src/Plugin/Condition/NodeIsPublished.php index dcf648ee..1b81270d 100644 --- a/src/Plugin/Condition/NodeIsPublished.php +++ b/src/Plugin/Condition/NodeIsPublished.php @@ -72,11 +72,12 @@ class NodeIsPublished extends ConditionPluginBase implements ContainerFactoryPlu if (!$node && !$this->isNegated()) { return FALSE; } - if ($node->isPublished() && !$this->isNegated()) { - return TRUE; + elseif (!$node) { + return FALSE; + } + else { + return $node->isPublished(); } - - return FALSE; } /** From 1b2ab9e76f032b3df847b4c38a1de6e38e79bbb3 Mon Sep 17 00:00:00 2001 From: Seth Shaw Date: Mon, 23 Mar 2020 05:46:53 -0700 Subject: [PATCH 03/23] save document media files to fedora by default (#765) --- ...eld.storage.media.field_media_document.yml | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 modules/islandora_core_feature/config/install/field.storage.media.field_media_document.yml diff --git a/modules/islandora_core_feature/config/install/field.storage.media.field_media_document.yml b/modules/islandora_core_feature/config/install/field.storage.media.field_media_document.yml new file mode 100644 index 00000000..6dad37c7 --- /dev/null +++ b/modules/islandora_core_feature/config/install/field.storage.media.field_media_document.yml @@ -0,0 +1,25 @@ +langcode: en +status: true +dependencies: + enforced: + module: + - islandora_core_feature + module: + - file + - media +id: media.field_media_document +field_name: field_media_document +entity_type: media +type: file +settings: + display_field: false + display_default: false + uri_scheme: fedora + target_type: file +module: file +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false From e9bea0d697000d6f6f2a6a2d8d672ca0e49f134a Mon Sep 17 00:00:00 2001 From: dannylamb Date: Wed, 25 Mar 2020 12:01:07 -0600 Subject: [PATCH 04/23] =?UTF-8?q?Using=20context=5Fdefinitions=20annotatio?= =?UTF-8?q?n=20instead=20of=20the=20deprecated=20contex=E2=80=A6=20(#764)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .travis.yml | 8 ++++---- .../tests/src/Functional/BreadcrumbsTest.php | 14 ++++++++++++-- src/Plugin/Condition/ContentEntityType.php | 2 +- src/Plugin/Condition/EntityBundle.php | 2 +- src/Plugin/Condition/FileUsesFilesystem.php | 2 +- src/Plugin/Condition/MediaHasTerm.php | 2 +- src/Plugin/Condition/MediaUsesFilesystem.php | 2 +- src/Plugin/Condition/NodeHadNamespace.php | 2 +- src/Plugin/Condition/NodeHasParent.php | 2 +- src/Plugin/Condition/NodeHasTerm.php | 2 +- src/Plugin/Condition/NodeIsPublished.php | 2 +- src/Plugin/Condition/ParentNodeHasTerm.php | 2 +- 12 files changed, 26 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index d5321085..b0dcc8ce 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,12 +27,12 @@ install: - $SCRIPT_DIR/travis_setup_drupal.sh - git -C "$TRAVIS_BUILD_DIR" checkout -b travis-testing - cd $DRUPAL_DIR; + - chmod -R u+w web/sites/default - COMPOSER_MEMORY_LIMIT=-1 php -d memory_limit=-1 $COMPOSER_PATH config repositories.local path "$TRAVIS_BUILD_DIR" - COMPOSER_MEMORY_LIMIT=-1 php -d memory_limit=-1 $COMPOSER_PATH require "islandora/islandora:dev-travis-testing as dev-8.x-1.x" --prefer-source --update-with-dependencies - - cd web; drush --uri=127.0.0.1:8282 en -y islandora - - (drush -y --uri=127.0.0.1:8282 en islandora_core_feature; drush -y --uri=127.0.0.1:8282 fim islandora_core_feature) - - drush -y --uri=127.0.0.1:8282 en islandora_audio islandora_breadcrumbs islandora_iiif islandora_image islandora_video - - (drush -y --uri=127.0.0.1:8282 en islandora_text_extraction_defaults; drush -y --uri=127.0.0.1:8282 fim islandora_text_extraction_defaults) + - cd 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 script: - $SCRIPT_DIR/travis_scripts.sh diff --git a/modules/islandora_breadcrumbs/tests/src/Functional/BreadcrumbsTest.php b/modules/islandora_breadcrumbs/tests/src/Functional/BreadcrumbsTest.php index c95d362c..18fa030e 100644 --- a/modules/islandora_breadcrumbs/tests/src/Functional/BreadcrumbsTest.php +++ b/modules/islandora_breadcrumbs/tests/src/Functional/BreadcrumbsTest.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\islandora_breadcrumbs\Functional; +use Drupal\Core\Url; use Drupal\Tests\islandora\Functional\IslandoraFunctionalTestBase; use Drupal\Tests\system\Functional\Menu\AssertBreadcrumbTrait; @@ -85,6 +86,14 @@ class BreadcrumbsTest extends IslandoraFunctionalTestBase { ]); $this->nodeD->set('field_member_of', [$this->nodeC->id()]); $this->nodeD->save(); + + $this->drupalPlaceBlock( + 'system_breadcrumb_block', + [ + 'region' => 'content', + 'theme' => $this->config('system.theme')->get('default'), + ] + ); } /** @@ -92,9 +101,10 @@ class BreadcrumbsTest extends IslandoraFunctionalTestBase { */ public function testDefaults() { $breadcrumbs = [ - $this->nodeC->toUrl()->toString() => $this->nodeC->label(), - $this->nodeB->toUrl()->toString() => $this->nodeB->label(), + Url::fromRoute('')->toString() => 'Home', $this->nodeA->toUrl()->toString() => $this->nodeA->label(), + $this->nodeB->toUrl()->toString() => $this->nodeB->label(), + $this->nodeC->toUrl()->toString() => $this->nodeC->label(), ]; $this->assertBreadcrumb($this->nodeD->toUrl()->toString(), $breadcrumbs); diff --git a/src/Plugin/Condition/ContentEntityType.php b/src/Plugin/Condition/ContentEntityType.php index 71379f94..e80eee42 100644 --- a/src/Plugin/Condition/ContentEntityType.php +++ b/src/Plugin/Condition/ContentEntityType.php @@ -11,7 +11,7 @@ use Drupal\Core\Form\FormStateInterface; * @Condition( * id = "content_entity_type", * label = @Translation("Content Entity Type"), - * context = { + * context_definitions = { * "node" = @ContextDefinition("entity:node", required = FALSE, label = @Translation("Node")), * "media" = @ContextDefinition("entity:media", required = FALSE, label = @Translation("Media")), * "file" = @ContextDefinition("entity:file", required = FALSE, label = @Translation("File")), diff --git a/src/Plugin/Condition/EntityBundle.php b/src/Plugin/Condition/EntityBundle.php index 13500f68..4803fd49 100644 --- a/src/Plugin/Condition/EntityBundle.php +++ b/src/Plugin/Condition/EntityBundle.php @@ -11,7 +11,7 @@ use Drupal\Core\Form\FormStateInterface; * @Condition( * id = "entity_bundle", * label = @Translation("Entity Bundle"), - * context = { + * context_definitions = { * "node" = @ContextDefinition("entity:node", required = FALSE, label = @Translation("Node")), * "media" = @ContextDefinition("entity:media", required = FALSE, label = @Translation("Media")), * "taxonomy_term" = @ContextDefinition("entity:taxonomy_term", required = FALSE, label = @Translation("Term")) diff --git a/src/Plugin/Condition/FileUsesFilesystem.php b/src/Plugin/Condition/FileUsesFilesystem.php index a5fc32f5..27e120e8 100644 --- a/src/Plugin/Condition/FileUsesFilesystem.php +++ b/src/Plugin/Condition/FileUsesFilesystem.php @@ -16,7 +16,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; * @Condition( * id = "file_uses_filesystem", * label = @Translation("File uses filesystem"), - * context = { + * context_definitions = { * "file" = @ContextDefinition("entity:file", required = TRUE , label = @Translation("file")) * } * ) diff --git a/src/Plugin/Condition/MediaHasTerm.php b/src/Plugin/Condition/MediaHasTerm.php index b170c7a6..f56a85ce 100644 --- a/src/Plugin/Condition/MediaHasTerm.php +++ b/src/Plugin/Condition/MediaHasTerm.php @@ -8,7 +8,7 @@ namespace Drupal\islandora\Plugin\Condition; * @Condition( * id = "media_has_term", * label = @Translation("Media has term with URI"), - * context = { + * context_definitions = { * "media" = @ContextDefinition("entity:media", required = TRUE , label = @Translation("media")) * } * ) diff --git a/src/Plugin/Condition/MediaUsesFilesystem.php b/src/Plugin/Condition/MediaUsesFilesystem.php index cb69a301..769e6c6d 100644 --- a/src/Plugin/Condition/MediaUsesFilesystem.php +++ b/src/Plugin/Condition/MediaUsesFilesystem.php @@ -13,7 +13,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; * @Condition( * id = "media_uses_filesystem", * label = @Translation("Media uses filesystem"), - * context = { + * context_definitions = { * "media" = @ContextDefinition("entity:media", required = TRUE , label = @Translation("media")) * } * ) diff --git a/src/Plugin/Condition/NodeHadNamespace.php b/src/Plugin/Condition/NodeHadNamespace.php index b1d1efe0..4872f7eb 100644 --- a/src/Plugin/Condition/NodeHadNamespace.php +++ b/src/Plugin/Condition/NodeHadNamespace.php @@ -16,7 +16,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; * @Condition( * id = "node_had_namespace", * label = @Translation("Node had 7.x namespace"), - * context = { + * context_definitions = { * "node" = @ContextDefinition("entity:node", required = TRUE , label = @Translation("node")) * } * ) diff --git a/src/Plugin/Condition/NodeHasParent.php b/src/Plugin/Condition/NodeHasParent.php index ca5703ec..5002707f 100644 --- a/src/Plugin/Condition/NodeHasParent.php +++ b/src/Plugin/Condition/NodeHasParent.php @@ -15,7 +15,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; * @Condition( * id = "node_has_parent", * label = @Translation("Node has parent"), - * context = { + * context_definitions = { * "node" = @ContextDefinition("entity:node", required = TRUE , label = @Translation("node")) * } * ) diff --git a/src/Plugin/Condition/NodeHasTerm.php b/src/Plugin/Condition/NodeHasTerm.php index 1f501fde..8558e14b 100644 --- a/src/Plugin/Condition/NodeHasTerm.php +++ b/src/Plugin/Condition/NodeHasTerm.php @@ -16,7 +16,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; * @Condition( * id = "node_has_term", * label = @Translation("Node has term with URI"), - * context = { + * context_definitions = { * "node" = @ContextDefinition("entity:node", required = TRUE , label = @Translation("node")) * } * ) diff --git a/src/Plugin/Condition/NodeIsPublished.php b/src/Plugin/Condition/NodeIsPublished.php index 1b81270d..54466df4 100644 --- a/src/Plugin/Condition/NodeIsPublished.php +++ b/src/Plugin/Condition/NodeIsPublished.php @@ -13,7 +13,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; * @Condition( * id = "node_is_published", * label = @Translation("Node is published"), - * context = { + * context_definitions = { * "node" = @ContextDefinition("entity:node", required = TRUE , label = @Translation("node")) * } * ) diff --git a/src/Plugin/Condition/ParentNodeHasTerm.php b/src/Plugin/Condition/ParentNodeHasTerm.php index 3bc08641..d14f1292 100644 --- a/src/Plugin/Condition/ParentNodeHasTerm.php +++ b/src/Plugin/Condition/ParentNodeHasTerm.php @@ -8,7 +8,7 @@ namespace Drupal\islandora\Plugin\Condition; * @Condition( * id = "parent_node_has_term", * label = @Translation("Parent node for media has term with URI"), - * context = { + * context_definitions = { * "media" = @ContextDefinition("entity:media", required = TRUE , label = @Translation("media")) * } * ) From dd47b16be90f39566fce451a3dfaa788487a41f6 Mon Sep 17 00:00:00 2001 From: J Hunt Date: Sat, 28 Mar 2020 02:19:34 +1300 Subject: [PATCH 05/23] #1475 Check derivative_term instead of source_term (#766) Co-authored-by: Jonathan Hunt --- src/Plugin/Action/AbstractGenerateDerivative.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plugin/Action/AbstractGenerateDerivative.php b/src/Plugin/Action/AbstractGenerateDerivative.php index 6ecc2259..fa41f7ff 100644 --- a/src/Plugin/Action/AbstractGenerateDerivative.php +++ b/src/Plugin/Action/AbstractGenerateDerivative.php @@ -160,7 +160,7 @@ class AbstractGenerateDerivative extends EmitEvent { // Find the term for the derivative and use it to set the destination url // in the data array. $derivative_term = $this->utils->getTermForUri($this->configuration['derivative_term_uri']); - if (!$source_term) { + if (!$derivative_term) { throw new \RuntimeException("Could not locate derivative term with uri" . $this->configuration['derivative_term_uri'], 500); } From 029bbcfe5dd6abe510bcda8717ed36d4fc61269e Mon Sep 17 00:00:00 2001 From: dannylamb Date: Wed, 1 Apr 2020 10:26:08 -0600 Subject: [PATCH 06/23] Reindexing parents of extracted text when updated (#767) --- .../islandora_text_extraction.module | 22 +++++++ .../islandora_text_extraction.services.yml | 8 +++ .../src/SearchReindexer.php | 65 +++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 modules/islandora_text_extraction/islandora_text_extraction.services.yml create mode 100644 modules/islandora_text_extraction/src/SearchReindexer.php diff --git a/modules/islandora_text_extraction/islandora_text_extraction.module b/modules/islandora_text_extraction/islandora_text_extraction.module index 2b2c1a5d..a9440c90 100644 --- a/modules/islandora_text_extraction/islandora_text_extraction.module +++ b/modules/islandora_text_extraction/islandora_text_extraction.module @@ -44,6 +44,28 @@ function islandora_text_extraction_media_presave(MediaInterface $media) { } } +/** + * Implements hook_media_insert(). + */ +function islandora_text_extraction_media_insert(MediaInterface $media) { + if ($media->bundle() != 'extracted_text') { + return; + } + + \Drupal::service('islandora_text_extraction.search_reindexer')->reindexParent($media); +} + +/** + * Implements hook_media_update(). + */ +function islandora_text_extraction_media_update(MediaInterface $media) { + if ($media->bundle() != 'extracted_text') { + return; + } + + \Drupal::service('islandora_text_extraction.search_reindexer')->reindexParent($media); +} + /** * Implements hook_form_form_id_alter(). */ diff --git a/modules/islandora_text_extraction/islandora_text_extraction.services.yml b/modules/islandora_text_extraction/islandora_text_extraction.services.yml new file mode 100644 index 00000000..72d63bdf --- /dev/null +++ b/modules/islandora_text_extraction/islandora_text_extraction.services.yml @@ -0,0 +1,8 @@ +services: + logger.channel.islandora_text_extraction: + parent: logger.channel_base + arguments: ['islandora_text_extraction'] + islandora_text_extraction.search_reindexer: + class: Drupal\islandora_text_extraction\SearchReindexer + arguments: ['@islandora.utils', '@logger.channel.islandora_text_extraction'] + diff --git a/modules/islandora_text_extraction/src/SearchReindexer.php b/modules/islandora_text_extraction/src/SearchReindexer.php new file mode 100644 index 00000000..791cf9e9 --- /dev/null +++ b/modules/islandora_text_extraction/src/SearchReindexer.php @@ -0,0 +1,65 @@ +utils = $utils; + $this->logger = $logger; + } + + /** + * Reindexes parent node for a media. No-op if parent does not exist. + * + * @param Drupal\media\MediaInterface $media + * Media whose parent you want to reindex. + */ + public function reindexParent(MediaInterface $media) { + $parent = $this->utils->getParentNode($media); + + if ($parent === NULL) { + return; + } + + $this->logger->debug( + "Re-indexing parent node @nid for extracted text @mid using the search_api", + ['@nid' => $parent->id(), '@mid' => $media->id()] + ); + + $parent->original = $parent; + search_api_entity_update($parent); + } + +} From 8b7caa9e8c0b4eac54cdb8c8365eec453e36f369 Mon Sep 17 00:00:00 2001 From: dannylamb Date: Wed, 1 Apr 2020 12:07:45 -0600 Subject: [PATCH 07/23] Fixes JSONLD endpoint fail for Extracted Text (#768) * wrapping string in array for case where there's no rdf mapping * Adding rdf mapping for extracted text --- .../rdf.mapping.media.extracted_text.yml | 51 +++++++++++++++++++ .../JsonldTypeAlterReaction.php | 3 ++ 2 files changed, 54 insertions(+) create mode 100644 modules/islandora_text_extraction_defaults/config/install/rdf.mapping.media.extracted_text.yml diff --git a/modules/islandora_text_extraction_defaults/config/install/rdf.mapping.media.extracted_text.yml b/modules/islandora_text_extraction_defaults/config/install/rdf.mapping.media.extracted_text.yml new file mode 100644 index 00000000..e0a0b155 --- /dev/null +++ b/modules/islandora_text_extraction_defaults/config/install/rdf.mapping.media.extracted_text.yml @@ -0,0 +1,51 @@ +langcode: en +status: true +dependencies: + config: + - media.type.extracted_text + enforced: + module: + - islandora_text_extraction_defaults + module: + - media +id: media.extracted_text +targetEntityType: media +bundle: extracted_text +types: + - 'pcdm:File' +fieldMappings: + name: + properties: + - 'dcterms:title' + - 'rdf:label' + created: + properties: + - 'schema:dateCreated' + datatype_callback: + callable: 'Drupal\rdf\CommonDataConverter::dateIso8601Value' + changed: + properties: + - 'schema:dateModified' + datatype_callback: + callable: 'Drupal\rdf\CommonDataConverter::dateIso8601Value' + uid: + properties: + - 'schema:author' + mapping_type: rel + field_mime_type: + properties: + - 'ebucore:hasMimeType' + field_media_of: + properties: + - 'pcdm:fileOf' + mapping_type: rel + field_original_name: + properties: + - 'premis3:originalName' + field_tags: + properties: + - 'schema:additionalType' + mapping_type: rel + field_file_size: + properties: + - 'premis:hasSize' diff --git a/src/Plugin/ContextReaction/JsonldTypeAlterReaction.php b/src/Plugin/ContextReaction/JsonldTypeAlterReaction.php index ae4bc55a..b2e757ff 100644 --- a/src/Plugin/ContextReaction/JsonldTypeAlterReaction.php +++ b/src/Plugin/ContextReaction/JsonldTypeAlterReaction.php @@ -44,6 +44,9 @@ class JsonldTypeAlterReaction extends NormalizerAlterReaction { // Search for the entity in the graph. foreach ($normalized['@graph'] as &$elem) { + if (!is_array($elem['@type'])) { + $elem['@type'] = [$elem['@type']]; + } if ($elem['@id'] === $this->getSubjectUrl($entity)) { foreach ($entity->get($config['source_field'])->getValue() as $type) { // If the configured field is using an entity reference, From 163a621bc499d32a3b72da58b16b6a38d77694b4 Mon Sep 17 00:00:00 2001 From: Seth Shaw Date: Thu, 2 Apr 2020 07:03:50 -0700 Subject: [PATCH 08/23] update field_edited_text when different from the file contents (#769) --- .../islandora_text_extraction.module | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/islandora_text_extraction/islandora_text_extraction.module b/modules/islandora_text_extraction/islandora_text_extraction.module index a9440c90..28a44553 100644 --- a/modules/islandora_text_extraction/islandora_text_extraction.module +++ b/modules/islandora_text_extraction/islandora_text_extraction.module @@ -34,11 +34,11 @@ function islandora_text_extraction_media_presave(MediaInterface $media) { return; } $text = $media->get('field_edited_text')->getValue(); - if (!$text) { - $file_id = $media->get('field_media_file')->getValue()[0]['target_id']; - $file = File::load($file_id); - $data = file_get_contents($file->getFileUri()); - $data = nl2br($data); + $file_id = $media->get('field_media_file')->getValue()[0]['target_id']; + $file = File::load($file_id); + $data = file_get_contents($file->getFileUri()); + $data = nl2br($data); + if ($text !== $data) { $media->set('field_edited_text', $data); $media->field_edited_text->format = 'basic_html'; } From 3c969bf14f1775ebb6c52cc71b7558703f154210 Mon Sep 17 00:00:00 2001 From: dannylamb Date: Tue, 7 Apr 2020 07:36:45 -0600 Subject: [PATCH 09/23] Revert "update field_edited_text when different from the file contents (#769)" (#770) This reverts commit 163a621bc499d32a3b72da58b16b6a38d77694b4. --- .../islandora_text_extraction.module | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/islandora_text_extraction/islandora_text_extraction.module b/modules/islandora_text_extraction/islandora_text_extraction.module index 28a44553..a9440c90 100644 --- a/modules/islandora_text_extraction/islandora_text_extraction.module +++ b/modules/islandora_text_extraction/islandora_text_extraction.module @@ -34,11 +34,11 @@ function islandora_text_extraction_media_presave(MediaInterface $media) { return; } $text = $media->get('field_edited_text')->getValue(); - $file_id = $media->get('field_media_file')->getValue()[0]['target_id']; - $file = File::load($file_id); - $data = file_get_contents($file->getFileUri()); - $data = nl2br($data); - if ($text !== $data) { + if (!$text) { + $file_id = $media->get('field_media_file')->getValue()[0]['target_id']; + $file = File::load($file_id); + $data = file_get_contents($file->getFileUri()); + $data = nl2br($data); $media->set('field_edited_text', $data); $media->field_edited_text->format = 'basic_html'; } From 7b24912fd3cc5cd737235a910e9aae5814962c88 Mon Sep 17 00:00:00 2001 From: dannylamb Date: Mon, 13 Apr 2020 12:55:40 -0600 Subject: [PATCH 10/23] Renames `entity_bundle` to `islandora_entity_bundle` to avoid name collision (#772) * #1470 Move entity_bundle context plugin to islandora_entity_bundle to avoid ctools * Update hook * Update EntityBundleTest.php * Coding standards * Touching up tests * plugin.manager.condition, not plugin.manager.context... Co-authored-by: Jonathan Hunt --- islandora.install | 28 +++++++++++++++++++ src/Plugin/Condition/EntityBundle.php | 4 ++- tests/src/Functional/EntityBundleTest.php | 6 ++-- .../JsonldTypeAlterReactionTest.php | 6 ++-- 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/islandora.install b/islandora.install index 526583d4..011ecb19 100644 --- a/islandora.install +++ b/islandora.install @@ -52,3 +52,31 @@ function islandora_update_8001(&$sandbox) { $action->delete(); } } + +/** + * Replaces 'entity_bundle' conditions with 'islandora_entity_bundle'. + * + * This prevents plugin naming collisions between islandora and ctools. + */ +function islandora_update_8002(&$sandbox) { + + // Find contexts that have the old 'entity_bundle' condition. + $results = \Drupal::entityQuery('context')->condition('conditions.entity_bundle.id', 'entity_bundle')->execute(); + + if (empty($results)) { + return; + } + + // Set each context config to use 'islandora_entity_bundle' instead. + foreach ($results as $result) { + $config = \Drupal::configFactory()->getEditable("context.context.$result"); + $condition = $config->get('conditions.entity_bundle'); + $condition['id'] = 'islandora_entity_bundle'; + $config->set('conditions.islandora_entity_bundle', $condition); + $config->clear('conditions.entity_bundle'); + $config->save(); + } + + // Force drupal to reload the config. + \Drupal::service('plugin.manager.condition')->clearCachedDefinitions(); +} diff --git a/src/Plugin/Condition/EntityBundle.php b/src/Plugin/Condition/EntityBundle.php index 4803fd49..bd42df54 100644 --- a/src/Plugin/Condition/EntityBundle.php +++ b/src/Plugin/Condition/EntityBundle.php @@ -8,8 +8,10 @@ use Drupal\Core\Form\FormStateInterface; /** * Provides a 'Entity Bundle' condition. * + * Namespaced to avoid conflict with ctools entity_bundle plugin. + * * @Condition( - * id = "entity_bundle", + * id = "islandora_entity_bundle", * label = @Translation("Entity Bundle"), * context_definitions = { * "node" = @ContextDefinition("entity:node", required = FALSE, label = @Translation("Node")), diff --git a/tests/src/Functional/EntityBundleTest.php b/tests/src/Functional/EntityBundleTest.php index 1ffc261e..740ce8c1 100644 --- a/tests/src/Functional/EntityBundleTest.php +++ b/tests/src/Functional/EntityBundleTest.php @@ -24,9 +24,9 @@ class EntityBundleTest extends IslandoraFunctionalTestBase { $this->drupalLogin($account); $this->createContext('Test', 'test'); - $this->addCondition('test', 'entity_bundle'); - $this->getSession()->getPage()->checkField("edit-conditions-entity-bundle-bundles-test-type"); - $this->getSession()->getPage()->findById("edit-conditions-entity-bundle-context-mapping-node")->selectOption("@node.node_route_context:node"); + $this->addCondition('test', 'islandora_entity_bundle'); + $this->getSession()->getPage()->checkField("edit-conditions-islandora-entity-bundle-bundles-test-type"); + $this->getSession()->getPage()->findById("edit-conditions-islandora-entity-bundle-context-mapping-node")->selectOption("@node.node_route_context:node"); $this->getSession()->getPage()->pressButton(t('Save and continue')); $this->addPresetReaction('test', 'index', 'hello_world'); diff --git a/tests/src/Functional/JsonldTypeAlterReactionTest.php b/tests/src/Functional/JsonldTypeAlterReactionTest.php index 0232518b..ce5aa081 100644 --- a/tests/src/Functional/JsonldTypeAlterReactionTest.php +++ b/tests/src/Functional/JsonldTypeAlterReactionTest.php @@ -70,9 +70,9 @@ class JsonldTypeAlterReactionTest extends JsonldSelfReferenceReactionTest { $this->assertSession() ->pageTextContains("The context $context_name has been saved"); - $this->addCondition('test', 'entity_bundle'); - $this->getSession()->getPage()->checkField("edit-conditions-entity-bundle-bundles-test-type"); - $this->getSession()->getPage()->findById("edit-conditions-entity-bundle-context-mapping-node")->selectOption("@node.node_route_context:node"); + $this->addCondition('test', 'islandora_entity_bundle'); + $this->getSession()->getPage()->checkField("edit-conditions-islandora-entity-bundle-bundles-test-type"); + $this->getSession()->getPage()->findById("edit-conditions-islandora-entity-bundle-context-mapping-node")->selectOption("@node.node_route_context:node"); $this->getSession()->getPage()->pressButton(t('Save and continue')); // The first time a Context is saved, you need to clear the cache. From 16d6cbab0243d0213fdc2c45ae7350e64ca369bd Mon Sep 17 00:00:00 2001 From: J Hunt Date: Thu, 16 Apr 2020 01:58:35 +1200 Subject: [PATCH 11/23] #1472 Update drupal/jwt to 8.x-1.0-beta1 (#773) Co-authored-by: Jonathan Hunt --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 05128bc4..9ee9572b 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "drupal/search_api": "~1.8", "islandora/jsonld": "dev-8.x-1.x", "stomp-php/stomp-php": "4.*", - "drupal/jwt": "1.0.0-alpha6", + "drupal/jwt": "1.0.0-beta1", "drupal/filehash": "^1.1", "drupal/prepopulate" : "^2.2", "drupal/eva" : "^2.0", From 82f3b006c319b38f480ab04fb8504a6cc5c3b1e3 Mon Sep 17 00:00:00 2001 From: dannylamb Date: Tue, 28 Apr 2020 16:35:27 -0300 Subject: [PATCH 12/23] Update field.field.media.extracted_text.field_mime_type.yml --- .../field.field.media.extracted_text.field_mime_type.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_mime_type.yml b/modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_mime_type.yml index 5666fb2b..b2d78293 100644 --- a/modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_mime_type.yml +++ b/modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_mime_type.yml @@ -11,7 +11,7 @@ bundle: extracted_text label: 'MIME type' description: '' required: false -translatable: true +translatable: false default_value: - value: text/plain From 057bc5cc3a2b8e6e770c474b8bf5a9eb7007817f Mon Sep 17 00:00:00 2001 From: J Hunt Date: Tue, 16 Jun 2020 01:43:16 +1200 Subject: [PATCH 13/23] #1497 Update drupal/jwt to 8.x-1.0-beta2 (#775) * #1497 Update drupal/jwt to 8.x-1.0-beta2 * Update JWT to 8.x-1.0-beta3 Co-authored-by: Jonathan Hunt --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 9ee9572b..e65eedbc 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "drupal/search_api": "~1.8", "islandora/jsonld": "dev-8.x-1.x", "stomp-php/stomp-php": "4.*", - "drupal/jwt": "1.0.0-beta1", + "drupal/jwt": "^1.0.0-beta3", "drupal/filehash": "^1.1", "drupal/prepopulate" : "^2.2", "drupal/eva" : "^2.0", From bc6e5a3f273b3b11e32c9e2fcdc3857573cf0336 Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Mon, 22 Jun 2020 13:26:24 -0300 Subject: [PATCH 14/23] Add configuration for a user and password to the broker. (#779) * Broker config. * Coding standards, clear not delete. --- src/Form/IslandoraSettingsForm.php | 90 ++++++++++++++++++++++++++---- src/StompFactory.php | 5 +- 2 files changed, 84 insertions(+), 11 deletions(-) diff --git a/src/Form/IslandoraSettingsForm.php b/src/Form/IslandoraSettingsForm.php index 27514c3b..4ee828d5 100644 --- a/src/Form/IslandoraSettingsForm.php +++ b/src/Form/IslandoraSettingsForm.php @@ -22,6 +22,8 @@ class IslandoraSettingsForm extends ConfigFormBase { const CONFIG_NAME = 'islandora.settings'; const BROKER_URL = 'broker_url'; + const BROKER_USER = 'broker_user'; + const BROKER_PASSWORD = 'broker_password'; const JWT_EXPIRY = 'jwt_expiry'; const GEMINI_URL = 'gemini_url'; const GEMINI_PSEUDO = 'gemini_pseudo_bundles'; @@ -34,6 +36,13 @@ class IslandoraSettingsForm extends ConfigFormBase { */ private $entityTypeBundleInfo; + /** + * The saved password (if set). + * + * @var string + */ + private $brokerPassword; + /** * Constructs a \Drupal\system\ConfigFormBase object. * @@ -45,6 +54,7 @@ class IslandoraSettingsForm extends ConfigFormBase { public function __construct(ConfigFactoryInterface $config_factory, EntityTypeBundleInfoInterface $entity_type_bundle_info) { $this->setConfigFactory($config_factory); $this->entityTypeBundleInfo = $entity_type_bundle_info; + $this->brokerPassword = $this->config(self::CONFIG_NAME)->get(self::BROKER_PASSWORD); } /** @@ -79,17 +89,51 @@ class IslandoraSettingsForm extends ConfigFormBase { public function buildForm(array $form, FormStateInterface $form_state) { $config = $this->config(self::CONFIG_NAME); - $form[self::BROKER_URL] = [ + $form['broker_info'] = [ + '#type' => 'details', + '#title' => $this->t('Broker'), + '#open' => TRUE, + ]; + $form['broker_info'][self::BROKER_URL] = [ '#type' => 'textfield', - '#title' => $this->t('Broker URL'), + '#title' => $this->t('URL'), '#default_value' => $config->get(self::BROKER_URL), ]; - + $broker_user = $config->get(self::BROKER_USER); + $form['broker_info']['provide_user_creds'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Provide user identification'), + '#default_value' => $broker_user ? TRUE : FALSE, + ]; + $state_selector = 'input[name="provide_user_creds"]'; + $form['broker_info'][self::BROKER_USER] = [ + '#type' => 'textfield', + '#title' => $this->t('User'), + '#default_value' => $broker_user, + '#states' => [ + 'visible' => [ + $state_selector => ['checked' => TRUE], + ], + 'required' => [ + $state_selector => ['checked' => TRUE], + ], + ], + ]; + $form['broker_info'][self::BROKER_PASSWORD] = [ + '#type' => 'password', + '#title' => $this->t('Password'), + '#description' => $this->t('If this field is left blank and the user is filled out, the current password will not be changed.'), + '#states' => [ + 'visible' => [ + $state_selector => ['checked' => TRUE], + ], + ], + ]; $form[self::JWT_EXPIRY] = [ '#type' => 'textfield', '#title' => $this->t('JWT Expiry'), '#default_value' => $config->get(self::JWT_EXPIRY), - '#description' => 'Eg: 60, "2 days", "10h", "7d". A numeric value is interpreted as a seconds count. If you use a string be sure you provide the time units (days, hours, etc), otherwise milliseconds unit is used by default ("120" is equal to "120ms").', + '#description' => $this->t('Eg: 60, "2 days", "10h", "7d". A numeric value is interpreted as a seconds count. If you use a string be sure you provide the time units (days, hours, etc), otherwise milliseconds unit is used by default ("120" is equal to "120ms").'), ]; $form[self::GEMINI_URL] = [ @@ -142,14 +186,24 @@ class IslandoraSettingsForm extends ConfigFormBase { public function validateForm(array &$form, FormStateInterface $form_state) { // Validate broker url by actually connecting with a stomp client. $brokerUrl = $form_state->getValue(self::BROKER_URL); - // Attempt to subscribe to a dummy queue. try { - $stomp = new StatefulStomp( - new Client( - $brokerUrl - ) - ); + $client = new Client($brokerUrl); + if ($form_state->getValue('provide_user_creds')) { + $broker_password = $form_state->getValue(self::BROKER_PASSWORD); + // When stored password type fields aren't rendered again. + if (!$broker_password) { + // Use the stored password if it exists. + if (!$this->brokerPassword) { + $form_state->setErrorByName(self::BROKER_PASSWORD, $this->t('A password must be supplied')); + } + else { + $broker_password = $this->brokerPassword; + } + } + $client->setLogin($form_state->getValue(self::BROKER_USER), $broker_password); + } + $stomp = new StatefulStomp($client); $stomp->subscribe('dummy-queue-for-validation'); $stomp->unsubscribe(); } @@ -224,6 +278,22 @@ class IslandoraSettingsForm extends ConfigFormBase { $pseudo_types = array_filter($form_state->getValue(self::GEMINI_PSEUDO)); + $broker_password = $form_state->getValue(self::BROKER_PASSWORD); + + // If there's no user set delete what may have been here before as password + // fields will also be blank. + if (!$form_state->getValue('provide_user_creds')) { + $config->clear(self::BROKER_USER); + $config->clear(self::BROKER_PASSWORD); + } + else { + $config->set(self::BROKER_USER, $form_state->getValue(self::BROKER_USER)); + // If the password has changed update it as well. + if ($broker_password && $broker_password != $this->brokerPassword) { + $config->set(self::BROKER_PASSWORD, $broker_password); + } + } + $config ->set(self::BROKER_URL, $form_state->getValue(self::BROKER_URL)) ->set(self::JWT_EXPIRY, $form_state->getValue(self::JWT_EXPIRY)) diff --git a/src/StompFactory.php b/src/StompFactory.php index 0e3528c1..b63ca90b 100644 --- a/src/StompFactory.php +++ b/src/StompFactory.php @@ -25,13 +25,16 @@ class StompFactory { // Get broker url from config. $settings = $config->get(IslandoraSettingsForm::CONFIG_NAME); $brokerUrl = $settings->get(IslandoraSettingsForm::BROKER_URL); - + $brokerUser = $settings->get(IslandoraSettingsForm::BROKER_USER); // Try a sensible default if one hasn't been configured. if (empty($brokerUrl)) { $brokerUrl = "tcp://localhost:61613"; } $client = new Client($brokerUrl); + if ($brokerUser) { + $client->setLogin($brokerUser, $settings->get(IslandoraSettingsForm::BROKER_PASSWORD)); + } return new StatefulStomp($client); } From bbcd28ccb53e5c7cff856961aba8779bb3d426aa Mon Sep 17 00:00:00 2001 From: Jared Whiklo Date: Mon, 22 Jun 2020 13:20:13 -0500 Subject: [PATCH 15/23] Validate JWT expiry (#776) * Validate JWT expiry * Fixing bad merge conflict from Github UI * whitespace Co-authored-by: dannylamb --- src/Form/IslandoraSettingsForm.php | 39 ++++++++++++++++++- .../Functional/IslandoraSettingsFormTest.php | 26 +++++++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/Form/IslandoraSettingsForm.php b/src/Form/IslandoraSettingsForm.php index 4ee828d5..72ebf11d 100644 --- a/src/Form/IslandoraSettingsForm.php +++ b/src/Form/IslandoraSettingsForm.php @@ -28,6 +28,16 @@ class IslandoraSettingsForm extends ConfigFormBase { const GEMINI_URL = 'gemini_url'; const GEMINI_PSEUDO = 'gemini_pseudo_bundles'; const FEDORA_URL = 'fedora_url'; + const TIME_INTERVALS = [ + 'sec', + 'second', + 'min', + 'minute', + 'hour', + 'week', + 'month', + 'year', + ]; /** * To list the available bundle types. @@ -133,7 +143,9 @@ class IslandoraSettingsForm extends ConfigFormBase { '#type' => 'textfield', '#title' => $this->t('JWT Expiry'), '#default_value' => $config->get(self::JWT_EXPIRY), - '#description' => $this->t('Eg: 60, "2 days", "10h", "7d". A numeric value is interpreted as a seconds count. If you use a string be sure you provide the time units (days, hours, etc), otherwise milliseconds unit is used by default ("120" is equal to "120ms").'), + '#description' => $this->t('A positive time interval expression. Eg: "60 secs", "2 days", "10 hours", "7 weeks". Be sure you provide the time units (@unit), plurals are accepted.', + ['@unit' => implode(self::TIME_INTERVALS, ", ")] + ), ]; $form[self::GEMINI_URL] = [ @@ -219,7 +231,8 @@ class IslandoraSettingsForm extends ConfigFormBase { } // Validate jwt expiry as a valid time string. - $expiry = $form_state->getValue(self::JWT_EXPIRY); + $expiry = trim($form_state->getValue(self::JWT_EXPIRY)); + $expiry = strtolower($expiry); if (strtotime($expiry) === FALSE) { $form_state->setErrorByName( self::JWT_EXPIRY, @@ -229,6 +242,28 @@ class IslandoraSettingsForm extends ConfigFormBase { ) ); } + elseif (substr($expiry, 0, 1) == "-") { + $form_state->setErrorByName( + self::JWT_EXPIRY, + $this->t('Time or interval expression cannot be negative') + ); + } + elseif (intval($expiry) === 0) { + $form_state->setErrorByName( + self::JWT_EXPIRY, + $this->t('No numeric interval specified, for example "1 day"') + ); + } + else { + if (!preg_match("/\b(" . implode(self::TIME_INTERVALS, "|") . ")s?\b/", $expiry)) { + $form_state->setErrorByName( + self::JWT_EXPIRY, + $this->t("No time interval found, please include one of (@int). Plurals are also accepted.", + ['@int' => implode(self::TIME_INTERVALS, ", ")] + ) + ); + } + } // Needed for the elseif below. $pseudo_types = array_filter($form_state->getValue(self::GEMINI_PSEUDO)); diff --git a/tests/src/Functional/IslandoraSettingsFormTest.php b/tests/src/Functional/IslandoraSettingsFormTest.php index f33a10a9..2e724be4 100644 --- a/tests/src/Functional/IslandoraSettingsFormTest.php +++ b/tests/src/Functional/IslandoraSettingsFormTest.php @@ -58,4 +58,30 @@ class IslandoraSettingsFormTest extends IslandoraFunctionalTestBase { } + /** + * Test form validation for JWT expiry. + */ + public function testJwtExpiry() { + $this->drupalGet('/admin/config/islandora/core'); + $this->assertSession()->statusCodeEquals(200); + $this->assertSession()->pageTextContains("JWT Expiry"); + $this->assertSession()->fieldValueEquals('edit-jwt-expiry', '+2 hour'); + // Blank is not allowed. + $this->drupalPostForm('/admin/config/islandora/core', ['edit-jwt-expiry' => ""], t('Save configuration')); + $this->assertSession()->pageTextContainsOnce('"" is not a valid time or interval expression.'); + // Negative is not allowed. + $this->drupalPostForm('/admin/config/islandora/core', ['edit-jwt-expiry' => "-2 hours"], t('Save configuration')); + $this->assertSession()->pageTextContainsOnce('Time or interval expression cannot be negative'); + // Must include an integer value. + $this->drupalPostForm('/admin/config/islandora/core', ['edit-jwt-expiry' => "last hour"], t('Save configuration')); + $this->assertSession()->pageTextContainsOnce('No numeric interval specified, for example "1 day"'); + // Must have an accepted interval. + $this->drupalPostForm('/admin/config/islandora/core', ['edit-jwt-expiry' => "1 fortnight"], t('Save configuration')); + $this->assertSession()->pageTextContainsOnce('No time interval found, please include one of'); + // Test a valid setting. + $this->drupalPostForm('/admin/config/islandora/core', ['edit-jwt-expiry' => "2 weeks"], t('Save configuration')); + $this->assertSession()->pageTextContainsOnce('The configuration options have been saved.'); + + } + } From a51db93ec10f8bf670904e106bc9de0f8854939f Mon Sep 17 00:00:00 2001 From: J Hunt Date: Thu, 25 Jun 2020 06:34:55 +1200 Subject: [PATCH 16/23] #1534 Change config permission to 'administer site configuration' (#780) Co-authored-by: Jonathan Hunt --- modules/islandora_iiif/islandora_iiif.routing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/islandora_iiif/islandora_iiif.routing.yml b/modules/islandora_iiif/islandora_iiif.routing.yml index dd69c2e5..23173324 100644 --- a/modules/islandora_iiif/islandora_iiif.routing.yml +++ b/modules/islandora_iiif/islandora_iiif.routing.yml @@ -4,6 +4,6 @@ islandora_iiif.islandora_iiif_config_form: _form: '\Drupal\islandora_iiif\Form\IslandoraIIIFConfigForm' _title: 'IslandoraIIIFConfigForm' requirements: - _permission: 'access administration pages' + _permission: 'administer site configuration' options: _admin_route: TRUE From 2ce358484bdc4a949c9aaaca126632ff812f6efe Mon Sep 17 00:00:00 2001 From: J Hunt Date: Thu, 16 Jul 2020 14:14:32 +1200 Subject: [PATCH 17/23] #1544 Update Migrate Plus to 8.x-5.1, Migrate Tools to 8.x-5.0 (#784) Co-authored-by: Jonathan Hunt --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index e65eedbc..d07d07e6 100644 --- a/composer.json +++ b/composer.json @@ -23,8 +23,8 @@ "drupal/prepopulate" : "^2.2", "drupal/eva" : "^2.0", "drupal/features" : "^3.7", - "drupal/migrate_plus" : "^4.1", - "drupal/migrate_tools" : "^4.1", + "drupal/migrate_plus" : "^5.1", + "drupal/migrate_tools" : "^5.0", "drupal/migrate_source_csv" : "^2.1", "drupal/token" : "^1.3", "drupal/flysystem" : "^1.0", From 75ae02b65af80c455e31dbaefc7a975e5b956745 Mon Sep 17 00:00:00 2001 From: J Hunt Date: Thu, 23 Jul 2020 07:17:12 +1200 Subject: [PATCH 18/23] #1560 Update JWT to 8.x-1.0-beta5 (#785) Co-authored-by: Jonathan Hunt --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index d07d07e6..c107fc22 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "drupal/search_api": "~1.8", "islandora/jsonld": "dev-8.x-1.x", "stomp-php/stomp-php": "4.*", - "drupal/jwt": "^1.0.0-beta3", + "drupal/jwt": "^1.0.0-beta5", "drupal/filehash": "^1.1", "drupal/prepopulate" : "^2.2", "drupal/eva" : "^2.0", From bfab343d32c3d4e00a7d9e5d205e99c073b38a7b Mon Sep 17 00:00:00 2001 From: Seth Shaw Date: Wed, 22 Jul 2020 12:25:46 -0700 Subject: [PATCH 19/23] verify entity before walking breadcrumb (#786) --- .../islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php b/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php index c58e7006..86090ff1 100644 --- a/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php +++ b/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php @@ -107,7 +107,8 @@ class IslandoraBreadcrumbBuilder implements BreadcrumbBuilderInterface { // 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'))->isEmpty() && + $entity->get($this->config->get('referenceField'))->entity instanceof EntityInterface) { $this->walkMembership($entity->get($this->config->get('referenceField'))->entity, $crumbs); } } From 22134df96f41cefb89eef71315637f74e7a6e7c5 Mon Sep 17 00:00:00 2001 From: dannylamb Date: Thu, 23 Jul 2020 11:43:49 -0300 Subject: [PATCH 20/23] Handling case where IIIF manifest generation fails if cantaloupe is down --- .../src/Plugin/views/style/IIIFManifest.php | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php index 0e33199b..51b51c7f 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -12,6 +12,7 @@ use Drupal\Core\Config\ImmutableConfig; use Drupal\Core\File\FileSystem; use GuzzleHttp\Client; use GuzzleHttp\Exception\ClientException; +use GuzzleHttp\Exception\ConnectException; use GuzzleHttp\Exception\ServerException; /** @@ -183,6 +184,7 @@ class IIIFManifest extends StylePluginBase { $canvas_id = $iiif_base_id . '/canvas/' . $entity->id(); $annotation_id = $iiif_base_id . '/annotation/' . $entity->id(); + dsm("BEFORE REQUEST"); // Try to fetch the IIIF metadata for the image. try { $info_json = $this->httpClient->get($iiif_url)->getBody(); @@ -190,28 +192,25 @@ class IIIFManifest extends StylePluginBase { $width = $resource['width']; $height = $resource['height']; } - catch (ClientException $e) { - } - catch (ServerException $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]; + 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]; + } } } } From 8ff6112045c363a4258382846cdae1349bd03752 Mon Sep 17 00:00:00 2001 From: dannylamb Date: Thu, 23 Jul 2020 11:59:42 -0300 Subject: [PATCH 21/23] coding standards and removing dsm --- modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php | 1 - 1 file changed, 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 51b51c7f..94b8f6e3 100644 --- a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -184,7 +184,6 @@ class IIIFManifest extends StylePluginBase { $canvas_id = $iiif_base_id . '/canvas/' . $entity->id(); $annotation_id = $iiif_base_id . '/annotation/' . $entity->id(); - dsm("BEFORE REQUEST"); // Try to fetch the IIIF metadata for the image. try { $info_json = $this->httpClient->get($iiif_url)->getBody(); From 0097808bddf2de94c772f7ca94c32bf373ebc730 Mon Sep 17 00:00:00 2001 From: dannylamb Date: Mon, 27 Jul 2020 15:16:27 -0300 Subject: [PATCH 22/23] Removing isladora_version_count table (#788) --- islandora.install | 47 +++++++++++------------------------------------ 1 file changed, 11 insertions(+), 36 deletions(-) diff --git a/islandora.install b/islandora.install index 011ecb19..98552efa 100644 --- a/islandora.install +++ b/islandora.install @@ -5,42 +5,6 @@ * Install/update hook implementations. */ -/** - * Implements hook_schema(). - */ -function islandora_schema() { - $schema = []; - $schema['islandora_version_count'] = [ - 'description' => 'Keeps track of the number of changes to an entity', - 'fields' => [ - 'id' => [ - 'description' => 'Autoincrementing id for record', - 'type' => 'serial', - 'unsigned' => TRUE, - 'not null' => TRUE, - ], - 'uuid' => [ - 'description' => 'UUID for an entity', - 'type' => 'varchar', - 'length' => 128, - 'not null' => TRUE, - 'unique' => TRUE, - ], - 'count' => [ - 'description' => 'Number of times an entity has been updated.', - 'type' => 'int', - 'unsigned' => TRUE, - 'default' => 0, - ], - ], - 'primary key' => ['id'], - 'unique keys' => [ - 'uuid' => ['uuid'], - ], - ]; - return $schema; -} - /** * Delete the 'delete_media' action we used to provide, if it exists. * @@ -80,3 +44,14 @@ function islandora_update_8002(&$sandbox) { // Force drupal to reload the config. \Drupal::service('plugin.manager.condition')->clearCachedDefinitions(); } + +/** + * Deletes the islandora_version_count table. + * + * We never implemented the functionality. + */ +function islandora_update_8003(&$sandbox) { + \Drupal::service('database') + ->schema() + ->dropTable('islandora_version_count'); +} From bfa2c39f1ff7877cd388a9c478d2a989e9cefa3a Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 29 Jul 2020 17:17:30 -0300 Subject: [PATCH 23/23] Skip link headers for non-canonicalizable entities (#781) * Update means of generating LinkHeader URL. ... allow for catching exceptions for entities without canonical URLs. * Coding standards... ... also, throw in the other throws declaration. * Adjust language. * Fix a stray capital... --- src/EventSubscriber/LinkHeaderSubscriber.php | 10 +++++++++- src/IslandoraUtils.php | 14 ++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/EventSubscriber/LinkHeaderSubscriber.php b/src/EventSubscriber/LinkHeaderSubscriber.php index efb0e638..a25b506c 100644 --- a/src/EventSubscriber/LinkHeaderSubscriber.php +++ b/src/EventSubscriber/LinkHeaderSubscriber.php @@ -9,6 +9,7 @@ use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Session\AccountInterface; use Drupal\islandora\IslandoraUtils; +use Drupal\Core\Entity\Exception\UndefinedLinkTemplateException; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; @@ -205,7 +206,14 @@ abstract class LinkHeaderSubscriber implements EventSubscriberInterface { // Headers are subject to an access check. if ($referencedEntity->access('view')) { - $entity_url = $this->utils->getEntityUrl($referencedEntity); + try { + $entity_url = $this->utils->getEntityUrl($referencedEntity); + } + catch (UndefinedLinkTemplateException $e) { + // Not all referencable entities can generate canonical URLs, for + // example: block entities. + continue; + } // Taxonomy terms are written out as // ; rel="tag"; title="Tag Name" diff --git a/src/IslandoraUtils.php b/src/IslandoraUtils.php index 1d337796..56422515 100644 --- a/src/IslandoraUtils.php +++ b/src/IslandoraUtils.php @@ -563,15 +563,17 @@ class IslandoraUtils { * * @return string * The entity URL. + * + * @throws \Drupal\Core\Entity\Exception\UndefinedLinkTemplateException + * Thrown if the given entity does not specify a "canonical" template. + * @throws \Drupal\Core\Entity\EntityMalformedException */ public function getEntityUrl(EntityInterface $entity) { $undefined = $this->languageManager->getLanguage('und'); - $entity_type = $entity->getEntityTypeId(); - return Url::fromRoute( - "entity.$entity_type.canonical", - [$entity_type => $entity->id()], - ['absolute' => TRUE, 'language' => $undefined] - )->toString(); + return $entity->toUrl('canonical', [ + 'absolute' => TRUE, + 'language' => $undefined, + ])->toString(); } /**