Compare commits

...

153 Commits

Author SHA1 Message Date
Rosie Le Faive b8f0b9c966
Allow NodeHasMediaUse view filter to work on views with node relationships. (#1010) 6 months ago
Akanksha Singh da47bcfb08
Node has Parent context does not explicitly check if the field exists. (#1019) 6 months ago
Rosie Le Faive 5e958a5e10 Allow application/xml in OCR Action. 6 months ago
Rosie Le Faive 3902cce0ac
Allow filehash 3 (#1016) 6 months ago
Aron Novak c80769580c
Do not have a fatal error on a missing action (#1014) 7 months ago
Adam 54206de712
Fix Functional Javascript CI tests (#1004) 7 months ago
Joe Corall 9b2661696d
Add hOCR functionality (#1006) 7 months ago
Alexander O'Neill 089a3654ba
Merge pull request #1007 from rosiel/2.x 7 months ago
Rosie Le Faive 263666f5fc Remove new_storage_type from form part 2. 7 months ago
Rosie Le Faive 95c2d6c0c9 Syntax. 7 months ago
Rosie Le Faive cde2c133e1 Update tests for D10.3's new field selector form. 7 months ago
Rosie Le Faive a2c31fcaad @adam-vessey's fix for drupalGet headers. 7 months ago
Rosie Le Faive 9ed3637339
Update islandora.module (#1008) 7 months ago
Rosie Le Faive 13bc15ea43 Last attempt to not pass translatables as button labels. 8 months ago
Rosie Le Faive 9f2277fc51 Exclude PHP 8.3 with Drupal 10.1. 8 months ago
Rosie Le Faive 89261c17ae Add some forgotten translateable markup. 8 months ago
Rosie Le Faive 3784def287 Tests use strings not translateable markup to select interface buttons. 8 months ago
Rosie Le Faive e30cdbf681 Update testing drupal and php versions 8 months ago
Rosie Le Faive 3065c87874
Remove Feature-ness of Islandora Core Feature. (#968) 11 months ago
Alan Stanley d0e0c29921
Issue 1000 (#1001) 11 months ago
Alan Stanley 28174c3ce4
Change to Boolean logic (#999) 11 months ago
ajstanley 4404dff246 reverting accidental commit 11 months ago
ajstanley c93c1ff940 change to Boolean logic 11 months ago
ajstanley b65881625a change to Boooean logic 11 months ago
ajstanley c149781da0 Merge branch '2.x' of https://github.com/Islandora/islandora into 2.x 11 months ago
Seth Shaw c6341649ca
Use FileUrlGeneratorInterface (#996) 12 months ago
Annie Oelschlager 4630439760
Merge pull request #986 from rosiel/coi 12 months ago
Rosie Le Faive 056695c79c
8.2 deprecations from tests (#995) 1 year ago
Rosie Le Faive 4b2b9b221b
Fix tests (#991) 1 year ago
Joe Corall f29fef2bac
Do not render the pdf_url metatag if there is no value (#985) 1 year ago
Adam 095e0ecf67
Update to use the new hook. (#992) 1 year ago
Rosie Le Faive d5556f445d
Add PHP 8.2 <strike>and Drupal 10.2</strike> to testing matrix (#987) 1 year ago
Rosie Le Faive 2c91dc6f58 syntax. 1 year ago
Rosie Le Faive 16617a9dd7 Composer suggest COI. 1 year ago
Rosie Le Faive c05236ac8c Add COI integration to IIIF module. 1 year ago
Rosie Le Faive 6cfaca36e7
Update src/Form/IslandoraSettingsForm.php 1 year ago
Rosie Le Faive f077af677b Add COI integration to islandora settings form. 1 year ago
Adam 572ffcf2e1
Fix up typo. (#984) 1 year ago
Alexander O'Neill f7a77820d3
Merge pull request #980 from rosiel/issue-975 1 year ago
Annie Oelschlager 58d1b37f11
Merge pull request #982 from Islandora/rosiel-patch-1 1 year ago
Rosie Le Faive 76eb4717a2
Specify fetch-depth during mirroring to gitlab. 1 year ago
Annie Oelschlager e2ec673017
Merge pull request #971 from rosiel/media-redirect 1 year ago
Rosie Le Faive d6e07491d2 UI text improvement. 1 year ago
Rosie Le Faive c2cd14cfd5 Add config option to redirect after media add. 1 year ago
Rosie Le Faive fdfdd87472 Add media save redirect. 1 year ago
Rosie Le Faive 84c6ca85d8 Remove extra file. 1 year ago
Rosie Le Faive 91253bef14 Declare httpClient variable. 1 year ago
dannylamb e3399d3968
Stripping out json metadata in the queue messages except for the ones… (#973) 1 year ago
aOelschlager fd8319b7b2
Merge pull request #977 from Islandora/revert-976-rosiel-patch-1 1 year ago
Rosie Le Faive 5d83504778
Revert "Revert gitlab mirror to checkout v1." 1 year ago
aOelschlager 33340c2722
Merge pull request #976 from Islandora/rosiel-patch-1 1 year ago
Rosie Le Faive d1357d347d
Revert gitlab mirror to checkout v1. 1 year ago
Rosie Le Faive 0408edb93f
Push tags to gitlab. (#974) 1 year ago
Alexander O'Neill 71f0945e3c
959 Use image dimension properties in IIIF Manifest if they exist… (#969) 1 year ago
Alexander O'Neill 11afd42c8a
Issue #964: Allow relative paths in IIIF manifests. (#965) 1 year ago
Rosie Le Faive 4eef5f566d Deprecate advanced_search. 1 year ago
Rosie Le Faive 5331b0b7d5
Add push to Gitlab action. (#966) 1 year ago
Alexander O'Neill 8f1537670d
Merge pull request #960 from rosiel/drupal10 1 year ago
Rosie Le Faive 0fe2a8f559 Update features spec. 1 year ago
Alexander O'Neill ac818a0f27
Issue #961: Put back accidentally-removed IIIF Manifest alter hooks. (#962) 1 year ago
Rosie Le Faive 408776437b phpcs. 1 year ago
Rosie Le Faive 6b05ff5f99 typo in permission name. 1 year ago
Rosie Le Faive 5c09a1e3f4 Use a better version compare call. 1 year ago
Rosie Le Faive 6d59c526d3 In Drupal 10.1, include new file delete permission. 1 year ago
Rosie Le Faive 91016fd237 Don't delete files in the thumbnail field. 1 year ago
Rosie Le Faive 9ef509b0ad Fix merge conflict. 1 year ago
Rosie Le Faive 621b7a2c7d Remove duplicate line. 1 year ago
Rosie Le Faive aec8178846 Stop using deprecated FILE_STATUS_PERMANENT. 1 year ago
Rosie Le Faive 8adc44859c Update fixtures to have config UUIDs. 1 year ago
Rosie Le Faive d1861de270 Test on 8.1. 1 year ago
Rosie Le Faive d293d7702a Change to check access (true). 1 year ago
Rosie Le Faive a88486ca28 Add accessCheck FALSE to all queries. 1 year ago
Rosie Le Faive 8ef277527b Fix tests. 1 year ago
Rosie Le Faive e67e8e5f25 Remove problematic comments. 1 year ago
Rosie Le Faive 52947f3f96 Use phpcs friendly comment... 1 year ago
Rosie Le Faive e4dc48fca2 Tests were not finding the media use field. 1 year ago
Rosie Le Faive 7470327871 Inject fileUrlGenerator into Image Field formatter. 1 year ago
Rosie Le Faive 8f8e6a3c35 Test: Breadcrumbs config dependencies missing schema. 1 year ago
Jordan Dukart 9cabfc2e23 Fix a typo. (#958) 1 year ago
Rosie Le Faive ffd128db80 Typo prevented submodule functional tests from running. 1 year ago
Rosie Le Faive 2c332348dc Undo overzealous Rector. 1 year ago
Rosie Le Faive 7d7f97746a Drupal Rector. 1 year ago
Seth Shaw 91490ddbe2 bump jwt version (#952) 1 year ago
Alexander O'Neill e492b92d9f Remove Islandora Utils from Islandora IIIF. 1 year ago
Alexander O'Neill d4cac72993 Fix PHPCS errors. 1 year ago
Alexander O'Neill 9f5eceea07 Fix PHPCS errors. 1 year ago
Alexander O'Neill cf243f368d Fix PHPCS errors. 1 year ago
Alexander O'Neill f41dc59f1b Remove term-based hOCR configuration since we can just use Views. 1 year ago
Alexander O'Neill 7527b1fa6f Address PHPCS errors. 1 year ago
Alexander O'Neill 723f102365 Update Islandora IIIF README. 1 year ago
Alexander O'Neill 9ef3bcf440 Refactor IIIF Manifest Views Style plugin. 1 year ago
Alexander O'Neill 622eaab6a0 Issue 944: Pull hOCR from separate media in IIIF manifest. 1 year ago
Rosie Le Faive 374ab02d07 phpcs 1 year ago
Alexander O'Neill a7eaacc1d5 Issue #947 Add tokens for Original File filename, extension. 1 year ago
Alexander O'Neill 61c6e737c1 Fix PHPCS errors. 1 year ago
Alexander O'Neill 17b5049578 Issue #944: Un-hide arguments field in Text Extraction action. 1 year ago
Alexander O'Neill 5bc1584dd7 Issue 937: More PHPCS fixes. 1 year ago
Alexander O'Neill 43f32d1bcf Issue #937: Fix PHPCS issues. 1 year ago
Alexander O'Neill 78baec07e8 Issue #973 Add hooks to IIIF manifest Views Style plugin. 1 year ago
kstapelfeldt 0bd05b6c44 Update README.md 1 year ago
Alexander O'Neill 06dd1651ac Issue #939: Fix incorrect IIIF Manifest canvas Ids. 1 year ago
Alexander O'Neill 138eab2016 Issue #941: Only add <br/> tags to plain text extracted text fields. (#942) 1 year ago
Jared Whiklo 7b0ff739cd Update dependencies to tagged versions 1 year ago
Jared Whiklo ff4e0cafc4 More code style 1 year ago
Jared Whiklo ba93ad35a3 Fix tests 1 year ago
Jared Whiklo 860abf3c06 code style 1 year ago
Jared Whiklo 5dd96b8f22 Use new chullo static methods 1 year ago
Jared Whiklo 2c1d88f400 Use new package 1 year ago
Jared Whiklo 8ce1ad2cda Remove deprecate MimeTypeGuesser 1 year ago
Noah W. Smith 58da2a6af1 Missed one link; corrected TAG link 1 year ago
Noah W. Smith 7d54a42d48 Update maintainer and sponsor info 1 year ago
Lucas van Schaik ee451667d4 Revert "Check if action is appropriate for entity before executing" 1 year ago
Lucas van Schaik 4bcc7d4417 Revert "Make sure that the action is appropriate: either system or with same entity type" 1 year ago
Lucas van Schaik b82accf763 Revert "Comment too long" 1 year ago
Lucas van Schaik 1bbb48f70f Be consistent with context module, issue 3177007 1 year ago
Lucas van Schaik 088f1fcdd0 Comment too long 1 year ago
Lucas van Schaik 50685aebe6 Make sure that the action is appropriate: either system or with same entity type 1 year ago
Lucas van Schaik 2c48c8795f Check if conditions exist before applying contexts to them 1 year ago
Lucas van Schaik 9f83322902 Check if action is appropriate for entity before executing 1 year ago
Lucas van Schaik 709938cf29 Implement solution for drupal issues 3089660 and 3045666 1 year ago
Rosie Le Faive c67f3185ec Update Crayfish Commons dependency 1 year ago
Jordan Dukart 46cd2f9950 Reset contexts before evaluation. (#932) 1 year ago
Seth Shaw 4e091e524f fix for deprecated Symfony Event class 1 year ago
Ant Brown ee2b964a07 Fix deprecated File::url(), use createFileUrl() instead (#855) 1 year ago
JojoVes 2376f77831 Replace deprecated 'context' condition annotation with 'context_definitions' (#925) 1 year ago
Rosie Le Faive 8686dbf74b Avoid duplicate counts of the same file being deleted. 1 year ago
Rosie Le Faive a77bd2d949 Return array not string. 1 year ago
Rosie Le Faive cb2e1c4809 Remove 8 for consistency. 1 year ago
Rosie Le Faive 2040952740 Integer weight selector test module to D10. 1 year ago
Rosie Le Faive 8f77733c84 Allow jsonld 3.x. 1 year ago
Rosie Le Faive 0665310346 Remove unused use statements. 1 year ago
Rosie Le Faive bf17ed9bbc Allow contexts module in RC. 1 year ago
Rosie Le Faive 354341988b Drupal 10 Compatibility from Upgrade Status 1 year ago
Jordan Dukart 8502a347ff
Merge pull request #957 from rosiel/get-tests-passing 1 year ago
Rosie Le Faive f474f7b745 Remove duplicate line. 1 year ago
Jordan Dukart ece94a24f5
Fix a typo. (#958) 1 year ago
Rosie Le Faive 58ab9a3b70 Stop using deprecated FILE_STATUS_PERMANENT. 1 year ago
Rosie Le Faive 0d7f5d927f Update fixtures to have config UUIDs. 1 year ago
Rosie Le Faive 05fc3f9b88 Test on 8.1. 1 year ago
Rosie Le Faive 4eae636383 Change to check access (true). 1 year ago
Rosie Le Faive dd514a3eb0 Add accessCheck FALSE to all queries. 1 year ago
Rosie Le Faive c49c131ed8 Fix tests. 1 year ago
Rosie Le Faive 760593b4e0 Remove problematic comments. 1 year ago
Rosie Le Faive 54116efbab Use phpcs friendly comment... 1 year ago
Rosie Le Faive 41e4dc6fff Tests were not finding the media use field. 1 year ago
Rosie Le Faive 8ee4fb5aff Inject fileUrlGenerator into Image Field formatter. 1 year ago
Rosie Le Faive 1f09439e1e Test: Breadcrumbs config dependencies missing schema. 1 year ago
Simon Hieu Mai 488a82b741
Update islandora_advanced_search.module 2 years ago
Simon Hieu Mai 71c720736f
Update islandora_advanced_search.module 2 years ago
Simon Hieu Mai da35fb8950
Delete soft-limit.js 2 years ago
Simon Hieu Mai af224e42cf
Delete facets-views-ajax.js 2 years ago
Simon Hieu Mai 0d2e584316
Update islandora_advanced_search.module 2 years ago
ajstanley b733713610 added additional exception 3 years ago
  1. 54
      .github/workflows/build-2.x.yml
  2. 26
      .github/workflows/gitlab-mirror.yml
  3. 10
      composer.json
  4. 1
      config/install/islandora.settings.yml
  5. 6
      config/schema/islandora.schema.yml
  6. 38
      islandora.info.yml
  7. 14
      islandora.install
  8. 24
      islandora.module
  9. 3
      islandora.tokens.inc
  10. 4
      modules/islandora_advanced_search/islandora_advanced_search.info.yml
  11. 102
      modules/islandora_advanced_search/islandora_advanced_search.module
  12. 147
      modules/islandora_advanced_search/js/facets/facets-views-ajax.js
  13. 70
      modules/islandora_advanced_search/js/facets/soft-limit.js
  14. 2
      modules/islandora_advanced_search/src/Form/AdvancedSearchForm.php
  15. 2
      modules/islandora_advanced_search/src/Plugin/Block/AdvancedSearchBlock.php
  16. 2
      modules/islandora_advanced_search/src/Plugin/Block/SearchResultsPagerBlock.php
  17. 3
      modules/islandora_audio/islandora_audio.info.yml
  18. 8
      modules/islandora_audio/tests/src/Functional/GenerateAudioDerivativeTest.php
  19. 6
      modules/islandora_breadcrumbs/config/install/islandora_breadcrumbs.breadcrumbs.yml
  20. 5
      modules/islandora_breadcrumbs/islandora_breadcrumbs.info.yml
  21. 100
      modules/islandora_core_feature/config/install/features.bundle.islandora.yml
  22. 0
      modules/islandora_core_feature/config/optional/core.entity_view_mode.media.source.yml
  23. 0
      modules/islandora_core_feature/config/optional/field.field.taxonomy_term.islandora_media_use.field_external_uri.yml
  24. 0
      modules/islandora_core_feature/config/optional/field.field.taxonomy_term.islandora_models.field_external_uri.yml
  25. 0
      modules/islandora_core_feature/config/optional/field.storage.media.field_file_size.yml
  26. 0
      modules/islandora_core_feature/config/optional/field.storage.media.field_height.yml
  27. 0
      modules/islandora_core_feature/config/optional/field.storage.media.field_media_audio_file.yml
  28. 0
      modules/islandora_core_feature/config/optional/field.storage.media.field_media_document.yml
  29. 0
      modules/islandora_core_feature/config/optional/field.storage.media.field_media_file.yml
  30. 0
      modules/islandora_core_feature/config/optional/field.storage.media.field_media_image.yml
  31. 0
      modules/islandora_core_feature/config/optional/field.storage.media.field_media_of.yml
  32. 0
      modules/islandora_core_feature/config/optional/field.storage.media.field_media_use.yml
  33. 0
      modules/islandora_core_feature/config/optional/field.storage.media.field_media_video_file.yml
  34. 0
      modules/islandora_core_feature/config/optional/field.storage.media.field_mime_type.yml
  35. 0
      modules/islandora_core_feature/config/optional/field.storage.media.field_original_name.yml
  36. 0
      modules/islandora_core_feature/config/optional/field.storage.media.field_width.yml
  37. 0
      modules/islandora_core_feature/config/optional/field.storage.node.field_member_of.yml
  38. 0
      modules/islandora_core_feature/config/optional/field.storage.node.field_model.yml
  39. 0
      modules/islandora_core_feature/config/optional/field.storage.node.field_weight.yml
  40. 0
      modules/islandora_core_feature/config/optional/field.storage.taxonomy_term.field_external_uri.yml
  41. 0
      modules/islandora_core_feature/config/optional/filehash.settings.yml
  42. 0
      modules/islandora_core_feature/config/optional/migrate_plus.migration.islandora_tags.yml
  43. 0
      modules/islandora_core_feature/config/optional/migrate_plus.migration_group.islandora.yml
  44. 0
      modules/islandora_core_feature/config/optional/rest.resource.entity.file.yml
  45. 0
      modules/islandora_core_feature/config/optional/rest.resource.entity.media.yml
  46. 0
      modules/islandora_core_feature/config/optional/rest.resource.entity.node.yml
  47. 0
      modules/islandora_core_feature/config/optional/rest.resource.entity.taxonomy_term.yml
  48. 0
      modules/islandora_core_feature/config/optional/system.action.delete_file_as_fedora_external_content.yml
  49. 0
      modules/islandora_core_feature/config/optional/system.action.delete_media_from_triplestore.yml
  50. 0
      modules/islandora_core_feature/config/optional/system.action.delete_node_from_fedora.yml
  51. 0
      modules/islandora_core_feature/config/optional/system.action.delete_node_from_triplestore.yml
  52. 0
      modules/islandora_core_feature/config/optional/system.action.delete_taxonomy_term_in_fedora.yml
  53. 0
      modules/islandora_core_feature/config/optional/system.action.delete_taxonomy_term_in_triplestore.yml
  54. 0
      modules/islandora_core_feature/config/optional/system.action.index_file_as_fedora_external_content.yml
  55. 0
      modules/islandora_core_feature/config/optional/system.action.index_media_in_fedora.yml
  56. 0
      modules/islandora_core_feature/config/optional/system.action.index_media_in_triplestore.yml
  57. 0
      modules/islandora_core_feature/config/optional/system.action.index_node_in_fedora.yml
  58. 0
      modules/islandora_core_feature/config/optional/system.action.index_node_in_triplestore.yml
  59. 0
      modules/islandora_core_feature/config/optional/system.action.index_taxonomy_term_in_fedora.yml
  60. 0
      modules/islandora_core_feature/config/optional/system.action.index_taxonomy_term_in_the_triplestore.yml
  61. 0
      modules/islandora_core_feature/config/optional/taxonomy.vocabulary.islandora_media_use.yml
  62. 0
      modules/islandora_core_feature/config/optional/taxonomy.vocabulary.islandora_models.yml
  63. 0
      modules/islandora_core_feature/config/optional/views.view.all_taxonomy_terms.yml
  64. 0
      modules/islandora_core_feature/config/optional/views.view.display_media.yml
  65. 0
      modules/islandora_core_feature/config/optional/views.view.file_checksum.yml
  66. 0
      modules/islandora_core_feature/config/optional/views.view.manage_members.yml
  67. 0
      modules/islandora_core_feature/config/optional/views.view.media_of.yml
  68. 0
      modules/islandora_core_feature/config/optional/views.view.non_fedora_files.yml
  69. 0
      modules/islandora_core_feature/config/optional/views.view.reorder_children.yml
  70. 16
      modules/islandora_core_feature/islandora_core_feature.features.yml
  71. 4
      modules/islandora_core_feature/islandora_core_feature.info.yml
  72. 18
      modules/islandora_iiif/config/schema/islandora_iiif.schema.yml
  73. 3
      modules/islandora_iiif/islandora_iiif.info.yml
  74. 26
      modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php
  75. 212
      modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php
  76. 3
      modules/islandora_image/islandora_image.info.yml
  77. 8
      modules/islandora_image/tests/src/Functional/GenerateImageDerivativeTest.php
  78. 3
      modules/islandora_text_extraction/islandora_text_extraction.info.yml
  79. 5
      modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php
  80. 2
      modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivativeFile.php
  81. 5
      modules/islandora_text_extraction/src/Plugin/Field/FieldFormatter/OcrTextFormatter.php
  82. 0
      modules/islandora_text_extraction_defaults/config/optional/core.entity_form_display.media.extracted_text.default.yml
  83. 0
      modules/islandora_text_extraction_defaults/config/optional/core.entity_view_display.media.extracted_text.default.yml
  84. 0
      modules/islandora_text_extraction_defaults/config/optional/field.field.media.extracted_text.field_edited_text.yml
  85. 0
      modules/islandora_text_extraction_defaults/config/optional/field.field.media.extracted_text.field_media_file.yml
  86. 0
      modules/islandora_text_extraction_defaults/config/optional/field.field.media.extracted_text.field_media_of.yml
  87. 0
      modules/islandora_text_extraction_defaults/config/optional/field.field.media.extracted_text.field_media_use.yml
  88. 0
      modules/islandora_text_extraction_defaults/config/optional/field.field.media.extracted_text.field_mime_type.yml
  89. 0
      modules/islandora_text_extraction_defaults/config/optional/field.storage.media.field_edited_text.yml
  90. 0
      modules/islandora_text_extraction_defaults/config/optional/language.content_settings.media.extracted_text.yml
  91. 0
      modules/islandora_text_extraction_defaults/config/optional/media.type.extracted_text.yml
  92. 0
      modules/islandora_text_extraction_defaults/config/optional/rdf.mapping.media.extracted_text.yml
  93. 0
      modules/islandora_text_extraction_defaults/config/optional/system.action.get_ocr_from_image.yml
  94. 2
      modules/islandora_text_extraction_defaults/islandora_text_extraction_defaults.features.yml
  95. 3
      modules/islandora_text_extraction_defaults/islandora_text_extraction_defaults.info.yml
  96. 3
      modules/islandora_video/islandora_video.info.yml
  97. 8
      modules/islandora_video/tests/src/Functional/GenerateVideoDerivativeTest.php
  98. 2
      phpunit.xml
  99. 2
      src/Controller/ManageMembersController.php
  100. 16
      src/EventGenerator/EventGenerator.php
  101. Some files were not shown because too many files have changed in this diff Show More

54
.github/workflows/build-2.x.yml

@ -1,36 +1,33 @@
# This is a basic workflow to help you get started with Actions
name: CI
# Controls when the action will run.
on:
# Triggers the workflow on push or pull request events but only for the 2.x branch
push:
branches: [ 2.x ]
pull_request:
branches: [ 2.x ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
env:
DRUPAL_VERSION: ${{ matrix.drupal-version }}
SCRIPT_DIR: ${{ github.workspace }}/islandora_ci
DRUPAL_DIR: /opt/drupal
PHPUNIT_FILE: ${{ github.workspace }}/build_dir/phpunit.xml
runs-on: ubuntu-latest
continue-on-error: ${{ matrix.allowed_failure }}
strategy:
fail-fast: false
matrix:
# PHP 8.1 fails - see https://github.com/Islandora/islandora/issues/887
php-versions: ["7.4", "8.0"]
# test-suite functional-javascript will appear to pass but will skip tests; missing chromedriver.
php-versions: ["8.1", "8.2", "8.3"]
test-suite: ["kernel", "functional", "functional-javascript"]
# Not yet Drupal 10 ready - see https://github.com/Islandora/islandora/issues/888
drupal-version: ["9.4.x", "9.5.x-dev"]
drupal-version: ["10.1.x", "10.2.x", "10.3.x-dev"]
mysql: ["8.0"]
allowed_failure: [false]
exclude:
- php-versions: "8.3"
drupal-version: "10.1.x"
name: PHP ${{ matrix.php-versions }} | drupal ${{ matrix.drupal-version }} | mysql ${{ matrix.mysql }} | test-suite ${{ matrix.test-suite }}
@ -50,17 +47,15 @@ jobs:
- 61616:61616
- 61613:61613
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
path: build_dir
- name: Checkout islandora_ci
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
repository: islandora/islandora_ci
ref: github-actions
@ -78,15 +73,8 @@ jobs:
sudo apt-get remove -y mysql-client mysql-common
sudo apt-get install -y mysql-client
- name: Set environment variables
run: |
echo "DRUPAL_VERSION=${{ matrix.drupal-version }}" >> $GITHUB_ENV
echo "SCRIPT_DIR=$GITHUB_WORKSPACE/islandora_ci" >> $GITHUB_ENV
echo "DRUPAL_DIR=/opt/drupal" >> $GITHUB_ENV
echo "PHPUNIT_FILE=$GITHUB_WORKSPACE/build_dir/phpunit.xml" >> $GITHUB_ENV
- name: Cache Composer dependencies
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: /tmp/composer-cache
key: ${{ runner.os }}-${{ hashFiles('**/composer.lock') }}
@ -111,15 +99,27 @@ jobs:
run: |
cd $DRUPAL_DIR/web
drush --uri=127.0.0.1:8282 en -y islandora_audio islandora_breadcrumbs islandora_iiif islandora_image islandora_video islandora_text_extraction_defaults
drush --uri=127.0.0.1:8282 fim -y islandora_core_feature,islandora_text_extraction_defaults
- name: Copy PHPunit file
run: cp $PHPUNIT_FILE $DRUPAL_DIR/web/core/phpunit.xml
- name: Test scripts
run: $SCRIPT_DIR/travis_scripts.sh
- name: Start chromedriver
if: matrix.test-suite == 'functional-javascript'
run: |-
/usr/local/share/chromedriver-linux64/chromedriver \
--log-path=/tmp/chromedriver.log \
--verbose \
--allowed-ips= \
--allowed-origins=* &
- name: PHPUNIT tests
run: |
cd $DRUPAL_DIR/web/core
$DRUPAL_DIR/vendor/bin/phpunit --verbose --testsuite "${{ matrix.test-suite }}"
- name: Print chromedriver logs
if: matrix.test-suite == 'functional-javascript'
run: cat /tmp/chromedriver.log

26
.github/workflows/gitlab-mirror.yml

@ -0,0 +1,26 @@
name: Mirror and run GitLab CI
on:
push:
branches: [2.x]
tags: '*'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Mirror + trigger CI
uses: SvanBoxel/gitlab-mirror-and-ci-action@master
with:
args: "https://git.drupalcode.org/project/islandora"
env:
FOLLOW_TAGS: "true"
FORCE_PUSH: "false"
GITLAB_HOSTNAME: "git.drupal.org"
GITLAB_USERNAME: "project_34868_bot"
GITLAB_PASSWORD: ${{ secrets.GITLAB_PASSWORD }}
GITLAB_PROJECT_ID: "34868"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

10
composer.json

@ -14,12 +14,11 @@
}
],
"require": {
"drupal/context": "^4",
"drupal/context": "^4 || ^5@RC",
"drupal/ctools": "^3.8 || ^4",
"drupal/eva" : "^3.0",
"drupal/features" : "^3.7",
"drupal/file_replace": "^1.1",
"drupal/filehash": "^2",
"drupal/filehash": "^2 || ^3",
"drupal/flysystem" : "^2.0@alpha",
"drupal/jwt": "^1.1 || ^2",
"drupal/migrate_plus" : "^5.1 || ^6",
@ -29,7 +28,7 @@
"drupal/token" : "^1.3",
"islandora/chullo": "^2.0",
"islandora/fedora-entity-mapper": "^1.0",
"islandora/jsonld": "^2",
"islandora/jsonld": "^2 || ^3",
"stomp-php/stomp-php": "4.* || ^5"
},
"require-dev": {
@ -39,7 +38,8 @@
"sebastian/phpcpd": "*"
},
"suggest": {
"drupal/transliterate_filenames": "Sanitizes filenames when they are uploaded so they don't break your repository."
"drupal/transliterate_filenames": "Sanitizes filenames when they are uploaded so they don't break your repository.",
"drupal/coi": "Some configuration fields work with Config Override Inspector."
},
"license": "GPL-2.0-or-later",
"authors": [

1
config/install/islandora.settings.yml

@ -1,5 +1,4 @@
broker_url: 'tcp://localhost:61613'
jwt_expiry: '+2 hour'
gemini_url: ''
delete_media_and_files: TRUE
gemini_pseudo_bundles: []

6
config/schema/islandora.schema.yml

@ -17,15 +17,15 @@ islandora.settings:
delete_media_and_files:
type: boolean
label: 'Node Delete with Media and Files'
redirect_after_media_save:
type: boolean
label: 'Redirect to node after media save.'
upload_form_location:
type: string
label: 'Upload Form Location'
upload_form_allowed_mimetypes:
type: string
label: 'Upload Form Allowed Extensions'
gemini_url:
type: uri
label: 'Url to Gemini microservice'
gemini_pseudo_bundles:
type: sequence
label: 'List of node, media and taxonomy terms that should include the linked Fedora URI'

38
islandora.info.yml

@ -4,32 +4,30 @@ name: 'islandora'
description: "Islandora Core"
type: module
package: Islandora
core: 8.x
core_version_requirement: ^8 || ^9
core_version_requirement: ^9 || ^10
dependencies:
- context:context_ui
- ctools:ctools
- drupal:action
- drupal:basic_auth
- drupal:block
- drupal:content_translation
- drupal:link
- drupal:media
- drupal:node
- drupal:path
- drupal:text
- drupal:options
- drupal:link
- jsonld:jsonld
- search_api:search_api
- jwt:jwt
- drupal:path
- drupal:rest
- filehash:filehash
- drupal:basic_auth
- context:context_ui
- drupal:action
- eva:eva
- drupal:taxonomy
- drupal:text
- drupal:views_ui
- drupal:media
- prepopulate:prepopulate
- features:features_ui
- migrate_source_csv:migrate_source_csv
- drupal:content_translation
- eva:eva
- file_replace:file_replace
- filehash:filehash
- flysystem:flysystem
- jsonld:jsonld
- jwt:jwt
- migrate_source_csv:migrate_source_csv
- prepopulate:prepopulate
- search_api:search_api
- token:token
- file_replace:file_replace
- ctools:ctools

14
islandora.install

@ -212,3 +212,17 @@ function islandora_update_8007() {
// have the here, just in case?
throw new UpdateException('Failed; hit the end of the update hook implementation, which is not expected.');
}
/**
* Set config to no redirect after media save.
*/
function islandora_update_8008() {
$config = \Drupal::configFactory()->getEditable('islandora.settings');
if ($config) {
$config->set('redirect_after_media_save', FALSE);
$config->save(TRUE);
return t('A new configuration option, "Redirect after media save" is now available.
It has been turned off to preserve existing behaviour. To enable this setting visit
Configuration > Islandora > Core Settings.');
}
}

24
islandora.module

@ -332,6 +332,7 @@ function islandora_form_alter(&$form, FormStateInterface $form_state, $form_id)
if ($node) {
$form['name']['widget'][0]['value']['#default_value'] = $node->getTitle();
}
$form['actions']['submit']['#submit'][] = 'islandora_media_custom_form_submit';
}
}
@ -387,6 +388,22 @@ function islandora_form_alter(&$form, FormStateInterface $form_state, $form_id)
return $form;
}
/**
* Redirect submit handler for media save.
*/
function islandora_media_custom_form_submit(&$form, FormStateInterface $form_state) {
// Check configuration to see whether a redirect is desired.
$redirect = \Drupal::config('islandora.settings')->get('redirect_after_media_save');
if ($redirect) {
$params = \Drupal::request()->query->all();
if (!empty($params)) {
$target_id = $params['edit']['field_media_of']['widget'][0]['target_id'];
$url = Url::fromRoute('view.media_of.page_1', ['node' => $target_id]);
$form_state->setRedirectUrl($url);
}
}
}
/**
* Implements a submit handler for the delete form.
*/
@ -528,14 +545,14 @@ function islandora_object_delete_form_submit($form, FormStateInterface $form_sta
}
/**
* Implements hook_field_widget_WIDGET_TYPE_form_alter().
* Implements hook_field_widget_single_element_WIDGET_TYPE_form_alter().
*/
function islandora_field_widget_image_image_form_alter(&$element, $form_state, $context) {
function islandora_field_widget_single_element_image_image_form_alter(&$element, $form_state, $context) {
$element['#process'][] = 'islandora_add_default_image_alt_text';
}
/**
* Callback for hook_field_widget_WIDGET_TYPE_form_alter().
* Callback for hook_field_widget_single_element_WIDGET_TYPE_form_alter().
*/
function islandora_add_default_image_alt_text($element, $form_state, $form) {
if ($element['alt']['#access']) {
@ -598,6 +615,7 @@ function islandora_form_block_form_alter(&$form, FormStateInterface $form_state,
unset($form['visibility']['media_is_islandora_media']);
unset($form['visibility']['media_uses_filesystem']);
unset($form['visibility']['node_had_namespace']);
unset($form['visibility']['node_has_ancestor']);
unset($form['visibility']['node_has_parent']);
unset($form['visibility']['node_has_term']);
unset($form['visibility']['node_is_islandora_object']);

3
islandora.tokens.inc

@ -134,7 +134,7 @@ function islandora_tokens($type, $tokens, array $data, array $options, Bubbleabl
break;
case 'pdf_url':
$replacements[$original] = ' ' . islandora_url_to_service_file_media_by_mimetype($data['node'], 'application/pdf');
$replacements[$original] = islandora_url_to_service_file_media_by_mimetype($data['node'], 'application/pdf');
break;
}
}
@ -188,4 +188,5 @@ function islandora_url_to_service_file_media_by_mimetype($node, $mime_type) {
}
}
}
return '';
}

4
modules/islandora_advanced_search/islandora_advanced_search.info.yml

@ -4,8 +4,10 @@ name: 'Islandora Advanced Search'
description: "Creates an Advanced Search block and other enhancements to search."
type: module
package: Islandora
core_version_requirement: ^8 || ^9
core_version_requirement: ^9 || ^10
dependencies:
- drupal:facets
- drupal:facets_summary
- drupal:search_api_solr
lifecycle: deprecated
lifecycle_link: https://groups.google.com/g/islandora/c/SEOAWJrfE_M

102
modules/islandora_advanced_search/islandora_advanced_search.module

@ -13,51 +13,13 @@
*/
use Drupal\block\Entity\Block;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Form\FormStateInterface;
use Drupal\islandora_advanced_search\AdvancedSearchQuery;
use Drupal\islandora_advanced_search\Form\SettingsForm;
use Drupal\islandora_advanced_search\Utilities;
use Drupal\search_api\Query\QueryInterface as DrupalQueryInterface;
use Drupal\views\ViewExecutable;
use Solarium\Core\Query\QueryInterface as SolariumQueryInterface;
/**
* Implements hook_theme().
*/
function islandora_advanced_search_theme() {
return [
'facets_item_list__include_exclude_links' => [
'template' => 'facets/facets-item-list--include-exclude-links',
'base hook' => 'facets_item_list',
],
'facets_result_item__include_exclude_links' => [
'template' => 'facets/facets-result-item--include-exclude-links',
'base hook' => 'facets_result_item',
],
'facets_result_item__summary' => [
'template' => 'facets/facets-result-item--summary',
'base hook' => 'facets_result_item',
],
];
}
/**
* Implements hook_library_info_alter().
*/
function islandora_advanced_search_library_info_alter(&$libraries, $extension) {
if ($extension == 'facets') {
// Override facets module javascript with customizations.
$path = '/' . \Drupal::service('extension.list.module')->getPath('islandora_advanced_search') . '/js/facets';
$libraries['soft-limit']['js'] = [
"$path/soft-limit.js" => [],
];
$libraries['drupal.facets.views-ajax']['js'] = [
"$path/facets-views-ajax.js" => [],
];
}
}
/**
* Implements hook_search_api_solr_converted_query_alter().
*/
@ -99,20 +61,6 @@ function islandora_advanced_search_form_block_form_alter(&$form, FormStateInterf
$form['visibility'][$condition_id] = $condition_form;
}
/**
* Implements hook_preprocess_block__facets_summary().
*/
function islandora_advanced_search_preprocess_block__facets_summary(&$variables) {
// Copy data-attributes to the content as the javascript expects
// there to be no elements between the data declaration and the
// content of the block.
foreach ($variables['attributes'] as $key => $value) {
if (substr($key, 0, 4) === "data") {
$variables['content_attributes'][$key] = $value;
}
}
}
/**
* Implements hook_preprocess_preprocess_views_view().
*/
@ -139,53 +87,3 @@ function islandora_advanced_search_views_pre_view(ViewExecutable $view, $display
$advanced_search_query = new AdvancedSearchQuery();
$advanced_search_query->alterView(\Drupal::request(), $view, $display_id);
}
/**
* Implements hook_preprocess_facets_summary_item_list().
*/
function islandora_advanced_search_preprocess_facets_summary_item_list(&$variables) {
foreach ($variables['items'] as &$item) {
$item['attributes']['class'][] = 'facet-summary-item';
}
}
/**
* Implements hook_preprocess_facets_item_list().
*/
function islandora_advanced_search_preprocess_facets_item_list(&$variables) {
$widget = $variables['facet']->getWidget();
$soft_limit = $widget['config']['soft_limit'];
// Break into two groups less / more which can display be toggled as a single
// element change rather than showing / hiding all <li> elements individually.
// As its slow and causes the page to snap when loading.
$variables['less'] = array_slice($variables['items'], 0, $soft_limit);
$variables['more'] = array_slice($variables['items'], $soft_limit);
$variables['show_more_label'] = $widget['config']['soft_limit_settings']['show_more_label'];
}
/**
* Implements hook_preprocess_facets_result_item().
*/
function islandora_advanced_search_preprocess_facets_result_item(&$variables) {
$settings = \Drupal::config(SettingsForm::CONFIG_NAME);
$length = $settings->get(SettingsForm::FACET_TRUNCATE);
if (is_numeric($length)) {
// Limit the length of facets display to at most 32 characters.
if (is_string($variables['value'])) {
$variables['value'] = Unicode::truncate(
$variables['value'],
$length,
TRUE,
TRUE
);
}
elseif (is_string($variables['value']['text']['#title'])) {
$variables['value']['text']['#title'] = Unicode::truncate(
$variables['value']['text']['#title'],
$length,
TRUE,
TRUE
);
}
}
}

147
modules/islandora_advanced_search/js/facets/facets-views-ajax.js

@ -1,147 +0,0 @@
//# sourceURL=modules/contrib/islandora/modules/islandora_advanced_search/js/facets/facets-view.ajax.js
/**
* @file
* Overrides the facets-view-ajax.js behavior from the 'facets' module.
*/
(function ($, Drupal) {
"use strict";
// Generate events on push state.
(function (history) {
var pushState = history.pushState;
history.pushState = function (state, title, url) {
var ret = pushState.apply(this, arguments);
var event = new Event("pushstate");
window.dispatchEvent(event);
return ret;
};
})(window.history);
function reload(url) {
// Update View.
if (drupalSettings && drupalSettings.views && drupalSettings.views.ajaxViews) {
var view_path = drupalSettings.views.ajax_path;
$.each(drupalSettings.views.ajaxViews, function (views_dom_id) {
var views_parameters = Drupal.Views.parseQueryString(url);
var views_arguments = Drupal.Views.parseViewArgs(url, "search");
var views_settings = $.extend(
{},
Drupal.views.instances[views_dom_id].settings,
views_arguments,
views_parameters
);
var views_ajax_settings =
Drupal.views.instances[views_dom_id].element_settings;
views_ajax_settings.submit = views_settings;
views_ajax_settings.url =
view_path + "?" + $.param(Drupal.Views.parseQueryString(url));
Drupal.ajax(views_ajax_settings).execute();
});
}
// Replace filter, pager, summary, and facet blocks.
var blocks = {};
$(
".block[class*='block-plugin-id--islandora-advanced-search-result-pager'], .block[class*='block-plugin-id--views-exposed-filter-block'], .block[class*='block-plugin-id--facet']"
).each(function () {
var id = $(this).attr("id");
var block_id = id
.slice("block-".length, id.length)
.replace(/--.*$/g, "")
.replace(/-/g, "_");
blocks[block_id] = "#" + id;
});
Drupal.ajax({
url: Drupal.url("islandora-advanced-search-ajax-blocks"),
submit: {
link: url,
blocks: blocks,
},
}).execute();
}
// On location change reload all the blocks / ajax view.
window.addEventListener("pushstate", function (e) {
reload(window.location.href);
});
window.addEventListener("popstate", function (e) {
if (e.state != null) {
reload(window.location.href);
}
});
/**
* Push state on form/pager/facet change.
*/
Drupal.behaviors.islandoraAdvancedSearchViewsAjax = {
attach: function (context, settings) {
window.historyInitiated = true;
// Remove existing behavior from form.
if (settings && settings.views && settings.views.ajaxViews) {
$.each(settings.views.ajaxViews, function (index, settings) {
var exposed_form = $(
"form#views-exposed-form-" +
settings.view_name.replace(/_/g, "-") +
"-" +
settings.view_display_id.replace(/_/g, "-")
);
exposed_form
.once()
.find("input[type=submit], input[type=image]")
.not("[data-drupal-selector=edit-reset]")
.each(function (index) {
$(this).unbind("click");
$(this).click(function (e) {
// Let ctrl/cmd click open in a new window.
if (e.shiftKey || e.ctrlKey || e.metaKey) {
return;
}
e.preventDefault();
e.stopPropagation();
var href = window.location.href;
var params = Drupal.Views.parseQueryString(href);
// Remove the page if set as submitting the form should always take
// the user to the first page (facets do the same).
delete params.page;
// Include values from the form in the URL.
$.each(exposed_form.serializeArray(), function () {
params[this.name] = this.value;
});
href = href.split("?")[0] + "?" + $.param(params);
window.history.pushState(null, document.title, href);
});
});
});
}
// Attach behavior to pager, summary, facet links.
$("[data-drupal-pager-id], [data-drupal-facets-summary-id], [data-drupal-facet-id]")
.once()
.find("a:not(.facets-soft-limit-link)")
.click(function (e) {
// Let ctrl/cmd click open in a new window.
if (e.shiftKey || e.ctrlKey || e.metaKey) {
return;
}
e.preventDefault();
window.history.pushState(null, document.title, $(this).attr("href"));
});
// Trigger on sort change.
$('[data-drupal-pager-id] select[name="order"]')
.once()
.change(function () {
var href = window.location.href;
var params = Drupal.Views.parseQueryString(href);
var selection = $(this).val();
var option = $('option[value="' + selection + '"]');
params.sort_order = option.data("sort_order");
params.sort_by = option.data("sort_by");
href = href.split("?")[0] + "?" + $.param(params);
window.history.pushState(null, document.title, href);
});
},
};
})(jQuery, Drupal);

70
modules/islandora_advanced_search/js/facets/soft-limit.js

@ -1,70 +0,0 @@
//# sourceURL=modules/contrib/islandora/modules/islandora_advanced_search/js/facets/soft-limit.js
/**
* @file
* Overrides the soft-limit.js behavior from the 'facets' module.
* As when having many facets the original version causes the page to slow down and snap to hidden when rendering.
*/
(function ($) {
'use strict';
Drupal.behaviors.facetSoftLimit = {
attach: function (context, settings) {
if (settings.facets.softLimit !== 'undefined') {
$.each(settings.facets.softLimit, function (facet, limit) {
Drupal.facets.applySoftLimit(facet, limit, settings);
});
}
}
};
Drupal.facets = Drupal.facets || {};
/**
* Applies the soft limit UI feature to a specific facets list.
*
* @param {string} facet
* The facet id.
* @param {string} limit
* The maximum amount of items to show.
* @param {object} settings
* Settings.
*/
Drupal.facets.applySoftLimit = function (facet, limit, settings) {
var zero_based_limit = (limit - 1);
var facet_id = facet;
var facetsList = $('ul[data-drupal-facet-id="' + facet_id + '"]');
// In case of multiple instances of a facet, we need to key them.
if (facetsList.length > 1) {
facetsList.each(function (key, $value) {
$(this).attr('data-drupal-facet-id', facet_id + '-' + key);
});
}
// Add "Show more" / "Show less" links.
facetsList.filter(function () {
return $(this).next('ul').length == 1; // Has expanding list.
}).each(function () {
var facet = $(this);
var expand = facet.next('ul');
var link = expand.next('a');
var showLessLabel = settings.facets.softLimitSettings[facet_id].showLessLabel;
var showMoreLabel = settings.facets.softLimitSettings[facet_id].showMoreLabel;
link.text(showMoreLabel)
.once()
.on('click', function () {
if (!expand.is(":visible")) {
expand.slideDown();
$(this).addClass('open').text(showLessLabel);
}
else {
expand.slideUp();
$(this).removeClass('open').text(showMoreLabel);
}
return false;
})
});
};
})(jQuery);

2
modules/islandora_advanced_search/src/Form/AdvancedSearchForm.php

@ -71,7 +71,7 @@ class AdvancedSearchForm extends FormBase {
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('request_stack')->getMasterRequest(),
$container->get('request_stack')->getMainRequest(),
$container->get('current_route_match')
);
}

2
modules/islandora_advanced_search/src/Plugin/Block/AdvancedSearchBlock.php

@ -108,7 +108,7 @@ class AdvancedSearchBlock extends BlockBase implements ContainerFactoryPluginInt
$plugin_definition,
$container->get('plugin.manager.search_api.display'),
$container->get('form_builder'),
$container->get('request_stack')->getMasterRequest()
$container->get('request_stack')->getMainRequest()
);
}

2
modules/islandora_advanced_search/src/Plugin/Block/SearchResultsPagerBlock.php

@ -58,7 +58,7 @@ class SearchResultsPagerBlock extends BlockBase implements ContainerFactoryPlugi
$configuration,
$plugin_id,
$plugin_definition,
$container->get('request_stack')->getMasterRequest()
$container->get('request_stack')->getMainRequest()
);
}

3
modules/islandora_audio/islandora_audio.info.yml

@ -2,7 +2,6 @@ name: 'Islandora Audio'
description: 'Islandora audio derivative actions'
type: module
package: Islandora
core: 8.x
core_version_requirement: ^8 || ^9
core_version_requirement: ^9 || ^10
dependencies:
- drupal:islandora

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

@ -40,7 +40,7 @@ class GenerateAudioDerivativeTest extends GenerateDerivativeTestBase {
// Create an action to generate a audio derivative.
$this->drupalGet('admin/config/system/actions');
$this->getSession()->getPage()->findById("edit-action")->selectOption("Generate a audio derivative");
$this->getSession()->getPage()->pressButton($this->t('Create'));
$this->getSession()->getPage()->pressButton('Create');
$this->assertSession()->statusCodeEquals(200);
$this->getSession()->getPage()->fillField('edit-label', "Generate audio test derivative");
@ -53,7 +53,7 @@ class GenerateAudioDerivativeTest extends GenerateDerivativeTestBase {
$this->getSession()->getPage()->fillField('edit-args', "-f mp3");
$this->getSession()->getPage()->fillField('edit-scheme', "public");
$this->getSession()->getPage()->fillField('edit-path', "derp.mov");
$this->getSession()->getPage()->pressButton($this->t('Save'));
$this->getSession()->getPage()->pressButton('Save');
$this->assertSession()->statusCodeEquals(200);
// Create a context and add the action as a derivative reaction.
@ -66,10 +66,10 @@ class GenerateAudioDerivativeTest extends GenerateDerivativeTestBase {
'name[0][value]' => 'Test Media',
'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt',
'field_media_of[0][target_id]' => 'Test Node',
'field_tags[0][target_id]' => 'Preservation Master',
'field_media_use[0][target_id]' => $this->preservationMasterTerm->label(),
];
$this->drupalGet('media/add/' . $this->testMediaType->id());
$this->submitForm($values, $this->t('Save'));
$this->submitForm($values, 'Save');
$expected = [
'source_uri' => 'test_file.txt',

6
modules/islandora_breadcrumbs/config/install/islandora_breadcrumbs.breadcrumbs.yml

@ -2,9 +2,3 @@ maxDepth: -1
includeSelf: FALSE
referenceFields:
- field_member_of
dependencies:
module:
- islandora
enforced:
module:
- islandora_breadcrumbs

5
modules/islandora_breadcrumbs/islandora_breadcrumbs.info.yml

@ -1,8 +1,7 @@
name: 'Islandora Breadcrumbs'
type: module
description: 'Builds breadcrumbs based on field_member_of relationships.'
core: 8.x
core_version_requirement: ^8 || ^9
core_version_requirement: ^9 || ^10
package: Islandora
dependencies:
- drupal:islandora
- islandora:islandora

100
modules/islandora_core_feature/config/install/features.bundle.islandora.yml

@ -1,100 +0,0 @@
langcode: en
status: true
dependencies:
enforced:
module:
- islandora_core_feature
name: Islandora
machine_name: islandora
description: 'Features for islandora'
assignments:
alter:
core: true
uuid: true
user_permissions: true
enabled: true
weight: 0
base:
types:
config:
comment_type: comment_type
node_type: node_type
content:
user: user
enabled: true
weight: -2
core:
types:
config:
date_format: date_format
field_storage_config: field_storage_config
entity_form_mode: entity_form_mode
image_style: image_style
menu: menu
responsive_image_style: responsive_image_style
user_role: user_role
entity_view_mode: entity_view_mode
enabled: true
weight: 5
dependency:
enabled: true
weight: 15
exclude:
types:
config:
features_bundle: features_bundle
curated: true
module:
installed: true
profile: true
namespace: true
namespace_any: false
enabled: true
weight: -5
existing:
enabled: true
weight: 12
forward_dependency:
enabled: true
weight: 4
namespace:
enabled: true
weight: 0
optional:
types:
config: { }
enabled: true
weight: 0
packages:
enabled: true
weight: -20
profile:
curated: true
standard:
files: true
dependencies: true
types:
config:
block: block
language_content_settings: language_content_settings
configurable_language: configurable_language
migration: migration
shortcut_set: shortcut_set
tour: tour
enabled: true
weight: 10
site:
types:
config:
action: action
contact_form: contact_form
block_content_type: block_content_type
rdf_mapping: rdf_mapping
search_page: search_page
taxonomy_vocabulary: taxonomy_vocabulary
editor: editor
filter_format: filter_format
enabled: true
weight: 7
profile_name: ''
is_profile: false

0
modules/islandora_core_feature/config/install/core.entity_view_mode.media.source.yml → modules/islandora_core_feature/config/optional/core.entity_view_mode.media.source.yml

0
modules/islandora_core_feature/config/install/field.field.taxonomy_term.islandora_media_use.field_external_uri.yml → modules/islandora_core_feature/config/optional/field.field.taxonomy_term.islandora_media_use.field_external_uri.yml

0
modules/islandora_core_feature/config/install/field.field.taxonomy_term.islandora_models.field_external_uri.yml → modules/islandora_core_feature/config/optional/field.field.taxonomy_term.islandora_models.field_external_uri.yml

0
modules/islandora_core_feature/config/install/field.storage.media.field_file_size.yml → modules/islandora_core_feature/config/optional/field.storage.media.field_file_size.yml

0
modules/islandora_core_feature/config/install/field.storage.media.field_height.yml → modules/islandora_core_feature/config/optional/field.storage.media.field_height.yml

0
modules/islandora_core_feature/config/install/field.storage.media.field_media_audio_file.yml → modules/islandora_core_feature/config/optional/field.storage.media.field_media_audio_file.yml

0
modules/islandora_core_feature/config/install/field.storage.media.field_media_document.yml → modules/islandora_core_feature/config/optional/field.storage.media.field_media_document.yml

0
modules/islandora_core_feature/config/install/field.storage.media.field_media_file.yml → modules/islandora_core_feature/config/optional/field.storage.media.field_media_file.yml

0
modules/islandora_core_feature/config/install/field.storage.media.field_media_image.yml → modules/islandora_core_feature/config/optional/field.storage.media.field_media_image.yml

0
modules/islandora_core_feature/config/install/field.storage.media.field_media_of.yml → modules/islandora_core_feature/config/optional/field.storage.media.field_media_of.yml

0
modules/islandora_core_feature/config/install/field.storage.media.field_media_use.yml → modules/islandora_core_feature/config/optional/field.storage.media.field_media_use.yml

0
modules/islandora_core_feature/config/install/field.storage.media.field_media_video_file.yml → modules/islandora_core_feature/config/optional/field.storage.media.field_media_video_file.yml

0
modules/islandora_core_feature/config/install/field.storage.media.field_mime_type.yml → modules/islandora_core_feature/config/optional/field.storage.media.field_mime_type.yml

0
modules/islandora_core_feature/config/install/field.storage.media.field_original_name.yml → modules/islandora_core_feature/config/optional/field.storage.media.field_original_name.yml

0
modules/islandora_core_feature/config/install/field.storage.media.field_width.yml → modules/islandora_core_feature/config/optional/field.storage.media.field_width.yml

0
modules/islandora_core_feature/config/install/field.storage.node.field_member_of.yml → modules/islandora_core_feature/config/optional/field.storage.node.field_member_of.yml

0
modules/islandora_core_feature/config/install/field.storage.node.field_model.yml → modules/islandora_core_feature/config/optional/field.storage.node.field_model.yml

0
modules/islandora_core_feature/config/install/field.storage.node.field_weight.yml → modules/islandora_core_feature/config/optional/field.storage.node.field_weight.yml

0
modules/islandora_core_feature/config/install/field.storage.taxonomy_term.field_external_uri.yml → modules/islandora_core_feature/config/optional/field.storage.taxonomy_term.field_external_uri.yml

0
modules/islandora_core_feature/config/install/filehash.settings.yml → modules/islandora_core_feature/config/optional/filehash.settings.yml

0
modules/islandora_core_feature/config/install/migrate_plus.migration.islandora_tags.yml → modules/islandora_core_feature/config/optional/migrate_plus.migration.islandora_tags.yml

0
modules/islandora_core_feature/config/install/migrate_plus.migration_group.islandora.yml → modules/islandora_core_feature/config/optional/migrate_plus.migration_group.islandora.yml

0
modules/islandora_core_feature/config/install/rest.resource.entity.file.yml → modules/islandora_core_feature/config/optional/rest.resource.entity.file.yml

0
modules/islandora_core_feature/config/install/rest.resource.entity.media.yml → modules/islandora_core_feature/config/optional/rest.resource.entity.media.yml

0
modules/islandora_core_feature/config/install/rest.resource.entity.node.yml → modules/islandora_core_feature/config/optional/rest.resource.entity.node.yml

0
modules/islandora_core_feature/config/install/rest.resource.entity.taxonomy_term.yml → modules/islandora_core_feature/config/optional/rest.resource.entity.taxonomy_term.yml

0
modules/islandora_core_feature/config/install/system.action.delete_file_as_fedora_external_content.yml → modules/islandora_core_feature/config/optional/system.action.delete_file_as_fedora_external_content.yml

0
modules/islandora_core_feature/config/install/system.action.delete_media_from_triplestore.yml → modules/islandora_core_feature/config/optional/system.action.delete_media_from_triplestore.yml

0
modules/islandora_core_feature/config/install/system.action.delete_node_from_fedora.yml → modules/islandora_core_feature/config/optional/system.action.delete_node_from_fedora.yml

0
modules/islandora_core_feature/config/install/system.action.delete_node_from_triplestore.yml → modules/islandora_core_feature/config/optional/system.action.delete_node_from_triplestore.yml

0
modules/islandora_core_feature/config/install/system.action.delete_taxonomy_term_in_fedora.yml → modules/islandora_core_feature/config/optional/system.action.delete_taxonomy_term_in_fedora.yml

0
modules/islandora_core_feature/config/install/system.action.delete_taxonomy_term_in_triplestore.yml → modules/islandora_core_feature/config/optional/system.action.delete_taxonomy_term_in_triplestore.yml

0
modules/islandora_core_feature/config/install/system.action.index_file_as_fedora_external_content.yml → modules/islandora_core_feature/config/optional/system.action.index_file_as_fedora_external_content.yml

0
modules/islandora_core_feature/config/install/system.action.index_media_in_fedora.yml → modules/islandora_core_feature/config/optional/system.action.index_media_in_fedora.yml

0
modules/islandora_core_feature/config/install/system.action.index_media_in_triplestore.yml → modules/islandora_core_feature/config/optional/system.action.index_media_in_triplestore.yml

0
modules/islandora_core_feature/config/install/system.action.index_node_in_fedora.yml → modules/islandora_core_feature/config/optional/system.action.index_node_in_fedora.yml

0
modules/islandora_core_feature/config/install/system.action.index_node_in_triplestore.yml → modules/islandora_core_feature/config/optional/system.action.index_node_in_triplestore.yml

0
modules/islandora_core_feature/config/install/system.action.index_taxonomy_term_in_fedora.yml → modules/islandora_core_feature/config/optional/system.action.index_taxonomy_term_in_fedora.yml

0
modules/islandora_core_feature/config/install/system.action.index_taxonomy_term_in_the_triplestore.yml → modules/islandora_core_feature/config/optional/system.action.index_taxonomy_term_in_the_triplestore.yml

0
modules/islandora_core_feature/config/install/taxonomy.vocabulary.islandora_media_use.yml → modules/islandora_core_feature/config/optional/taxonomy.vocabulary.islandora_media_use.yml

0
modules/islandora_core_feature/config/install/taxonomy.vocabulary.islandora_models.yml → modules/islandora_core_feature/config/optional/taxonomy.vocabulary.islandora_models.yml

0
modules/islandora_core_feature/config/install/views.view.all_taxonomy_terms.yml → modules/islandora_core_feature/config/optional/views.view.all_taxonomy_terms.yml

0
modules/islandora_core_feature/config/install/views.view.display_media.yml → modules/islandora_core_feature/config/optional/views.view.display_media.yml

0
modules/islandora_core_feature/config/install/views.view.file_checksum.yml → modules/islandora_core_feature/config/optional/views.view.file_checksum.yml

0
modules/islandora_core_feature/config/install/views.view.manage_members.yml → modules/islandora_core_feature/config/optional/views.view.manage_members.yml

0
modules/islandora_core_feature/config/install/views.view.media_of.yml → modules/islandora_core_feature/config/optional/views.view.media_of.yml

0
modules/islandora_core_feature/config/install/views.view.non_fedora_files.yml → modules/islandora_core_feature/config/optional/views.view.non_fedora_files.yml

0
modules/islandora_core_feature/config/install/views.view.reorder_children.yml → modules/islandora_core_feature/config/optional/views.view.reorder_children.yml

16
modules/islandora_core_feature/islandora_core_feature.features.yml

@ -1,16 +0,0 @@
bundle: islandora
excluded:
- language.content_settings.taxonomy_term.islandora_media_use
- language.content_settings.taxonomy_term.islandora_models
required:
- features.bundle.islandora
- field.storage.media.field_file_size
- field.storage.media.field_height
- field.storage.media.field_media_of
- field.storage.media.field_media_use
- field.storage.media.field_mime_type
- field.storage.media.field_width
- field.storage.node.field_member_of
- field.storage.node.field_model
- field.storage.node.field_weight
- field.storage.taxonomy_term.field_external_uri

4
modules/islandora_core_feature/islandora_core_feature.info.yml

@ -1,13 +1,11 @@
name: 'Islandora Core Feature'
description: 'Minimum configuration required for Islandora.'
type: module
core: 8.x
core_version_requirement: ^8 || ^9
core_version_requirement: ^9 || ^10
dependencies:
- drupal:basic_auth
- drupal:content_translation
- drupal:eva
- drupal:features
- drupal:field
- drupal:file
- drupal:filehash

18
modules/islandora_iiif/config/schema/islandora_iiif.schema.yml

@ -5,11 +5,29 @@ islandora_iiif.settings:
iiif_server:
type: string
label: 'IIIF Server Url'
use_relative_paths:
type: boolean
label: 'Use relative paths in manifest.'
show_title:
type: string
label: 'Show title in view'
views.style.iiif_manifest:
type: views_style
mapping:
iiif_tile_field:
type: sequence
label: "Tile source field(s)"
sequence:
type: string
iiif_ocr_file_field:
type: sequence
label: "Structured OCR data file field"
sequence:
type: string
structured_text_term_uri:
type: string
label: "Structured text term"
search_endpoint:
type: string
label: "Search endpoint path"

3
modules/islandora_iiif/islandora_iiif.info.yml

@ -1,8 +1,7 @@
name: 'Islandora IIIF'
type: module
description: 'IIIF support for Islandora'
core: 8.x
core_version_requirement: ^8 || ^9
core_version_requirement: ^9 || ^10
package: Islandora
dependencies:
- drupal:islandora

26
modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php

@ -66,13 +66,37 @@ class IslandoraIIIFConfigForm extends ConfigFormBase {
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$options = [
'none' => $this->t('None'),
'view' => $this->t("From view title"),
'node' => $this->t("From node title"),
];
$config = $this->config('islandora_iiif.settings');
$form['iiif_server'] = [
'#type' => 'url',
'#title' => $this->t('IIIF Image server location'),
'#description' => $this->t('Please enter the image server location without trailing slash. e.g. http://www.example.org/iiif/2.'),
'#default_value' => $config->get('iiif_server'),
'#config' => [
'key' => 'islandora_iiif.settings:iiif_server',
],
];
$form['use_relative_paths'] = [
'#type' => 'checkbox',
'#title' => $this->t("Use relative file paths in manifest."),
'#description' => $this->t("Check this if your IIIF Server is configured to access files locally. If unchecked, the absolute URL will be given and the IIIF server will make requests to this site to retrieve images."),
'#default_value' => $config->get('use_relative_paths'),
];
$form['show_title'] = [
'#type' => 'select',
'#options' => $options,
'#title' => $this->t("Show title in viewer."),
'#description' => $this->t("Show title on your viewer, if viewer allows"),
'#default_value' => $config->get('show_title'),
];
return parent::buildForm($form, $form_state);
}
@ -99,6 +123,8 @@ class IslandoraIIIFConfigForm extends ConfigFormBase {
$this->config('islandora_iiif.settings')
->set('iiif_server', $form_state->getValue('iiif_server'))
->set('use_relative_paths', $form_state->getValue('use_relative_paths'))
->set('show_title', $form_state->getValue('show_title'))
->save();
}

212
modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php

@ -5,11 +5,14 @@ namespace Drupal\islandora_iiif\Plugin\views\style;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Field\FieldItemInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Url;
use Drupal\islandora\IslandoraUtils;
use Drupal\taxonomy\TermInterface;
use Drupal\views\Plugin\views\style\StylePluginBase;
use Drupal\views\ResultRow;
use GuzzleHttp\Client;
@ -34,6 +37,13 @@ use Symfony\Component\HttpFoundation\Request;
*/
class IIIFManifest extends StylePluginBase {
/**
* Islandora utility functions.
*
* @var \Drupal\islandora\IslandoraUtils
*/
protected $utils;
/**
* {@inheritdoc}
*/
@ -86,6 +96,13 @@ class IIIFManifest extends StylePluginBase {
*/
protected $fileSystem;
/**
* The Guzzle HTTP Client.
*
* @var \GuzzleHttp\Client
*/
protected $httpClient;
/**
* The messenger.
*
@ -93,10 +110,31 @@ class IIIFManifest extends StylePluginBase {
*/
protected $messenger;
/**
* Module Handler for running hooks.
*
* @var \Drupal\Core\Extention\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* Memoized structured text term.
*
* @var \Drupal\taxonomy\TermInterface|null
*/
protected ?TermInterface $structuredTextTerm;
/**
* Flag to track if we _have_ attempted a lookup, as the value is nullable.
*
* @var bool
*/
protected bool $structuredTextTermMemoized = FALSE;
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system, Client $http_client, MessengerInterface $messenger) {
public function __construct(array $configuration, $plugin_id, $plugin_definition, SerializerInterface $serializer, Request $request, ImmutableConfig $iiif_config, EntityTypeManagerInterface $entity_type_manager, FileSystemInterface $file_system, Client $http_client, MessengerInterface $messenger, ModuleHandlerInterface $moduleHandler, IslandoraUtils $utils) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->serializer = $serializer;
@ -106,6 +144,8 @@ class IIIFManifest extends StylePluginBase {
$this->fileSystem = $file_system;
$this->httpClient = $http_client;
$this->messenger = $messenger;
$this->utils = $utils;
$this->moduleHandler = $moduleHandler;
}
/**
@ -122,10 +162,22 @@ class IIIFManifest extends StylePluginBase {
$container->get('entity_type.manager'),
$container->get('file_system'),
$container->get('http_client'),
$container->get('messenger')
$container->get('messenger'),
$container->get('module_handler'),
$container->get('islandora.utils')
);
}
/**
* Return the request property.
*
* @return \Symfony\Component\HttpFoundation\Request
* The Symfony request object
*/
public function getRequest() {
return $this->request;
}
/**
* {@inheritdoc}
*/
@ -140,15 +192,33 @@ class IIIFManifest extends StylePluginBase {
// @todo assumming the view is a path like /node/1/manifest.json
$url_components = explode('/', trim($request_url, '/'));
array_pop($url_components);
$content_path = implode('/', $url_components);
$iiif_base_id = $request_host . '/' . $content_path;
$content_path = '/' . implode('/', $url_components);
$iiif_base_id = "{$request_host}{$content_path}";
$display = $this->iiifConfig->get('show_title');
switch ($display) {
case 'none':
$label = '';
break;
case 'view':
$label = $this->view->getTitle();
break;
case 'node':
$label = $this->getEntityTitle($content_path);
break;
default:
$label = $this->t("IIIF Manifest");
}
// @see https://iiif.io/api/presentation/2.1/#manifest
$json += [
'@type' => 'sc:Manifest',
'@id' => $request_url,
// If the View has a title, set the View title as the manifest label.
'label' => $this->view->getTitle() ?: $this->getEntityTitle($content_path),
'label' => $label,
'@context' => 'http://iiif.io/api/presentation/2/context.json',
// @see https://iiif.io/api/presentation/2.1/#sequence
'sequences' => [
@ -172,6 +242,12 @@ class IIIFManifest extends StylePluginBase {
$content_type = 'json';
// Add a search endpoint if one is defined.
$this->addSearchEndpoint($json, $url_components);
// Give other modules a chance to alter the manifest.
$this->moduleHandler->alter('islandora_iiif_manifest', $json, $this);
return $this->serializer->serialize($json, $content_type, ['views_style_plugin' => $this]);
}
@ -206,7 +282,13 @@ class IIIFManifest extends StylePluginBase {
// Create the IIIF URL for this file
// Visiting $iiif_url will resolve to the info.json for the image.
$file_url = $image->entity->createFileUrl(FALSE);
if ($this->iiifConfig->get('use_relative_paths')) {
$file_url = ltrim($image->entity->createFileUrl(TRUE), '/');
}
else {
$file_url = $image->entity->createFileUrl(FALSE);
}
$mime_type = $image->entity->getMimeType();
$iiif_url = rtrim($iiif_address, '/') . '/' . urlencode($file_url);
@ -246,7 +328,7 @@ class IIIFManifest extends StylePluginBase {
],
];
if ($ocr_url = $this->getOcrUrl($entity, $row, $i)) {
if ($ocr_url = $this->getOcrUrl($entity)) {
$tmp_canvas['seeAlso'] = [
'@id' => $ocr_url,
'format' => 'text/vnd.hocr+html',
@ -255,6 +337,13 @@ class IIIFManifest extends StylePluginBase {
];
}
// Give other modules a chance to alter the canvas.
$alter_options = [
'options' => $this->options,
'views_plugin' => $this,
];
$this->moduleHandler->alter('islandora_iiif_manifest_canvas', $tmp_canvas, $row, $alter_options);
$canvases[] = $tmp_canvas;
}
}
@ -277,6 +366,12 @@ class IIIFManifest extends StylePluginBase {
* The width and height of the image.
*/
protected function getCanvasDimensions(string $iiif_url, FieldItemInterface $image, string $mime_type) {
if (isset($image->width) && is_numeric($image->width)
&& isset($image->height) && is_numeric($image->height)) {
return [intval($image->width), intval($image->height)];
}
try {
$info_json = $this->httpClient->get($iiif_url)->getBody();
$resource = json_decode($info_json, TRUE);
@ -294,7 +389,7 @@ class IIIFManifest extends StylePluginBase {
// 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) {
if ($mime_type === 'image/tiff' && (!$width || !$height)) {
$uri = $image->entity->getFileUri();
$path = $this->fileSystem->realpath($uri);
$image_size = getimagesize($path);
@ -313,30 +408,38 @@ class IIIFManifest extends StylePluginBase {
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity at the current row.
* @param \Drupal\views\ResultRow $row
* Result row.
* @param int $delta
* The delta in case there are multiple canvases on one media.
*
* @return string|false
* The absolute URL of the current row's structured text,
* or FALSE if none.
*/
protected function getOcrUrl(EntityInterface $entity, ResultRow $row, $delta) {
protected function getOcrUrl(EntityInterface $entity) {
$ocr_url = FALSE;
$iiif_ocr_file_field = !empty($this->options['iiif_ocr_file_field']) ? array_filter(array_values($this->options['iiif_ocr_file_field'])) : [];
$ocrField = count($iiif_ocr_file_field) > 0 ? $this->view->field[$iiif_ocr_file_field[0]] : NULL;
if ($ocrField) {
$ocr_entity = $ocrField->getEntity($row);
$ocr_entity = $entity;
$ocr_field_name = $ocrField->definition['field_name'];
if (!is_null($ocr_field_name)) {
$ocrs = $ocr_entity->{$ocr_field_name};
$ocr = isset($ocrs[$delta]) ? $ocrs[$delta] : FALSE;
$ocr = $ocrs[0] ?? FALSE;
if ($ocr) {
$ocr_url = $ocr->entity->createFileUrl(FALSE);
}
}
}
elseif ($structured_text_term = $this->getStructuredTextTerm()) {
$parent_node = $this->utils->getParentNode($entity);
$ocr_entity_array = $this->utils->getMediaReferencingNodeAndTerm($parent_node, $structured_text_term);
$ocr_entity_id = is_array($ocr_entity_array) ? array_shift($ocr_entity_array) : NULL;
$ocr_entity = $ocr_entity_id ? $this->entityTypeManager->getStorage('media')->load($ocr_entity_id) : NULL;
if ($ocr_entity) {
$ocr_file_source = $ocr_entity->getSource();
$ocr_fid = $ocr_file_source->getSourceFieldValue($ocr_entity);
$ocr_file = $this->entityTypeManager->getStorage('file')->load($ocr_fid);
$ocr_url = $ocr_file->createFileUrl(FALSE);
}
}
return $ocr_url;
}
@ -381,6 +484,29 @@ class IIIFManifest extends StylePluginBase {
return $options;
}
/**
* Add the configured search endpoint to the manifest.
*
* @param array $json
* The IIIF manifest.
* @param array $url_components
* The search endpoint URL as array.
*/
protected function addSearchEndpoint(array &$json, array $url_components) {
$url_base = $this->getRequest()->getSchemeAndHttpHost();
$hocr_search_path = $this->options['search_endpoint'];
$hocr_search_url = $url_base . '/' . ltrim($hocr_search_path, '/');
$hocr_search_url = str_replace('%node', $url_components[1], $hocr_search_url);
$json['service'][] = [
"@context" => "http://iiif.io/api/search/0/context.json",
"@id" => $hocr_search_url,
"profile" => "http://iiif.io/api/search/0/search",
"label" => t("Search inside this work"),
];
}
/**
* {@inheritdoc}
*/
@ -437,10 +563,27 @@ class IIIFManifest extends StylePluginBase {
'#title' => $this->t('Structured OCR data file field'),
'#type' => 'checkboxes',
'#default_value' => $this->options['iiif_ocr_file_field'],
'#description' => $this->t('The source of structured OCR text for each entity.'),
'#description' => $this->t("If the hOCR is a field on the same entity as the image source field above, select it here. If it's found in a related entity via the term below, leave this blank."),
'#options' => $field_options,
'#required' => FALSE,
];
$form['structured_text_term'] = [
'#type' => 'entity_autocomplete',
'#target_type' => 'taxonomy_term',
'#title' => $this->t('Structured OCR text term'),
'#default_value' => $this->getStructuredTextTerm(),
'#required' => FALSE,
'#description' => $this->t('Term indicating the media that holds structured text, such as hOCR, for the given object. Use this if the text is on a separate media from the tile source.'),
];
$form['search_endpoint'] = [
'#type' => 'textfield',
'#title' => $this->t("Search endpoint path."),
'#description' => $this->t("If there is a search endpoint to search within the book that returns IIIF annotations, put it here. Use %node substitution where needed.<br>E.g., paged-content-search/%node"),
'#default_value' => $this->options['search_endpoint'],
'#required' => FALSE,
];
}
/**
@ -453,4 +596,41 @@ class IIIFManifest extends StylePluginBase {
return ['json' => 'json'];
}
/**
* Submit handler for options form.
*
* Used to store the structured text media term by URL instead of Ttid.
*
* @param array $form
* The form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state object.
*/
// @codingStandardsIgnoreStart
public function submitOptionsForm(&$form, FormStateInterface $form_state) {
// @codingStandardsIgnoreEnd
$style_options = $form_state->getValue('style_options');
$tid = $style_options['structured_text_term'];
unset($style_options['structured_text_term']);
$term = $this->entityTypeManager->getStorage('taxonomy_term')->load($tid);
$style_options['structured_text_term_uri'] = $this->utils->getUriForTerm($term);
$form_state->setValue('style_options', $style_options);
parent::submitOptionsForm($form, $form_state);
}
/**
* Get the structured text term.
*
* @return \Drupal\taxonomy\TermInterface|null
* The term if it could be found; otherwise, NULL.
*/
protected function getStructuredTextTerm() : ?TermInterface {
if (!$this->structuredTextTermMemoized) {
$this->structuredTextTermMemoized = TRUE;
$this->structuredTextTerm = $this->utils->getTermForUri($this->options['structured_text_term_uri']);
}
return $this->structuredTextTerm;
}
}

3
modules/islandora_image/islandora_image.info.yml

@ -1,8 +1,7 @@
name: 'Islandora Image'
type: module
description: 'Islandora Image derivative actions'
core: 8.x
core_version_requirement: ^8 || ^9
core_version_requirement: ^9 || ^10
package: Islandora
dependencies:
- drupal:islandora

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

@ -42,7 +42,7 @@ class GenerateImageDerivativeTest extends GenerateDerivativeTestBase {
// Create an action to generate a jpeg thumbnail.
$this->drupalGet('admin/config/system/actions');
$this->getSession()->getPage()->findById("edit-action")->selectOption("Generate an image derivative");
$this->getSession()->getPage()->pressButton($this->t('Create'));
$this->getSession()->getPage()->pressButton('Create');
$this->assertSession()->statusCodeEquals(200);
$this->getSession()->getPage()->fillField('edit-label', "Generate image test derivative");
@ -55,7 +55,7 @@ class GenerateImageDerivativeTest extends GenerateDerivativeTestBase {
$this->getSession()->getPage()->fillField('edit-args', "-thumbnail 20x20");
$this->getSession()->getPage()->fillField('edit-scheme', "public");
$this->getSession()->getPage()->fillField('edit-path', "derp.jpeg");
$this->getSession()->getPage()->pressButton($this->t('Save'));
$this->getSession()->getPage()->pressButton('Save');
$this->assertSession()->statusCodeEquals(200);
// Create a context and add the action as a derivative reaction.
@ -68,10 +68,10 @@ class GenerateImageDerivativeTest extends GenerateDerivativeTestBase {
'name[0][value]' => 'Test Media',
'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt',
'field_media_of[0][target_id]' => 'Test Node',
'field_tags[0][target_id]' => 'Preservation Master',
'field_media_use[0][target_id]' => $this->preservationMasterTerm->label(),
];
$this->drupalGet('media/add/' . $this->testMediaType->id());
$this->submitForm($values, $this->t('Save'));
$this->submitForm($values, 'Save');
$expected = [
'source_uri' => 'test_file.txt',

3
modules/islandora_text_extraction/islandora_text_extraction.info.yml

@ -1,8 +1,7 @@
name: 'Islandora Text Extraction'
type: module
description: 'Islandora 8 module to connect to Hypercube microservice, and to get text from PDF ingest'
core: 8.x
core_version_requirement: ^8 || ^9
core_version_requirement: ^9 || ^10
package: 'Islandora'
dependencies:
- drupal:islandora

5
modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php

@ -48,8 +48,9 @@ class GenerateOCRDerivative extends AbstractGenerateDerivative {
*/
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
parent::validateConfigurationForm($form, $form_state);
$exploded_mime = explode('/', $form_state->getValue('mimetype'));
if ($exploded_mime[0] != 'text') {
$mime = $form_state->getValue('mimetype');
$exploded_mime = explode('/', $mime);
if ($exploded_mime[0] != 'text' && $mime != 'application/xml') {
$form_state->setErrorByName(
'mimetype',
$this->t('Please enter file mimetype (e.g. text/plain.)')

2
modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivativeFile.php

@ -99,7 +99,7 @@ class GenerateOCRDerivativeFile extends AbstractGenerateDerivativeMediaFile {
break;
case 'plain_text':
$his->configuration['args'] = '';
$this->configuration['args'] = '';
break;
}
}

5
modules/islandora_text_extraction/src/Plugin/Field/FieldFormatter/OcrTextFormatter.php

@ -132,8 +132,9 @@ class OcrTextFormatter extends FormatterBase implements ContainerFactoryPluginIn
$fileItem = $item->getValue();
$file = $this->entityTypeManager->getStorage('file')->load($fileItem['target_id']);
$contents = file_get_contents($file->getFileUri());
if (mb_detect_encoding($contents) != 'UTF-8') {
$contents = utf8_encode($contents);
$detected_encoding = mb_detect_encoding($contents);
if ($detected_encoding != 'UTF-8') {
$contents = mb_convert_encoding($contents, 'UTF-8', $detected_encoding);
}
$contents = nl2br($contents);
return $contents;

0
modules/islandora_text_extraction_defaults/config/install/core.entity_form_display.media.extracted_text.default.yml → modules/islandora_text_extraction_defaults/config/optional/core.entity_form_display.media.extracted_text.default.yml

0
modules/islandora_text_extraction_defaults/config/install/core.entity_view_display.media.extracted_text.default.yml → modules/islandora_text_extraction_defaults/config/optional/core.entity_view_display.media.extracted_text.default.yml

0
modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_edited_text.yml → modules/islandora_text_extraction_defaults/config/optional/field.field.media.extracted_text.field_edited_text.yml

0
modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_media_file.yml → modules/islandora_text_extraction_defaults/config/optional/field.field.media.extracted_text.field_media_file.yml

0
modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_media_of.yml → modules/islandora_text_extraction_defaults/config/optional/field.field.media.extracted_text.field_media_of.yml

0
modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_media_use.yml → modules/islandora_text_extraction_defaults/config/optional/field.field.media.extracted_text.field_media_use.yml

0
modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_mime_type.yml → modules/islandora_text_extraction_defaults/config/optional/field.field.media.extracted_text.field_mime_type.yml

0
modules/islandora_text_extraction_defaults/config/install/field.storage.media.field_edited_text.yml → modules/islandora_text_extraction_defaults/config/optional/field.storage.media.field_edited_text.yml

0
modules/islandora_text_extraction_defaults/config/install/language.content_settings.media.extracted_text.yml → modules/islandora_text_extraction_defaults/config/optional/language.content_settings.media.extracted_text.yml

0
modules/islandora_text_extraction_defaults/config/install/media.type.extracted_text.yml → modules/islandora_text_extraction_defaults/config/optional/media.type.extracted_text.yml

0
modules/islandora_text_extraction_defaults/config/install/rdf.mapping.media.extracted_text.yml → modules/islandora_text_extraction_defaults/config/optional/rdf.mapping.media.extracted_text.yml

0
modules/islandora_text_extraction_defaults/config/install/system.action.get_ocr_from_image.yml → modules/islandora_text_extraction_defaults/config/optional/system.action.get_ocr_from_image.yml

2
modules/islandora_text_extraction_defaults/islandora_text_extraction_defaults.features.yml

@ -1,2 +0,0 @@
bundle: islandora
required: true

3
modules/islandora_text_extraction_defaults/islandora_text_extraction_defaults.info.yml

@ -1,8 +1,7 @@
name: 'Islandora Text Extraction Defaults'
type: module
description: 'Default config for the Islandora Text Extraction module.'
core: 8.x
core_version_requirement: ^8 || ^9
core_version_requirement: ^9 || ^10
package: Islandora
dependencies:
- drupal:field

3
modules/islandora_video/islandora_video.info.yml

@ -2,7 +2,6 @@ name: 'Islandora Video'
description: 'Islandora video derivative actions'
type: module
package: Islandora
core: 8.x
core_version_requirement: ^8 || ^9
core_version_requirement: ^9 || ^10
dependencies:
- drupal:islandora

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

@ -37,7 +37,7 @@ class GenerateVideoDerivativeTest extends GenerateDerivativeTestBase {
// Create an action to generate a jpeg thumbnail.
$this->drupalGet('admin/config/system/actions');
$this->getSession()->getPage()->findById("edit-action")->selectOption("Generate a video derivative");
$this->getSession()->getPage()->pressButton($this->t('Create'));
$this->getSession()->getPage()->pressButton('Create');
$this->assertSession()->statusCodeEquals(200);
$this->getSession()->getPage()->fillField('edit-label', "Generate video test derivative");
@ -50,7 +50,7 @@ class GenerateVideoDerivativeTest extends GenerateDerivativeTestBase {
$this->getSession()->getPage()->fillField('edit-args', "-f mp4");
$this->getSession()->getPage()->fillField('edit-scheme', "public");
$this->getSession()->getPage()->fillField('edit-path', "derp.mov");
$this->getSession()->getPage()->pressButton($this->t('Save'));
$this->getSession()->getPage()->pressButton('Save');
$this->assertSession()->statusCodeEquals(200);
// Create a context and add the action as a derivative reaction.
@ -63,10 +63,10 @@ class GenerateVideoDerivativeTest extends GenerateDerivativeTestBase {
'name[0][value]' => 'Test Media',
'files[field_media_file_0]' => __DIR__ . '/../../fixtures/test_file.txt',
'field_media_of[0][target_id]' => 'Test Node',
'field_tags[0][target_id]' => 'Preservation Master',
'field_media_use[0][target_id]' => $this->preservationMasterTerm->label(),
];
$this->drupalGet('media/add/' . $this->testMediaType->id());
$this->submitForm($values, $this->t('Save'));
$this->submitForm($values, 'Save');
$expected = [
'source_uri' => 'test_file.txt',

2
phpunit.xml

@ -47,7 +47,7 @@
<!-- Example for changing the driver args to phantomjs tests MINK_DRIVER_ARGS_PHANTOMJS value: '["http://127.0.0.1:8510"]' -->
<env name="MINK_DRIVER_ARGS_PHANTOMJS" value=""/>
<!-- Example for changing the driver args to webdriver tests MINK_DRIVER_ARGS_WEBDRIVER value: '["chrome", { "chromeOptions": { "w3c": false } }, "http://localhost:4444/wd/hub"]' For using the Firefox browser, replace "chrome" with "firefox" -->
<env name="MINK_DRIVER_ARGS_WEBDRIVER" value=""/>
<env name="MINK_DRIVER_ARGS_WEBDRIVER" value='["chrome", {"browserName":"chrome","chromeOptions":{"args":["--disable-gpu","--headless", "--no-sandbox", "--disable-dev-shm-usage"]}}, "http://localhost:9515"]'/>
</php>
<testsuites>
<testsuite name="unit">

2
src/Controller/ManageMembersController.php

@ -29,7 +29,7 @@ class ManageMembersController extends EntityController {
*
* @var \Drupal\Core\Entity\EntityFieldManagerInterface
*/
protected $entityFieldManger;
protected $entityFieldManager;
/**
* The renderer.

16
src/EventGenerator/EventGenerator.php

@ -147,8 +147,19 @@ class EventGenerator implements EventGeneratorInterface {
}
}
unset($data["event"]);
unset($data["queue"]);
$allowed_keys = [
"file_upload_uri",
"fedora_uri",
"source_uri",
"destination_uri",
"args",
"mimetype",
"source_field",
];
$keys_to_unset = array_diff(array_keys($data), $allowed_keys);
foreach ($keys_to_unset as $key) {
unset($data[$key]);
}
if (!empty($data)) {
$event["attachment"] = [
@ -192,6 +203,7 @@ class EventGenerator implements EventGeneratorInterface {
protected function getRevisionIds(Media $media, EntityStorageInterface $media_storage) {
$result = $media_storage->getQuery()
->allRevisions()
->accessCheck(TRUE)
->condition($media->getEntityType()->getKey('id'), $media->id())
->sort($media->getEntityType()->getKey('revision'), 'DESC')
->execute();

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save