Browse Source

Merge branch '8.x-1.x' into issue-1291

pull/730/head
Alan Stanley 5 years ago committed by GitHub
parent
commit
be64b05c07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .github/PULL_REQUEST_TEMPLATE.md
  2. 35
      .travis.yml
  3. 16
      CONTRIBUTING.md
  4. 15
      COPYRIGHT
  5. 299
      README.md
  6. 21
      composer.json
  7. 9
      config/schema/islandora.schema.yml
  8. 75
      islandora.install
  9. 37
      islandora.module
  10. 73
      modules/islandora_audio/CONTRIBUTING.md
  11. 36
      modules/islandora_audio/README.md
  12. 3
      modules/islandora_audio/config/schema/islandora_audio.schema.yml
  13. 1
      modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php
  14. 73
      modules/islandora_breadcrumbs/CONTRIBUTING.md
  15. 339
      modules/islandora_breadcrumbs/LICENSE
  16. 42
      modules/islandora_breadcrumbs/README.md
  17. 7
      modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php
  18. 14
      modules/islandora_breadcrumbs/tests/src/Functional/BreadcrumbsTest.php
  19. 73
      modules/islandora_core_feature/CONTRIBUTING.md
  20. 339
      modules/islandora_core_feature/LICENSE
  21. 41
      modules/islandora_core_feature/README.md
  22. 25
      modules/islandora_core_feature/config/install/field.storage.media.field_media_document.yml
  23. 21
      modules/islandora_core_feature/config/install/field.storage.media.field_original_name.yml
  24. 73
      modules/islandora_iiif/CONTRIBUTING.md
  25. 339
      modules/islandora_iiif/LICENSE
  26. 49
      modules/islandora_iiif/README.md
  27. 2
      modules/islandora_iiif/islandora_iiif.routing.yml
  28. 42
      modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php
  29. 4
      modules/islandora_image/.travis.yml
  30. 73
      modules/islandora_image/CONTRIBUTING.md
  31. 41
      modules/islandora_image/README.md
  32. 3
      modules/islandora_image/config/schema/islandora_image.schema.yml
  33. 1
      modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php
  34. 73
      modules/islandora_text_extraction/CONTRIBUTING.md
  35. 69
      modules/islandora_text_extraction/README.md
  36. 23
      modules/islandora_text_extraction/islandora_text_extraction.install
  37. 22
      modules/islandora_text_extraction/islandora_text_extraction.module
  38. 8
      modules/islandora_text_extraction/islandora_text_extraction.services.yml
  39. 65
      modules/islandora_text_extraction/src/SearchReindexer.php
  40. 6
      modules/islandora_text_extraction/tests/src/Functional/LoadTest.php
  41. 73
      modules/islandora_text_extraction_defaults/CONTRIBUTING.md
  42. 339
      modules/islandora_text_extraction_defaults/LICENSE
  43. 42
      modules/islandora_text_extraction_defaults/README.md
  44. 2
      modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_mime_type.yml
  45. 51
      modules/islandora_text_extraction_defaults/config/install/rdf.mapping.media.extracted_text.yml
  46. 73
      modules/islandora_video/CONTRIBUTING.md
  47. 36
      modules/islandora_video/README.md
  48. 3
      modules/islandora_video/config/schema/islandora_video.schema.yml
  49. 6
      modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php
  50. 65
      src/Commands/IslandoraCommands.php
  51. 6
      src/ContextReaction/DisplayAlterReaction.php
  52. 11
      src/Controller/ManageMembersController.php
  53. 8
      src/EventGenerator/EmitEvent.php
  54. 52
      src/EventGenerator/EventGenerator.php
  55. 26
      src/EventSubscriber/LinkHeaderSubscriber.php
  56. 31
      src/Flysystem/Fedora.php
  57. 151
      src/Form/IslandoraSettingsForm.php
  58. 2
      src/GeminiLookup.php
  59. 87
      src/IslandoraUtils.php
  60. 16
      src/MediaSource/MediaSourceService.php
  61. 16
      src/Plugin/Action/AbstractGenerateDerivative.php
  62. 14
      src/Plugin/Action/EmitFileEvent.php
  63. 6
      src/Plugin/Action/EmitMediaEvent.php
  64. 2
      src/Plugin/Condition/ContentEntityType.php
  65. 10
      src/Plugin/Condition/EntityBundle.php
  66. 10
      src/Plugin/Condition/FileUsesFilesystem.php
  67. 12
      src/Plugin/Condition/MediaHasMimetype.php
  68. 4
      src/Plugin/Condition/MediaHasTerm.php
  69. 8
      src/Plugin/Condition/MediaUsesFilesystem.php
  70. 14
      src/Plugin/Condition/NodeHadNamespace.php
  71. 13
      src/Plugin/Condition/NodeHasParent.php
  72. 74
      src/Plugin/Condition/NodeHasTerm.php
  73. 19
      src/Plugin/Condition/NodeIsPublished.php
  74. 4
      src/Plugin/Condition/ParentNodeHasTerm.php
  75. 56
      src/Plugin/ContextReaction/JsonldSelfReferenceReaction.php
  76. 3
      src/Plugin/ContextReaction/JsonldTypeAlterReaction.php
  77. 125
      src/Plugin/EntityReferenceSelection/ExternalUriSelection.php
  78. 5
      src/StompFactory.php
  79. 6
      tests/src/Functional/EntityBundleTest.php
  80. 26
      tests/src/Functional/IslandoraSettingsFormTest.php
  81. 26
      tests/src/Functional/JsonldSelfReferenceReactionTest.php
  82. 12
      tests/src/Functional/JsonldTypeAlterReactionTest.php
  83. 26
      tests/src/Functional/NodeHasTermTest.php

2
.github/PULL_REQUEST_TEMPLATE.md

@ -34,4 +34,4 @@ Any additional information that you think would be helpful when reviewing this
PR.
# Interested parties
Tag (@ mention) interested parties or, if unsure, @Islandora-CLAW/committers
Tag (@ mention) interested parties or, if unsure, @Islandora/8-x-committers

35
.travis.yml

@ -1,44 +1,53 @@
sudo: true
language: php
php:
- 7.1
- 7.2
services:
- mysql
- 7.3
matrix:
fast_finish: true
allow_failures:
- php: 7.3
services:
- mysql
branches:
only:
- /^8.x/
- /master/
before_install:
- export SCRIPT_DIR=$HOME/CLAW/.scripts
- export SCRIPT_DIR=$HOME/islandora/.scripts
- export DRUPAL_DIR=/opt/drupal
- export COMPOSER_PATH="/home/travis/.phpenv/versions/$TRAVIS_PHP_VERSION/bin/composer"
install:
- git clone https://github.com/Islandora-CLAW/CLAW.git $HOME/CLAW
- git clone https://github.com/Islandora/documentation.git $HOME/islandora
- $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
- $SCRIPT_DIR/run-tests.sh "islandora"
- $SCRIPT_DIR/run-tests.sh "islandora_breadcrumbs"
- $SCRIPT_DIR/run-tests.sh "islandora_image"
- $SCRIPT_DIR/run-tests.sh "islandora_audio"
- $SCRIPT_DIR/run-tests.sh "islandora_video"
- $SCRIPT_DIR/run-tests.sh "islandora_text_extraction"
after_success:
- bash <(curl -s https://codecov.io/bash)
notifications:
irc:
channels:
- "irc.freenode.org#islandora"
slack:
on_success: change
on_failure: always
skip_join: true
secure: $SLACK_NOTIFICATION_KEY

16
CONTRIBUTING.md

@ -8,23 +8,23 @@ Please note that this project operates under the [Islandora Community Code of Co
## Workflows
The group meets each Wednesday at 1:00 PM Eastern. Meeting notes and announcements are posted to the [Islandora community list](https://groups.google.com/forum/#!forum/islandora) and the [Islandora developers list](https://groups.google.com/forum/#!forum/islandora-dev). You can view meeting agendas, notes, and call-in information [here](https://github.com/Islandora-CLAW/CLAW/wiki#islandora-claw-tech-calls). Anybody is welcome to join the calls, and add items to the agenda.
The group meets each Wednesday at 1:00 PM Eastern. Meeting notes and announcements are posted to the [Islandora community list](https://groups.google.com/forum/#!forum/islandora) and the [Islandora developers list](https://groups.google.com/forum/#!forum/islandora-dev). You can view meeting agendas, notes, and call-in information [here](https://github.com/Islandora/documentation/wiki#islandora-8-tech-calls). Anybody is welcome to join the calls, and add items to the agenda.
### Use cases
If you would like to submit a use case to the Islandora 8 project, please submit an issue [here](https://github.com/Islandora-CLAW/CLAW/issues/new) using the [Use Case template](https://github.com/Islandora-CLAW/CLAW/wiki/Use-Case-template), prepending "Use Case:" to the title of the issue.
If you would like to submit a use case to the Islandora 8 project, please submit an issue [here](https://github.com/Islandora/documentation/issues/new) using the [Use Case template](https://github.com/Islandora/documentation/wiki/Use-Case-template), prepending "Use Case:" to the title of the issue.
### Documentation
You can contribute documentation in two different ways. One way is to create an issue [here](https://github.com/Islandora-CLAW/CLAW/issues/new), prepending "Documentation:" to the title of the issue. Another way is by pull request, which is the same process as [Contribute Code](https://github.com/Islandora-CLAW/CLAW/blob/master/CONTRIBUTING.md#contribute-code). All documentation resides in [`docs`](https://github.com/Islandora-CLAW/CLAW/tree/master/docs).
You can contribute documentation in two different ways. One way is to create an issue [here](https://github.com/Islandora/documentation/issues/new), prepending "Documentation:" to the title of the issue. Another way is by pull request, which is the same process as [Contribute Code](https://github.com/Islandora/documentation/blob/master/CONTRIBUTING.md#contribute-code). All documentation resides in [`docs`](https://github.com/Islandora/documentation/tree/master/docs).
### Request a new feature
To request a new feature you should [open an issue in the Islandora 8 repository](https://github.com/Islandora-CLAW/CLAW/issues/new) or create a use case (see the _Use cases_ section above), and summarize the desired functionality. Prepend "Enhancement:" if creating an issue on the project repo, and "Use Case:" if creating a use case.
To request a new feature you should [open an issue in the Islandora 8 repository](https://github.com/Islandora/documentation/issues/new) or create a use case (see the _Use cases_ section above), and summarize the desired functionality. Prepend "Enhancement:" if creating an issue on the project repo, and "Use Case:" if creating a use case.
### Report a bug
To report a bug you should [open an issue in the Islandora 8 repository](https://github.com/Islandora-CLAW/CLAW/issues/new) that summarizes the bug. Prepend the label "Bug:" to the title of the issue.
To report a bug you should [open an issue in the Islandora 8 repository](https://github.com/Islandora/documentation/issues/new) that summarizes the bug. Prepend the label "Bug:" to the title of the issue.
In order to help us understand and fix the bug it would be great if you could provide us with:
@ -44,7 +44,7 @@ Before you set out to contribute code you will need to have completed a [Contrib
_If you are interested in contributing code to Islandora but do not know where to begin:_
In this case you should [browse open issues](https://github.com/Islandora-CLAW/CLAW/issues) and check out [use cases](https://github.com/Islandora-CLAW/CLAW/labels/use%20case).
In this case you should [browse open issues](https://github.com/Islandora/documentation/issues) and check out [use cases](https://github.com/Islandora/documentation/labels/use%20case).
If you are contributing Drupal code, it must adhere to [Drupal Coding Standards](https://www.drupal.org/coding-standards); Travis CI will check for this on pull requests.
@ -53,7 +53,7 @@ Contributions to the Islandora codebase should be sent as GitHub pull requests.
* For _small patches_, feel free to submit pull requests directly for those patches.
* For _larger code contributions_, please use the following process. The idea behind this process is to prevent any wasted work and catch design issues early on.
1. [Open an issue](https://github.com/Islandora-CLAW/CLAW/issues), prepending "Enhancement:" in the title if a similar issue does not exist already. If a similar issue does exist, then you may consider participating in the work on the existing issue.
1. [Open an issue](https://github.com/Islandora/documentation/issues), prepending "Enhancement:" in the title if a similar issue does not exist already. If a similar issue does exist, then you may consider participating in the work on the existing issue.
2. Comment on the issue with your plan for implementing the issue. Explain what pieces of the codebase you are going to touch and how everything is going to fit together.
3. Islandora committers will work with you on the design to make sure you are on the right track.
4. Implement your issue, create a pull request (see below), and iterate from there.
@ -64,7 +64,7 @@ Take a look at [Creating a pull request](https://help.github.com/articles/creati
1. [Fork](https://help.github.com/articles/fork-a-repo) this repository to your personal or institutional GitHub account (depending on the CLA you are working under). Be cautious of which branches you work from though (you'll want to base your work off master, or for Drupal modules use the most recent version branch). See [Fork a repo](https://help.github.com/articles/fork-a-repo) for detailed instructions.
2. Commit any changes to your fork.
3. Send a [pull request](https://help.github.com/articles/creating-a-pull-request) using the [pull request template](https://github.com/Islandora-CLAW/CLAW/blob/master/.github/PULL_REQUEST_TEMPLATE.md) to the Islandora GitHub repository that you forked in step 1. If your pull request is related to an existing issue -- for instance, because you reported a [bug/issue](https://github.com/Islandora-CLAW/CLAW/issues) earlier -- prefix the title of your pull request with the corresponding issue number (e.g. `issue-123: ...`). Please also include a reference to the issue in the description of the pull. This can be done by using '#' plus the issue number like so '#123', also try to pick an appropriate name for the branch in which you're issuing the pull request from.
3. Send a [pull request](https://help.github.com/articles/creating-a-pull-request) using the [pull request template](https://github.com/Islandora/documentation/blob/master/.github/PULL_REQUEST_TEMPLATE.md) to the Islandora GitHub repository that you forked in step 1. If your pull request is related to an existing issue -- for instance, because you reported a [bug/issue](https://github.com/Islandora/documentation/issues) earlier -- prefix the title of your pull request with the corresponding issue number (e.g. `issue-123: ...`). Please also include a reference to the issue in the description of the pull. This can be done by using '#' plus the issue number like so '#123', also try to pick an appropriate name for the branch in which you're issuing the pull request from.
You may want to read [Syncing a fork](https://help.github.com/articles/syncing-a-fork) for instructions on how to keep your fork up to date with the latest changes of the upstream (official) repository.

15
COPYRIGHT

@ -0,0 +1,15 @@
Copyright (C) 2015 The Islandora Foundation and contributors
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with this program as the file LICENSE.txt; if not, please see
http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.

299
README.md

@ -1,234 +1,119 @@
# ![Islandora](https://cloud.githubusercontent.com/assets/2371345/25624809/f95b0972-2f30-11e7-8992-a8f135402cdc.png) Islandora
[![Build Status][1]](https://travis-ci.com/Islandora-CLAW/islandora)
[![Contribution Guidelines][2]](./CONTRIBUTING.md)
[![LICENSE][3]](./LICENSE)
## Introduction
Islandora is a module that turns a Drupal 8 site into a control panel for your digital repository. Through a user
interface, it allows repository administrators to
- Persist digital content in a Fedora repository
- Model digital content using core Drupal entities (nodes, media, files, and taxonomy terms). Currently, there is
support for
- collections
- images
- binary files (including PDfs)
- audio
- video
- Design forms for editing metadata
- Control the display and theming of digital content
- Perform full text searching of content and metadata
- Bulk ingest content (using Drupal's migrate framework)
- Administer fine grained access control
- Index RDF metadata in a triplestore
- Generate derivative files, such as web quality representations.
- Currently, only image derivatives are supported (requires islandora_image), but more to come.
- Apply bulk operations to lists of content (re-index content, regenerate derivatives, etc...)
- And much, much more...
Content in an Islandora repository is treated as ordinary Drupal content, so the entire Drupal ecosystem of contributed
modules is at your disposal. In fact, Islandora uses many contributed modules itself, including the extremely powerful
and flexible `context` module. The `context` module allows users to do many things through a UI that normally would
require programming custom modules or themes. Want to show certain users a simplified form for data entry? Want to
give each collection a different theme? Want to give anonymous users a restricted view? All of this can be done using
the `context` module. It is similar to the `rules` module, and it allows repository administrators to filter repository events (view, create,
update, delete, etc...) by the criteria of their choice and respond by executing configurable actions.
## Requirements / Installation
Setting up a full digital repository is a daunting task involving many moving parts on one or more servers. To make things
easier to get started, you can fully bootstrap a complete repository solution using our Ansible installer, claw-playbook.
It can install both to a local Vagrant environment for development purposes, or it can install to one or more remote servers
by providing your own playbook. By default you'll get one server with everything on it (i.e. the kitchen sink install). But
we have broken down each component into its own Ansible role, so more advanced users can create customized builds containing
only what their needs require. See the README for more details.
## Configuration
If you want to get up and running as quickly as possible, import the `islanora_demo_feature` feature to install example configuration
and bootstrap your site. If you're starting from scratch, then _at a minimum_, you must:
1. Set the URL to your message broker at `admin/config/islandora`
1. Enable the `islandora_core_feature` module, then visit `admin/config/development/features` and import its config. It contains
everything required for basic content modeling. You can also use Drush to import the feature
`drush -y fim --bundle=islandora islandora_core_feature`.
1. Run the migration to load the taxonomy terms required by Islandora. This can be done by visiting `admin/structure/migrate`, or executed via drush
`drush -l http://localhost:8000 mim --group=islandora`.
## Content Modeling
Islandora uses core Drupal 8 functionality for modeling content. Most core content entities are utilized:
1. Nodes
1. Nodes hold descriptive and structural metadata about objects in your repository. Membership between nodes (e.g. members
of a collection, or pages of a book) is denoted with `field_member_of`, which is provided by `islandora_core_feature`.
Additional behavior can be controlled by tagging nodes with taxonomy terms using `field_tags`.
1. Media
1. Media hold technical metadata for the files they represent. There are four core media types, used for audio, video,
images, and generic files. Media are associated with a node using `field_media_of`, which is provided by `islandora_core_feature`.
The role of the media is indicated by tagging it with a taxonomy term using `field_tags`. For example,
tagging a media as 'Preservation Master' indicates that it is the master archival copy of a file, while 'Service File' would
indicate that it is a lower quality derivative intended to be shown to the average user.
1. Files
1. Files hold the binary contents that are described by Media. They often created along with a media to hold its technical metadata,
but can be created and then later associated with a Media in a separate process.
1. Taxonomy Terms
1. Taxonomy terms are used to tag nodes and media so they can be classified, organized, and acted upon. They must contain a
`field_external_uri` field that holds an external URI for the term from a controlled vocabulary / ontology. The `islandora_core_feature`
provides a migration that can be executed to load all of the required terms for basic use into your repository.
The `islandora_demo_feature` provides a complete example of content modeling in Islandora for audio, video, files, and images, including
tiff and JP2 support (e.g. large images). This includes some more advanced techniques, like switching display modes based on
taxonomy terms so 'images' and 'large images' can share a metadata profile but be displayed differently. It also includes
example actions for generating image derivatives (using the `islandora_image` module). You may not, however, want all of this functionality.
In fact, this feature is not meant to be the end-all-be-all of content modeling, but serves as an example of how it's done using
Islandora. You can take as much or as little of it as you'd like. If you're doing you're own thing, the gist is:
- When making your own content type, it will require `field_member_of`, `field_tags`, and an RDF mapping.
- When making your own media type, it will require `field_media_of`, `field_tags`, `field_mimetype`, an RDF mapping, and a field to hold the file.
You can re-use `field_media_file`, `field_media_image`, `field_media_audio`, and `field_media_video` to do so. Media should
always be tagged (`field_tags`) with a term from the pcdmuse ontology (preservation master, service file, thumbnail image) to denote its usage.
- When making your own taxonomy vocabulary, its terms will require `field_external_uri` and an RDF mapping.
- All RDF mappings need to map the `changed` time to `schema:dateModified`.
## Actions
Islandora provides several useful actions for repository administrators that can be configured and executed through the user
interface. Any view can expose bulk operations by adding a `Bulk update` field to its display.
Islandora also provides a thin wrapper around Actions so that they can be used in conjunction with the `context` module.
Repository events for indexing, deletion, and derivative generation are all handled by selecting one or more preconfigured
actions using the `context` user interface.
### Delete Media
You can use the `Delete media` action to bulk delete media, but not delete source files.
### Delete Media and File(s)
You can use the `Delete media and file(s)` action to bulk delete media and their source files.
### Emit Node/Media/File/Term Event
You can use `Emit a * event to a queue/topic` actions to produce messages so background processes can consume them and
perform work. The `islandora_core_feature` contains several preconfigured actions to perform indexing and removal
operations for Fedora and a triplestore.
## REST API
Islandora has a light, mostly RESTful HTTP API that relies heavily on Drupal's core Rest module. The majority of what Islandora
provides is Link headers in GET and HEAD responses. These headers can be used to locate related resources and navigate your
repository. In addition to these link headers, there are additional endpoints exposed for uploading files, as well as a couple
of useful REST exports.
### Exposed Headers
#### Referenced taxonomy terms (Nodes and Media)
The taxonomy terms used to tag content are exposed as link headers with `rel="tag"` and a title equal to the taxonomy term's display
label. If the term has an external URI in a controlled vocabulary, then that URI is provided. Otherwise, the local Drupal URI is
provided. For example, if a piece of content is tagged with `taxonomy/term/1`, which has a display label of "Example Term", then the
link header returned in a GET or HEAD response would look like `Link: <http://example.org/taxonomy/term/1>; rel="tag"; title="Example Term"`
If instead the term were to have the `field_external_uri` field with a value of `http://purl.org/dc/dcmitype/Collection` then the link
header would look like `Link: <http://purl.org/dc/dcmitype/Collection>; rel="tag"; title="Example Term"`.
#### Referenced entities (Nodes and Media)
Entity reference fields are exposed as link headers with `rel="related"` and a title equal to the entity reference field's display label.
For example, if `http://example.org/node/1` has an entity reference field name "Associated Content" that references
`http://example.org/node/2`, then the link header returned in a GET or HEAD response would look like
`Link: <http://example.org/node/2>; rel="related"; title="Associated Content"`.
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.2-8892BF.svg?style=flat-square)](https://php.net/)
[![Build Status](https://travis-ci.org/Islandora/islandora.png?branch=8.x-1.x)](https://travis-ci.com/Islandora/islandora)
[![Contribution Guidelines](http://img.shields.io/badge/CONTRIBUTING-Guidelines-blue.svg)](./CONTRIBUTING.md)
[![LICENSE](https://img.shields.io/badge/license-GPLv2-blue.svg?style=flat-square)](./LICENSE)
[![codecov](https://codecov.io/gh/Islandora/islandora/branch/8.x-1.x/graph/badge.svg)](https://codecov.io/gh/Islandora/islandora)
#### Associated media (Nodes only)
Media entities that belong to nodes and are tagged with terms from the PCDM Use ontology are exposed as link headers with `rel="related"`
and a title equal to the display label of the taxonomy term. For example, if a Media is tagged as `Preservation Master` indicating
that it is the archival copy, the link header returned in a GET or HEAD response for a node would look like
`Link: <http://example.org/media/1>; rel="related"; title="Preservation Master"`.
#### Source files (Media only)
Files that are the source for Media entities are exposed as Link headers in the GET and HEAD responses with `rel="describes"`. The endpoint
to edit the contents of the source file is also exposed using `rel="edit-media"`. For example, if `http://example.org/media/1` has the source
file `http://example.org/file.txt`, then a GET or HEAD response would contain both
- `Link: <http://example.org/file.txt>; rel="describes"`
- `Link: <http://example.org/media/1/source>; rel="edit-media"`
### Exposed Endpoints
#### /media/{media}/source
You can PUT content to the `/media/{media}/source` endpoint to update the source file for a media. The `Content-Type`
header is required in addition to the PUT body. Requests with empty bodies or no `Content-Type` header will be rejected.
## Introduction
Example usage:
```
curl -u admin:islandora -v -X PUT -H 'Content-Type: image/png' --data-binary @my_image.png localhost:8000/media/1/source
This is the core module of Islandora's digital repository ecosystem. The `islandora` module provides:
- Fedora 5 integration via the [flysystem](https://drupal.org/project/flysystem) module
- Integration with the [context](https://drupal.org/project/context) module to control your digital repository's behaviour
- Publishing messages to a queue so they can be processed in the background
`islandora` contains several submodules and features:
- `islandora_core_feature` (**required**)
- Configuration required by the `islandora` module
- `islandora_image`
- Integrates with a [Houdini](https://github.com/Islandora/Crayfish/tree/dev/Houdini) (Imagemagick) server for image processing
- `islandora_audio` and `islandora_video`
- Integrate with a [Homarus](https://github.com/Islandora/Crayfish/tree/dev/Homarus) (`ffmpeg`) server for audio/video processing
- `islandora_text_extraction` and `islandora_text_extraction_defaults`
- Integrate with a [Hypercube](https://github.com/Islandora/Crayfish/tree/dev/Hypercube) (`tessseract` and `pdftotext`) server for text extraction
- `islandora_breadcrumbs`
- Provides breadcrumbs following collection structure
- `islandora_iiif`
- Provides IIIF manifests for repository content
## Requirements
Installing via composer will download all required libraries and modules. However, for reference, `islandora` requires the following drupal modules:
- [context](http://drupal.org/project/context)
- [search_api](http://drupal.org/project/search_api)
- [jsonld](http://drupal.org/project/jsonld)
- [jwt](http://drupal.org/project/jwt)
- [filehash](http://drupal.org/project/filehash)
- [prepopulate](http://drupal.org/project/prepopulate)
- [eva](http://drupal.org/project/eva)
- [features](http://drupal.org/project/features)
- [migrate_plus](http://drupal.org/project/migrate_plus)
- [migrate_tools](http://drupal.org/project/migrate_tools)
- [migrate_source_csv](http://drupal.org/project/migrate_source_csv)
- [flysystem](http://drupal.org/project/flysystem)
It also requires the following PHP libraries:
- [Crayfish Commons](https://packagist.org/packages/islandora/crayfish-commons)
- [Stomp PHP](http://drupal.org/project/)
## Installation
For a full digital repository solution, see our [installation documentation](https://islandora.github.io/documentation/installation/).
To download/enable just this module, use the following from the command line:
```bash
$ composer require islandora/islandora
$ drush en islandora_core_feature
$ drush mim islandora_tags
```
#### /node/{node}/media/{media_type}/{taxonomy_term}
You can PUT content to the `/node/{node}/media/{media_type}/{taxonomy_term}` endpoint to create or update Media for Nodes. Media created
in this way will automatically be assigned to the node in the route and tagged with the term in the route. The `Content-Type`
header is expected, as well as a `Content-Disposition` header of the form `attachment; filename="your_filename"` to indicate
the name to give the file if it's new. Requests with empty bodies or that are without `Content-Type` and `Content-Disposition`
headers will be rejected.
For example, to create a new Image media for node 1, and tag it with taxonomy term 1:
```
curl -v -u admin:islandora -H "Content-Type: image/jpeg" -H "Content-Disposition: attachment; filename=\"test.jpeg\"" --data-binary @test.jpeg http://localhost:8000/node/1/media/image/1
```
## Configuration
Or, to update an existing image media that is tagged with taxonomy term 2:
```
curl -v -u admin:islandora -H "Content-Type: image/jpeg" -H "Content-Disposition: attachment; filename=\"test2.jpeg\"" --data-binary @test2.jpeg http://localhost:8000/node/1/media/image/2
```
![image](https://user-images.githubusercontent.com/20773151/67234502-ac171900-f41b-11e9-964e-c7d4cfadbd67.png)
#### /node/{node}/members
You can set the following configuration at `admin/config/islandora/core`:
- Broker URL
- The URL to your message broker (i.e. Activemq)
- JWT Expiry
- Set to increase the amount of time that authorization tokens remain valid. If you have a long running derivative processes or a migration, you may need to set this to be a very long time, e.g. `500d`. Otherwise, it's best to leave it alone.
- Gemini URL
- The URL to your Gemini server, which keeps track of where Islandora content is in Fedora.
- Fedora URL Display
- Selected bundles can display the Fedora URL for repository content.
You can issue GET requests to this endpoint to get a list of members of a node. It is actually a REST export, and requires the `_format` query param. It can (read should) also be paged
like other REST export. For example, to get a paged list of members for a node, ten at a time:
## Documentation
```
curl -v -u admin:islandora http://localhost:8000/node/1/members?_format=json&items_per_page=10&offset=0
```
Further documentation for this module is available on the [Islandora 8 documentation site](https://islandora.github.io/documentation/).
#### /node/{node}/media
## Troubleshooting/Issues
You can issue GET requests to this endpoint to get a list of media of a node. It is actually a REST export, and requires the `_format` query param. Like the members endpoint, it can
be paged, but is less likely to be necessary as most nodes don't have that many media. For example, to get the full list of media for a node:
Having problems or solved a problem? Check out the Islandora google groups for a solution.
```
curl -v -u admin:islandora http://localhost:8000/node/1/media?_format=json
```
* [Islandora Group](https://groups.google.com/forum/?hl=en&fromgroups#!forum/islandora)
* [Islandora Dev Group](https://groups.google.com/forum/?hl=en&fromgroups#!forum/islandora-dev)
## Maintainers
Current maintainers:
* [Diego Pino](https://github.com/diegopino)
* [Jared Whiklo](https://github.com/whikloj)
* [Danny Lamb](https://github.com/dannylamb)
## Sponsors
* UPEI
* discoverygarden inc.
* LYRASIS
* McMaster University
* University of Limerick
* York University
* University of Manitoba
* Simon Fraser University
* PALS
* American Philosophical Society
* Common Media Inc.
## Development
If you would like to contribute, please get involved by attending our weekly
[Tech Call][4]. We love to hear from you!
If you would like to contribute, please get involved by attending our weekly [Tech Call](https://github.com/Islandora/documentation/wiki). We love to hear from you!
If you would like to contribute code to the project, you need to be covered by
an Islandora Foundation [Contributor License Agreement][5] or
[Corporate Contributor License Agreement][6]. Please see the
[Contributors][7] pages on Islandora.ca for more information.
If you would like to contribute code to the project, you need to be covered by an Islandora Foundation [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). Please see the [Contributors](http://islandora.ca/resources/contributors) pages on Islandora.ca for more information.
We recommend using the [islandora-playbook](https://github.com/Islandora-Devops/islandora-playbook) to get started.
## License
[GPLv2](http://www.gnu.org/licenses/gpl-2.0.txt)
[1]: https://travis-ci.org/Islandora-CLAW/islandora.png?branch=8.x-1.x
[2]: http://img.shields.io/badge/CONTRIBUTING-Guidelines-blue.svg
[3]: https://img.shields.io/badge/license-GPLv2-blue.svg?style=flat-square
[4]: https://github.com/Islandora-CLAW/CLAW/wiki
[5]: http://islandora.ca/sites/default/files/islandora_cla.pdf
[6]: http://islandora.ca/sites/default/files/islandora_ccla.pdf
[7]: http://islandora.ca/resources/contributors

21
composer.json

@ -3,10 +3,9 @@
"description": "Core Islandora module",
"type": "drupal-module",
"keywords": ["Drupal", "Islandora"],
"homepage": "https://github.com/islandora-claw/islandora",
"homepage": "https://github.com/Islandora/islandora",
"support": {
"issues": "https://github.com/islandora-claw/CLAW/issues",
"irc": "irc://irc.freenode.net/islandora"
"issues": "https://github.com/Islandora/documentation/issues"
},
"repositories": [
{
@ -19,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",
@ -37,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": [
{
@ -48,11 +50,6 @@
"name": "Daniel Lamb",
"email": "dlamb@islandora.ca",
"role": "Maintainer"
},
{
"name": "Diego Pino",
"email": "dpino@krayon.cl",
"role": "Maintainer"
}
]
}

9
config/schema/islandora.schema.yml

@ -78,6 +78,9 @@ condition.plugin.node_has_term:
uri:
type: text
label: 'Taxonomy Term URI'
logic:
type: string
label: 'Logic (AND or OR)'
condition.plugin.node_has_parent:
type: condition.plugin
@ -95,6 +98,9 @@ condition.plugin.media_has_term:
uri:
type: text
label: 'Taxonomy Term URI'
logic:
type: string
label: 'Logic (AND or OR)'
condition.plugin.parent_node_has_term:
type: condition.plugin
@ -102,6 +108,9 @@ condition.plugin.parent_node_has_term:
uri:
type: text
label: 'Taxonomy Term URI'
logic:
type: string
label: 'Logic (AND or OR)'
condition.plugin.file_uses_filesystem:
type: condition.plugin

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

37
islandora.module

@ -14,6 +14,7 @@
* @author Diego Pino Navarro <dpino@metro.org> https://github.com/diegopino
*/
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
@ -50,17 +51,19 @@ 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#',
'owl' => 'http://www.w3.org/2002/07/owl#',
'ore' => 'http://www.openarchives.org/ore/terms/',
'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
'islandora' => 'http://islandora.ca/CLAW/',
'islandora' => 'http://islandora.ca/',
'pcdm' => 'http://pcdm.org/models#',
'use' => 'http://pcdm.org/use#',
'iana' => 'http://www.iana.org/assignments/relation/',
'premis' => 'http://www.loc.gov/premis/rdf/v1#',
'premis3' => 'http://www.loc.gov/premis/rdf/v3/',
'co' => 'http://purl.org/co/',
];
}
@ -221,7 +224,7 @@ function islandora_file_delete(FileInterface $file) {
function islandora_taxonomy_term_insert(TermInterface $term) {
$utils = \Drupal::service('islandora.utils');
// Execute delete reactions.
// Execute index reactions.
$utils->executeTermReactions('\Drupal\islandora\Plugin\ContextReaction\IndexReaction', $term);
}
@ -231,7 +234,7 @@ function islandora_taxonomy_term_insert(TermInterface $term) {
function islandora_taxonomy_term_update(TermInterface $term) {
$utils = \Drupal::service('islandora.utils');
// Execute delete reactions.
// Execute index reactions.
$utils->executeTermReactions('\Drupal\islandora\Plugin\ContextReaction\IndexReaction', $term);
}
@ -252,6 +255,16 @@ function islandora_jsonld_alter_normalized_array(EntityInterface $entity, array
$context_manager = \Drupal::service('context.manager');
foreach ($context_manager->getActiveReactions('\Drupal\islandora\ContextReaction\NormalizerAlterReaction') as $reaction) {
$reaction->execute($entity, $normalized, $context);
foreach ($context_manager->getActiveContexts() as $context_config) {
try {
if ($context_config->getReaction($reaction->getPluginId())) {
$context['cacheability']->addCacheTags($context_config->getCacheTags());
};
}
catch (PluginNotFoundException $e) {
// Squash :(.
}
}
}
}
@ -365,14 +378,16 @@ function islandora_entity_extra_field_info() {
$pseudo_bundles = $config_factory->get(IslandoraSettingsForm::GEMINI_PSEUDO);
foreach ($pseudo_bundles as $key) {
list($bundle, $content_entity) = explode(":", $key);
$extra_field[$content_entity][$bundle]['display']['field_gemini_uri'] = [
'label' => t('Fedora URI'),
'description' => t('The URI to the persistent'),
'weight' => 100,
'visible' => TRUE,
];
if (!empty($pseudo_bundles)) {
foreach ($pseudo_bundles as $key) {
list($bundle, $content_entity) = explode(":", $key);
$extra_field[$content_entity][$bundle]['display']['field_gemini_uri'] = [
'label' => t('Fedora URI'),
'description' => t('The URI to the persistent'),
'weight' => 100,
'visible' => TRUE,
];
}
}
return $extra_field;
}

73
modules/islandora_audio/CONTRIBUTING.md

@ -0,0 +1,73 @@
# Welcome!
If you are reading this document then you are interested in contributing to Islandora 8. All contributions are welcome: use-cases, documentation, code, patches, bug reports, feature requests, etc. You do not need to be a programmer to speak up!
We also have an IRC channel -- #islandora -- on freenode.net. Feel free to hang out there, ask questions, and help others out if you can.
Please note that this project operates under the [Islandora Community Code of Conduct](http://islandora.ca/codeofconduct). By participating in this project you agree to abide by its terms.
## Workflows
The group meets each Wednesday at 1:00 PM Eastern. Meeting notes and announcements are posted to the [Islandora community list](https://groups.google.com/forum/#!forum/islandora) and the [Islandora developers list](https://groups.google.com/forum/#!forum/islandora-dev). You can view meeting agendas, notes, and call-in information [here](https://github.com/Islandora/documentation/wiki#islandora-8-tech-calls). Anybody is welcome to join the calls, and add items to the agenda.
### Use cases
If you would like to submit a use case to the Islandora 8 project, please submit an issue [here](https://github.com/Islandora/documentation/issues/new) using the [Use Case template](https://github.com/Islandora/documentation/wiki/Use-Case-template), prepending "Use Case:" to the title of the issue.
### Documentation
You can contribute documentation in two different ways. One way is to create an issue [here](https://github.com/Islandora/documentation/issues/new), prepending "Documentation:" to the title of the issue. Another way is by pull request, which is the same process as [Contribute Code](https://github.com/Islandora/documentation/blob/master/CONTRIBUTING.md#contribute-code). All documentation resides in [`docs`](https://github.com/Islandora/documentation/tree/master/docs).
### Request a new feature
To request a new feature you should [open an issue in the Islandora 8 repository](https://github.com/Islandora/documentation/issues/new) or create a use case (see the _Use cases_ section above), and summarize the desired functionality. Prepend "Enhancement:" if creating an issue on the project repo, and "Use Case:" if creating a use case.
### Report a bug
To report a bug you should [open an issue in the Islandora 8 repository](https://github.com/Islandora/documentation/issues/new) that summarizes the bug. Prepend the label "Bug:" to the title of the issue.
In order to help us understand and fix the bug it would be great if you could provide us with:
1. The steps to reproduce the bug. This includes information about e.g. the Islandora version you were using along with the versions of stack components.
2. The expected behavior.
3. The actual, incorrect behavior.
Feel free to search the issue queue for existing issues (aka tickets) that already describe the problem; if there is such a ticket please add your information as a comment.
**If you want to provide a pull along with your bug report:**
That is great! In this case please send us a pull request as described in the section _Create a pull request_ below.
### Contribute code
Before you set out to contribute code you will need to have completed a [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or be covered by a [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). The signed copy of the license agreement should be sent to <mailto:community@islandora.ca>
_If you are interested in contributing code to Islandora but do not know where to begin:_
In this case you should [browse open issues](https://github.com/Islandora/documentation/issues) and check out [use cases](https://github.com/Islandora/documentation/labels/use%20case).
If you are contributing Drupal code, it must adhere to [Drupal Coding Standards](https://www.drupal.org/coding-standards); Travis CI will check for this on pull requests.
Contributions to the Islandora codebase should be sent as GitHub pull requests. See section _Create a pull request_ below for details. If there is any problem with the pull request we can work through it using the commenting features of GitHub.
* For _small patches_, feel free to submit pull requests directly for those patches.
* For _larger code contributions_, please use the following process. The idea behind this process is to prevent any wasted work and catch design issues early on.
1. [Open an issue](https://github.com/Islandora/documentation/issues), prepending "Enhancement:" in the title if a similar issue does not exist already. If a similar issue does exist, then you may consider participating in the work on the existing issue.
2. Comment on the issue with your plan for implementing the issue. Explain what pieces of the codebase you are going to touch and how everything is going to fit together.
3. Islandora committers will work with you on the design to make sure you are on the right track.
4. Implement your issue, create a pull request (see below), and iterate from there.
### Create a pull request
Take a look at [Creating a pull request](https://help.github.com/articles/creating-a-pull-request). In a nutshell you need to:
1. [Fork](https://help.github.com/articles/fork-a-repo) this repository to your personal or institutional GitHub account (depending on the CLA you are working under). Be cautious of which branches you work from though (you'll want to base your work off master, or for Drupal modules use the most recent version branch). See [Fork a repo](https://help.github.com/articles/fork-a-repo) for detailed instructions.
2. Commit any changes to your fork.
3. Send a [pull request](https://help.github.com/articles/creating-a-pull-request) using the [pull request template](https://github.com/Islandora/documentation/blob/master/.github/PULL_REQUEST_TEMPLATE.md) to the Islandora GitHub repository that you forked in step 1. If your pull request is related to an existing issue -- for instance, because you reported a [bug/issue](https://github.com/Islandora/documentation/issues) earlier -- prefix the title of your pull request with the corresponding issue number (e.g. `issue-123: ...`). Please also include a reference to the issue in the description of the pull. This can be done by using '#' plus the issue number like so '#123', also try to pick an appropriate name for the branch in which you're issuing the pull request from.
You may want to read [Syncing a fork](https://help.github.com/articles/syncing-a-fork) for instructions on how to keep your fork up to date with the latest changes of the upstream (official) repository.
## License Agreements
The Islandora Foundation requires that contributors complete a [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or be covered by a [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). The signed copy of the license agreement should be sent to <a href="mailto:community@islandora.ca?Subject=Contributor%20License%20Agreement" target="_top">community@islandora.ca</a>. This license is for your protection as a contributor as well as the protection of the Foundation and its users; it does not change your rights to use your own contributions for any other purpose. A list of current CLAs is kept [here](https://github.com/Islandora/islandora/wiki/Contributor-License-Agreements).

36
modules/islandora_audio/README.md

@ -1,23 +1,45 @@
# Islandora Video
[![Contribution Guidelines](http://img.shields.io/badge/CONTRIBUTING-Guidelines-blue.svg)](../../CONTRIBUTING.md)
# Islandora Audio
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.2-8892BF.svg?style=flat-square)](https://php.net/)
[![Contribution Guidelines](http://img.shields.io/badge/CONTRIBUTING-Guidelines-blue.svg)](./CONTRIBUTING.md)
[![LICENSE](https://img.shields.io/badge/license-GPLv2-blue.svg?style=flat-square)](./LICENSE)
## Introduction
Islandora Video module for Drupal 8.2.x
Provides actions to convert audio with a [Homarus](https://github.com/Islandora/Crayfish/tree/dev/Homarus) (`ffmpeg`) server.
## Requirements
- `islandora` and `islandora_core_feature`
- A Homarus microservice
- A message broker (e.g. Activemq) for Islandora 8
- An instance of `islandora-connector-derivative` (from [Alpaca](https://github.com/Islandora/Alpaca/tree/dev/islandora-connector-derivative)) configured for Homarus
## Installation
## Maintainers
For a full digital repository solution (including a Homarus microservice), see our [installation documentation](https://islandora.github.io/documentation/installation/).
Current maintainers:
To download/enable just this module, use the following from the command line:
* [Danny Lamb](https://github.com/dannylamb)
```bash
$ composer require islandora/islandora
$ drush en islandora_core_feature
$ drush mim islandora_tags
$ drush en islandora_audio
```
## Documentation
Official documentation is available on the [Islandora 8 documentation site](https://islandora.github.io/documentation/).
## Development
If you would like to contribute, please get involved by attending our weekly [Tech Call](https://github.com/Islandora-CLAW/CLAW/wiki). We love to hear from you!
If you would like to contribute, please get involved by attending our weekly [Tech Call](https://github.com/Islandora/documentation/wiki). We love to hear from you!
If you would like to contribute code to the project, you need to be covered by an Islandora Foundation [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). Please see the [Contributors](http://islandora.ca/resources/contributors) pages on Islandora.ca for more information.
We recommend using the [islandora-playbook](https://github.com/Islandora-Devops/islandora-playbook) to get started.
## License
[GPLv2](http://www.gnu.org/licenses/gpl-2.0.txt)

3
modules/islandora_audio/config/schema/islandora_audio.info.yml → modules/islandora_audio/config/schema/islandora_audio.schema.yml

@ -8,6 +8,9 @@ action.configuration.generate_audio_derivative:
event:
type: text
label: 'Event Type'
destination_media_type:
type: text
label: 'Destination media type'
source_term_uri:
type: text
label: 'Source term uri'

1
modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php

@ -46,6 +46,7 @@ class GenerateAudioDerivativeTest extends GenerateDerivativeTestBase {
$this->getSession()->getPage()->fillField('edit-label', "Generate audio test derivative");
$this->getSession()->getPage()->fillField('edit-id', "generate_audio_test_derivative");
$this->getSession()->getPage()->fillField('edit-queue', "generate-audio-test-derivative");
$this->getSession()->getPage()->fillField('edit-destination-media-type', $this->testMediaType->label());
$this->getSession()->getPage()->fillField("edit-source-term", $this->preservationMasterTerm->label());
$this->getSession()->getPage()->fillField("edit-derivative-term", $this->serviceFileTerm->label());
$this->getSession()->getPage()->fillField('edit-mimetype', "audio/mpeg");

73
modules/islandora_breadcrumbs/CONTRIBUTING.md

@ -0,0 +1,73 @@
# Welcome!
If you are reading this document then you are interested in contributing to Islandora 8. All contributions are welcome: use-cases, documentation, code, patches, bug reports, feature requests, etc. You do not need to be a programmer to speak up!
We also have an IRC channel -- #islandora -- on freenode.net. Feel free to hang out there, ask questions, and help others out if you can.
Please note that this project operates under the [Islandora Community Code of Conduct](http://islandora.ca/codeofconduct). By participating in this project you agree to abide by its terms.
## Workflows
The group meets each Wednesday at 1:00 PM Eastern. Meeting notes and announcements are posted to the [Islandora community list](https://groups.google.com/forum/#!forum/islandora) and the [Islandora developers list](https://groups.google.com/forum/#!forum/islandora-dev). You can view meeting agendas, notes, and call-in information [here](https://github.com/Islandora/documentation/wiki#islandora-8-tech-calls). Anybody is welcome to join the calls, and add items to the agenda.
### Use cases
If you would like to submit a use case to the Islandora 8 project, please submit an issue [here](https://github.com/Islandora/documentation/issues/new) using the [Use Case template](https://github.com/Islandora/documentation/wiki/Use-Case-template), prepending "Use Case:" to the title of the issue.
### Documentation
You can contribute documentation in two different ways. One way is to create an issue [here](https://github.com/Islandora/documentation/issues/new), prepending "Documentation:" to the title of the issue. Another way is by pull request, which is the same process as [Contribute Code](https://github.com/Islandora/documentation/blob/master/CONTRIBUTING.md#contribute-code). All documentation resides in [`docs`](https://github.com/Islandora/documentation/tree/master/docs).
### Request a new feature
To request a new feature you should [open an issue in the Islandora 8 repository](https://github.com/Islandora/documentation/issues/new) or create a use case (see the _Use cases_ section above), and summarize the desired functionality. Prepend "Enhancement:" if creating an issue on the project repo, and "Use Case:" if creating a use case.
### Report a bug
To report a bug you should [open an issue in the Islandora 8 repository](https://github.com/Islandora/documentation/issues/new) that summarizes the bug. Prepend the label "Bug:" to the title of the issue.
In order to help us understand and fix the bug it would be great if you could provide us with:
1. The steps to reproduce the bug. This includes information about e.g. the Islandora version you were using along with the versions of stack components.
2. The expected behavior.
3. The actual, incorrect behavior.
Feel free to search the issue queue for existing issues (aka tickets) that already describe the problem; if there is such a ticket please add your information as a comment.
**If you want to provide a pull along with your bug report:**
That is great! In this case please send us a pull request as described in the section _Create a pull request_ below.
### Contribute code
Before you set out to contribute code you will need to have completed a [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or be covered by a [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). The signed copy of the license agreement should be sent to <mailto:community@islandora.ca>
_If you are interested in contributing code to Islandora but do not know where to begin:_
In this case you should [browse open issues](https://github.com/Islandora/documentation/issues) and check out [use cases](https://github.com/Islandora/documentation/labels/use%20case).
If you are contributing Drupal code, it must adhere to [Drupal Coding Standards](https://www.drupal.org/coding-standards); Travis CI will check for this on pull requests.
Contributions to the Islandora codebase should be sent as GitHub pull requests. See section _Create a pull request_ below for details. If there is any problem with the pull request we can work through it using the commenting features of GitHub.
* For _small patches_, feel free to submit pull requests directly for those patches.
* For _larger code contributions_, please use the following process. The idea behind this process is to prevent any wasted work and catch design issues early on.
1. [Open an issue](https://github.com/Islandora/documentation/issues), prepending "Enhancement:" in the title if a similar issue does not exist already. If a similar issue does exist, then you may consider participating in the work on the existing issue.
2. Comment on the issue with your plan for implementing the issue. Explain what pieces of the codebase you are going to touch and how everything is going to fit together.
3. Islandora committers will work with you on the design to make sure you are on the right track.
4. Implement your issue, create a pull request (see below), and iterate from there.
### Create a pull request
Take a look at [Creating a pull request](https://help.github.com/articles/creating-a-pull-request). In a nutshell you need to:
1. [Fork](https://help.github.com/articles/fork-a-repo) this repository to your personal or institutional GitHub account (depending on the CLA you are working under). Be cautious of which branches you work from though (you'll want to base your work off master, or for Drupal modules use the most recent version branch). See [Fork a repo](https://help.github.com/articles/fork-a-repo) for detailed instructions.
2. Commit any changes to your fork.
3. Send a [pull request](https://help.github.com/articles/creating-a-pull-request) using the [pull request template](https://github.com/Islandora/documentation/blob/master/.github/PULL_REQUEST_TEMPLATE.md) to the Islandora GitHub repository that you forked in step 1. If your pull request is related to an existing issue -- for instance, because you reported a [bug/issue](https://github.com/Islandora/documentation/issues) earlier -- prefix the title of your pull request with the corresponding issue number (e.g. `issue-123: ...`). Please also include a reference to the issue in the description of the pull. This can be done by using '#' plus the issue number like so '#123', also try to pick an appropriate name for the branch in which you're issuing the pull request from.
You may want to read [Syncing a fork](https://help.github.com/articles/syncing-a-fork) for instructions on how to keep your fork up to date with the latest changes of the upstream (official) repository.
## License Agreements
The Islandora Foundation requires that contributors complete a [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or be covered by a [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). The signed copy of the license agreement should be sent to <a href="mailto:community@islandora.ca?Subject=Contributor%20License%20Agreement" target="_top">community@islandora.ca</a>. This license is for your protection as a contributor as well as the protection of the Foundation and its users; it does not change your rights to use your own contributions for any other purpose. A list of current CLAs is kept [here](https://github.com/Islandora/islandora/wiki/Contributor-License-Agreements).

339
modules/islandora_breadcrumbs/LICENSE

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

42
modules/islandora_breadcrumbs/README.md

@ -0,0 +1,42 @@
# Islandora Breadcrumbs
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.2-8892BF.svg?style=flat-square)](https://php.net/)
[![Contribution Guidelines](http://img.shields.io/badge/CONTRIBUTING-Guidelines-blue.svg)](./CONTRIBUTING.md)
[![LICENSE](https://img.shields.io/badge/license-GPLv2-blue.svg?style=flat-square)](./LICENSE)
## Introduction
Provides breadcrumbs for Islandora content.
## Requirements
- `islandora` and `islandora_core_feature`
## Installation
For a full digital repository solution, see our [installation documentation](https://islandora.github.io/documentation/installation/).
To download/enable just this module, use the following from the command line:
```bash
$ composer require islandora/islandora
$ drush en islandora_core_feature
$ drush mim islandora_tags
$ drush en islandora_breadcrumbs
```
## Documentation
Official documentation is available on the [Islandora 8 documentation site](https://islandora.github.io/documentation/).
## Development
If you would like to contribute, please get involved by attending our weekly [Tech Call](https://github.com/Islandora/documentation/wiki). We love to hear from you!
If you would like to contribute code to the project, you need to be covered by an Islandora Foundation [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). Please see the [Contributors](http://islandora.ca/resources/contributors) pages on Islandora.ca for more information.
We recommend using the [islandora-playbook](https://github.com/Islandora-Devops/islandora-playbook) to get started.
## License
[GPLv2](http://www.gnu.org/licenses/gpl-2.0.txt)

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

73
modules/islandora_core_feature/CONTRIBUTING.md

@ -0,0 +1,73 @@
# Welcome!
If you are reading this document then you are interested in contributing to Islandora 8. All contributions are welcome: use-cases, documentation, code, patches, bug reports, feature requests, etc. You do not need to be a programmer to speak up!
We also have an IRC channel -- #islandora -- on freenode.net. Feel free to hang out there, ask questions, and help others out if you can.
Please note that this project operates under the [Islandora Community Code of Conduct](http://islandora.ca/codeofconduct). By participating in this project you agree to abide by its terms.
## Workflows
The group meets each Wednesday at 1:00 PM Eastern. Meeting notes and announcements are posted to the [Islandora community list](https://groups.google.com/forum/#!forum/islandora) and the [Islandora developers list](https://groups.google.com/forum/#!forum/islandora-dev). You can view meeting agendas, notes, and call-in information [here](https://github.com/Islandora/documentation/wiki#islandora-8-tech-calls). Anybody is welcome to join the calls, and add items to the agenda.
### Use cases
If you would like to submit a use case to the Islandora 8 project, please submit an issue [here](https://github.com/Islandora/documentation/issues/new) using the [Use Case template](https://github.com/Islandora/documentation/wiki/Use-Case-template), prepending "Use Case:" to the title of the issue.
### Documentation
You can contribute documentation in two different ways. One way is to create an issue [here](https://github.com/Islandora/documentation/issues/new), prepending "Documentation:" to the title of the issue. Another way is by pull request, which is the same process as [Contribute Code](https://github.com/Islandora/documentation/blob/master/CONTRIBUTING.md#contribute-code). All documentation resides in [`docs`](https://github.com/Islandora/documentation/tree/master/docs).
### Request a new feature
To request a new feature you should [open an issue in the Islandora 8 repository](https://github.com/Islandora/documentation/issues/new) or create a use case (see the _Use cases_ section above), and summarize the desired functionality. Prepend "Enhancement:" if creating an issue on the project repo, and "Use Case:" if creating a use case.
### Report a bug
To report a bug you should [open an issue in the Islandora 8 repository](https://github.com/Islandora/documentation/issues/new) that summarizes the bug. Prepend the label "Bug:" to the title of the issue.
In order to help us understand and fix the bug it would be great if you could provide us with:
1. The steps to reproduce the bug. This includes information about e.g. the Islandora version you were using along with the versions of stack components.
2. The expected behavior.
3. The actual, incorrect behavior.
Feel free to search the issue queue for existing issues (aka tickets) that already describe the problem; if there is such a ticket please add your information as a comment.
**If you want to provide a pull along with your bug report:**
That is great! In this case please send us a pull request as described in the section _Create a pull request_ below.
### Contribute code
Before you set out to contribute code you will need to have completed a [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or be covered by a [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). The signed copy of the license agreement should be sent to <mailto:community@islandora.ca>
_If you are interested in contributing code to Islandora but do not know where to begin:_
In this case you should [browse open issues](https://github.com/Islandora/documentation/issues) and check out [use cases](https://github.com/Islandora/documentation/labels/use%20case).
If you are contributing Drupal code, it must adhere to [Drupal Coding Standards](https://www.drupal.org/coding-standards); Travis CI will check for this on pull requests.
Contributions to the Islandora codebase should be sent as GitHub pull requests. See section _Create a pull request_ below for details. If there is any problem with the pull request we can work through it using the commenting features of GitHub.
* For _small patches_, feel free to submit pull requests directly for those patches.
* For _larger code contributions_, please use the following process. The idea behind this process is to prevent any wasted work and catch design issues early on.
1. [Open an issue](https://github.com/Islandora/documentation/issues), prepending "Enhancement:" in the title if a similar issue does not exist already. If a similar issue does exist, then you may consider participating in the work on the existing issue.
2. Comment on the issue with your plan for implementing the issue. Explain what pieces of the codebase you are going to touch and how everything is going to fit together.
3. Islandora committers will work with you on the design to make sure you are on the right track.
4. Implement your issue, create a pull request (see below), and iterate from there.
### Create a pull request
Take a look at [Creating a pull request](https://help.github.com/articles/creating-a-pull-request). In a nutshell you need to:
1. [Fork](https://help.github.com/articles/fork-a-repo) this repository to your personal or institutional GitHub account (depending on the CLA you are working under). Be cautious of which branches you work from though (you'll want to base your work off master, or for Drupal modules use the most recent version branch). See [Fork a repo](https://help.github.com/articles/fork-a-repo) for detailed instructions.
2. Commit any changes to your fork.
3. Send a [pull request](https://help.github.com/articles/creating-a-pull-request) using the [pull request template](https://github.com/Islandora/documentation/blob/master/.github/PULL_REQUEST_TEMPLATE.md) to the Islandora GitHub repository that you forked in step 1. If your pull request is related to an existing issue -- for instance, because you reported a [bug/issue](https://github.com/Islandora/documentation/issues) earlier -- prefix the title of your pull request with the corresponding issue number (e.g. `issue-123: ...`). Please also include a reference to the issue in the description of the pull. This can be done by using '#' plus the issue number like so '#123', also try to pick an appropriate name for the branch in which you're issuing the pull request from.
You may want to read [Syncing a fork](https://help.github.com/articles/syncing-a-fork) for instructions on how to keep your fork up to date with the latest changes of the upstream (official) repository.
## License Agreements
The Islandora Foundation requires that contributors complete a [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or be covered by a [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). The signed copy of the license agreement should be sent to <a href="mailto:community@islandora.ca?Subject=Contributor%20License%20Agreement" target="_top">community@islandora.ca</a>. This license is for your protection as a contributor as well as the protection of the Foundation and its users; it does not change your rights to use your own contributions for any other purpose. A list of current CLAs is kept [here](https://github.com/Islandora/islandora/wiki/Contributor-License-Agreements).

339
modules/islandora_core_feature/LICENSE

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

41
modules/islandora_core_feature/README.md

@ -0,0 +1,41 @@
# Islandora Core Feature
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.2-8892BF.svg?style=flat-square)](https://php.net/)
[![Contribution Guidelines](http://img.shields.io/badge/CONTRIBUTING-Guidelines-blue.svg)](./CONTRIBUTING.md)
[![LICENSE](https://img.shields.io/badge/license-GPLv2-blue.svg?style=flat-square)](./LICENSE)
## Introduction
Core configuration required by Islandora.
## Requirements
- `islandora`
## Installation
For a full digital repository solution, see our [installation documentation](https://islandora.github.io/documentation/installation/).
To download/enable just this module, use the following from the command line:
```bash
$ composer require islandora/islandora
$ drush en islandora_core_feature
$ drush mim islandora_tags
```
## Documentation
Official documentation is available on the [Islandora 8 documentation site](https://islandora.github.io/documentation/).
## Development
If you would like to contribute, please get involved by attending our weekly [Tech Call](https://github.com/Islandora/documentation/wiki). We love to hear from you!
If you would like to contribute code to the project, you need to be covered by an Islandora Foundation [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). Please see the [Contributors](http://islandora.ca/resources/contributors) pages on Islandora.ca for more information.
We recommend using the [islandora-playbook](https://github.com/Islandora-Devops/islandora-playbook) to get started.
## License
[GPLv2](http://www.gnu.org/licenses/gpl-2.0.txt)

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

21
modules/islandora_core_feature/config/install/field.storage.media.field_original_name.yml

@ -0,0 +1,21 @@
langcode: en
status: true
dependencies:
enforced:
module:
- islandora_core_feature
module:
- media
id: media.field_original_name
field_name: field_original_name
entity_type: media
type: string_long
settings:
case_sensitive: false
module: core
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false

73
modules/islandora_iiif/CONTRIBUTING.md

@ -0,0 +1,73 @@
# Welcome!
If you are reading this document then you are interested in contributing to Islandora 8. All contributions are welcome: use-cases, documentation, code, patches, bug reports, feature requests, etc. You do not need to be a programmer to speak up!
We also have an IRC channel -- #islandora -- on freenode.net. Feel free to hang out there, ask questions, and help others out if you can.
Please note that this project operates under the [Islandora Community Code of Conduct](http://islandora.ca/codeofconduct). By participating in this project you agree to abide by its terms.
## Workflows
The group meets each Wednesday at 1:00 PM Eastern. Meeting notes and announcements are posted to the [Islandora community list](https://groups.google.com/forum/#!forum/islandora) and the [Islandora developers list](https://groups.google.com/forum/#!forum/islandora-dev). You can view meeting agendas, notes, and call-in information [here](https://github.com/Islandora/documentation/wiki#islandora-8-tech-calls). Anybody is welcome to join the calls, and add items to the agenda.
### Use cases
If you would like to submit a use case to the Islandora 8 project, please submit an issue [here](https://github.com/Islandora/documentation/issues/new) using the [Use Case template](https://github.com/Islandora/documentation/wiki/Use-Case-template), prepending "Use Case:" to the title of the issue.
### Documentation
You can contribute documentation in two different ways. One way is to create an issue [here](https://github.com/Islandora/documentation/issues/new), prepending "Documentation:" to the title of the issue. Another way is by pull request, which is the same process as [Contribute Code](https://github.com/Islandora/documentation/blob/master/CONTRIBUTING.md#contribute-code). All documentation resides in [`docs`](https://github.com/Islandora/documentation/tree/master/docs).
### Request a new feature
To request a new feature you should [open an issue in the Islandora 8 repository](https://github.com/Islandora/documentation/issues/new) or create a use case (see the _Use cases_ section above), and summarize the desired functionality. Prepend "Enhancement:" if creating an issue on the project repo, and "Use Case:" if creating a use case.
### Report a bug
To report a bug you should [open an issue in the Islandora 8 repository](https://github.com/Islandora/documentation/issues/new) that summarizes the bug. Prepend the label "Bug:" to the title of the issue.
In order to help us understand and fix the bug it would be great if you could provide us with:
1. The steps to reproduce the bug. This includes information about e.g. the Islandora version you were using along with the versions of stack components.
2. The expected behavior.
3. The actual, incorrect behavior.
Feel free to search the issue queue for existing issues (aka tickets) that already describe the problem; if there is such a ticket please add your information as a comment.
**If you want to provide a pull along with your bug report:**
That is great! In this case please send us a pull request as described in the section _Create a pull request_ below.
### Contribute code
Before you set out to contribute code you will need to have completed a [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or be covered by a [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). The signed copy of the license agreement should be sent to <mailto:community@islandora.ca>
_If you are interested in contributing code to Islandora but do not know where to begin:_
In this case you should [browse open issues](https://github.com/Islandora/documentation/issues) and check out [use cases](https://github.com/Islandora/documentation/labels/use%20case).
If you are contributing Drupal code, it must adhere to [Drupal Coding Standards](https://www.drupal.org/coding-standards); Travis CI will check for this on pull requests.
Contributions to the Islandora codebase should be sent as GitHub pull requests. See section _Create a pull request_ below for details. If there is any problem with the pull request we can work through it using the commenting features of GitHub.
* For _small patches_, feel free to submit pull requests directly for those patches.
* For _larger code contributions_, please use the following process. The idea behind this process is to prevent any wasted work and catch design issues early on.
1. [Open an issue](https://github.com/Islandora/documentation/issues), prepending "Enhancement:" in the title if a similar issue does not exist already. If a similar issue does exist, then you may consider participating in the work on the existing issue.
2. Comment on the issue with your plan for implementing the issue. Explain what pieces of the codebase you are going to touch and how everything is going to fit together.
3. Islandora committers will work with you on the design to make sure you are on the right track.
4. Implement your issue, create a pull request (see below), and iterate from there.
### Create a pull request
Take a look at [Creating a pull request](https://help.github.com/articles/creating-a-pull-request). In a nutshell you need to:
1. [Fork](https://help.github.com/articles/fork-a-repo) this repository to your personal or institutional GitHub account (depending on the CLA you are working under). Be cautious of which branches you work from though (you'll want to base your work off master, or for Drupal modules use the most recent version branch). See [Fork a repo](https://help.github.com/articles/fork-a-repo) for detailed instructions.
2. Commit any changes to your fork.
3. Send a [pull request](https://help.github.com/articles/creating-a-pull-request) using the [pull request template](https://github.com/Islandora/documentation/blob/master/.github/PULL_REQUEST_TEMPLATE.md) to the Islandora GitHub repository that you forked in step 1. If your pull request is related to an existing issue -- for instance, because you reported a [bug/issue](https://github.com/Islandora/documentation/issues) earlier -- prefix the title of your pull request with the corresponding issue number (e.g. `issue-123: ...`). Please also include a reference to the issue in the description of the pull. This can be done by using '#' plus the issue number like so '#123', also try to pick an appropriate name for the branch in which you're issuing the pull request from.
You may want to read [Syncing a fork](https://help.github.com/articles/syncing-a-fork) for instructions on how to keep your fork up to date with the latest changes of the upstream (official) repository.
## License Agreements
The Islandora Foundation requires that contributors complete a [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or be covered by a [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). The signed copy of the license agreement should be sent to <a href="mailto:community@islandora.ca?Subject=Contributor%20License%20Agreement" target="_top">community@islandora.ca</a>. This license is for your protection as a contributor as well as the protection of the Foundation and its users; it does not change your rights to use your own contributions for any other purpose. A list of current CLAs is kept [here](https://github.com/Islandora/islandora/wiki/Contributor-License-Agreements).

339
modules/islandora_iiif/LICENSE

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

49
modules/islandora_iiif/README.md

@ -0,0 +1,49 @@
# Islandora IIIF
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.2-8892BF.svg?style=flat-square)](https://php.net/)
[![Contribution Guidelines](http://img.shields.io/badge/CONTRIBUTING-Guidelines-blue.svg)](./CONTRIBUTING.md)
[![LICENSE](https://img.shields.io/badge/license-GPLv2-blue.svg?style=flat-square)](./LICENSE)
## Introduction
Provides IIIF manifests using views.
## Requirements
- `islandora` and `islandora_core_feature`
- A IIIF image server (such as Cantaloupe)
## Installation
For a full digital repository solution, see our [installation documentation](https://islandora.github.io/documentation/installation/).
To download/enable just this module, use the following from the command line:
```bash
$ composer require islandora/islandora
$ drush en islandora_core_feature
$ drush mim islandora_tags
$ drush en islandora_iiif
```
## Configuration
You can set the following configuration at `admin/config/islandora/iiif`:
- IIIF Image server location
- The URL to your IIIF image server (without trailing slash).
## Documentation
Official documentation is available on the [Islandora 8 documentation site](https://islandora.github.io/documentation/).
## Development
If you would like to contribute, please get involved by attending our weekly [Tech Call](https://github.com/Islandora/documentation/wiki). We love to hear from you!
If you would like to contribute code to the project, you need to be covered by an Islandora Foundation [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). Please see the [Contributors](http://islandora.ca/resources/contributors) pages on Islandora.ca for more information.
We recommend using the [islandora-playbook](https://github.com/Islandora-Devops/islandora-playbook) to get started.
## License
[GPLv2](http://www.gnu.org/licenses/gpl-2.0.txt)

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

4
modules/islandora_image/.travis.yml

@ -13,12 +13,12 @@ branches:
- /^8.x/
before_install:
- export SCRIPT_DIR=$HOME/CLAW/.scripts
- export SCRIPT_DIR=$HOME/islandora/.scripts
- export DRUPAL_DIR=/opt/drupal
- export COMPOSER_PATH="/home/travis/.phpenv/versions/$TRAVIS_PHP_VERSION/bin/composer"
install:
- git clone https://github.com/Islandora-CLAW/CLAW.git $HOME/CLAW
- git clone https://github.com/Islandora/documentation.git $HOME/islandora
- $SCRIPT_DIR/travis_setup_drupal.sh
- git -C "$TRAVIS_BUILD_DIR" checkout -b travis-testing
- cd $DRUPAL_DIR;

73
modules/islandora_image/CONTRIBUTING.md

@ -0,0 +1,73 @@
# Welcome!
If you are reading this document then you are interested in contributing to Islandora 8. All contributions are welcome: use-cases, documentation, code, patches, bug reports, feature requests, etc. You do not need to be a programmer to speak up!
We also have an IRC channel -- #islandora -- on freenode.net. Feel free to hang out there, ask questions, and help others out if you can.
Please note that this project operates under the [Islandora Community Code of Conduct](http://islandora.ca/codeofconduct). By participating in this project you agree to abide by its terms.
## Workflows
The group meets each Wednesday at 1:00 PM Eastern. Meeting notes and announcements are posted to the [Islandora community list](https://groups.google.com/forum/#!forum/islandora) and the [Islandora developers list](https://groups.google.com/forum/#!forum/islandora-dev). You can view meeting agendas, notes, and call-in information [here](https://github.com/Islandora/documentation/wiki#islandora-8-tech-calls). Anybody is welcome to join the calls, and add items to the agenda.
### Use cases
If you would like to submit a use case to the Islandora 8 project, please submit an issue [here](https://github.com/Islandora/documentation/issues/new) using the [Use Case template](https://github.com/Islandora/documentation/wiki/Use-Case-template), prepending "Use Case:" to the title of the issue.
### Documentation
You can contribute documentation in two different ways. One way is to create an issue [here](https://github.com/Islandora/documentation/issues/new), prepending "Documentation:" to the title of the issue. Another way is by pull request, which is the same process as [Contribute Code](https://github.com/Islandora/documentation/blob/master/CONTRIBUTING.md#contribute-code). All documentation resides in [`docs`](https://github.com/Islandora/documentation/tree/master/docs).
### Request a new feature
To request a new feature you should [open an issue in the Islandora 8 repository](https://github.com/Islandora/documentation/issues/new) or create a use case (see the _Use cases_ section above), and summarize the desired functionality. Prepend "Enhancement:" if creating an issue on the project repo, and "Use Case:" if creating a use case.
### Report a bug
To report a bug you should [open an issue in the Islandora 8 repository](https://github.com/Islandora/documentation/issues/new) that summarizes the bug. Prepend the label "Bug:" to the title of the issue.
In order to help us understand and fix the bug it would be great if you could provide us with:
1. The steps to reproduce the bug. This includes information about e.g. the Islandora version you were using along with the versions of stack components.
2. The expected behavior.
3. The actual, incorrect behavior.
Feel free to search the issue queue for existing issues (aka tickets) that already describe the problem; if there is such a ticket please add your information as a comment.
**If you want to provide a pull along with your bug report:**
That is great! In this case please send us a pull request as described in the section _Create a pull request_ below.
### Contribute code
Before you set out to contribute code you will need to have completed a [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or be covered by a [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). The signed copy of the license agreement should be sent to <mailto:community@islandora.ca>
_If you are interested in contributing code to Islandora but do not know where to begin:_
In this case you should [browse open issues](https://github.com/Islandora/documentation/issues) and check out [use cases](https://github.com/Islandora/documentation/labels/use%20case).
If you are contributing Drupal code, it must adhere to [Drupal Coding Standards](https://www.drupal.org/coding-standards); Travis CI will check for this on pull requests.
Contributions to the Islandora codebase should be sent as GitHub pull requests. See section _Create a pull request_ below for details. If there is any problem with the pull request we can work through it using the commenting features of GitHub.
* For _small patches_, feel free to submit pull requests directly for those patches.
* For _larger code contributions_, please use the following process. The idea behind this process is to prevent any wasted work and catch design issues early on.
1. [Open an issue](https://github.com/Islandora/documentation/issues), prepending "Enhancement:" in the title if a similar issue does not exist already. If a similar issue does exist, then you may consider participating in the work on the existing issue.
2. Comment on the issue with your plan for implementing the issue. Explain what pieces of the codebase you are going to touch and how everything is going to fit together.
3. Islandora committers will work with you on the design to make sure you are on the right track.
4. Implement your issue, create a pull request (see below), and iterate from there.
### Create a pull request
Take a look at [Creating a pull request](https://help.github.com/articles/creating-a-pull-request). In a nutshell you need to:
1. [Fork](https://help.github.com/articles/fork-a-repo) this repository to your personal or institutional GitHub account (depending on the CLA you are working under). Be cautious of which branches you work from though (you'll want to base your work off master, or for Drupal modules use the most recent version branch). See [Fork a repo](https://help.github.com/articles/fork-a-repo) for detailed instructions.
2. Commit any changes to your fork.
3. Send a [pull request](https://help.github.com/articles/creating-a-pull-request) using the [pull request template](https://github.com/Islandora/documentation/blob/master/.github/PULL_REQUEST_TEMPLATE.md) to the Islandora GitHub repository that you forked in step 1. If your pull request is related to an existing issue -- for instance, because you reported a [bug/issue](https://github.com/Islandora/documentation/issues) earlier -- prefix the title of your pull request with the corresponding issue number (e.g. `issue-123: ...`). Please also include a reference to the issue in the description of the pull. This can be done by using '#' plus the issue number like so '#123', also try to pick an appropriate name for the branch in which you're issuing the pull request from.
You may want to read [Syncing a fork](https://help.github.com/articles/syncing-a-fork) for instructions on how to keep your fork up to date with the latest changes of the upstream (official) repository.
## License Agreements
The Islandora Foundation requires that contributors complete a [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or be covered by a [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). The signed copy of the license agreement should be sent to <a href="mailto:community@islandora.ca?Subject=Contributor%20License%20Agreement" target="_top">community@islandora.ca</a>. This license is for your protection as a contributor as well as the protection of the Foundation and its users; it does not change your rights to use your own contributions for any other purpose. A list of current CLAs is kept [here](https://github.com/Islandora/islandora/wiki/Contributor-License-Agreements).

41
modules/islandora_image/README.md

@ -1,23 +1,52 @@
# ![Islandora Image](https://cloud.githubusercontent.com/assets/2371345/24199472/6f7bfb7a-0ee8-11e7-9c94-754762fd5566.png) Islandora Image
[![Contribution Guidelines](http://img.shields.io/badge/CONTRIBUTING-Guidelines-blue.svg)](../../CONTRIBUTING.md)
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.2-8892BF.svg?style=flat-square)](https://php.net/)
[![Contribution Guidelines](http://img.shields.io/badge/CONTRIBUTING-Guidelines-blue.svg)](./CONTRIBUTING.md)
[![LICENSE](https://img.shields.io/badge/license-GPLv2-blue.svg?style=flat-square)](./LICENSE)
## Introduction
Islandora Image module for Drupal 8.2.x
Provides an action to convert images with a [Houdini](https://github.com/Islandora/Crayfish/tree/dev/Houdini) (`imagemagick`) server.
## Requirements
- `islandora` and `islandora_core_feature`
- A Houdini microservice
- A message broker (e.g. Activemq) for Islandora 8
- `islandora-connector-derivative` (from [Alpaca](https://github.com/Islandora/Alpaca/tree/dev/islandora-connector-derivative)) configured for Houdini
## Installation
For a full digital repository solution (including Houdini), see our [installation documentation](https://islandora.github.io/documentation/installation/).
## Maintainers
To download/enable just this module, use the following from the command line:
Current maintainers:
```bash
$ composer require islandora/islandora
$ drush en islandora_core_feature
$ drush mim islandora_tags
$ drush en islandora_image
```
* [Danny Lamb](https://github.com/dannylamb)
## Documentation
Further documentation for this module is available on the [Islandora 8 documentation site](https://islandora.github.io/documentation/).
## Troubleshooting/Issues
Having problems or solved a problem? Check out the Islandora google groups for a solution.
* [Islandora Group](https://groups.google.com/forum/?hl=en&fromgroups#!forum/islandora)
* [Islandora Dev Group](https://groups.google.com/forum/?hl=en&fromgroups#!forum/islandora-dev)
## Development
If you would like to contribute, please get involved by attending our weekly [Tech Call](https://github.com/Islandora-CLAW/CLAW/wiki). We love to hear from you!
If you would like to contribute, please get involved by attending our weekly [Tech Call](https://github.com/Islandora/documentation/wiki). We love to hear from you!
If you would like to contribute code to the project, you need to be covered by an Islandora Foundation [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). Please see the [Contributors](http://islandora.ca/resources/contributors) pages on Islandora.ca for more information.
We recommend using the [islandora-playbook](https://github.com/Islandora-Devops/islandora-playbook) to get started.
## License
[GPLv2](http://www.gnu.org/licenses/gpl-2.0.txt)

3
modules/islandora_image/config/schema/islandora_image.info.yml → modules/islandora_image/config/schema/islandora_image.schema.yml

@ -8,6 +8,9 @@ action.configuration.generate_image_derivative:
event:
type: text
label: 'Event Type'
destination_media_type:
type: text
label: 'Destination media type'
source_term_uri:
type: text
label: 'Source term uri'

1
modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php

@ -48,6 +48,7 @@ class GenerateImageDerivativeTest extends GenerateDerivativeTestBase {
$this->getSession()->getPage()->fillField('edit-label', "Generate image test derivative");
$this->getSession()->getPage()->fillField('edit-id', "generate_image_test_derivative");
$this->getSession()->getPage()->fillField('edit-queue', "generate-image-test-derivative");
$this->getSession()->getPage()->fillField('edit-destination-media-type', $this->testMediaType->label());
$this->getSession()->getPage()->fillField("edit-source-term", $this->preservationMasterTerm->label());
$this->getSession()->getPage()->fillField("edit-derivative-term", $this->serviceFileTerm->label());
$this->getSession()->getPage()->fillField('edit-mimetype', "image/jpeg");

73
modules/islandora_text_extraction/CONTRIBUTING.md

@ -0,0 +1,73 @@
# Welcome!
If you are reading this document then you are interested in contributing to Islandora 8. All contributions are welcome: use-cases, documentation, code, patches, bug reports, feature requests, etc. You do not need to be a programmer to speak up!
We also have an IRC channel -- #islandora -- on freenode.net. Feel free to hang out there, ask questions, and help others out if you can.
Please note that this project operates under the [Islandora Community Code of Conduct](http://islandora.ca/codeofconduct). By participating in this project you agree to abide by its terms.
## Workflows
The group meets each Wednesday at 1:00 PM Eastern. Meeting notes and announcements are posted to the [Islandora community list](https://groups.google.com/forum/#!forum/islandora) and the [Islandora developers list](https://groups.google.com/forum/#!forum/islandora-dev). You can view meeting agendas, notes, and call-in information [here](https://github.com/Islandora/documentation/wiki#islandora-8-tech-calls). Anybody is welcome to join the calls, and add items to the agenda.
### Use cases
If you would like to submit a use case to the Islandora 8 project, please submit an issue [here](https://github.com/Islandora/documentation/issues/new) using the [Use Case template](https://github.com/Islandora/documentation/wiki/Use-Case-template), prepending "Use Case:" to the title of the issue.
### Documentation
You can contribute documentation in two different ways. One way is to create an issue [here](https://github.com/Islandora/documentation/issues/new), prepending "Documentation:" to the title of the issue. Another way is by pull request, which is the same process as [Contribute Code](https://github.com/Islandora/documentation/blob/master/CONTRIBUTING.md#contribute-code). All documentation resides in [`docs`](https://github.com/Islandora/documentation/tree/master/docs).
### Request a new feature
To request a new feature you should [open an issue in the Islandora 8 repository](https://github.com/Islandora/documentation/issues/new) or create a use case (see the _Use cases_ section above), and summarize the desired functionality. Prepend "Enhancement:" if creating an issue on the project repo, and "Use Case:" if creating a use case.
### Report a bug
To report a bug you should [open an issue in the Islandora 8 repository](https://github.com/Islandora/documentation/issues/new) that summarizes the bug. Prepend the label "Bug:" to the title of the issue.
In order to help us understand and fix the bug it would be great if you could provide us with:
1. The steps to reproduce the bug. This includes information about e.g. the Islandora version you were using along with the versions of stack components.
2. The expected behavior.
3. The actual, incorrect behavior.
Feel free to search the issue queue for existing issues (aka tickets) that already describe the problem; if there is such a ticket please add your information as a comment.
**If you want to provide a pull along with your bug report:**
That is great! In this case please send us a pull request as described in the section _Create a pull request_ below.
### Contribute code
Before you set out to contribute code you will need to have completed a [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or be covered by a [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). The signed copy of the license agreement should be sent to <mailto:community@islandora.ca>
_If you are interested in contributing code to Islandora but do not know where to begin:_
In this case you should [browse open issues](https://github.com/Islandora/documentation/issues) and check out [use cases](https://github.com/Islandora/documentation/labels/use%20case).
If you are contributing Drupal code, it must adhere to [Drupal Coding Standards](https://www.drupal.org/coding-standards); Travis CI will check for this on pull requests.
Contributions to the Islandora codebase should be sent as GitHub pull requests. See section _Create a pull request_ below for details. If there is any problem with the pull request we can work through it using the commenting features of GitHub.
* For _small patches_, feel free to submit pull requests directly for those patches.
* For _larger code contributions_, please use the following process. The idea behind this process is to prevent any wasted work and catch design issues early on.
1. [Open an issue](https://github.com/Islandora/documentation/issues), prepending "Enhancement:" in the title if a similar issue does not exist already. If a similar issue does exist, then you may consider participating in the work on the existing issue.
2. Comment on the issue with your plan for implementing the issue. Explain what pieces of the codebase you are going to touch and how everything is going to fit together.
3. Islandora committers will work with you on the design to make sure you are on the right track.
4. Implement your issue, create a pull request (see below), and iterate from there.
### Create a pull request
Take a look at [Creating a pull request](https://help.github.com/articles/creating-a-pull-request). In a nutshell you need to:
1. [Fork](https://help.github.com/articles/fork-a-repo) this repository to your personal or institutional GitHub account (depending on the CLA you are working under). Be cautious of which branches you work from though (you'll want to base your work off master, or for Drupal modules use the most recent version branch). See [Fork a repo](https://help.github.com/articles/fork-a-repo) for detailed instructions.
2. Commit any changes to your fork.
3. Send a [pull request](https://help.github.com/articles/creating-a-pull-request) using the [pull request template](https://github.com/Islandora/documentation/blob/master/.github/PULL_REQUEST_TEMPLATE.md) to the Islandora GitHub repository that you forked in step 1. If your pull request is related to an existing issue -- for instance, because you reported a [bug/issue](https://github.com/Islandora/documentation/issues) earlier -- prefix the title of your pull request with the corresponding issue number (e.g. `issue-123: ...`). Please also include a reference to the issue in the description of the pull. This can be done by using '#' plus the issue number like so '#123', also try to pick an appropriate name for the branch in which you're issuing the pull request from.
You may want to read [Syncing a fork](https://help.github.com/articles/syncing-a-fork) for instructions on how to keep your fork up to date with the latest changes of the upstream (official) repository.
## License Agreements
The Islandora Foundation requires that contributors complete a [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or be covered by a [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). The signed copy of the license agreement should be sent to <a href="mailto:community@islandora.ca?Subject=Contributor%20License%20Agreement" target="_top">community@islandora.ca</a>. This license is for your protection as a contributor as well as the protection of the Foundation and its users; it does not change your rights to use your own contributions for any other purpose. A list of current CLAs is kept [here](https://github.com/Islandora/islandora/wiki/Contributor-License-Agreements).

69
modules/islandora_text_extraction/README.md

@ -1,44 +1,49 @@
# islandora_text_extraction
### Connects Islandora 8 to Hypercube microservice and extracts text from PDFs
# Islandora Text Extraction
Install module in the usual way,
then copy `assets/ca.islandora.alpaca.connector.ocr.blueprint.xml`
to `/opt/karaf/deploy` on the server.
_note:_ This config file assumes a URL of `http://localhost:8000/hypercube`.
If your service is found elsewhere this must be changed.
There is no need to restart.
In the usual Ansible build this will require no modification.
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.2-8892BF.svg?style=flat-square)](https://php.net/)
[![Contribution Guidelines](http://img.shields.io/badge/CONTRIBUTING-Guidelines-blue.svg)](./CONTRIBUTING.md)
[![LICENSE](https://img.shields.io/badge/license-GPLv2-blue.svg?style=flat-square)](./LICENSE)
If a parent node is tagged as `Digital Document` an `Image` tagged media
will extract text from that image at the time of ingestion.
The content type of the parent node should be configured to allow multiple tags.
## Introduction
_note:_ Media are linked to their parent nodes with the `Media Of`
entity reference field. If you wish to attach the PDF (or any other ) media type
to a parent node which has any content type other than Repository Item
(islandora_object) the parent content type will have to be added to the `Media Of`
field in the media type description.
Provides an action to extract text with a [Hypercube](https://github.com/Islandora/Crayfish/tree/dev/Hypercube) (`tessseract` and `pdftotext`) server, as well as a Media type to hold the extracted text.
## Prepare module for PDF text extraction
Install `texttopdf` on your server if not already present.
On an Ubuntu/Debian machine like the default claw playbook run
`sudo apt-get install poppler-utils`
## Requirements
test to see its been properly installed with `which pdftotext`
- `islandora` and `islandora_core_feature`
- A Hypercube microservice
- A message broker (e.g. Activemq) for Islandora 8
- An instance of `islandora-connector-derivative` (from [Alpaca](https://github.com/Islandora/Alpaca/tree/dev/islandora-connector-derivative)) configured for Hypercube
Install php libraries with `composer require spatie/pdf-to-text`
## Installation
In the unlikely event that your `pdftotext` binary exists on your server
outside of the system path, the path to the binary can be set at
`/admin/config/islandora/text_extraction`.
For a full digital repository solution (including a Hypercube microservice), see our [installation documentation](https://islandora.github.io/documentation/installation/).
## Using text extraction ##
The containing document must be tagged as `Digital Document`,
and the media must be tagged as `Original File`.
A new editable `Extracted Text` media will be created and attached when `PDF` or
`Image` media types are added to a node.
To download/enable just this module, use the following from the command line:
```bash
$ composer require islandora/islandora
$ drush en islandora_core_feature
$ drush mim islandora_tags
$ drush en islandora_text_extraction
```
## Documentation
Official documentation is available on the [Islandora 8 documentation site](https://islandora.github.io/documentation/).
## Sponsors
Original work for this module was done by @ajstanley for @roblib at University of Prince Edward Island.
## Development
If you would like to contribute, please get involved by attending our weekly [Tech Call](https://github.com/Islandora/documentation/wiki). We love to hear from you!
If you would like to contribute code to the project, you need to be covered by an Islandora Foundation [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). Please see the [Contributors](http://islandora.ca/resources/contributors) pages on Islandora.ca for more information.
We recommend using the [islandora-playbook](https://github.com/Islandora-Devops/islandora-playbook) to get started.
## License
[GPLv2](http://www.gnu.org/licenses/gpl-2.0.txt)

23
modules/islandora_text_extraction/islandora_text_extraction.install

@ -1,23 +0,0 @@
<?php
/**
* @file
* Install/update hook implementations.
*/
use Drupal\field\Entity\FieldConfig;
/**
* Implements hook_install().
*/
function islandora_text_extraction_install() {
// Add txt extension if it doesn't already exist;.
$field = FieldConfig::load("media.file.field_media_file");
$fieldSettings = $field->getSettings();
$extensions = $fieldSettings['file_extensions'];
if (!strpos($extensions, 'txt')) {
$fieldSettings['file_extensions'] .= ' txt';
$field->set('settings', $fieldSettings);
$field->save();
}
}

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

6
modules/islandora_text_extraction/tests/src/Functional/LoadTest.php

@ -3,14 +3,14 @@
namespace Drupal\Tests\islandora_text_extraction\Functional;
use Drupal\Core\Url;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\islandora\Functional\IslandoraFunctionalTestBase;
/**
* Simple test to ensure that main page loads with module enabled.
*
* @group islandora_text_extraction
*/
class LoadTest extends BrowserTestBase {
class LoadTest extends IslandoraFunctionalTestBase {
/**
* Modules to enable.
@ -29,7 +29,7 @@ class LoadTest extends BrowserTestBase {
/**
* {@inheritdoc}
*/
protected function setUp() {
public function setUp() {
parent::setUp();
$this->user = $this->drupalCreateUser(['administer site configuration']);
$this->drupalLogin($this->user);

73
modules/islandora_text_extraction_defaults/CONTRIBUTING.md

@ -0,0 +1,73 @@
# Welcome!
If you are reading this document then you are interested in contributing to Islandora 8. All contributions are welcome: use-cases, documentation, code, patches, bug reports, feature requests, etc. You do not need to be a programmer to speak up!
We also have an IRC channel -- #islandora -- on freenode.net. Feel free to hang out there, ask questions, and help others out if you can.
Please note that this project operates under the [Islandora Community Code of Conduct](http://islandora.ca/codeofconduct). By participating in this project you agree to abide by its terms.
## Workflows
The group meets each Wednesday at 1:00 PM Eastern. Meeting notes and announcements are posted to the [Islandora community list](https://groups.google.com/forum/#!forum/islandora) and the [Islandora developers list](https://groups.google.com/forum/#!forum/islandora-dev). You can view meeting agendas, notes, and call-in information [here](https://github.com/Islandora/documentation/wiki#islandora-8-tech-calls). Anybody is welcome to join the calls, and add items to the agenda.
### Use cases
If you would like to submit a use case to the Islandora 8 project, please submit an issue [here](https://github.com/Islandora/documentation/issues/new) using the [Use Case template](https://github.com/Islandora/documentation/wiki/Use-Case-template), prepending "Use Case:" to the title of the issue.
### Documentation
You can contribute documentation in two different ways. One way is to create an issue [here](https://github.com/Islandora/documentation/issues/new), prepending "Documentation:" to the title of the issue. Another way is by pull request, which is the same process as [Contribute Code](https://github.com/Islandora/documentation/blob/master/CONTRIBUTING.md#contribute-code). All documentation resides in [`docs`](https://github.com/Islandora/documentation/tree/master/docs).
### Request a new feature
To request a new feature you should [open an issue in the Islandora 8 repository](https://github.com/Islandora/documentation/issues/new) or create a use case (see the _Use cases_ section above), and summarize the desired functionality. Prepend "Enhancement:" if creating an issue on the project repo, and "Use Case:" if creating a use case.
### Report a bug
To report a bug you should [open an issue in the Islandora 8 repository](https://github.com/Islandora/documentation/issues/new) that summarizes the bug. Prepend the label "Bug:" to the title of the issue.
In order to help us understand and fix the bug it would be great if you could provide us with:
1. The steps to reproduce the bug. This includes information about e.g. the Islandora version you were using along with the versions of stack components.
2. The expected behavior.
3. The actual, incorrect behavior.
Feel free to search the issue queue for existing issues (aka tickets) that already describe the problem; if there is such a ticket please add your information as a comment.
**If you want to provide a pull along with your bug report:**
That is great! In this case please send us a pull request as described in the section _Create a pull request_ below.
### Contribute code
Before you set out to contribute code you will need to have completed a [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or be covered by a [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). The signed copy of the license agreement should be sent to <mailto:community@islandora.ca>
_If you are interested in contributing code to Islandora but do not know where to begin:_
In this case you should [browse open issues](https://github.com/Islandora/documentation/issues) and check out [use cases](https://github.com/Islandora/documentation/labels/use%20case).
If you are contributing Drupal code, it must adhere to [Drupal Coding Standards](https://www.drupal.org/coding-standards); Travis CI will check for this on pull requests.
Contributions to the Islandora codebase should be sent as GitHub pull requests. See section _Create a pull request_ below for details. If there is any problem with the pull request we can work through it using the commenting features of GitHub.
* For _small patches_, feel free to submit pull requests directly for those patches.
* For _larger code contributions_, please use the following process. The idea behind this process is to prevent any wasted work and catch design issues early on.
1. [Open an issue](https://github.com/Islandora/documentation/issues), prepending "Enhancement:" in the title if a similar issue does not exist already. If a similar issue does exist, then you may consider participating in the work on the existing issue.
2. Comment on the issue with your plan for implementing the issue. Explain what pieces of the codebase you are going to touch and how everything is going to fit together.
3. Islandora committers will work with you on the design to make sure you are on the right track.
4. Implement your issue, create a pull request (see below), and iterate from there.
### Create a pull request
Take a look at [Creating a pull request](https://help.github.com/articles/creating-a-pull-request). In a nutshell you need to:
1. [Fork](https://help.github.com/articles/fork-a-repo) this repository to your personal or institutional GitHub account (depending on the CLA you are working under). Be cautious of which branches you work from though (you'll want to base your work off master, or for Drupal modules use the most recent version branch). See [Fork a repo](https://help.github.com/articles/fork-a-repo) for detailed instructions.
2. Commit any changes to your fork.
3. Send a [pull request](https://help.github.com/articles/creating-a-pull-request) using the [pull request template](https://github.com/Islandora/documentation/blob/master/.github/PULL_REQUEST_TEMPLATE.md) to the Islandora GitHub repository that you forked in step 1. If your pull request is related to an existing issue -- for instance, because you reported a [bug/issue](https://github.com/Islandora/documentation/issues) earlier -- prefix the title of your pull request with the corresponding issue number (e.g. `issue-123: ...`). Please also include a reference to the issue in the description of the pull. This can be done by using '#' plus the issue number like so '#123', also try to pick an appropriate name for the branch in which you're issuing the pull request from.
You may want to read [Syncing a fork](https://help.github.com/articles/syncing-a-fork) for instructions on how to keep your fork up to date with the latest changes of the upstream (official) repository.
## License Agreements
The Islandora Foundation requires that contributors complete a [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or be covered by a [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). The signed copy of the license agreement should be sent to <a href="mailto:community@islandora.ca?Subject=Contributor%20License%20Agreement" target="_top">community@islandora.ca</a>. This license is for your protection as a contributor as well as the protection of the Foundation and its users; it does not change your rights to use your own contributions for any other purpose. A list of current CLAs is kept [here](https://github.com/Islandora/islandora/wiki/Contributor-License-Agreements).

339
modules/islandora_text_extraction_defaults/LICENSE

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

42
modules/islandora_text_extraction_defaults/README.md

@ -0,0 +1,42 @@
# Islandora Text Extraction Defaults
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.2-8892BF.svg?style=flat-square)](https://php.net/)
[![Contribution Guidelines](http://img.shields.io/badge/CONTRIBUTING-Guidelines-blue.svg)](./CONTRIBUTING.md)
[![LICENSE](https://img.shields.io/badge/license-GPLv2-blue.svg?style=flat-square)](./LICENSE)
## Introduction
Default configuration for `islandora_text_extraction`.
## Requirements
- `islandora_text_extraction`
## Installation
For a full digital repository solution (including a Hypercube microservice), see our [installation documentation](https://islandora.github.io/documentation/installation/).
To download/enable just this module, use the following from the command line:
```bash
$ composer require islandora/islandora
$ drush en islandora_core_feature
$ drush mim islandora_tags
$ drush en islandora_text_extraction
```
## Documentation
Official documentation is available on the [Islandora 8 documentation site](https://islandora.github.io/documentation/).
## Development
If you would like to contribute, please get involved by attending our weekly [Tech Call](https://github.com/Islandora/documentation/wiki). We love to hear from you!
If you would like to contribute code to the project, you need to be covered by an Islandora Foundation [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). Please see the [Contributors](http://islandora.ca/resources/contributors) pages on Islandora.ca for more information.
We recommend using the [islandora-playbook](https://github.com/Islandora-Devops/islandora-playbook) to get started.
## License
[GPLv2](http://www.gnu.org/licenses/gpl-2.0.txt)

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'

73
modules/islandora_video/CONTRIBUTING.md

@ -0,0 +1,73 @@
# Welcome!
If you are reading this document then you are interested in contributing to Islandora 8. All contributions are welcome: use-cases, documentation, code, patches, bug reports, feature requests, etc. You do not need to be a programmer to speak up!
We also have an IRC channel -- #islandora -- on freenode.net. Feel free to hang out there, ask questions, and help others out if you can.
Please note that this project operates under the [Islandora Community Code of Conduct](http://islandora.ca/codeofconduct). By participating in this project you agree to abide by its terms.
## Workflows
The group meets each Wednesday at 1:00 PM Eastern. Meeting notes and announcements are posted to the [Islandora community list](https://groups.google.com/forum/#!forum/islandora) and the [Islandora developers list](https://groups.google.com/forum/#!forum/islandora-dev). You can view meeting agendas, notes, and call-in information [here](https://github.com/Islandora/documentation/wiki#islandora-8-tech-calls). Anybody is welcome to join the calls, and add items to the agenda.
### Use cases
If you would like to submit a use case to the Islandora 8 project, please submit an issue [here](https://github.com/Islandora/documentation/issues/new) using the [Use Case template](https://github.com/Islandora/documentation/wiki/Use-Case-template), prepending "Use Case:" to the title of the issue.
### Documentation
You can contribute documentation in two different ways. One way is to create an issue [here](https://github.com/Islandora/documentation/issues/new), prepending "Documentation:" to the title of the issue. Another way is by pull request, which is the same process as [Contribute Code](https://github.com/Islandora/documentation/blob/master/CONTRIBUTING.md#contribute-code). All documentation resides in [`docs`](https://github.com/Islandora/documentation/tree/master/docs).
### Request a new feature
To request a new feature you should [open an issue in the Islandora 8 repository](https://github.com/Islandora/documentation/issues/new) or create a use case (see the _Use cases_ section above), and summarize the desired functionality. Prepend "Enhancement:" if creating an issue on the project repo, and "Use Case:" if creating a use case.
### Report a bug
To report a bug you should [open an issue in the Islandora 8 repository](https://github.com/Islandora/documentation/issues/new) that summarizes the bug. Prepend the label "Bug:" to the title of the issue.
In order to help us understand and fix the bug it would be great if you could provide us with:
1. The steps to reproduce the bug. This includes information about e.g. the Islandora version you were using along with the versions of stack components.
2. The expected behavior.
3. The actual, incorrect behavior.
Feel free to search the issue queue for existing issues (aka tickets) that already describe the problem; if there is such a ticket please add your information as a comment.
**If you want to provide a pull along with your bug report:**
That is great! In this case please send us a pull request as described in the section _Create a pull request_ below.
### Contribute code
Before you set out to contribute code you will need to have completed a [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or be covered by a [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). The signed copy of the license agreement should be sent to <mailto:community@islandora.ca>
_If you are interested in contributing code to Islandora but do not know where to begin:_
In this case you should [browse open issues](https://github.com/Islandora/documentation/issues) and check out [use cases](https://github.com/Islandora/documentation/labels/use%20case).
If you are contributing Drupal code, it must adhere to [Drupal Coding Standards](https://www.drupal.org/coding-standards); Travis CI will check for this on pull requests.
Contributions to the Islandora codebase should be sent as GitHub pull requests. See section _Create a pull request_ below for details. If there is any problem with the pull request we can work through it using the commenting features of GitHub.
* For _small patches_, feel free to submit pull requests directly for those patches.
* For _larger code contributions_, please use the following process. The idea behind this process is to prevent any wasted work and catch design issues early on.
1. [Open an issue](https://github.com/Islandora/documentation/issues), prepending "Enhancement:" in the title if a similar issue does not exist already. If a similar issue does exist, then you may consider participating in the work on the existing issue.
2. Comment on the issue with your plan for implementing the issue. Explain what pieces of the codebase you are going to touch and how everything is going to fit together.
3. Islandora committers will work with you on the design to make sure you are on the right track.
4. Implement your issue, create a pull request (see below), and iterate from there.
### Create a pull request
Take a look at [Creating a pull request](https://help.github.com/articles/creating-a-pull-request). In a nutshell you need to:
1. [Fork](https://help.github.com/articles/fork-a-repo) this repository to your personal or institutional GitHub account (depending on the CLA you are working under). Be cautious of which branches you work from though (you'll want to base your work off master, or for Drupal modules use the most recent version branch). See [Fork a repo](https://help.github.com/articles/fork-a-repo) for detailed instructions.
2. Commit any changes to your fork.
3. Send a [pull request](https://help.github.com/articles/creating-a-pull-request) using the [pull request template](https://github.com/Islandora/documentation/blob/master/.github/PULL_REQUEST_TEMPLATE.md) to the Islandora GitHub repository that you forked in step 1. If your pull request is related to an existing issue -- for instance, because you reported a [bug/issue](https://github.com/Islandora/documentation/issues) earlier -- prefix the title of your pull request with the corresponding issue number (e.g. `issue-123: ...`). Please also include a reference to the issue in the description of the pull. This can be done by using '#' plus the issue number like so '#123', also try to pick an appropriate name for the branch in which you're issuing the pull request from.
You may want to read [Syncing a fork](https://help.github.com/articles/syncing-a-fork) for instructions on how to keep your fork up to date with the latest changes of the upstream (official) repository.
## License Agreements
The Islandora Foundation requires that contributors complete a [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or be covered by a [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). The signed copy of the license agreement should be sent to <a href="mailto:community@islandora.ca?Subject=Contributor%20License%20Agreement" target="_top">community@islandora.ca</a>. This license is for your protection as a contributor as well as the protection of the Foundation and its users; it does not change your rights to use your own contributions for any other purpose. A list of current CLAs is kept [here](https://github.com/Islandora/islandora/wiki/Contributor-License-Agreements).

36
modules/islandora_video/README.md

@ -1,23 +1,45 @@
# Islandora Video
[![Contribution Guidelines](http://img.shields.io/badge/CONTRIBUTING-Guidelines-blue.svg)](../../CONTRIBUTING.md)
# Islandora Video
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.2-8892BF.svg?style=flat-square)](https://php.net/)
[![Contribution Guidelines](http://img.shields.io/badge/CONTRIBUTING-Guidelines-blue.svg)](./CONTRIBUTING.md)
[![LICENSE](https://img.shields.io/badge/license-GPLv2-blue.svg?style=flat-square)](./LICENSE)
## Introduction
Islandora Video module for Drupal 8.2.x
Provides actions to convert audio with a [Homarus](https://github.com/Islandora/Crayfish/tree/dev/Homarus) (`ffmpeg`) server.
## Requirements
- `islandora` and `islandora_core_feature`
- A Homarus microservice
- A message broker (e.g. Activemq) for Islandora 8
- An instance of `islandora-connector-derivative` (from [Alpaca](https://github.com/Islandora/Alpaca/tree/dev/islandora-connector-derivative)) configured for Homarus
## Installation
## Maintainers
For a full digital repository solution (including a Homarus microservice), see our [installation documentation](https://islandora.github.io/documentation/installation/).
Current maintainers:
To download/enable just this module, use the following from the command line:
* [Danny Lamb](https://github.com/dannylamb)
```bash
$ composer require islandora/islandora
$ drush en islandora_core_feature
$ drush mim islandora_tags
$ drush en islandora_video
```
## Documentation
Official documentation is available on the [Islandora 8 documentation site](https://islandora.github.io/documentation/).
## Development
If you would like to contribute, please get involved by attending our weekly [Tech Call](https://github.com/Islandora-CLAW/CLAW/wiki). We love to hear from you!
If you would like to contribute, please get involved by attending our weekly [Tech Call](https://github.com/Islandora/documentation/wiki). We love to hear from you!
If you would like to contribute code to the project, you need to be covered by an Islandora Foundation [Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_cla.pdf) or [Corporate Contributor License Agreement](http://islandora.ca/sites/default/files/islandora_ccla.pdf). Please see the [Contributors](http://islandora.ca/resources/contributors) pages on Islandora.ca for more information.
We recommend using the [islandora-playbook](https://github.com/Islandora-Devops/islandora-playbook) to get started.
## License
[GPLv2](http://www.gnu.org/licenses/gpl-2.0.txt)

3
modules/islandora_video/config/schema/islandora_video.info.yml → modules/islandora_video/config/schema/islandora_video.schema.yml

@ -8,6 +8,9 @@ action.configuration.generate_video_derivative:
event:
type: text
label: 'Event Type'
destination_media_type:
type: text
label: 'Destination media type'
source_term_uri:
type: text
label: 'Source term uri'

6
modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php

@ -19,10 +19,7 @@ class GenerateVideoDerivativeTest extends GenerateDerivativeTestBase {
/**
* @covers \Drupal\islandora_video\Plugin\Action\GenerateVideoDerivative::defaultConfiguration
* @covers \Drupal\islandora_video\Plugin\Action\GenerateVideoDerivative::buildConfigurationForm
* @covers \Drupal\islandora\Plugin\Action\AbstractGenerateDerivative::defaultConfiguration
* @covers \Drupal\islandora\Plugin\Action\AbstractGenerateDerivative::buildConfigurationForm
* @covers \Drupal\islandora\Plugin\Action\AbstractGenerateDerivative::submitConfigurationForm
* @covers \Drupal\islandora\Plugin\Action\AbstractGenerateDerivative::execute
* @covers \Drupal\islandora_video\Plugin\Action\GenerateVideoDerivative::validateConfigurationForm
*/
public function testGenerateVideoDerivativeFromScratch() {
@ -46,6 +43,7 @@ class GenerateVideoDerivativeTest extends GenerateDerivativeTestBase {
$this->getSession()->getPage()->fillField('edit-label', "Generate video test derivative");
$this->getSession()->getPage()->fillField('edit-id', "generate_video_test_derivative");
$this->getSession()->getPage()->fillField('edit-queue', "generate-video-test-derivative");
$this->getSession()->getPage()->fillField('edit-destination-media-type', $this->testMediaType->label());
$this->getSession()->getPage()->fillField("edit-source-term", $this->preservationMasterTerm->label());
$this->getSession()->getPage()->fillField("edit-derivative-term", $this->serviceFileTerm->label());
$this->getSession()->getPage()->fillField('edit-mimetype', "video/mp4");

65
src/Commands/IslandoraCommands.php

@ -24,11 +24,36 @@ class IslandoraCommands extends DrushCommands {
}
/**
* Validate the provided userid.
* Add the userid option.
*
* @hook option migrate:rollback
* @option userid User ID to rollback the migration.
*/
public function optionsetRollbackUser($options = ['userid' => self::REQ]) {
}
/**
* Implement migrate import validate hook.
*
* @hook validate migrate:import
*/
public function validateUser(CommandData $commandData) {
public function validateUserImport(CommandData $commandData) {
$this->validateUser($commandData);;
}
/**
* Implement migrate rollback validate hook.
*
* @hook validate migrate:rollback
*/
public function validateUserRollback(CommandData $commandData) {
$this->validateUser($commandData);
}
/**
* Validate the provided userid.
*/
protected function validateUser(CommandData $commandData) {
$userid = $commandData->input()->getOption('userid');
if ($userid) {
$account = User::load($userid);
@ -39,11 +64,27 @@ class IslandoraCommands extends DrushCommands {
}
/**
* Switch the active user account to perform the import.
* Implement migrate import pre-command hook.
*
* @hook pre-command migrate:import
*/
public function preImport(CommandData $commandData) {
$this->switchUser($commandData);
}
/**
* Implement migrate rollback pre-command hook.
*
* @hook pre-command migrate:rollback
*/
public function preRollback(CommandData $commandData) {
$this->switchUser($commandData);
}
/**
* Switch the active user account using the provided userid.
*/
protected function switchUser(CommandData $commandData) {
$userid = $commandData->input()->getOption('userid');
if ($userid) {
$account = User::load($userid);
@ -64,11 +105,27 @@ class IslandoraCommands extends DrushCommands {
}
/**
* Switch the user back once the migration is complete.
* Implement migrate import post-command hook.
*
* @hook post-command migrate:import
*/
public function postImport($result, CommandData $commandData) {
$this->switchUserBack($commandData);
}
/**
* Implement migrate rollback post-command hook.
*
* @hook post-command migrate:rollback
*/
public function postRollback($result, CommandData $commandData) {
$this->switchUserBack($commandData);
}
/**
* Switch the user back.
*/
protected function switchUserBack(CommandData $commandData) {
if ($commandData->input()->getOption('userid')) {
$accountSwitcher = \Drupal::service('account_switcher');
$this->logger()->notice(dt(

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

11
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\Core\Session\AccountProxyInterface;
use Drupal\node\NodeInterface;
@ -26,7 +26,7 @@ class ManageMembersController extends EntityController {
/**
* The entity field manager.
*
* @var \Drupal\Core\Entity\EntityFieldManager
* @var \Drupal\Core\Entity\EntityFieldManagerInterface
*/
protected $entityFieldManger;
@ -48,7 +48,7 @@ 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.
@ -57,9 +57,10 @@ class ManageMembersController extends EntityController {
*/
public function __construct(
EntityTypeManagerInterface $entity_type_manager,
EntityFieldManager $entity_field_manager,
RendererInterface $renderer,
AccountProxyInterface $currentUser
EntityFieldManagerInterface $entity_field_manager,
RendererInterface $renderer
) {
$this->entityTypeManager = $entity_type_manager;
$this->entityFieldManager = $entity_field_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

52
src/EventGenerator/EventGenerator.php

@ -6,6 +6,9 @@ use Drupal\Core\Entity\EntityInterface;
use Drupal\islandora\IslandoraUtils;
use Drupal\islandora\MediaSource\MediaSourceService;
use Drupal\user\UserInterface;
use Drupal\Core\Site\Settings;
use Drupal\media\Entity\Media;
use Drupal\Core\Entity\EntityStorageInterface;
/**
* The default EventGenerator implementation.
@ -88,6 +91,10 @@ class EventGenerator implements EventGeneratorInterface {
],
];
$flysystem_config = Settings::get('flysystem');
$fedora_url = $flysystem_config['fedora']['config']['root'];
$event["target"] = $fedora_url;
$entity_type = $entity->getEntityTypeId();
$event_type = $data["event"];
if ($data["event"] == "Generate Derivative") {
@ -99,6 +106,14 @@ class EventGenerator implements EventGeneratorInterface {
$event["summary"] = ucfirst($data["event"]) . " a " . ucfirst($entity_type);
}
if ($data['event'] != "Generate Derivative") {
$isNewRev = FALSE;
if ($entity->getEntityType()->isRevisionable()) {
$isNewRev = $this->isNewRevision($entity);
}
$event["object"]["isNewVersion"] = $isNewRev;
}
// Add REST links for non-file entities.
if ($entity_type != 'file') {
$event['object']['url'][] = [
@ -145,4 +160,41 @@ class EventGenerator implements EventGeneratorInterface {
return json_encode($event);
}
/**
* Method to check if an entity is a new revision.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* Drupal Entity.
*
* @return bool
* Is new version.
*/
protected function isNewRevision(EntityInterface $entity) {
if ($entity->getEntityTypeId() == "node") {
$revision_ids = \Drupal::entityTypeManager()->getStorage($entity->getEntityTypeId())->revisionIds($entity);
return count($revision_ids) > 1;
}
elseif ($entity->getEntityTypeId() == "media") {
$mediaStorage = \Drupal::entityTypeManager()->getStorage($entity->getEntityTypeId());
return count($this->getRevisionIds($entity, $mediaStorage)) > 1;
}
}
/**
* Method to get the revisionIds of a media object.
*
* @param \Drupal\media\Entity\Media $media
* Media object.
* @param \Drupal\Core\Entity\EntityStorageInterface $media_storage
* Media Storage.
*/
protected function getRevisionIds(Media $media, EntityStorageInterface $media_storage) {
$result = $media_storage->getQuery()
->allRevisions()
->condition($media->getEntityType()->getKey('id'), $media->id())
->sort($media->getEntityType()->getKey('revision'), 'DESC')
->execute();
return array_keys($result);
}
}

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

151
src/Form/IslandoraSettingsForm.php

@ -3,9 +3,10 @@
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;
use Drupal\Core\Url;
use GuzzleHttp\Exception\ConnectException;
use Islandora\Crayfish\Commons\Client\GeminiClient;
@ -21,28 +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);
}
/**
@ -77,16 +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' => $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] = [
@ -95,6 +154,16 @@ class IslandoraSettingsForm extends ConfigFormBase {
'#default_value' => $config->get(self::GEMINI_URL),
];
$flysystem_config = Settings::get('flysystem');
$fedora_url = $flysystem_config['fedora']['config']['root'];
$form[self::FEDORA_URL] = [
'#type' => 'textfield',
'#title' => $this->t('Fedora URL'),
'#attributes' => ['readonly' => 'readonly'],
'#default_value' => $fedora_url,
];
$selected_bundles = $config->get(self::GEMINI_PSEUDO);
$options = [];
@ -111,8 +180,8 @@ class IslandoraSettingsForm extends ConfigFormBase {
$form['bundle_container'] = [
'#type' => 'details',
'#title' => $this->t('Bundles with Gemini URI Pseudo field'),
'#description' => $this->t('The selected bundles can display the pseudo-field showing the Gemini linked URI. Configured in the field display.'),
'#title' => $this->t('Fedora URL Display'),
'#description' => $this->t('Selected bundles can display the Fedora URL of repository content.'),
'#open' => TRUE,
self::GEMINI_PSEUDO => [
'#type' => 'checkboxes',
@ -129,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();
}
@ -152,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,
@ -162,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));
@ -201,7 +303,6 @@ class IslandoraSettingsForm extends ConfigFormBase {
$this->t('Must enter Gemini URL before selecting bundles to display a pseudo field on.')
);
}
}
/**
@ -212,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'],

87
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,
@ -235,12 +235,32 @@ class IslandoraUtils {
* Calling getStorage() throws if the storage handler couldn't be loaded.
*/
public function getTermForUri($uri) {
$results = $this->entityQuery->get('taxonomy_term')
->condition(self::EXTERNAL_URI_FIELD . '.uri', $uri)
// Get authority link fields to search.
$field_map = $this->entityFieldManager->getFieldMap();
$fields = [];
foreach ($field_map['taxonomy_term'] as $field_name => $field_data) {
if ($field_data['type'] == 'authority_link') {
$fields[] = $field_name;
}
}
// Add field_external_uri.
$fields[] = self::EXTERNAL_URI_FIELD;
$query = $this->entityQuery->get('taxonomy_term');
$orGroup = $query->orConditionGroup();
foreach ($fields as $field) {
$orGroup->condition("$field.uri", $uri);
}
$results = $query
->condition($orGroup)
->execute();
if (empty($results)) {
return NULL;
}
return $this->entityTypeManager->getStorage('taxonomy_term')->load(reset($results));
}
@ -258,16 +278,39 @@ class IslandoraUtils {
* be created.
*/
public function getUriForTerm(TermInterface $term) {
if ($term && $term->hasField(self::EXTERNAL_URI_FIELD)) {
$field = $term->get(self::EXTERNAL_URI_FIELD);
if (!$field->isEmpty()) {
$link = $field->first()->getValue();
return $link['uri'];
$fields = $this->getUriFieldNamesForTerms();
foreach ($fields as $field_name) {
if ($term && $term->hasField($field_name)) {
$field = $term->get($field_name);
if (!$field->isEmpty()) {
$link = $field->first()->getValue();
return $link['uri'];
}
}
}
return NULL;
}
/**
* Gets every field name that might contain an external uri for a term.
*
* @return string[]
* Field names for fields that a term may have as an external uri.
*/
public function getUriFieldNamesForTerms() {
// Get authority link fields to search.
$field_map = $this->entityFieldManager->getFieldMap();
$fields = [];
foreach ($field_map['taxonomy_term'] as $field_name => $field_data) {
if ($field_data['type'] == 'authority_link') {
$fields[] = $field_name;
}
}
// Add field_external_uri.
$fields[] = self::EXTERNAL_URI_FIELD;
return $fields;
}
/**
* Executes context reactions for a Node.
*
@ -520,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;

12
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;
@ -19,7 +19,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
*
* @Condition(
* id = "media_has_mimetype",
* label = @Translation("Media has Mime type"),
* label = @Translation("Node has Media with Mime type"),
* context_definitions = {
* "node" = @ContextDefinition("entity:node", label = @Translation("node"))
* }
@ -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;
}
}
}

4
src/Plugin/Condition/MediaHasTerm.php

@ -7,8 +7,8 @@ namespace Drupal\islandora\Plugin\Condition;
*
* @Condition(
* id = "media_has_term",
* label = @Translation("Media has term"),
* context = {
* label = @Translation("Media has term with URI"),
* 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;
}
/**

74
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;
@ -15,8 +15,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
*
* @Condition(
* id = "node_has_term",
* label = @Translation("Node has term"),
* context = {
* label = @Translation("Node has term with URI"),
* 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;
@ -79,6 +79,16 @@ class NodeHasTerm extends ConditionPluginBase implements ContainerFactoryPluginI
);
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return array_merge(
['logic' => 'and'],
parent::defaultConfiguration()
);
}
/**
* {@inheritdoc}
*/
@ -94,12 +104,24 @@ class NodeHasTerm extends ConditionPluginBase implements ContainerFactoryPluginI
$form['term'] = [
'#type' => 'entity_autocomplete',
'#title' => $this->t('Term'),
'#description' => $this->t('Only terms that have external URIs/URLs will appear here.'),
'#tags' => TRUE,
'#default_value' => $default,
'#target_type' => 'taxonomy_term',
'#required' => TRUE,
'#selection_handler' => 'islandora:external_uri',
];
$form['logic'] = [
'#type' => 'radios',
'#title' => $this->t('Logic'),
'#description' => $this->t('Whether to use AND or OR logic to evaluate multiple terms'),
'#options' => [
'and' => 'And',
'or' => 'Or',
],
'#default_value' => $this->configuration['logic'],
];
return parent::buildConfigurationForm($form, $form_state);
}
@ -124,6 +146,9 @@ class NodeHasTerm extends ConditionPluginBase implements ContainerFactoryPluginI
$this->configuration['uri'] = implode(',', $uris);
}
}
$this->configuration['logic'] = $form_state->getValue('logic');
parent::submitConfigurationForm($form, $form_state);
}
@ -153,22 +178,30 @@ class NodeHasTerm extends ConditionPluginBase implements ContainerFactoryPluginI
*/
protected function evaluateEntity(EntityInterface $entity) {
// Find the terms on the node.
$terms = array_filter($entity->referencedEntities(), function ($entity) {
return $entity->getEntityTypeId() == 'taxonomy_term' &&
$entity->hasField(IslandoraUtils::EXTERNAL_URI_FIELD) &&
!$entity->get(IslandoraUtils::EXTERNAL_URI_FIELD)->isEmpty();
$field_names = $this->utils->getUriFieldNamesForTerms();
$terms = array_filter($entity->referencedEntities(), function ($entity) use ($field_names) {
if ($entity->getEntityTypeId() != 'taxonomy_term') {
return FALSE;
}
foreach ($field_names as $field_name) {
if ($entity->hasField($field_name) && !$entity->get($field_name)->isEmpty()) {
return TRUE;
}
}
return FALSE;
});
// Get their URIs.
$haystack = array_map(function ($term) {
return $term->get(IslandoraUtils::EXTERNAL_URI_FIELD)->first()->getValue()['uri'];
return $this->utils->getUriForTerm($term);
},
$terms
);
// FALSE if there's no URIs on the node.
if (empty($haystack)) {
return $this->isNegated() ? TRUE : FALSE;
return FALSE;
}
// Get the URIs to look for. It's a required field, so there
@ -176,12 +209,19 @@ class NodeHasTerm extends ConditionPluginBase implements ContainerFactoryPluginI
$needles = explode(',', $this->configuration['uri']);
// TRUE if every needle is in the haystack.
if (count(array_intersect($needles, $haystack)) == count($needles)) {
return $this->isNegated() ? FALSE : TRUE;
if ($this->configuration['logic'] == 'and') {
if (count(array_intersect($needles, $haystack)) == count($needles)) {
return TRUE;
}
return FALSE;
}
// TRUE if any needle is in the haystack.
else {
if (count(array_intersect($needles, $haystack)) > 0) {
return TRUE;
}
return FALSE;
}
// Otherwise, FALSE.
return $this->isNegated() ? TRUE : FALSE;
}
/**

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;
}
/**

4
src/Plugin/Condition/ParentNodeHasTerm.php

@ -7,8 +7,8 @@ namespace Drupal\islandora\Plugin\Condition;
*
* @Condition(
* id = "parent_node_has_term",
* label = @Translation("Parent node for media has term"),
* context = {
* label = @Translation("Parent node for media has term with URI"),
* context_definitions = {
* "media" = @ContextDefinition("entity:media", required = TRUE , label = @Translation("media"))
* }
* )

56
src/Plugin/ContextReaction/MappingUriPredicateReaction.php → src/Plugin/ContextReaction/JsonldSelfReferenceReaction.php

@ -13,16 +13,18 @@ use Drupal\islandora\IslandoraUtils;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Map URI to predicate context reaction.
* Create a self-reference in RDF when creating JSON-LD.
*
* Formerly called "Map URI to predicate". Renamed for clarity.
*
* @ContextReaction(
* id = "islandora_map_uri_predicate",
* label = @Translation("Map URI to predicate")
* label = @Translation("JSON-LD self-reference")
* )
*/
class MappingUriPredicateReaction extends NormalizerAlterReaction {
class JsonldSelfReferenceReaction extends NormalizerAlterReaction {
const URI_PREDICATE = 'drupal_uri_predicate';
const SELF_REFERENCE_PREDICATE = 'drupal_uri_predicate';
/**
* Media source service.
@ -69,7 +71,7 @@ class MappingUriPredicateReaction extends NormalizerAlterReaction {
* {@inheritdoc}
*/
public function summary() {
return $this->t('Map Drupal URI to configured predicate.');
return $this->t('When creating the JSON-LD for this Drupal entity, add a relationship to itself using this predicate.');
}
/**
@ -77,11 +79,11 @@ class MappingUriPredicateReaction extends NormalizerAlterReaction {
*/
public function execute(EntityInterface $entity = NULL, array &$normalized = NULL, array $context = NULL) {
$config = $this->getConfiguration();
$drupal_predicate = $config[self::URI_PREDICATE];
if (!is_null($drupal_predicate) && !empty($drupal_predicate)) {
$self_ref_predicate = $config[self::SELF_REFERENCE_PREDICATE];
if (!is_null($self_ref_predicate) && !empty($self_ref_predicate)) {
$url = $this->getSubjectUrl($entity);
if ($context['needs_jsonldcontext'] === FALSE) {
$drupal_predicate = NormalizerBase::escapePrefix($drupal_predicate, $context['namespaces']);
$self_ref_predicate = NormalizerBase::escapePrefix($self_ref_predicate, $context['namespaces']);
}
if (isset($normalized['@graph']) && is_array($normalized['@graph'])) {
foreach ($normalized['@graph'] as &$graph) {
@ -91,24 +93,24 @@ class MappingUriPredicateReaction extends NormalizerAlterReaction {
$file = $this->mediaSource->getSourceFile($entity);
$graph['@id'] = $this->utils->getDownloadUrl($file);
}
if (isset($graph[$drupal_predicate])) {
if (!is_array($graph[$drupal_predicate])) {
if ($graph[$drupal_predicate] == $url) {
if (isset($graph[$self_ref_predicate])) {
if (!is_array($graph[$self_ref_predicate])) {
if ($graph[$self_ref_predicate] == $url) {
// Don't add it if it already exists.
return;
}
$tmp = $graph[$drupal_predicate];
$graph[$drupal_predicate] = [$tmp];
$tmp = $graph[$self_ref_predicate];
$graph[$self_ref_predicate] = [$tmp];
}
elseif (array_search($url, array_column($graph[$drupal_predicate], '@id'))) {
elseif (array_search($url, array_column($graph[$self_ref_predicate], '@id'))) {
// Don't add it if it already exists.
return;
}
}
else {
$graph[$drupal_predicate] = [];
$graph[$self_ref_predicate] = [];
}
$graph[$drupal_predicate][] = ["@id" => $url];
$graph[$self_ref_predicate][] = ["@id" => $url];
return;
}
}
@ -121,11 +123,11 @@ class MappingUriPredicateReaction extends NormalizerAlterReaction {
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$config = $this->getConfiguration();
$form[self::URI_PREDICATE] = [
$form[self::SELF_REFERENCE_PREDICATE] = [
'#type' => 'textfield',
'#title' => $this->t('Drupal URI predicate'),
'#description' => $this->t("The Drupal object's URI will be added to the resource with this predicate. Must use a defined prefix."),
'#default_value' => isset($config[self::URI_PREDICATE]) ? $config[self::URI_PREDICATE] : '',
'#title' => $this->t('Self-reference predicate'),
'#description' => $this->t("When creating the JSON-LD for this Drupal entity, add a relationship from the entity to itself using this predicate. It must use a defined RDF namespace prefix."),
'#default_value' => isset($config[self::SELF_REFERENCE_PREDICATE]) ? $config[self::SELF_REFERENCE_PREDICATE] : '',
'#size' => 35,
];
return $form;
@ -135,19 +137,19 @@ class MappingUriPredicateReaction extends NormalizerAlterReaction {
* {@inheritdoc}
*/
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
$drupal_predicate = $form_state->getValue(self::URI_PREDICATE);
if (!is_null($drupal_predicate) and !empty($drupal_predicate)) {
if (preg_match('/^https?:\/\//', $drupal_predicate)) {
$self_ref_predicate = $form_state->getValue(self::SELF_REFERENCE_PREDICATE);
if (!is_null($self_ref_predicate) and !empty($self_ref_predicate)) {
if (preg_match('/^https?:\/\//', $self_ref_predicate)) {
// Can't validate all URIs so we have to trust them.
return;
}
elseif (preg_match('/^([^\s:]+):/', $drupal_predicate, $matches)) {
elseif (preg_match('/^([^\s:]+):/', $self_ref_predicate, $matches)) {
$predicate_prefix = $matches[1];
$rdf = rdf_get_namespaces();
$rdf_prefixes = array_keys($rdf);
if (!in_array($predicate_prefix, $rdf_prefixes)) {
$form_state->setErrorByName(
self::URI_PREDICATE,
self::SELF_REFERENCE_PREDICATE,
$this->t('Namespace prefix @prefix is not registered.',
['@prefix' => $predicate_prefix]
)
@ -156,7 +158,7 @@ class MappingUriPredicateReaction extends NormalizerAlterReaction {
}
else {
$form_state->setErrorByName(
self::URI_PREDICATE,
self::SELF_REFERENCE_PREDICATE,
$this->t('Predicate must use a defined prefix or be a full URI')
);
}
@ -168,7 +170,7 @@ class MappingUriPredicateReaction extends NormalizerAlterReaction {
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
$this->setConfiguration([self::URI_PREDICATE => $form_state->getValue(self::URI_PREDICATE)]);
$this->setConfiguration([self::SELF_REFERENCE_PREDICATE => $form_state->getValue(self::SELF_REFERENCE_PREDICATE)]);
}
}

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,

125
src/Plugin/EntityReferenceSelection/ExternalUriSelection.php

@ -0,0 +1,125 @@
<?php
namespace Drupal\islandora\Plugin\EntityReferenceSelection;
use Drupal\taxonomy\Plugin\EntityReferenceSelection\TermSelection;
use Drupal\islandora\IslandoraUtils;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Filters by looking for entities with Authority Links or External Uris.
*
* @EntityReferenceSelection(
* id = "islandora:external_uri",
* label = @Translation("Taxonomy Term with external URI selection"),
* entity_types = {"taxonomy_term"},
* group = "islandora",
* weight = 1
* )
*/
class ExternalUriSelection extends TermSelection {
/**
* Islandora utils.
*
* @var \Drupal\islandora\IslandoraUtils
*/
protected $utils;
/**
* Constructs a new ExternalUriSelection object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity manager service.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler service.
* @param \Drupal\Core\Session\AccountInterface $current_user
* The current user.
* @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
* The entity field manager.
* @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
* The entity type bundle info service.
* @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository
* The entity repository.
* @param \Drupal\islandora\IslandoraUtils $utils
* Islandora utils.
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
EntityTypeManagerInterface $entity_type_manager,
ModuleHandlerInterface $module_handler,
AccountInterface $current_user,
EntityFieldManagerInterface $entity_field_manager = NULL,
EntityTypeBundleInfoInterface $entity_type_bundle_info = NULL,
EntityRepositoryInterface $entity_repository = NULL,
IslandoraUtils $utils
) {
parent::__construct(
$configuration,
$plugin_id,
$plugin_definition,
$entity_type_manager,
$module_handler,
$current_user,
$entity_field_manager,
$entity_type_bundle_info,
$entity_repository
);
$this->utils = $utils;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('entity_type.manager'),
$container->get('module_handler'),
$container->get('current_user'),
$container->get('entity_field.manager'),
$container->get('entity_type.bundle.info'),
$container->get('entity.repository'),
$container->get('islandora.utils')
);
}
/**
* {@inheritdoc}
*/
public function getReferenceableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) {
$options = parent::getReferenceableEntities($match, $match_operator, $limit);
foreach (array_keys($options) as $vid) {
foreach (array_keys($options[$vid]) as $tid) {
$term = $this->entityTypeManager->getStorage('taxonomy_term')->load($tid);
$uri = $this->utils->getUriForTerm($term);
if (empty($uri)) {
unset($options[$vid][$tid]);
}
}
if (empty($options[$vid])) {
unset($options[$vid]);
}
}
return $options;
}
}

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

26
tests/src/Functional/MappingUriPredicateReactionTest.php → tests/src/Functional/JsonldSelfReferenceReactionTest.php

@ -8,7 +8,7 @@ namespace Drupal\Tests\islandora\Functional;
* @package Drupal\Tests\islandora\Functional
* @group islandora
*/
class MappingUriPredicateReactionTest extends IslandoraFunctionalTestBase {
class JsonldSelfReferenceReactionTest extends IslandoraFunctionalTestBase {
/**
* {@inheritdoc}
@ -28,7 +28,7 @@ class MappingUriPredicateReactionTest extends IslandoraFunctionalTestBase {
->setBundleMapping(['types' => $types])
->setFieldMapping('created', $created_mapping)
->setFieldMapping('title', [
'properties' => ['dc:title'],
'properties' => ['dcterms:title'],
'datatype' => 'xsd:string',
])
->save();
@ -37,7 +37,7 @@ class MappingUriPredicateReactionTest extends IslandoraFunctionalTestBase {
}
/**
* @covers \Drupal\islandora\Plugin\ContextReaction\MappingUriPredicateReaction
* @covers \Drupal\islandora\Plugin\ContextReaction\JsonldSelfReferenceReaction
*/
public function testMappingReaction() {
$account = $this->drupalCreateUser([
@ -79,25 +79,29 @@ class MappingUriPredicateReactionTest extends IslandoraFunctionalTestBase {
$this->drupalGet("admin/structure/context/$context_name");
// Can't use an undefined prefix.
$this->getSession()->getPage()
->fillField("Drupal URI predicate", "bob:smith");
->fillField("Self-reference predicate", "bob:smith");
$this->getSession()->getPage()->pressButton("Save and continue");
$this->assertSession()
->pageTextContains("Namespace prefix bob is not registered");
// Can't use a straight string.
$this->getSession()->getPage()
->fillField("Drupal URI predicate", "woohoo");
->fillField("Self-reference predicate", "woohoo");
$this->getSession()->getPage()->pressButton("Save and continue");
$this->assertSession()
->pageTextContains("Predicate must use a defined prefix or be a full URI");
// Use an existing prefix.
$this->getSession()->getPage()
->fillField("Drupal URI predicate", "owl:sameAs");
->fillField("Self-reference predicate", "owl:sameAs");
$this->getSession()->getPage()->pressButton("Save and continue");
$this->assertSession()
->pageTextContains("The context $context_name has been saved");
// The first time a Context is saved, you need to clear the cache.
// Subsequent changes to the context don't need a cache rebuild, though.
drupal_flush_all_caches();
$new_contents = $this->drupalGet($url . '?_format=jsonld');
$json = \GuzzleHttp\json_decode($new_contents, TRUE);
$this->assertEquals(
@ -114,7 +118,7 @@ class MappingUriPredicateReactionTest extends IslandoraFunctionalTestBase {
$this->drupalGet("admin/structure/context/$context_name");
// Change to a random URL.
$this->getSession()->getPage()
->fillField("Drupal URI predicate", "http://example.org/first/second");
->fillField("Self-reference predicate", "http://example.org/first/second");
$this->getSession()->getPage()->pressButton("Save and continue");
$this->assertSession()
->pageTextContains("The context $context_name has been saved");
@ -135,7 +139,7 @@ class MappingUriPredicateReactionTest extends IslandoraFunctionalTestBase {
}
/**
* @covers \Drupal\islandora\Plugin\ContextReaction\MappingUriPredicateReaction
* @covers \Drupal\islandora\Plugin\ContextReaction\JsonldSelfReferenceReaction
*/
public function testMappingReactionForMedia() {
$account = $this->drupalCreateUser([
@ -172,11 +176,15 @@ class MappingUriPredicateReactionTest extends IslandoraFunctionalTestBase {
// Use an existing prefix.
$this->getSession()->getPage()
->fillField("Drupal URI predicate", "iana:describedby");
->fillField("Self-reference predicate", "iana:describedby");
$this->getSession()->getPage()->pressButton("Save and continue");
$this->assertSession()
->pageTextContains("The context $context_name has been saved");
// The first time a Context is saved, you need to clear the cache.
// Subsequent changes to the context don't need a cache rebuild, though.
drupal_flush_all_caches();
$new_contents = $this->drupalGet($media_url . '?_format=jsonld');
$json = \GuzzleHttp\json_decode($new_contents, TRUE);
$this->assertEquals(

12
tests/src/Functional/JsonldTypeAlterReactionTest.php

@ -8,7 +8,7 @@ namespace Drupal\Tests\islandora\Functional;
* @package Drupal\Tests\islandora\Functional
* @group islandora
*/
class JsonldTypeAlterReactionTest extends MappingUriPredicateReactionTest {
class JsonldTypeAlterReactionTest extends JsonldSelfReferenceReactionTest {
/**
* @covers \Drupal\islandora\Plugin\ContextReaction\JsonldTypeAlterReaction
@ -70,11 +70,15 @@ class JsonldTypeAlterReactionTest extends MappingUriPredicateReactionTest {
$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.
// Subsequent changes to the context don't need a cache rebuild, though.
drupal_flush_all_caches();
// Check for the new @type from the field_type_predicate value.
$new_contents = $this->drupalGet($url . '?_format=jsonld');
$json = \GuzzleHttp\json_decode($new_contents, TRUE);

26
tests/src/Functional/NodeHasTermTest.php

@ -77,14 +77,36 @@ class NodeHasTermTest extends IslandoraFunctionalTestBase {
$condition->setContextValue('node', $node);
$this->assertFalse($condition->execute(), "Condition should fail if node does not have both terms");
// Create a node with both tags.
// Check for two tags this time.
// Node still only has one.
$condition = $condition_manager->createInstance(
'node_has_term',
[
'uri' => 'http://purl.org/coar/resource_type/c_c513,http://pcdm.org/use#PreservationMasterFile',
'logic' => 'or',
]
);
$condition->setContextValue('node', $node);
$this->assertTrue($condition->execute(), "Condition should pass if has one of two terms using OR logic.");
// Create a node with both tags and try it with OR.
$node = $this->container->get('entity_type.manager')->getStorage('node')->create([
'type' => 'test_type',
'title' => 'Test Node',
'field_tags' => [$this->imageTerm->id(), $this->preservationMasterTerm->id()],
]);
$condition->setContextValue('node', $node);
$this->assertTrue($condition->execute(), "Condition should pass if node has both terms");
$this->assertTrue($condition->execute(), "Condition should pass if node has both terms using OR logic");
// Try it with AND.
$condition = $condition_manager->createInstance(
'node_has_term',
[
'uri' => 'http://purl.org/coar/resource_type/c_c513,http://pcdm.org/use#PreservationMasterFile',
]
);
$condition->setContextValue('node', $node);
$this->assertTrue($condition->execute(), "Condition should pass if node has both terms using AND logic");
}
}

Loading…
Cancel
Save