Browse Source

Merge branch '8.x-1.x' into media_multifile

pull/756/head
Alan Stanley 5 years ago
parent
commit
ab9daf04da
  1. 8
      .travis.yml
  2. 11
      composer.json
  3. 75
      islandora.install
  4. 1
      islandora.module
  5. 7
      modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php
  6. 14
      modules/islandora_breadcrumbs/tests/src/Functional/BreadcrumbsTest.php
  7. 25
      modules/islandora_core_feature/config/install/field.storage.media.field_media_document.yml
  8. 2
      modules/islandora_iiif/islandora_iiif.routing.yml
  9. 42
      modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php
  10. 22
      modules/islandora_text_extraction/islandora_text_extraction.module
  11. 8
      modules/islandora_text_extraction/islandora_text_extraction.services.yml
  12. 65
      modules/islandora_text_extraction/src/SearchReindexer.php
  13. 2
      modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_mime_type.yml
  14. 51
      modules/islandora_text_extraction_defaults/config/install/rdf.mapping.media.extracted_text.yml
  15. 6
      src/ContextReaction/DisplayAlterReaction.php
  16. 8
      src/Controller/ManageMembersController.php
  17. 8
      src/EventGenerator/EmitEvent.php
  18. 26
      src/EventSubscriber/LinkHeaderSubscriber.php
  19. 31
      src/Flysystem/Fedora.php
  20. 135
      src/Form/IslandoraSettingsForm.php
  21. 2
      src/GeminiLookup.php
  22. 30
      src/IslandoraUtils.php
  23. 16
      src/MediaSource/MediaSourceService.php
  24. 16
      src/Plugin/Action/AbstractGenerateDerivative.php
  25. 14
      src/Plugin/Action/EmitFileEvent.php
  26. 6
      src/Plugin/Action/EmitMediaEvent.php
  27. 2
      src/Plugin/Condition/ContentEntityType.php
  28. 10
      src/Plugin/Condition/EntityBundle.php
  29. 10
      src/Plugin/Condition/FileUsesFilesystem.php
  30. 10
      src/Plugin/Condition/MediaHasMimetype.php
  31. 2
      src/Plugin/Condition/MediaHasTerm.php
  32. 8
      src/Plugin/Condition/MediaUsesFilesystem.php
  33. 14
      src/Plugin/Condition/NodeHadNamespace.php
  34. 13
      src/Plugin/Condition/NodeHasParent.php
  35. 10
      src/Plugin/Condition/NodeHasTerm.php
  36. 19
      src/Plugin/Condition/NodeIsPublished.php
  37. 2
      src/Plugin/Condition/ParentNodeHasTerm.php
  38. 3
      src/Plugin/ContextReaction/JsonldTypeAlterReaction.php
  39. 5
      src/StompFactory.php
  40. 6
      tests/src/Functional/EntityBundleTest.php
  41. 26
      tests/src/Functional/IslandoraSettingsFormTest.php
  42. 2
      tests/src/Functional/JsonldSelfReferenceReactionTest.php
  43. 6
      tests/src/Functional/JsonldTypeAlterReactionTest.php

8
.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

11
composer.json

@ -18,13 +18,13 @@
"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-beta5",
"drupal/filehash": "^1.1",
"drupal/prepopulate" : "^2.2",
"drupal/eva" : "^1.3",
"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",
@ -36,6 +36,9 @@
"drupal/coder": "*",
"sebastian/phpcpd": "*"
},
"suggest": {
"drupal/transliterate_filenames": "Sanitizes filenames when they are uploaded so they don't break your repository."
},
"license": "GPL-2.0+",
"authors": [
{

75
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.
*
@ -52,3 +16,42 @@ 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();
}
/**
* Deletes the islandora_version_count table.
*
* We never implemented the functionality.
*/
function islandora_update_8003(&$sandbox) {
\Drupal::service('database')
->schema()
->dropTable('islandora_version_count');
}

1
islandora.module

@ -51,6 +51,7 @@ function islandora_rdf_namespaces() {
return [
'ldp' => 'http://www.w3.org/ns/ldp#',
'dc11' => 'http://purl.org/dc/elements/1.1/',
'dcterms' => 'http://purl.org/dc/terms/',
'nfo' => 'http://www.semanticdesktop.org/ontologies/2007/03/22/nfo/v1.1/',
'ebucore' => 'http://www.ebu.ch/metadata/ontologies/ebucore/ebucore#',
'fedora' => 'http://fedora.info/definitions/v4/repository#',

7
modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php

@ -7,12 +7,15 @@ 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;
/**
* Provides breadcrumbs for nodes using a configured entity reference field.
*/
class IslandoraBreadcrumbBuilder implements BreadcrumbBuilderInterface {
use StringTranslationTrait;
/**
* The configuration.
@ -63,6 +66,7 @@ class IslandoraBreadcrumbBuilder implements BreadcrumbBuilderInterface {
$nid = $route_match->getRawParameters()->get('node');
$node = $this->nodeStorage->load($nid);
$breadcrumb = new Breadcrumb();
$breadcrumb->addLink(Link::createFromRoute($this->t('Home'), '<front>'));
$chain = [];
$this->walkMembership($node, $chain);
@ -103,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);
}
}

14
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('<front>')->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);

25
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

2
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

42
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;
/**
@ -190,28 +191,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];
}
}
}
}

22
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().
*/

8
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']

65
modules/islandora_text_extraction/src/SearchReindexer.php

@ -0,0 +1,65 @@
<?php
namespace Drupal\islandora_text_extraction;
use Drupal\islandora\IslandoraUtils;
use Drupal\media\MediaInterface;
use Psr\Log\LoggerInterface;
/**
* Creates a GeminiClient as a Drupal service.
*
* @package Drupal\islandora
*/
class SearchReindexer {
/**
* Islandora Utils.
*
* @var \Drupal\islandora\IslandoraUtils
*/
protected $utils;
/**
* Logger.
*
* @var \Psr\Log\LoggerInterface
*/
protected $logger;
/**
* Constructor.
*
* @param \Drupal\islandora\IslandoraUtils $utils
* Islandora utils.
* @param \Psr\Log\LoggerInterface $logger
* The logger channel.
*/
public function __construct(IslandoraUtils $utils, LoggerInterface $logger) {
$this->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);
}
}

2
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

51
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'

6
src/ContextReaction/DisplayAlterReaction.php

@ -2,7 +2,7 @@
namespace Drupal\islandora\ContextReaction;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\context\ContextReactionPluginBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
@ -18,14 +18,14 @@ abstract class DisplayAlterReaction extends ContextReactionPluginBase implements
/**
* View mode storage.
*
* @var \Drupal\Core\Entity\EntityTypeManager
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManager $entity_type_manager) {
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->entityTypeManager = $entity_type_manager;
}

8
src/Controller/ManageMembersController.php

@ -5,7 +5,7 @@ namespace Drupal\islandora\Controller;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Entity\Controller\EntityController;
use Drupal\Core\Entity\EntityFieldManager;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Link;
use Drupal\node\NodeInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
@ -25,7 +25,7 @@ class ManageMembersController extends EntityController {
/**
* The entity field manager.
*
* @var \Drupal\Core\Entity\EntityFieldManager
* @var \Drupal\Core\Entity\EntityFieldManagerInterface
*/
protected $entityFieldManger;
@ -41,14 +41,14 @@ class ManageMembersController extends EntityController {
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\Entity\EntityFieldManager $entity_field_manager
* @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
* The entity field manager.
* @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer.
*/
public function __construct(
EntityTypeManagerInterface $entity_type_manager,
EntityFieldManager $entity_field_manager,
EntityFieldManagerInterface $entity_field_manager,
RendererInterface $renderer
) {
$this->entityTypeManager = $entity_type_manager;

8
src/EventGenerator/EmitEvent.php

@ -5,7 +5,7 @@ namespace Drupal\islandora\EventGenerator;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Action\ConfigurableActionBase;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
@ -30,7 +30,7 @@ abstract class EmitEvent extends ConfigurableActionBase implements ContainerFact
/**
* Entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManager
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
@ -66,7 +66,7 @@ abstract class EmitEvent extends ConfigurableActionBase implements ContainerFact
* The plugin implementation definition.
* @param \Drupal\Core\Session\AccountInterface $account
* Current user.
* @param \Drupal\Core\Entity\EntityTypeManager $entity_type_manager
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* Entity type manager.
* @param \Drupal\islandora\EventGenerator\EventGeneratorInterface $event_generator
* EventGenerator service to serialize AS2 events.
@ -80,7 +80,7 @@ abstract class EmitEvent extends ConfigurableActionBase implements ContainerFact
$plugin_id,
$plugin_definition,
AccountInterface $account,
EntityTypeManager $entity_type_manager,
EntityTypeManagerInterface $entity_type_manager,
EventGeneratorInterface $event_generator,
StatefulStomp $stomp,
JwtAuth $auth

26
src/EventSubscriber/LinkHeaderSubscriber.php

@ -3,12 +3,13 @@
namespace Drupal\islandora\EventSubscriber;
use Drupal\Core\Access\AccessManagerInterface;
use Drupal\Core\Entity\EntityFieldManager;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManager;
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;
@ -25,14 +26,14 @@ abstract class LinkHeaderSubscriber implements EventSubscriberInterface {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManager
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The entity field manager.
*
* @var \Drupal\Core\Entity\EntityFieldManager
* @var \Drupal\Core\Entity\EntityFieldManagerInterface
*/
protected $entityFieldManager;
@ -74,9 +75,9 @@ abstract class LinkHeaderSubscriber implements EventSubscriberInterface {
/**
* Constructor.
*
* @param \Drupal\Core\Entity\EntityTypeManager $entity_type_manager
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\Entity\EntityFieldManager $entity_field_manager
* @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
* The entity field manager.
* @param \Drupal\Core\Access\AccessManagerInterface $access_manager
* The access manager.
@ -90,8 +91,8 @@ abstract class LinkHeaderSubscriber implements EventSubscriberInterface {
* Islandora utils.
*/
public function __construct(
EntityTypeManager $entity_type_manager,
EntityFieldManager $entity_field_manager,
EntityTypeManagerInterface $entity_type_manager,
EntityFieldManagerInterface $entity_field_manager,
AccessManagerInterface $access_manager,
AccountInterface $account,
RouteMatchInterface $route_match,
@ -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
// <url>; rel="tag"; title="Tag Name"

31
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 [];
}

135
src/Form/IslandoraSettingsForm.php

@ -3,7 +3,7 @@
namespace Drupal\islandora\Form;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeBundleInfo;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Site\Settings;
@ -22,29 +22,49 @@ 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';
const FEDORA_URL = 'fedora_url';
const TIME_INTERVALS = [
'sec',
'second',
'min',
'minute',
'hour',
'week',
'month',
'year',
];
/**
* To list the available bundle types.
*
* @var \Drupal\Core\Entity\EntityTypeBundleInfo
* @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
*/
private $entityTypeBundleInfo;
/**
* The saved password (if set).
*
* @var string
*/
private $brokerPassword;
/**
* Constructs a \Drupal\system\ConfigFormBase object.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The factory for configuration objects.
* @param \Drupal\Core\Entity\EntityTypeBundleInfo $entity_type_bundle_info
* @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
* The EntityTypeBundleInfo service.
*/
public function __construct(ConfigFactoryInterface $config_factory, EntityTypeBundleInfo $entity_type_bundle_info) {
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 +99,53 @@ 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('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] = [
@ -142,14 +198,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();
}
@ -165,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,
@ -175,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));
@ -224,6 +313,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))

2
src/GeminiLookup.php

@ -144,7 +144,7 @@ class GeminiLookup {
}
}
catch (RequestException $e) {
$this->logger->warn(
$this->logger->warning(
"Error performing Gemini lookup for media. Fedora HEAD to @url returned @status => @message",
[
'@url' => $urls['fedora'],

30
src/IslandoraUtils.php

@ -5,8 +5,8 @@ namespace Drupal\islandora;
use Drupal\context\ContextManager;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityFieldManager;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\Query\QueryException;
use Drupal\Core\Entity\Query\QueryFactory;
use Drupal\Core\Entity\Query\QueryInterface;
@ -35,14 +35,14 @@ class IslandoraUtils {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManager
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The entity field manager.
*
* @var \Drupal\Core\Entity\EntityFieldManager
* @var \Drupal\Core\Entity\EntityFieldManagerInterface
*/
protected $entityFieldManager;
@ -77,9 +77,9 @@ class IslandoraUtils {
/**
* Constructor.
*
* @param \Drupal\Core\Entity\EntityTypeManager $entity_type_manager
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\Entity\EntityFieldManager $entity_field_manager
* @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
* The entity field manager.
* @param \Drupal\Core\Entity\Query\QueryFactory $entity_query
* Entity query.
@ -91,8 +91,8 @@ class IslandoraUtils {
* Language manager.
*/
public function __construct(
EntityTypeManager $entity_type_manager,
EntityFieldManager $entity_field_manager,
EntityTypeManagerInterface $entity_type_manager,
EntityFieldManagerInterface $entity_field_manager,
QueryFactory $entity_query,
ContextManager $context_manager,
FlysystemFactory $flysystem_factory,
@ -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();
}
/**

16
src/MediaSource/MediaSourceService.php

@ -2,9 +2,9 @@
namespace Drupal\islandora\MediaSource;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\Query\QueryFactory;
use Drupal\Core\File\FileSystem;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\file\FileInterface;
@ -25,7 +25,7 @@ class MediaSourceService {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManager
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
@ -53,7 +53,7 @@ class MediaSourceService {
/**
* File system service.
*
* @var \Drupal\Core\File\FileSystem
* @var \Drupal\Core\File\FileSystemInterface
*/
protected $fileSystem;
@ -67,7 +67,7 @@ class MediaSourceService {
/**
* Constructor.
*
* @param \Drupal\Core\Entity\EntityTypeManager $entity_type_manager
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\Session\AccountInterface $account
* The current user.
@ -75,17 +75,17 @@ class MediaSourceService {
* Language manager.
* @param \Drupal\Core\Entity\Query\QueryFactory $entity_query
* Entity query.
* @param \Drupal\Core\File\FileSystem $file_system
* @param \Drupal\Core\File\FileSystemInterface $file_system
* File system service.
* @param \Drupal\islandora\IslandoraUtils $islandora_utils
* Utility service.
*/
public function __construct(
EntityTypeManager $entity_type_manager,
EntityTypeManagerInterface $entity_type_manager,
AccountInterface $account,
LanguageManagerInterface $language_manager,
QueryFactory $entity_query,
FileSystem $file_system,
FileSystemInterface $file_system,
IslandoraUtils $islandora_utils
) {
$this->entityTypeManager = $entity_type_manager;

16
src/Plugin/Action/AbstractGenerateDerivative.php

@ -3,7 +3,7 @@
namespace Drupal\islandora\Plugin\Action;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
@ -12,7 +12,7 @@ use Drupal\islandora\EventGenerator\EmitEvent;
use Drupal\islandora\EventGenerator\EventGeneratorInterface;
use Drupal\islandora\MediaSource\MediaSourceService;
use Drupal\jwt\Authentication\Provider\JwtAuth;
use Drupal\token\Token;
use Drupal\token\TokenInterface;
use Stomp\StatefulStomp;
use Symfony\Component\DependencyInjection\ContainerInterface;
@ -38,7 +38,7 @@ class AbstractGenerateDerivative extends EmitEvent {
/**
* Token replacement service.
*
* @var \Drupal\token\Token
* @var \Drupal\token\TokenInterface
*/
protected $token;
@ -53,7 +53,7 @@ class AbstractGenerateDerivative extends EmitEvent {
* The plugin implementation definition.
* @param \Drupal\Core\Session\AccountInterface $account
* Current user.
* @param \Drupal\Core\Entity\EntityTypeManager $entity_type_manager
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* Entity type manager.
* @param \Drupal\islandora\EventGenerator\EventGeneratorInterface $event_generator
* EventGenerator service to serialize AS2 events.
@ -65,7 +65,7 @@ class AbstractGenerateDerivative extends EmitEvent {
* Islandora utility functions.
* @param \Drupal\islandora\MediaSource\MediaSourceService $media_source
* Media source service.
* @param \Drupal\token\Token $token
* @param \Drupal\token\TokenInterface $token
* Token service.
*/
public function __construct(
@ -73,13 +73,13 @@ class AbstractGenerateDerivative extends EmitEvent {
$plugin_id,
$plugin_definition,
AccountInterface $account,
EntityTypeManager $entity_type_manager,
EntityTypeManagerInterface $entity_type_manager,
EventGeneratorInterface $event_generator,
StatefulStomp $stomp,
JwtAuth $auth,
IslandoraUtils $utils,
MediaSourceService $media_source,
Token $token
TokenInterface $token
) {
parent::__construct(
$configuration,
@ -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);
}

14
src/Plugin/Action/EmitFileEvent.php

@ -3,8 +3,8 @@
namespace Drupal\islandora\Plugin\Action;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\File\FileSystem;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Site\Settings;
use Drupal\jwt\Authentication\Provider\JwtAuth;
@ -27,7 +27,7 @@ class EmitFileEvent extends EmitEvent {
/**
* File system service.
*
* @var \Drupal\Core\File\FileSystem
* @var \Drupal\Core\File\FileSystemInterface
*/
protected $fileSystem;
@ -42,7 +42,7 @@ class EmitFileEvent extends EmitEvent {
* The plugin implementation definition.
* @param \Drupal\Core\Session\AccountInterface $account
* Current user.
* @param \Drupal\Core\Entity\EntityTypeManager $entity_type_manager
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* Entity type manager.
* @param \Drupal\islandora\EventGenerator\EventGeneratorInterface $event_generator
* EventGenerator service to serialize AS2 events.
@ -50,7 +50,7 @@ class EmitFileEvent extends EmitEvent {
* Stomp client.
* @param \Drupal\jwt\Authentication\Provider\JwtAuth $auth
* JWT Auth client.
* @param \Drupal\Core\File\FileSystem $file_system
* @param \Drupal\Core\File\FileSystemInterface $file_system
* File system service.
*/
public function __construct(
@ -58,11 +58,11 @@ class EmitFileEvent extends EmitEvent {
$plugin_id,
$plugin_definition,
AccountInterface $account,
EntityTypeManager $entity_type_manager,
EntityTypeManagerInterface $entity_type_manager,
EventGeneratorInterface $event_generator,
StatefulStomp $stomp,
JwtAuth $auth,
FileSystem $file_system
FileSystemInterface $file_system
) {
parent::__construct(
$configuration,

6
src/Plugin/Action/EmitMediaEvent.php

@ -3,7 +3,7 @@
namespace Drupal\islandora\Plugin\Action;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\jwt\Authentication\Provider\JwtAuth;
use Drupal\islandora\EventGenerator\EmitEvent;
@ -41,7 +41,7 @@ class EmitMediaEvent extends EmitEvent {
* The plugin implementation definition.
* @param \Drupal\Core\Session\AccountInterface $account
* Current user.
* @param \Drupal\Core\Entity\EntityTypeManager $entity_type_manager
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* Entity type manager.
* @param \Drupal\islandora\EventGenerator\EventGeneratorInterface $event_generator
* EventGenerator service to serialize AS2 events.
@ -57,7 +57,7 @@ class EmitMediaEvent extends EmitEvent {
$plugin_id,
$plugin_definition,
AccountInterface $account,
EntityTypeManager $entity_type_manager,
EntityTypeManagerInterface $entity_type_manager,
EventGeneratorInterface $event_generator,
StatefulStomp $stomp,
JwtAuth $auth,

2
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")),

10
src/Plugin/Condition/EntityBundle.php

@ -8,10 +8,12 @@ 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 = {
* 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"))
@ -61,11 +63,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;
}
/**

10
src/Plugin/Condition/FileUsesFilesystem.php

@ -3,7 +3,7 @@
namespace Drupal\islandora\Plugin\Condition;
use Drupal\Core\Condition\ConditionPluginBase;
use Drupal\Core\File\FileSystem;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\file\FileInterface;
@ -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"))
* }
* )
@ -33,7 +33,7 @@ class FileUsesFilesystem extends ConditionPluginBase implements ContainerFactory
/**
* File system service.
*
* @var \Drupal\Core\File\FileSystem
* @var \Drupal\Core\File\FileSystemInterface
*/
protected $fileSystem;
@ -51,7 +51,7 @@ class FileUsesFilesystem extends ConditionPluginBase implements ContainerFactory
* The plugin implementation definition.
* @param \Drupal\islandora\IslandoraUtils $utils
* Islandora utility functions.
* @param \Drupal\Core\File\FileSystem $file_system
* @param \Drupal\Core\File\FileSystemInterface $file_system
* File system service.
*/
public function __construct(
@ -59,7 +59,7 @@ class FileUsesFilesystem extends ConditionPluginBase implements ContainerFactory
$plugin_id,
$plugin_definition,
IslandoraUtils $utils,
FileSystem $file_system
FileSystemInterface $file_system
) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->utils = $utils;

10
src/Plugin/Condition/MediaHasMimetype.php

@ -3,7 +3,7 @@
namespace Drupal\islandora\Plugin\Condition;
use Drupal\Core\Condition\ConditionPluginBase;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\islandora\IslandoraUtils;
@ -37,7 +37,7 @@ class MediaHasMimetype extends ConditionPluginBase implements ContainerFactoryPl
/**
* Term storage.
*
* @var \Drupal\Core\Entity\EntityTypeManager
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
@ -62,7 +62,7 @@ class MediaHasMimetype extends ConditionPluginBase implements ContainerFactoryPl
* The plugin implementation definition.
* @param \Drupal\islandora\IslandoraUtils $utils
* Islandora utility functions.
* @param \Drupal\Core\Entity\EntityTypeManager $entity_type_manager
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* Entity type manager.
* @param \Drupal\islandora\MediaSource\MediaSourceService $media_source
* Media source service.
@ -72,7 +72,7 @@ class MediaHasMimetype extends ConditionPluginBase implements ContainerFactoryPl
$plugin_id,
$plugin_definition,
IslandoraUtils $utils,
EntityTypeManager $entity_type_manager,
EntityTypeManagerInterface $entity_type_manager,
MediaSourceService $media_source
) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $utils);
@ -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;
}
}
}

2
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"))
* }
* )

8
src/Plugin/Condition/MediaUsesFilesystem.php

@ -2,7 +2,7 @@
namespace Drupal\islandora\Plugin\Condition;
use Drupal\Core\File\FileSystem;
use Drupal\Core\File\FileSystemInterface;
use Drupal\islandora\MediaSource\MediaSourceService;
use Drupal\islandora\IslandoraUtils;
use Symfony\Component\DependencyInjection\ContainerInterface;
@ -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"))
* }
* )
@ -41,7 +41,7 @@ class MediaUsesFilesystem extends FileUsesFilesystem {
* The plugin implementation definition.
* @param \Drupal\islandora\IslandoraUtils $utils
* Islandora utility functions.
* @param \Drupal\Core\File\FileSystem $file_system
* @param \Drupal\Core\File\FileSystemInterface $file_system
* File system service.
* @param \Drupal\islandora\MediaSource\MediaSourceService $media_source
* Media source service.
@ -51,7 +51,7 @@ class MediaUsesFilesystem extends FileUsesFilesystem {
$plugin_id,
$plugin_definition,
IslandoraUtils $utils,
FileSystem $file_system,
FileSystemInterface $file_system,
MediaSourceService $media_source
) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $utils, $file_system);

14
src/Plugin/Condition/NodeHadNamespace.php

@ -4,7 +4,7 @@ namespace Drupal\islandora\Plugin\Condition;
use Drupal\Core\Condition\ConditionPluginBase;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\islandora\IslandoraUtils;
@ -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"))
* }
* )
@ -33,7 +33,7 @@ class NodeHadNamespace extends ConditionPluginBase implements ContainerFactoryPl
/**
* Term storage.
*
* @var \Drupal\Core\Entity\EntityTypeManager
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
@ -51,7 +51,7 @@ class NodeHadNamespace extends ConditionPluginBase implements ContainerFactoryPl
* The plugin implementation definition.
* @param \Drupal\islandora\IslandoraUtils $utils
* Islandora utils.
* @param \Drupal\Core\Entity\EntityTypeManager $entity_type_manager
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* Entity type manager.
*/
public function __construct(
@ -59,7 +59,7 @@ class NodeHadNamespace extends ConditionPluginBase implements ContainerFactoryPl
$plugin_id,
$plugin_definition,
IslandoraUtils $utils,
EntityTypeManager $entity_type_manager
EntityTypeManagerInterface $entity_type_manager
) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->utils = $utils;
@ -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;
}
/**

13
src/Plugin/Condition/NodeHasParent.php

@ -4,7 +4,7 @@ namespace Drupal\islandora\Plugin\Condition;
use Drupal\Core\Condition\ConditionPluginBase;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
@ -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"))
* }
* )
@ -25,7 +25,7 @@ class NodeHasParent extends ConditionPluginBase implements ContainerFactoryPlugi
/**
* Node storage.
*
* @var \Drupal\Core\Entity\EntityTypeManager
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
@ -41,14 +41,14 @@ class NodeHasParent extends ConditionPluginBase implements ContainerFactoryPlugi
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Entity\EntityTypeManager $entity_type_manager
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* Entity type manager.
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
EntityTypeManager $entity_type_manager
EntityTypeManagerInterface $entity_type_manager
) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->entityTypeManager = $entity_type_manager;
@ -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;
}
/**

10
src/Plugin/Condition/NodeHasTerm.php

@ -4,7 +4,7 @@ namespace Drupal\islandora\Plugin\Condition;
use Drupal\Core\Condition\ConditionPluginBase;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\islandora\IslandoraUtils;
@ -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"))
* }
* )
@ -33,7 +33,7 @@ class NodeHasTerm extends ConditionPluginBase implements ContainerFactoryPluginI
/**
* Term storage.
*
* @var \Drupal\Core\Entity\EntityTypeManager
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
@ -51,7 +51,7 @@ class NodeHasTerm extends ConditionPluginBase implements ContainerFactoryPluginI
* The plugin implementation definition.
* @param \Drupal\islandora\IslandoraUtils $utils
* Islandora utils.
* @param \Drupal\Core\Entity\EntityTypeManager $entity_type_manager
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* Entity type manager.
*/
public function __construct(
@ -59,7 +59,7 @@ class NodeHasTerm extends ConditionPluginBase implements ContainerFactoryPluginI
$plugin_id,
$plugin_definition,
IslandoraUtils $utils,
EntityTypeManager $entity_type_manager
EntityTypeManagerInterface $entity_type_manager
) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->utils = $utils;

19
src/Plugin/Condition/NodeIsPublished.php

@ -3,7 +3,7 @@
namespace Drupal\islandora\Plugin\Condition;
use Drupal\Core\Condition\ConditionPluginBase;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
@ -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"))
* }
* )
@ -23,7 +23,7 @@ class NodeIsPublished extends ConditionPluginBase implements ContainerFactoryPlu
/**
* Term storage.
*
* @var \Drupal\Core\Entity\EntityTypeManager
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
@ -39,14 +39,14 @@ class NodeIsPublished extends ConditionPluginBase implements ContainerFactoryPlu
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Entity\EntityTypeManager $entity_type_manager
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* Entity type manager.
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
EntityTypeManager $entity_type_manager
EntityTypeManagerInterface $entity_type_manager
) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->entityTypeManager = $entity_type_manager;
@ -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;
}
/**

2
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"))
* }
* )

3
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,

5
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);
}

6
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');

26
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.');
}
}

2
tests/src/Functional/JsonldSelfReferenceReactionTest.php

@ -28,7 +28,7 @@ class JsonldSelfReferenceReactionTest extends IslandoraFunctionalTestBase {
->setBundleMapping(['types' => $types])
->setFieldMapping('created', $created_mapping)
->setFieldMapping('title', [
'properties' => ['dc:title'],
'properties' => ['dcterms:title'],
'datatype' => 'xsd:string',
])
->save();

6
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.

Loading…
Cancel
Save