diff --git a/.travis.yml b/.travis.yml index 2743abda..685620f9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,6 +26,9 @@ install: - 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) script: - $SCRIPT_DIR/travis_scripts.sh diff --git a/islandora.links.action.yml b/islandora.links.action.yml index 97b16e10..f8bf7d2b 100644 --- a/islandora.links.action.yml +++ b/islandora.links.action.yml @@ -6,6 +6,12 @@ islandora.add_media_to_node: islandora.add_member_to_node: route_name: islandora.add_member_to_node_page - title: Add member + title: Add child + appears_on: + - view.manage_members.page_1 + +islandora.reorder_children: + route_name: view.reorder_children.page_1 + title: Reorder Children appears_on: - view.manage_members.page_1 diff --git a/islandora.module b/islandora.module index 183adabc..2e3107a1 100644 --- a/islandora.module +++ b/islandora.module @@ -60,6 +60,8 @@ function islandora_rdf_namespaces() { '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#', + 'co' => 'http://purl.org/co/', ]; } @@ -377,11 +379,9 @@ function islandora_entity_extra_field_info() { * Implements hook_entity_view(). */ function islandora_entity_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) { - $route_match_item = \Drupal::routeMatch()->getParameters()->all(); - // Get the parameter, which might be node, media or taxonomy term. - $current_entity = reset($route_match_item); - // Match exactly to ensure they are the same entity type too. - if ($entity === $current_entity) { + $route_match_item = \Drupal::routeMatch()->getParameters()->get($entity->getEntityTypeId()); + // Ensure the entity matches the route. + if ($entity === $route_match_item) { if ($display->getComponent('field_gemini_uri')) { $gemini = \Drupal::service('islandora.gemini.lookup'); if ($gemini instanceof GeminiLookup) { @@ -407,3 +407,47 @@ function islandora_entity_view(array &$build, EntityInterface $entity, EntityVie } } } + +/** + * Implements hook_preprocess_views_view_table(). + * + * Used for the integer-weight drag-n-drop. Taken almost + * verbatim from the weight module. + */ +function islandora_preprocess_views_view_table(&$variables) { + + // Check for a weight selector field. + foreach ($variables['view']->field as $field_key => $field) { + if ($field->options['plugin_id'] == 'integer_weight_selector') { + + // Check if the weight selector is on the first column. + $is_first_column = array_search($field_key, array_keys($variables['view']->field)) > 0 ? FALSE : TRUE; + + // Add the tabledrag attributes. + foreach ($variables['rows'] as $key => $row) { + if ($is_first_column) { + // If the weight selector is the first column move it to the last + // column, in order to make the draggable widget appear. + $weight_selector = $variables['rows'][$key]['columns'][$field->field]; + unset($variables['rows'][$key]['columns'][$field->field]); + $variables['rows'][$key]['columns'][$field->field] = $weight_selector; + } + // Add draggable attribute. + $variables['rows'][$key]['attributes']->addClass('draggable'); + } + // The row key identify in an unique way a view grouped by a field. + // Without row number, all the groups will share the same table_id + // and just the first table can be draggable. + $table_id = 'weight-table-' . $variables['view']->dom_id . '-row-' . $key; + $variables['attributes']['id'] = $table_id; + + $options = [ + 'table_id' => $table_id, + 'action' => 'order', + 'relationship' => 'sibling', + 'group' => 'weight-selector', + ]; + drupal_attach_tabledrag($variables, $options); + } + } +} diff --git a/islandora.views.inc b/islandora.views.inc new file mode 100644 index 00000000..cd826d08 --- /dev/null +++ b/islandora.views.inc @@ -0,0 +1,25 @@ +getFieldStorageDefinitions('node'); + foreach ($fields as $field => $field_storage_definition) { + if ($field_storage_definition->getType() == 'integer' && strpos($field, "field_") === 0) { + $data['node__' . $field][$field . '_value']['field'] = $data['node__' . $field][$field]['field']; + $data['node__' . $field][$field]['title'] = t('Integer Weight Selector (@field)', [ + '@field' => $field, + ]); + $data['node__' . $field][$field]['help'] = t('Provides a drag-n-drop reordering of integer-based weight fields.'); + $data['node__' . $field][$field]['title short'] = t('Integer weight selector'); + $data['node__' . $field][$field]['field']['id'] = 'integer_weight_selector'; + } + } +} diff --git a/migrate/tags.csv b/migrate/tags.csv index c5054546..60705a2b 100644 --- a/migrate/tags.csv +++ b/migrate/tags.csv @@ -12,3 +12,6 @@ islandora_models,"Collection","A collection is an aggregation of items",http://p islandora_models,"Image","A visual representation other than text, including all types of moving image and still image",http://purl.org/coar/resource_type/c_c513 islandora_models,"Video","A recording of visual images, usually in motion and with sound accompaniment",http://purl.org/coar/resource_type/c_12ce islandora_models,"Digital Document","An electronic file or document.",https://schema.org/DigitalDocument +islandora_models,"Paged Content","An Electronic Book, object with pages",https://schema.org/Book +islandora_models,"Page","A page in an Electronic Paged Content Object",http://id.loc.gov/ontologies/bibframe/part +islandora_models,"Publication Issue","A part of a successively published publication such as a periodical or publication volume, often numbered, usually containing a grouping of works such as articles.",https://schema.org/PublicationIssue diff --git a/modules/islandora_breadcrumbs/islandora_breadcrumbs.services.yml b/modules/islandora_breadcrumbs/islandora_breadcrumbs.services.yml index af9efa06..58e3c959 100644 --- a/modules/islandora_breadcrumbs/islandora_breadcrumbs.services.yml +++ b/modules/islandora_breadcrumbs/islandora_breadcrumbs.services.yml @@ -1,6 +1,6 @@ services: islandora_breadcrumbs.breadcrumb: class: Drupal\islandora_breadcrumbs\IslandoraBreadcrumbBuilder - arguments: ['@config.factory'] + arguments: ['@entity_type.manager', '@config.factory'] tags: - { name: breadcrumb_builder, priority: 100 } diff --git a/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php b/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php index 763c523a..54fe9534 100644 --- a/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php +++ b/modules/islandora_breadcrumbs/src/IslandoraBreadcrumbBuilder.php @@ -3,6 +3,7 @@ namespace Drupal\islandora_breadcrumbs; use Drupal\Core\Config\ConfigFactoryInterface; +use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Breadcrumb\Breadcrumb; use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface; @@ -20,13 +21,23 @@ class IslandoraBreadcrumbBuilder implements BreadcrumbBuilderInterface { */ protected $config; + /** + * Storage to load nodes. + * + * @var \Drupal\Core\Entity\EntityStorageInterface + */ + protected $nodeStorage; + /** * Constructs a breadcrumb builder. * + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_manager + * Storage to load nodes. * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * The configuration factory. */ - public function __construct(ConfigFactoryInterface $config_factory) { + public function __construct(EntityTypeManagerInterface $entity_manager, ConfigFactoryInterface $config_factory) { + $this->nodeStorage = $entity_manager->getStorage('node'); $this->config = $config_factory->get('islandora.breadcrumbs'); } @@ -34,10 +45,13 @@ class IslandoraBreadcrumbBuilder implements BreadcrumbBuilderInterface { * {@inheritdoc} */ public function applies(RouteMatchInterface $attributes) { - $parameters = $attributes->getParameters()->all(); - if (!empty($parameters['node'])) { - return ($parameters['node']->hasField($this->config->get('referenceField')) && - !$parameters['node']->get($this->config->get('referenceField'))->isEmpty()); + // Using getRawParameters for consistency (always gives a + // node ID string) because getParameters sometimes returns + // a node ID string and sometimes returns a node object. + $nid = $attributes->getRawParameters()->get('node'); + if (!empty($nid)) { + $node = $this->nodeStorage->load($nid); + return (!empty($node) && $node->hasField($this->config->get('referenceField')) && !$node->get($this->config->get('referenceField'))->isEmpty()); } } @@ -46,7 +60,8 @@ class IslandoraBreadcrumbBuilder implements BreadcrumbBuilderInterface { */ public function build(RouteMatchInterface $route_match) { - $node = $route_match->getParameter('node'); + $nid = $route_match->getRawParameters()->get('node'); + $node = $this->nodeStorage->load($nid); $breadcrumb = new Breadcrumb(); $chain = []; diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.audio.changed.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.audio.changed.yml deleted file mode 100644 index 6e3dd09b..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.audio.changed.yml +++ /dev/null @@ -1,17 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.audio -id: media.audio.changed -field_name: changed -entity_type: media -bundle: audio -label: Changed -description: 'The time the media item was last edited.' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: { } -field_type: changed diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.audio.created.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.audio.created.yml deleted file mode 100644 index 1bc3e0b6..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.audio.created.yml +++ /dev/null @@ -1,17 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.audio -id: media.audio.created -field_name: created -entity_type: media -bundle: audio -label: 'Authored on' -description: 'The time the media item was created.' -required: false -translatable: false -default_value: { } -default_value_callback: 'Drupal\media\Entity\Media::getRequestTime' -settings: { } -field_type: created diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.audio.name.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.audio.name.yml deleted file mode 100644 index 6d4e96ae..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.audio.name.yml +++ /dev/null @@ -1,19 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.audio -id: media.audio.name -field_name: name -entity_type: media -bundle: audio -label: Name -description: '' -required: true -translatable: true -default_value: - - - value: '' -default_value_callback: '' -settings: { } -field_type: string diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.audio.path.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.audio.path.yml deleted file mode 100644 index 70eae702..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.audio.path.yml +++ /dev/null @@ -1,19 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.audio - module: - - path -id: media.audio.path -field_name: path -entity_type: media -bundle: audio -label: 'URL alias' -description: '' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: { } -field_type: path diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.audio.status.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.audio.status.yml deleted file mode 100644 index 8afd972d..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.audio.status.yml +++ /dev/null @@ -1,21 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.audio -id: media.audio.status -field_name: status -entity_type: media -bundle: audio -label: Published -description: '' -required: false -translatable: false -default_value: - - - value: 1 -default_value_callback: '' -settings: - on_label: 'On' - off_label: 'Off' -field_type: boolean diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.audio.thumbnail.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.audio.thumbnail.yml deleted file mode 100644 index 3d3b22fd..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.audio.thumbnail.yml +++ /dev/null @@ -1,36 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.audio - module: - - image -id: media.audio.thumbnail -field_name: thumbnail -entity_type: media -bundle: audio -label: Thumbnail -description: 'The thumbnail of the media item.' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: - file_extensions: 'png gif jpg jpeg' - alt_field: true - alt_field_required: true - title_field: false - title_field_required: false - max_resolution: '' - min_resolution: '' - default_image: - uuid: null - alt: '' - title: '' - width: null - height: null - file_directory: '[date:custom:Y]-[date:custom:m]' - max_filesize: '' - handler: default - handler_settings: { } -field_type: image diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.audio.uid.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.audio.uid.yml deleted file mode 100644 index 5d492fda..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.audio.uid.yml +++ /dev/null @@ -1,19 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.audio -id: media.audio.uid -field_name: uid -entity_type: media -bundle: audio -label: 'Authored by' -description: 'The user ID of the author.' -required: false -translatable: false -default_value: { } -default_value_callback: 'Drupal\media\Entity\Media::getCurrentUserId' -settings: - handler: default - handler_settings: { } -field_type: entity_reference diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.file.changed.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.file.changed.yml deleted file mode 100644 index c352057b..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.file.changed.yml +++ /dev/null @@ -1,17 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.file -id: media.file.changed -field_name: changed -entity_type: media -bundle: file -label: Changed -description: 'The time the media item was last edited.' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: { } -field_type: changed diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.file.created.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.file.created.yml deleted file mode 100644 index e1ea67ef..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.file.created.yml +++ /dev/null @@ -1,17 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.file -id: media.file.created -field_name: created -entity_type: media -bundle: file -label: 'Authored on' -description: 'The time the media item was created.' -required: false -translatable: false -default_value: { } -default_value_callback: 'Drupal\media\Entity\Media::getRequestTime' -settings: { } -field_type: created diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.file.name.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.file.name.yml deleted file mode 100644 index ba40efd8..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.file.name.yml +++ /dev/null @@ -1,19 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.file -id: media.file.name -field_name: name -entity_type: media -bundle: file -label: Name -description: '' -required: true -translatable: true -default_value: - - - value: '' -default_value_callback: '' -settings: { } -field_type: string diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.file.path.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.file.path.yml deleted file mode 100644 index a0975993..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.file.path.yml +++ /dev/null @@ -1,19 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.file - module: - - path -id: media.file.path -field_name: path -entity_type: media -bundle: file -label: 'URL alias' -description: '' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: { } -field_type: path diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.file.status.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.file.status.yml deleted file mode 100644 index 3d0e2915..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.file.status.yml +++ /dev/null @@ -1,21 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.file -id: media.file.status -field_name: status -entity_type: media -bundle: file -label: Published -description: '' -required: false -translatable: false -default_value: - - - value: 1 -default_value_callback: '' -settings: - on_label: 'On' - off_label: 'Off' -field_type: boolean diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.file.thumbnail.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.file.thumbnail.yml deleted file mode 100644 index 37dac458..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.file.thumbnail.yml +++ /dev/null @@ -1,36 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.file - module: - - image -id: media.file.thumbnail -field_name: thumbnail -entity_type: media -bundle: file -label: Thumbnail -description: 'The thumbnail of the media item.' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: - file_extensions: 'png gif jpg jpeg' - alt_field: true - alt_field_required: true - title_field: false - title_field_required: false - max_resolution: '' - min_resolution: '' - default_image: - uuid: null - alt: '' - title: '' - width: null - height: null - file_directory: '[date:custom:Y]-[date:custom:m]' - max_filesize: '' - handler: default - handler_settings: { } -field_type: image diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.file.uid.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.file.uid.yml deleted file mode 100644 index 7e7f5300..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.file.uid.yml +++ /dev/null @@ -1,19 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.file -id: media.file.uid -field_name: uid -entity_type: media -bundle: file -label: 'Authored by' -description: 'The user ID of the author.' -required: false -translatable: false -default_value: { } -default_value_callback: 'Drupal\media\Entity\Media::getCurrentUserId' -settings: - handler: default - handler_settings: { } -field_type: entity_reference diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.image.changed.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.image.changed.yml deleted file mode 100644 index f32d9575..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.image.changed.yml +++ /dev/null @@ -1,17 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.image -id: media.image.changed -field_name: changed -entity_type: media -bundle: image -label: Changed -description: 'The time the media item was last edited.' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: { } -field_type: changed diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.image.created.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.image.created.yml deleted file mode 100644 index d930ca8d..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.image.created.yml +++ /dev/null @@ -1,17 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.image -id: media.image.created -field_name: created -entity_type: media -bundle: image -label: 'Authored on' -description: 'The time the media item was created.' -required: false -translatable: false -default_value: { } -default_value_callback: 'Drupal\media\Entity\Media::getRequestTime' -settings: { } -field_type: created diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.image.name.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.image.name.yml deleted file mode 100644 index a7e36651..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.image.name.yml +++ /dev/null @@ -1,19 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.image -id: media.image.name -field_name: name -entity_type: media -bundle: image -label: Name -description: '' -required: true -translatable: true -default_value: - - - value: '' -default_value_callback: '' -settings: { } -field_type: string diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.image.path.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.image.path.yml deleted file mode 100644 index 37bd07d2..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.image.path.yml +++ /dev/null @@ -1,19 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.image - module: - - path -id: media.image.path -field_name: path -entity_type: media -bundle: image -label: 'URL alias' -description: '' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: { } -field_type: path diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.image.status.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.image.status.yml deleted file mode 100644 index e8be8e17..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.image.status.yml +++ /dev/null @@ -1,21 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.image -id: media.image.status -field_name: status -entity_type: media -bundle: image -label: Published -description: '' -required: false -translatable: false -default_value: - - - value: 1 -default_value_callback: '' -settings: - on_label: 'On' - off_label: 'Off' -field_type: boolean diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.image.thumbnail.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.image.thumbnail.yml deleted file mode 100644 index 47a4bedd..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.image.thumbnail.yml +++ /dev/null @@ -1,36 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.image - module: - - image -id: media.image.thumbnail -field_name: thumbnail -entity_type: media -bundle: image -label: Thumbnail -description: 'The thumbnail of the media item.' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: - file_extensions: 'png gif jpg jpeg' - alt_field: true - alt_field_required: true - title_field: false - title_field_required: false - max_resolution: '' - min_resolution: '' - default_image: - uuid: null - alt: '' - title: '' - width: null - height: null - file_directory: '[date:custom:Y]-[date:custom:m]' - max_filesize: '' - handler: default - handler_settings: { } -field_type: image diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.image.uid.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.image.uid.yml deleted file mode 100644 index 3f5374c1..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.image.uid.yml +++ /dev/null @@ -1,19 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.image -id: media.image.uid -field_name: uid -entity_type: media -bundle: image -label: 'Authored by' -description: 'The user ID of the author.' -required: false -translatable: false -default_value: { } -default_value_callback: 'Drupal\media\Entity\Media::getCurrentUserId' -settings: - handler: default - handler_settings: { } -field_type: entity_reference diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.video.changed.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.video.changed.yml deleted file mode 100644 index 1ae9065b..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.video.changed.yml +++ /dev/null @@ -1,17 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.video -id: media.video.changed -field_name: changed -entity_type: media -bundle: video -label: Changed -description: 'The time the media item was last edited.' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: { } -field_type: changed diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.video.created.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.video.created.yml deleted file mode 100644 index 775f468e..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.video.created.yml +++ /dev/null @@ -1,17 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.video -id: media.video.created -field_name: created -entity_type: media -bundle: video -label: 'Authored on' -description: 'The time the media item was created.' -required: false -translatable: false -default_value: { } -default_value_callback: 'Drupal\media\Entity\Media::getRequestTime' -settings: { } -field_type: created diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.video.name.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.video.name.yml deleted file mode 100644 index 4a43e072..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.video.name.yml +++ /dev/null @@ -1,19 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.video -id: media.video.name -field_name: name -entity_type: media -bundle: video -label: Name -description: '' -required: true -translatable: true -default_value: - - - value: '' -default_value_callback: '' -settings: { } -field_type: string diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.video.path.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.video.path.yml deleted file mode 100644 index 423d097b..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.video.path.yml +++ /dev/null @@ -1,19 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.video - module: - - path -id: media.video.path -field_name: path -entity_type: media -bundle: video -label: 'URL alias' -description: '' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: { } -field_type: path diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.video.status.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.video.status.yml deleted file mode 100644 index dc7b5bea..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.video.status.yml +++ /dev/null @@ -1,21 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.video -id: media.video.status -field_name: status -entity_type: media -bundle: video -label: Published -description: '' -required: false -translatable: false -default_value: - - - value: 1 -default_value_callback: '' -settings: - on_label: 'On' - off_label: 'Off' -field_type: boolean diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.video.thumbnail.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.video.thumbnail.yml deleted file mode 100644 index 8b4eb3b0..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.video.thumbnail.yml +++ /dev/null @@ -1,36 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.video - module: - - image -id: media.video.thumbnail -field_name: thumbnail -entity_type: media -bundle: video -label: Thumbnail -description: 'The thumbnail of the media item.' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: - file_extensions: 'png gif jpg jpeg' - alt_field: true - alt_field_required: true - title_field: false - title_field_required: false - max_resolution: '' - min_resolution: '' - default_image: - uuid: null - alt: '' - title: '' - width: null - height: null - file_directory: '[date:custom:Y]-[date:custom:m]' - max_filesize: '' - handler: default - handler_settings: { } -field_type: image diff --git a/modules/islandora_core_feature/config/install/core.base_field_override.media.video.uid.yml b/modules/islandora_core_feature/config/install/core.base_field_override.media.video.uid.yml deleted file mode 100644 index 4f7c78e9..00000000 --- a/modules/islandora_core_feature/config/install/core.base_field_override.media.video.uid.yml +++ /dev/null @@ -1,19 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.video -id: media.video.uid -field_name: uid -entity_type: media -bundle: video -label: 'Authored by' -description: 'The user ID of the author.' -required: false -translatable: false -default_value: { } -default_value_callback: 'Drupal\media\Entity\Media::getCurrentUserId' -settings: - handler: default - handler_settings: { } -field_type: entity_reference diff --git a/modules/islandora_core_feature/config/install/core.entity_view_display.media.audio.source.yml b/modules/islandora_core_feature/config/install/core.entity_view_display.media.audio.source.yml deleted file mode 100644 index b305bc80..00000000 --- a/modules/islandora_core_feature/config/install/core.entity_view_display.media.audio.source.yml +++ /dev/null @@ -1,42 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - core.entity_view_mode.media.source - - field.field.media.audio.field_file_size - - field.field.media.audio.field_media_audio_file - - field.field.media.audio.field_media_of - - field.field.media.audio.field_media_use - - field.field.media.audio.field_mime_type - - media.type.audio - enforced: - module: - - islandora_core_feature - module: - - file -id: media.audio.source -targetEntityType: media -bundle: audio -mode: source -content: - field_media_audio_file: - type: file_audio - weight: 0 - label: visually_hidden - settings: - controls: true - multiple_file_display_type: tags - autoplay: false - loop: false - third_party_settings: { } - region: content -hidden: - created: true - field_file_size: true - field_media_of: true - field_media_use: true - field_mime_type: true - langcode: true - name: true - thumbnail: true - uid: true diff --git a/modules/islandora_core_feature/config/install/core.entity_view_display.media.file.source.yml b/modules/islandora_core_feature/config/install/core.entity_view_display.media.file.source.yml deleted file mode 100644 index 986ea1fa..00000000 --- a/modules/islandora_core_feature/config/install/core.entity_view_display.media.file.source.yml +++ /dev/null @@ -1,40 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - core.entity_view_mode.media.source - - field.field.media.file.field_file_size - - field.field.media.file.field_media_file - - field.field.media.file.field_media_of - - field.field.media.file.field_media_use - - field.field.media.file.field_mime_type - - media.type.file - enforced: - module: - - islandora_core_feature - module: - - file -id: media.file.source -targetEntityType: media -bundle: file -mode: source -content: - field_media_file: - label: hidden - settings: - use_description_as_link_text: true - third_party_settings: { } - type: file_default - weight: 0 - region: content -hidden: - created: true - field_file_size: true - field_gemini_uri: true - field_media_of: true - field_media_use: true - field_mime_type: true - langcode: true - name: true - thumbnail: true - uid: true diff --git a/modules/islandora_core_feature/config/install/core.entity_view_display.media.image.source.yml b/modules/islandora_core_feature/config/install/core.entity_view_display.media.image.source.yml deleted file mode 100644 index 107ff4ff..00000000 --- a/modules/islandora_core_feature/config/install/core.entity_view_display.media.image.source.yml +++ /dev/null @@ -1,45 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - core.entity_view_mode.media.source - - field.field.media.image.field_file_size - - field.field.media.image.field_height - - field.field.media.image.field_media_image - - field.field.media.image.field_media_of - - field.field.media.image.field_media_use - - field.field.media.image.field_mime_type - - field.field.media.image.field_width - - media.type.image - enforced: - module: - - islandora_core_feature - module: - - islandora -id: media.image.source -targetEntityType: media -bundle: image -mode: source -content: - field_media_image: - label: visually_hidden - settings: - image_style: '' - image_link: content - third_party_settings: { } - type: islandora_image - weight: 0 - region: content -hidden: - created: true - field_file_size: true - field_gemini_uri: true - field_height: true - field_media_of: true - field_media_use: true - field_mime_type: true - field_width: true - langcode: true - name: true - thumbnail: true - uid: true diff --git a/modules/islandora_core_feature/config/install/core.entity_view_display.media.video.source.yml b/modules/islandora_core_feature/config/install/core.entity_view_display.media.video.source.yml deleted file mode 100644 index 3b81c2ef..00000000 --- a/modules/islandora_core_feature/config/install/core.entity_view_display.media.video.source.yml +++ /dev/null @@ -1,45 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - core.entity_view_mode.media.source - - field.field.media.video.field_file_size - - field.field.media.video.field_media_of - - field.field.media.video.field_media_use - - field.field.media.video.field_media_video_file - - field.field.media.video.field_mime_type - - media.type.video - enforced: - module: - - islandora_core_feature - module: - - file -id: media.video.source -targetEntityType: media -bundle: video -mode: source -content: - field_media_video_file: - type: file_video - weight: 0 - label: visually_hidden - settings: - muted: false - width: 640 - height: 480 - controls: true - autoplay: false - loop: false - multiple_file_display_type: tags - third_party_settings: { } - region: content -hidden: - created: true - field_file_size: true - field_media_of: true - field_media_use: true - field_mime_type: true - langcode: true - name: true - thumbnail: true - uid: true diff --git a/modules/islandora_core_feature/config/install/field.field.media.audio.field_file_size.yml b/modules/islandora_core_feature/config/install/field.field.media.audio.field_file_size.yml deleted file mode 100644 index 9f2daccb..00000000 --- a/modules/islandora_core_feature/config/install/field.field.media.audio.field_file_size.yml +++ /dev/null @@ -1,25 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - field.storage.media.field_file_size - - media.type.audio - enforced: - module: - - islandora_core_feature -id: media.audio.field_file_size -field_name: field_file_size -entity_type: media -bundle: audio -label: 'File size' -description: '' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: - min: null - max: null - prefix: '' - suffix: '' -field_type: integer diff --git a/modules/islandora_core_feature/config/install/field.field.media.audio.field_media_audio_file.yml b/modules/islandora_core_feature/config/install/field.field.media.audio.field_media_audio_file.yml deleted file mode 100644 index 5da282ea..00000000 --- a/modules/islandora_core_feature/config/install/field.field.media.audio.field_media_audio_file.yml +++ /dev/null @@ -1,29 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - field.storage.media.field_media_audio_file - - media.type.audio - enforced: - module: - - islandora_core_feature - module: - - file -id: media.audio.field_media_audio_file -field_name: field_media_audio_file -entity_type: media -bundle: audio -label: 'Audio file' -description: '' -required: true -translatable: false -default_value: { } -default_value_callback: '' -settings: - file_extensions: 'mp3 wav aac' - file_directory: '[date:custom:Y]-[date:custom:m]' - max_filesize: '' - description_field: false - handler: 'default:file' - handler_settings: { } -field_type: file diff --git a/modules/islandora_core_feature/config/install/field.field.media.audio.field_media_of.yml b/modules/islandora_core_feature/config/install/field.field.media.audio.field_media_of.yml deleted file mode 100644 index a5f7d0f8..00000000 --- a/modules/islandora_core_feature/config/install/field.field.media.audio.field_media_of.yml +++ /dev/null @@ -1,23 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - field.storage.media.field_media_of - - media.type.audio - enforced: - module: - - islandora_core_feature -id: media.audio.field_media_of -field_name: field_media_of -entity_type: media -bundle: audio -label: 'Media of' -description: '' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: - handler: 'default:node' - handler_settings: { } -field_type: entity_reference diff --git a/modules/islandora_core_feature/config/install/field.field.media.audio.field_media_use.yml b/modules/islandora_core_feature/config/install/field.field.media.audio.field_media_use.yml deleted file mode 100644 index 2f1bdda8..00000000 --- a/modules/islandora_core_feature/config/install/field.field.media.audio.field_media_use.yml +++ /dev/null @@ -1,28 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - field.storage.media.field_media_use - - media.type.audio - - taxonomy.vocabulary.islandora_media_use -id: media.audio.field_media_use -field_name: field_media_use -entity_type: media -bundle: audio -label: 'Media Use' -description: 'Defined by Portland Common Data Model: Use Extension https://pcdm.org/2015/05/12/use. ''Original File'' will trigger creation of derivatives.' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: - handler: 'default:taxonomy_term' - handler_settings: - target_bundles: - islandora_media_use: islandora_media_use - sort: - field: name - direction: asc - auto_create: false - auto_create_bundle: '' -field_type: entity_reference diff --git a/modules/islandora_core_feature/config/install/field.field.media.file.field_file_size.yml b/modules/islandora_core_feature/config/install/field.field.media.file.field_file_size.yml deleted file mode 100644 index a52a893f..00000000 --- a/modules/islandora_core_feature/config/install/field.field.media.file.field_file_size.yml +++ /dev/null @@ -1,25 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - field.storage.media.field_file_size - - media.type.file - enforced: - module: - - islandora_core_feature -id: media.file.field_file_size -field_name: field_file_size -entity_type: media -bundle: file -label: 'File size' -description: '' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: - min: null - max: null - prefix: '' - suffix: '' -field_type: integer diff --git a/modules/islandora_core_feature/config/install/field.field.media.file.field_media_of.yml b/modules/islandora_core_feature/config/install/field.field.media.file.field_media_of.yml deleted file mode 100644 index fdde1e82..00000000 --- a/modules/islandora_core_feature/config/install/field.field.media.file.field_media_of.yml +++ /dev/null @@ -1,23 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - field.storage.media.field_media_of - - media.type.file - enforced: - module: - - islandora_core_feature -id: media.file.field_media_of -field_name: field_media_of -entity_type: media -bundle: file -label: 'Media of' -description: '' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: - handler: 'default:node' - handler_settings: { } -field_type: entity_reference diff --git a/modules/islandora_core_feature/config/install/field.field.media.file.field_mime_type.yml b/modules/islandora_core_feature/config/install/field.field.media.file.field_mime_type.yml deleted file mode 100644 index a93d6b8a..00000000 --- a/modules/islandora_core_feature/config/install/field.field.media.file.field_mime_type.yml +++ /dev/null @@ -1,21 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - field.storage.media.field_mime_type - - media.type.file - enforced: - module: - - islandora_core_feature -id: media.file.field_mime_type -field_name: field_mime_type -entity_type: media -bundle: file -label: 'MIME type' -description: 'MIME type of the underlying file' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: { } -field_type: string diff --git a/modules/islandora_core_feature/config/install/field.field.media.image.field_file_size.yml b/modules/islandora_core_feature/config/install/field.field.media.image.field_file_size.yml deleted file mode 100644 index a8db6e5c..00000000 --- a/modules/islandora_core_feature/config/install/field.field.media.image.field_file_size.yml +++ /dev/null @@ -1,25 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - field.storage.media.field_file_size - - media.type.image - enforced: - module: - - islandora_core_feature -id: media.image.field_file_size -field_name: field_file_size -entity_type: media -bundle: image -label: 'File size' -description: '' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: - min: null - max: null - prefix: '' - suffix: '' -field_type: integer diff --git a/modules/islandora_core_feature/config/install/field.field.media.image.field_height.yml b/modules/islandora_core_feature/config/install/field.field.media.image.field_height.yml deleted file mode 100644 index 7ea6a093..00000000 --- a/modules/islandora_core_feature/config/install/field.field.media.image.field_height.yml +++ /dev/null @@ -1,25 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - field.storage.media.field_height - - media.type.image - enforced: - module: - - islandora_core_feature -id: media.image.field_height -field_name: field_height -entity_type: media -bundle: image -label: Height -description: '' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: - min: null - max: null - prefix: '' - suffix: '' -field_type: integer diff --git a/modules/islandora_core_feature/config/install/field.field.media.image.field_media_image.yml b/modules/islandora_core_feature/config/install/field.field.media.image.field_media_image.yml deleted file mode 100644 index 6d8d887b..00000000 --- a/modules/islandora_core_feature/config/install/field.field.media.image.field_media_image.yml +++ /dev/null @@ -1,41 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - field.storage.media.field_media_image - - media.type.image - enforced: - module: - - media - - islandora_core_feature - module: - - image -id: media.image.field_media_image -field_name: field_media_image -entity_type: media -bundle: image -label: Image -description: '' -required: true -translatable: false -default_value: { } -default_value_callback: '' -settings: - alt_field: true - alt_field_required: true - title_field: false - title_field_required: false - max_resolution: '' - min_resolution: '' - default_image: - uuid: null - alt: '' - title: '' - width: null - height: null - file_directory: '[date:custom:Y]-[date:custom:m]' - file_extensions: 'png gif jpg jpeg' - max_filesize: '' - handler: 'default:file' - handler_settings: { } -field_type: image diff --git a/modules/islandora_core_feature/config/install/field.field.media.image.field_media_of.yml b/modules/islandora_core_feature/config/install/field.field.media.image.field_media_of.yml deleted file mode 100644 index e716dcfe..00000000 --- a/modules/islandora_core_feature/config/install/field.field.media.image.field_media_of.yml +++ /dev/null @@ -1,23 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - field.storage.media.field_media_of - - media.type.image - enforced: - module: - - islandora_core_feature -id: media.image.field_media_of -field_name: field_media_of -entity_type: media -bundle: image -label: 'Media of' -description: '' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: - handler: 'default:node' - handler_settings: { } -field_type: entity_reference diff --git a/modules/islandora_core_feature/config/install/field.field.media.image.field_media_use.yml b/modules/islandora_core_feature/config/install/field.field.media.image.field_media_use.yml deleted file mode 100644 index f9f2d259..00000000 --- a/modules/islandora_core_feature/config/install/field.field.media.image.field_media_use.yml +++ /dev/null @@ -1,28 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - field.storage.media.field_media_use - - media.type.image - - taxonomy.vocabulary.islandora_media_use -id: media.image.field_media_use -field_name: field_media_use -entity_type: media -bundle: image -label: 'Media Use' -description: 'Defined by Portland Common Data Model: Use Extension https://pcdm.org/2015/05/12/use. ''Original File'' will trigger creation of derivatives.' -required: false -translatable: true -default_value: { } -default_value_callback: '' -settings: - handler: 'default:taxonomy_term' - handler_settings: - target_bundles: - islandora_media_use: islandora_media_use - sort: - field: name - direction: asc - auto_create: false - auto_create_bundle: '' -field_type: entity_reference diff --git a/modules/islandora_core_feature/config/install/field.field.media.image.field_mime_type.yml b/modules/islandora_core_feature/config/install/field.field.media.image.field_mime_type.yml deleted file mode 100644 index eb8845fb..00000000 --- a/modules/islandora_core_feature/config/install/field.field.media.image.field_mime_type.yml +++ /dev/null @@ -1,21 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - field.storage.media.field_mime_type - - media.type.image - enforced: - module: - - islandora_core_feature -id: media.image.field_mime_type -field_name: field_mime_type -entity_type: media -bundle: image -label: 'MIME type' -description: '' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: { } -field_type: string diff --git a/modules/islandora_core_feature/config/install/field.field.media.image.field_width.yml b/modules/islandora_core_feature/config/install/field.field.media.image.field_width.yml deleted file mode 100644 index 42aa19c1..00000000 --- a/modules/islandora_core_feature/config/install/field.field.media.image.field_width.yml +++ /dev/null @@ -1,25 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - field.storage.media.field_width - - media.type.image - enforced: - module: - - islandora_core_feature -id: media.image.field_width -field_name: field_width -entity_type: media -bundle: image -label: Width -description: '' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: - min: null - max: null - prefix: '' - suffix: '' -field_type: integer diff --git a/modules/islandora_core_feature/config/install/field.field.media.video.field_file_size.yml b/modules/islandora_core_feature/config/install/field.field.media.video.field_file_size.yml deleted file mode 100644 index 656f898f..00000000 --- a/modules/islandora_core_feature/config/install/field.field.media.video.field_file_size.yml +++ /dev/null @@ -1,25 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - field.storage.media.field_file_size - - media.type.video - enforced: - module: - - islandora_core_feature -id: media.video.field_file_size -field_name: field_file_size -entity_type: media -bundle: video -label: 'File size' -description: '' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: - min: null - max: null - prefix: '' - suffix: '' -field_type: integer diff --git a/modules/islandora_core_feature/config/install/field.field.media.video.field_media_use.yml b/modules/islandora_core_feature/config/install/field.field.media.video.field_media_use.yml deleted file mode 100644 index 1fea8534..00000000 --- a/modules/islandora_core_feature/config/install/field.field.media.video.field_media_use.yml +++ /dev/null @@ -1,28 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - field.storage.media.field_media_use - - media.type.video - - taxonomy.vocabulary.islandora_media_use -id: media.video.field_media_use -field_name: field_media_use -entity_type: media -bundle: video -label: 'Media Use' -description: 'Defined by Portland Common Data Model: Use Extension https://pcdm.org/2015/05/12/use. ''Original File'' will trigger creation of derivatives.' -required: false -translatable: true -default_value: { } -default_value_callback: '' -settings: - handler: 'default:taxonomy_term' - handler_settings: - target_bundles: - islandora_media_use: islandora_media_use - sort: - field: name - direction: asc - auto_create: false - auto_create_bundle: '' -field_type: entity_reference diff --git a/modules/islandora_core_feature/config/install/field.field.media.video.field_media_video_file.yml b/modules/islandora_core_feature/config/install/field.field.media.video.field_media_video_file.yml deleted file mode 100644 index 0b4364fd..00000000 --- a/modules/islandora_core_feature/config/install/field.field.media.video.field_media_video_file.yml +++ /dev/null @@ -1,29 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - field.storage.media.field_media_video_file - - media.type.video - enforced: - module: - - islandora_core_feature - module: - - file -id: media.video.field_media_video_file -field_name: field_media_video_file -entity_type: media -bundle: video -label: 'Video file' -description: '' -required: true -translatable: false -default_value: { } -default_value_callback: '' -settings: - file_extensions: mp4 - file_directory: '[date:custom:Y]-[date:custom:m]' - max_filesize: '' - description_field: false - handler: 'default:file' - handler_settings: { } -field_type: file diff --git a/modules/islandora_core_feature/config/install/field.field.media.video.field_mime_type.yml b/modules/islandora_core_feature/config/install/field.field.media.video.field_mime_type.yml deleted file mode 100644 index 7ecf0114..00000000 --- a/modules/islandora_core_feature/config/install/field.field.media.video.field_mime_type.yml +++ /dev/null @@ -1,21 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - field.storage.media.field_mime_type - - media.type.video - enforced: - module: - - islandora_core_feature -id: media.video.field_mime_type -field_name: field_mime_type -entity_type: media -bundle: video -label: 'MIME type' -description: '' -required: false -translatable: false -default_value: { } -default_value_callback: '' -settings: { } -field_type: string diff --git a/modules/islandora_core_feature/config/install/field.field.taxonomy_term.islandora_display.field_external_uri.yml b/modules/islandora_core_feature/config/install/field.field.taxonomy_term.islandora_display.field_external_uri.yml deleted file mode 100644 index 5c4d2661..00000000 --- a/modules/islandora_core_feature/config/install/field.field.taxonomy_term.islandora_display.field_external_uri.yml +++ /dev/null @@ -1,22 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - field.storage.taxonomy_term.field_external_uri - - taxonomy.vocabulary.islandora_display - module: - - link -id: taxonomy_term.islandora_display.field_external_uri -field_name: field_external_uri -entity_type: taxonomy_term -bundle: islandora_display -label: 'External URI' -description: '' -required: false -translatable: true -default_value: { } -default_value_callback: '' -settings: - title: 1 - link_type: 17 -field_type: link diff --git a/modules/islandora_core_feature/config/install/field.storage.node.field_display_hints.yml b/modules/islandora_core_feature/config/install/field.storage.node.field_weight.yml similarity index 62% rename from modules/islandora_core_feature/config/install/field.storage.node.field_display_hints.yml rename to modules/islandora_core_feature/config/install/field.storage.node.field_weight.yml index 08590174..97619cd2 100644 --- a/modules/islandora_core_feature/config/install/field.storage.node.field_display_hints.yml +++ b/modules/islandora_core_feature/config/install/field.storage.node.field_weight.yml @@ -3,13 +3,13 @@ status: true dependencies: module: - node - - taxonomy -id: node.field_display_hints -field_name: field_display_hints +id: node.field_weight +field_name: field_weight entity_type: node -type: entity_reference +type: integer settings: - target_type: taxonomy_term + unsigned: false + size: normal module: core locked: false cardinality: 1 diff --git a/modules/islandora_core_feature/config/install/language.content_settings.media.audio.yml b/modules/islandora_core_feature/config/install/language.content_settings.media.audio.yml deleted file mode 100644 index c55d16c9..00000000 --- a/modules/islandora_core_feature/config/install/language.content_settings.media.audio.yml +++ /dev/null @@ -1,17 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.audio - module: - - content_translation -third_party_settings: - content_translation: - enabled: true - bundle_settings: - untranslatable_fields_hide: '0' -id: media.audio -target_entity_type_id: media -target_bundle: audio -default_langcode: site_default -language_alterable: true diff --git a/modules/islandora_core_feature/config/install/language.content_settings.media.file.yml b/modules/islandora_core_feature/config/install/language.content_settings.media.file.yml deleted file mode 100644 index e52f830e..00000000 --- a/modules/islandora_core_feature/config/install/language.content_settings.media.file.yml +++ /dev/null @@ -1,17 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.file - module: - - content_translation -third_party_settings: - content_translation: - enabled: true - bundle_settings: - untranslatable_fields_hide: '0' -id: media.file -target_entity_type_id: media -target_bundle: file -default_langcode: site_default -language_alterable: true diff --git a/modules/islandora_core_feature/config/install/language.content_settings.media.image.yml b/modules/islandora_core_feature/config/install/language.content_settings.media.image.yml deleted file mode 100644 index 5c943aa4..00000000 --- a/modules/islandora_core_feature/config/install/language.content_settings.media.image.yml +++ /dev/null @@ -1,17 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.image - module: - - content_translation -third_party_settings: - content_translation: - enabled: true - bundle_settings: - untranslatable_fields_hide: '0' -id: media.image -target_entity_type_id: media -target_bundle: image -default_langcode: site_default -language_alterable: true diff --git a/modules/islandora_core_feature/config/install/language.content_settings.media.video.yml b/modules/islandora_core_feature/config/install/language.content_settings.media.video.yml deleted file mode 100644 index d92fc6b2..00000000 --- a/modules/islandora_core_feature/config/install/language.content_settings.media.video.yml +++ /dev/null @@ -1,17 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.video - module: - - content_translation -third_party_settings: - content_translation: - enabled: true - bundle_settings: - untranslatable_fields_hide: '0' -id: media.video -target_entity_type_id: media -target_bundle: video -default_langcode: site_default -language_alterable: true diff --git a/modules/islandora_core_feature/config/install/language.content_settings.taxonomy_term.islandora_media_use.yml b/modules/islandora_core_feature/config/install/language.content_settings.taxonomy_term.islandora_media_use.yml deleted file mode 100644 index 63ef8494..00000000 --- a/modules/islandora_core_feature/config/install/language.content_settings.taxonomy_term.islandora_media_use.yml +++ /dev/null @@ -1,15 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - taxonomy.vocabulary.islandora_media_use - module: - - content_translation -third_party_settings: - content_translation: - enabled: true -id: taxonomy_term.islandora_media_use -target_entity_type_id: taxonomy_term -target_bundle: islandora_media_use -default_langcode: site_default -language_alterable: false diff --git a/modules/islandora_core_feature/config/install/language.content_settings.taxonomy_term.islandora_models.yml b/modules/islandora_core_feature/config/install/language.content_settings.taxonomy_term.islandora_models.yml deleted file mode 100644 index 646fab08..00000000 --- a/modules/islandora_core_feature/config/install/language.content_settings.taxonomy_term.islandora_models.yml +++ /dev/null @@ -1,15 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - taxonomy.vocabulary.islandora_models - module: - - content_translation -third_party_settings: - content_translation: - enabled: true -id: taxonomy_term.islandora_models -target_entity_type_id: taxonomy_term -target_bundle: islandora_models -default_langcode: site_default -language_alterable: false diff --git a/modules/islandora_core_feature/config/install/media.type.audio.yml b/modules/islandora_core_feature/config/install/media.type.audio.yml deleted file mode 100644 index 5a4456e0..00000000 --- a/modules/islandora_core_feature/config/install/media.type.audio.yml +++ /dev/null @@ -1,18 +0,0 @@ -langcode: en -status: true -dependencies: - enforced: - module: - - islandora_core_feature -id: audio -label: Audio -description: 'A locally hosted audio file.' -source: audio_file -queue_thumbnail_downloads: false -new_revision: true -source_configuration: - source_field: field_media_audio_file -field_map: - name: name - mimetype: field_mime_type - filesize: field_file_size diff --git a/modules/islandora_core_feature/config/install/media.type.file.yml b/modules/islandora_core_feature/config/install/media.type.file.yml deleted file mode 100644 index a79d9518..00000000 --- a/modules/islandora_core_feature/config/install/media.type.file.yml +++ /dev/null @@ -1,18 +0,0 @@ -langcode: en -status: true -dependencies: - enforced: - module: - - islandora_core_feature -id: file -label: File -description: 'Use local files for reusable media.' -source: file -queue_thumbnail_downloads: false -new_revision: true -source_configuration: - source_field: field_media_file -field_map: - name: name - mimetype: field_mime_type - filesize: field_file_size diff --git a/modules/islandora_core_feature/config/install/media.type.image.yml b/modules/islandora_core_feature/config/install/media.type.image.yml deleted file mode 100644 index 4ecfbf64..00000000 --- a/modules/islandora_core_feature/config/install/media.type.image.yml +++ /dev/null @@ -1,20 +0,0 @@ -langcode: en -status: true -dependencies: - enforced: - module: - - islandora_core_feature -id: image -label: Image -description: 'Use local images for reusable media.' -source: image -queue_thumbnail_downloads: false -new_revision: true -source_configuration: - source_field: field_media_image -field_map: - name: name - mimetype: field_mime_type - filesize: field_file_size - width: field_width - height: field_height diff --git a/modules/islandora_core_feature/config/install/media.type.video.yml b/modules/islandora_core_feature/config/install/media.type.video.yml deleted file mode 100644 index c4a7c9a1..00000000 --- a/modules/islandora_core_feature/config/install/media.type.video.yml +++ /dev/null @@ -1,18 +0,0 @@ -langcode: en -status: true -dependencies: - enforced: - module: - - islandora_core_feature -id: video -label: Video -description: 'A locally hosted video file.' -source: video_file -queue_thumbnail_downloads: false -new_revision: true -source_configuration: - source_field: field_media_video_file -field_map: - name: name - mimetype: field_mime_type - filesize: field_file_size diff --git a/modules/islandora_core_feature/config/install/rdf.mapping.media.audio.yml b/modules/islandora_core_feature/config/install/rdf.mapping.media.audio.yml deleted file mode 100644 index 6fb8df40..00000000 --- a/modules/islandora_core_feature/config/install/rdf.mapping.media.audio.yml +++ /dev/null @@ -1,45 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.audio - enforced: - module: - - islandora_core_feature - module: - - media -id: media.audio -targetEntityType: media -bundle: audio -types: - - 'pcdm:File' -fieldMappings: - name: - properties: - - 'dc: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_tags: - properties: - - 'schema:additionalType' - mapping_type: rel diff --git a/modules/islandora_core_feature/config/install/rdf.mapping.media.file.yml b/modules/islandora_core_feature/config/install/rdf.mapping.media.file.yml deleted file mode 100644 index e298c2db..00000000 --- a/modules/islandora_core_feature/config/install/rdf.mapping.media.file.yml +++ /dev/null @@ -1,45 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.file - enforced: - module: - - islandora_core_feature - module: - - media -id: media.file -targetEntityType: media -bundle: file -types: - - 'pcdm:File' -fieldMappings: - name: - properties: - - 'dc: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_tags: - properties: - - 'schema:additionalType' - mapping_type: rel diff --git a/modules/islandora_core_feature/config/install/rdf.mapping.media.image.yml b/modules/islandora_core_feature/config/install/rdf.mapping.media.image.yml deleted file mode 100644 index 3cc7a2ee..00000000 --- a/modules/islandora_core_feature/config/install/rdf.mapping.media.image.yml +++ /dev/null @@ -1,51 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.image - enforced: - module: - - islandora_core_feature - module: - - media -id: media.image -targetEntityType: media -bundle: image -types: - - 'pcdm:File' -fieldMappings: - name: - properties: - - 'dc: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_tags: - properties: - - 'schema:additionalType' - mapping_type: rel - field_width: - properties: - - 'ebucore:width' - field_height: - properties: - - 'ebucore:height' diff --git a/modules/islandora_core_feature/config/install/rdf.mapping.media.video.yml b/modules/islandora_core_feature/config/install/rdf.mapping.media.video.yml deleted file mode 100644 index c70bc50d..00000000 --- a/modules/islandora_core_feature/config/install/rdf.mapping.media.video.yml +++ /dev/null @@ -1,45 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - media.type.video - enforced: - module: - - islandora_core_feature - module: - - media -id: media.video -targetEntityType: media -bundle: video -types: - - 'pcdm:File' -fieldMappings: - name: - properties: - - 'dc: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_tags: - properties: - - 'schema:additionalType' - mapping_type: rel diff --git a/modules/islandora_core_feature/config/install/rdf.mapping.taxonomy_term.islandora_display.yml b/modules/islandora_core_feature/config/install/rdf.mapping.taxonomy_term.islandora_display.yml deleted file mode 100644 index f746b1ea..00000000 --- a/modules/islandora_core_feature/config/install/rdf.mapping.taxonomy_term.islandora_display.yml +++ /dev/null @@ -1,30 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - taxonomy.vocabulary.islandora_display - enforced: - module: - - islandora_core_feature - module: - - taxonomy -id: taxonomy_term.islandora_display -targetEntityType: taxonomy_term -bundle: islandora_display -types: - - 'schema:Thing' -fieldMappings: - name: - properties: - - 'dc:title' - description: - properties: - - 'dc:description' - field_external_uri: - properties: - - 'owl:sameAs' - changed: - properties: - - 'schema:dateModified' - datatype_callback: - callable: 'Drupal\rdf\CommonDataConverter::dateIso8601Value' diff --git a/modules/islandora_core_feature/config/install/rdf.mapping.taxonomy_term.islandora_media_use.yml b/modules/islandora_core_feature/config/install/rdf.mapping.taxonomy_term.islandora_media_use.yml deleted file mode 100644 index 4e809514..00000000 --- a/modules/islandora_core_feature/config/install/rdf.mapping.taxonomy_term.islandora_media_use.yml +++ /dev/null @@ -1,30 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - taxonomy.vocabulary.islandora_media_use - enforced: - module: - - islandora_core_feature - module: - - taxonomy -id: taxonomy_term.islandora_media_use -targetEntityType: taxonomy_term -bundle: islandora_media_use -types: - - 'schema:Thing' -fieldMappings: - name: - properties: - - 'dc:title' - description: - properties: - - 'dc:description' - field_external_uri: - properties: - - 'owl:sameAs' - changed: - properties: - - 'schema:dateModified' - datatype_callback: - callable: 'Drupal\rdf\CommonDataConverter::dateIso8601Value' diff --git a/modules/islandora_core_feature/config/install/rdf.mapping.taxonomy_term.islandora_models.yml b/modules/islandora_core_feature/config/install/rdf.mapping.taxonomy_term.islandora_models.yml deleted file mode 100644 index b1a6bebb..00000000 --- a/modules/islandora_core_feature/config/install/rdf.mapping.taxonomy_term.islandora_models.yml +++ /dev/null @@ -1,30 +0,0 @@ -langcode: en -status: true -dependencies: - config: - - taxonomy.vocabulary.islandora_models - enforced: - module: - - islandora_core_feature - module: - - taxonomy -id: taxonomy_term.islandora_models -targetEntityType: taxonomy_term -bundle: islandora_models -types: - - 'schema:Thing' -fieldMappings: - name: - properties: - - 'dc:title' - description: - properties: - - 'dc:description' - field_external_uri: - properties: - - 'owl:sameAs' - changed: - properties: - - 'schema:dateModified' - datatype_callback: - callable: 'Drupal\rdf\CommonDataConverter::dateIso8601Value' diff --git a/modules/islandora_core_feature/config/install/taxonomy.vocabulary.islandora_display.yml b/modules/islandora_core_feature/config/install/taxonomy.vocabulary.islandora_display.yml deleted file mode 100644 index f121cbb3..00000000 --- a/modules/islandora_core_feature/config/install/taxonomy.vocabulary.islandora_display.yml +++ /dev/null @@ -1,8 +0,0 @@ -langcode: en -status: true -dependencies: { } -name: 'Islandora Display' -vid: islandora_display -description: 'Terms used to alter how a repository item is viewed. ie. basic image vs large image' -hierarchy: 0 -weight: 0 diff --git a/modules/islandora_core_feature/config/install/taxonomy.vocabulary.islandora_media_use.yml b/modules/islandora_core_feature/config/install/taxonomy.vocabulary.islandora_media_use.yml index fb922bcf..8b3ed5ee 100644 --- a/modules/islandora_core_feature/config/install/taxonomy.vocabulary.islandora_media_use.yml +++ b/modules/islandora_core_feature/config/install/taxonomy.vocabulary.islandora_media_use.yml @@ -4,5 +4,4 @@ dependencies: { } name: 'Islandora Media Use' vid: islandora_media_use description: 'Terms to define how a media object is to be used.' -hierarchy: 0 weight: 0 diff --git a/modules/islandora_core_feature/config/install/taxonomy.vocabulary.islandora_models.yml b/modules/islandora_core_feature/config/install/taxonomy.vocabulary.islandora_models.yml index b82e075c..274387ca 100644 --- a/modules/islandora_core_feature/config/install/taxonomy.vocabulary.islandora_models.yml +++ b/modules/islandora_core_feature/config/install/taxonomy.vocabulary.islandora_models.yml @@ -4,5 +4,4 @@ dependencies: { } name: 'Islandora Models' vid: islandora_models description: 'Types of repository objects' -hierarchy: 0 weight: 0 diff --git a/modules/islandora_core_feature/config/install/views.view.manage_members.yml b/modules/islandora_core_feature/config/install/views.view.manage_members.yml index 68208b04..a978f1d2 100644 --- a/modules/islandora_core_feature/config/install/views.view.manage_members.yml +++ b/modules/islandora_core_feature/config/install/views.view.manage_members.yml @@ -294,7 +294,7 @@ display: path: node/%node/members menu: type: tab - title: Members + title: Children description: '' expanded: false parent: '' diff --git a/modules/islandora_core_feature/config/install/views.view.reorder_children.yml b/modules/islandora_core_feature/config/install/views.view.reorder_children.yml new file mode 100644 index 00000000..c8318abc --- /dev/null +++ b/modules/islandora_core_feature/config/install/views.view.reorder_children.yml @@ -0,0 +1,271 @@ +langcode: en +status: true +dependencies: + enforced: + module: + - islandora_core_feature + module: + - islandora + - node + - user +id: reorder_children +label: 'Reorder children' +module: views +description: 'Manage members belonging to a piece of content' +tag: '' +base_table: node_field_data +base_field: nid +core: 8.x +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + display_options: + access: + type: perm + options: + perm: 'manage members' + cache: + type: tag + options: { } + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + replica: false + query_comment: '' + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: full + options: + items_per_page: 10 + offset: 0 + id: 0 + total_pages: null + tags: + previous: ‹‹ + next: ›› + first: '« First' + last: 'Last »' + expose: + items_per_page: true + items_per_page_label: 'Items per page' + items_per_page_options: '10, 25, 50, 100' + items_per_page_options_all: true + items_per_page_options_all_label: '- All -' + offset: false + offset_label: Offset + quantity: 9 + style: + type: table + row: + type: fields + fields: + title: + id: title + table: node_field_data + field: title + entity_type: node + entity_field: title + alter: + alter_text: false + make_link: false + absolute: false + trim: false + word_boundary: false + ellipsis: false + strip_tags: false + html: false + hide_empty: false + empty_zero: false + settings: + link_to_entity: true + plugin_id: field + relationship: none + group_type: group + admin_label: '' + label: Title + exclude: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_alter_empty: true + click_sort_column: value + type: string + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + field_weight: + id: field_weight + table: node__field_weight + field: field_weight + relationship: none + group_type: group + admin_label: '' + label: '' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: false + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + plugin_id: integer_weight_selector + filters: { } + sorts: + field_weight_value: + id: field_weight_value + table: node__field_weight + field: field_weight_value + relationship: none + group_type: group + admin_label: '' + order: ASC + exposed: false + expose: + label: '' + plugin_id: standard + title: 'Reorder children' + header: { } + footer: { } + empty: { } + relationships: { } + arguments: + field_member_of_target_id: + id: field_member_of_target_id + table: node__field_member_of + field: field_member_of_target_id + relationship: none + group_type: group + admin_label: '' + default_action: default + exception: + value: all + title_enable: false + title: All + title_enable: false + title: '' + default_argument_type: node + default_argument_options: { } + default_argument_skip_url: false + summary_options: + base_path: '' + count: true + items_per_page: 25 + override: false + summary: + sort_order: asc + number_of_records: 0 + format: default_summary + specify_validation: true + validate: + type: 'entity:node' + fail: 'not found' + validate_options: + operation: view + multiple: 0 + bundles: { } + access: false + break_phrase: false + not: false + plugin_id: numeric + display_extenders: { } + filter_groups: + operator: AND + groups: { } + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url + - url.query_args + - 'user.node_grants:view' + - user.permissions + tags: { } + page_1: + display_plugin: page + id: page_1 + display_title: Page + position: 1 + display_options: + display_extenders: { } + path: node/%node/members/reorder + menu: + type: none + title: 'Reorder Children' + description: '' + expanded: false + parent: '' + weight: 0 + context: '0' + menu_name: main + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url + - url.query_args + - 'user.node_grants:view' + - user.permissions + tags: { } diff --git a/modules/islandora_core_feature/islandora_core_feature.features.yml b/modules/islandora_core_feature/islandora_core_feature.features.yml index c3ff6620..5af003a7 100755 --- a/modules/islandora_core_feature/islandora_core_feature.features.yml +++ b/modules/islandora_core_feature/islandora_core_feature.features.yml @@ -1,14 +1,16 @@ bundle: islandora excluded: - - core.entity_view_display.node.article.default - - core.entity_view_display.node.article.rss - - core.entity_view_display.node.article.teaser - - core.entity_view_display.taxonomy_term.islandora_display.default - - core.entity_view_display.taxonomy_term.islandora_media_use.default - - core.entity_view_display.taxonomy_term.islandora_models.default - - field.field.node.article.field_tags - - core.entity_form_display.taxonomy_term.islandora_display.default - - core.entity_form_display.taxonomy_term.islandora_media_use.default - - core.entity_form_display.taxonomy_term.islandora_models.default - - taxonomy.vocabulary.islandora_access -required: true + - 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 diff --git a/modules/islandora_core_feature/islandora_core_feature.info.yml b/modules/islandora_core_feature/islandora_core_feature.info.yml index dd4c7ea4..eda5da43 100755 --- a/modules/islandora_core_feature/islandora_core_feature.info.yml +++ b/modules/islandora_core_feature/islandora_core_feature.info.yml @@ -4,7 +4,6 @@ type: module core: 8.x dependencies: - basic_auth - - comment - content_translation - eva - features @@ -20,13 +19,10 @@ dependencies: - media - migrate_plus - node - - path - - rdf - rest - serialization - system - taxonomy - - text - user - views package: Islandora diff --git a/modules/islandora_iiif/config/install/islandora_iiif.settings.yml b/modules/islandora_iiif/config/install/islandora_iiif.settings.yml new file mode 100644 index 00000000..760946fb --- /dev/null +++ b/modules/islandora_iiif/config/install/islandora_iiif.settings.yml @@ -0,0 +1 @@ +iiif_server: diff --git a/modules/islandora_iiif/config/schema/islandora_iiif.schema.yml b/modules/islandora_iiif/config/schema/islandora_iiif.schema.yml new file mode 100644 index 00000000..6ef42bc4 --- /dev/null +++ b/modules/islandora_iiif/config/schema/islandora_iiif.schema.yml @@ -0,0 +1,7 @@ +islandora_iiif.settings: + type: config_object + label: 'Islandora IIIF Settings' + mapping: + iiif_server: + type: string + label: 'IIIF Server Url' diff --git a/modules/islandora_iiif/islandora_iiif.info.yml b/modules/islandora_iiif/islandora_iiif.info.yml new file mode 100644 index 00000000..06c249e1 --- /dev/null +++ b/modules/islandora_iiif/islandora_iiif.info.yml @@ -0,0 +1,7 @@ +name: 'Islandora IIIF' +type: module +description: 'IIIF support for Islandora' +core: 8.x +package: Islandora +dependencies: + - islandora diff --git a/modules/islandora_iiif/islandora_iiif.links.menu.yml b/modules/islandora_iiif/islandora_iiif.links.menu.yml new file mode 100644 index 00000000..4d5b5060 --- /dev/null +++ b/modules/islandora_iiif/islandora_iiif.links.menu.yml @@ -0,0 +1,6 @@ +islandora_iiif.islandora_iiif_config_form: + title: 'IIIF Settings' + route_name: islandora_iiif.islandora_iiif_config_form + description: 'Configure Islandora IIIF settings' + parent: system.admin_config_islandora + weight: 99 diff --git a/modules/islandora_iiif/islandora_iiif.module b/modules/islandora_iiif/islandora_iiif.module new file mode 100644 index 00000000..e9e7526e --- /dev/null +++ b/modules/islandora_iiif/islandora_iiif.module @@ -0,0 +1,24 @@ +' . t('About') . ''; + $output .= '

' . t('IIIF support for Islandora') . '

'; + return $output; + + default: + } +} diff --git a/modules/islandora_iiif/islandora_iiif.routing.yml b/modules/islandora_iiif/islandora_iiif.routing.yml new file mode 100644 index 00000000..dd69c2e5 --- /dev/null +++ b/modules/islandora_iiif/islandora_iiif.routing.yml @@ -0,0 +1,9 @@ +islandora_iiif.islandora_iiif_config_form: + path: '/admin/config/islandora/iiif' + defaults: + _form: '\Drupal\islandora_iiif\Form\IslandoraIIIFConfigForm' + _title: 'IslandoraIIIFConfigForm' + requirements: + _permission: 'access administration pages' + options: + _admin_route: TRUE diff --git a/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php b/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php new file mode 100644 index 00000000..5bb73de4 --- /dev/null +++ b/modules/islandora_iiif/src/Form/IslandoraIIIFConfigForm.php @@ -0,0 +1,92 @@ +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'), + ]; + return parent::buildForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, FormStateInterface $form_state) { + if (!empty($form_state->getValue('iiif_server'))) { + $server = $form_state->getValue('iiif_server'); + if (!UrlHelper::isValid($server, UrlHelper::isExternal($server))) { + $form_state->setErrorByName('iiif_server', "IIIF Server address is not a valid URL"); + } + elseif (!$this->validateIiifUrl($server)) { + $form_state->setErrorByName('iiif_server', "IIIF Server does not seem to be accessible."); + } + } + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + parent::submitForm($form, $form_state); + + $this->config('islandora_iiif.settings') + ->set('iiif_server', $form_state->getValue('iiif_server')) + ->save(); + } + + /** + * Ensure the IIIF server is accessible. + * + * @param string $server_uri + * The absolute or relative URI to the server. + * + * @return bool + * True if server returns 200 on a HEAD request. + */ + private function validateIiifUrl($server_uri) { + $client = \Drupal::httpClient(); + try { + $result = $client->head($server_uri); + return ($result->getStatusCode() == 200); + } + catch (ClientException $e) { + return FALSE; + } + + } + +} diff --git a/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php new file mode 100644 index 00000000..0e33199b --- /dev/null +++ b/modules/islandora_iiif/src/Plugin/views/style/IIIFManifest.php @@ -0,0 +1,329 @@ +serializer = $serializer; + $this->request = $request; + $this->iiifConfig = $iiif_config; + $this->fileSystem = $file_system; + $this->httpClient = $http_client; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('serializer'), + $container->get('request_stack')->getCurrentRequest(), + $container->get('config.factory')->get('islandora_iiif.settings'), + $container->get('file_system'), + $container->get('http_client') + ); + } + + /** + * {@inheritdoc} + */ + public function render() { + $json = []; + $iiif_address = $this->iiifConfig->get('iiif_server'); + if (!is_null($iiif_address) && !empty($iiif_address)) { + // Get the current URL being requested. + $request_url = $this->request->getSchemeAndHttpHost() . $this->request->getRequestUri(); + // Strip off the last URI component to get the base ID of the URL. + // @todo assumming the view is a path like /node/1/manifest.json + $url_components = explode('/', $request_url); + array_pop($url_components); + $iiif_base_id = implode('/', $url_components); + // @see https://iiif.io/api/presentation/2.1/#manifest + $json += [ + '@type' => 'sc:Manifest', + '@id' => $request_url, + // If the View has a title, set the View title as the manifest label. + 'label' => $this->view->getTitle() ?: 'IIIF Manifest', + '@context' => 'http://iiif.io/api/presentation/2/context.json', + // @see https://iiif.io/api/presentation/2.1/#sequence + 'sequences' => [ + [ + '@context' => 'http://iiif.io/api/presentation/2/context.json', + '@id' => $iiif_base_id . '/sequence/normal', + '@type' => 'sc:Sequence', + ], + ], + ]; + // For each row in the View result. + foreach ($this->view->result as $row) { + // Add the IIIF URL to the image to print out as JSON. + $canvases = $this->getTileSourceFromRow($row, $iiif_address, $iiif_base_id); + foreach ($canvases as $tile_source) { + $json['sequences'][0]['canvases'][] = $tile_source; + } + } + } + unset($this->view->row_index); + + $content_type = 'json'; + + return $this->serializer->serialize($json, $content_type, ['views_style_plugin' => $this]); + } + + /** + * Render array from views result row. + * + * @param \Drupal\views\ResultRow $row + * Result row. + * @param string $iiif_address + * The URL to the IIIF server endpoint. + * @param string $iiif_base_id + * The URL for the request, minus the last part of the URL, + * which is likely "manifest". + * + * @return array + * List of IIIF URLs to display in the Openseadragon viewer. + */ + protected function getTileSourceFromRow(ResultRow $row, $iiif_address, $iiif_base_id) { + $canvases = []; + foreach ($this->options['iiif_tile_field'] as $iiif_tile_field) { + $viewsField = $this->view->field[$iiif_tile_field]; + $entity = $viewsField->getEntity($row); + + if (isset($entity->{$viewsField->definition['field_name']})) { + + /** @var \Drupal\Core\Field\FieldItemListInterface $images */ + $images = $entity->{$viewsField->definition['field_name']}; + foreach ($images as $image) { + // Create the IIIF URL for this file + // Visiting $iiif_url will resolve to the info.json for the image. + $file_url = $image->entity->url(); + $mime_type = $image->entity->getMimeType(); + $iiif_url = rtrim($iiif_address, '/') . '/' . urlencode($file_url); + + // Create the necessary ID's for the canvas and annotation. + $canvas_id = $iiif_base_id . '/canvas/' . $entity->id(); + $annotation_id = $iiif_base_id . '/annotation/' . $entity->id(); + + // Try to fetch the IIIF metadata for the image. + try { + $info_json = $this->httpClient->get($iiif_url)->getBody(); + $resource = json_decode($info_json, TRUE); + $width = $resource['width']; + $height = $resource['height']; + } + catch (ClientException $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]; + } + } + } + + $canvases[] = [ + // @see https://iiif.io/api/presentation/2.1/#canvas + '@id' => $canvas_id, + '@type' => 'sc:Canvas', + 'label' => $image->entity->label(), + 'height' => $height, + 'width' => $width, + // @see https://iiif.io/api/presentation/2.1/#image-resources + 'images' => [ + [ + '@id' => $annotation_id, + "@type" => "oa:Annotation", + 'motivation' => 'sc:painting', + 'resource' => [ + '@id' => $iiif_url . '/full/full/0/default.jpg', + "@type" => "dctypes:Image", + 'format' => $mime_type, + 'height' => $height, + 'width' => $width, + 'service' => [ + '@id' => $iiif_url, + '@context' => 'http://iiif.io/api/image/2/context.json', + 'profile' => 'http://iiif.io/api/image/2/profiles/level2.json', + ], + ], + 'on' => $canvas_id, + ], + ], + ]; + } + } + } + + return $canvases; + } + + /** + * {@inheritdoc} + */ + protected function defineOptions() { + $options = parent::defineOptions(); + + $options['iiif_tile_field'] = ['default' => '']; + + return $options; + } + + /** + * {@inheritdoc} + */ + public function buildOptionsForm(&$form, FormStateInterface $form_state) { + parent::buildOptionsForm($form, $form_state); + + $field_options = []; + + $fields = $this->displayHandler->getHandlers('field'); + $islandora_default_file_fields = [ + 'field_media_file', + 'field_media_image', + ]; + $file_views_field_formatters = [ + // Image formatters. + 'image', 'image_url', + // File formatters. + 'file_default', 'file_url_plain', + ]; + /** @var \Drupal\views\Plugin\views\field\FieldPluginBase[] $fields */ + foreach ($fields as $field_name => $field) { + // If this is a known Islandora file/image field + // OR it is another/custom field add it as an available option. + // @todo find better way to identify file fields + // Currently $field->options['type'] is storing the "formatter" of the + // file/image so there are a lot of possibilities. + // The default formatters are 'image' and 'file_default' + // so this approach should catch most... + if (in_array($field_name, $islandora_default_file_fields) || + (!empty($field->options['type']) && in_array($field->options['type'], $file_views_field_formatters))) { + $field_options[$field_name] = $field->adminLabel(); + } + } + + // If no fields to choose from, add an error message indicating such. + if (count($field_options) == 0) { + drupal_set_message($this->t('No image or file fields were found in the View. + You will need to add a field to this View'), 'error'); + } + + $form['iiif_tile_field'] = [ + '#title' => $this->t('Tile source field(s)'), + '#type' => 'checkboxes', + '#default_value' => $this->options['iiif_tile_field'], + '#description' => $this->t("The source of image for each entity."), + '#options' => $field_options, + // Only make the form element required if + // we have more than one option to choose from + // otherwise could lock up the form when setting up a View. + '#required' => count($field_options) > 0, + ]; + } + + /** + * Returns an array of format options. + * + * @return string[] + * An array of the allowed serializer formats. In this case just JSON. + */ + public function getFormats() { + return ['json' => 'json']; + } + +} diff --git a/modules/islandora_text_extraction/LICENSE b/modules/islandora_text_extraction/LICENSE new file mode 100644 index 00000000..ecbc0593 --- /dev/null +++ b/modules/islandora_text_extraction/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. + + + Copyright (C) + + 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. + + , 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. \ No newline at end of file diff --git a/modules/islandora_text_extraction/README.md b/modules/islandora_text_extraction/README.md new file mode 100644 index 00000000..84daf0db --- /dev/null +++ b/modules/islandora_text_extraction/README.md @@ -0,0 +1,44 @@ +# islandora_text_extraction +### Connects Islandora 8 to Hypercube microservice and extracts text from PDFs + +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. + +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. + +_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. + +## 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` + +test to see its been properly installed with `which pdftotext` + +Install php libraries with `composer require spatie/pdf-to-text` + +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`. + +## 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. + + + + diff --git a/modules/islandora_text_extraction/islandora_text_extraction.info.yml b/modules/islandora_text_extraction/islandora_text_extraction.info.yml new file mode 100644 index 00000000..a22048f2 --- /dev/null +++ b/modules/islandora_text_extraction/islandora_text_extraction.info.yml @@ -0,0 +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 +package: 'Islandora' +dependencies: + - islandora diff --git a/modules/islandora_text_extraction/islandora_text_extraction.install b/modules/islandora_text_extraction/islandora_text_extraction.install new file mode 100644 index 00000000..95c857f9 --- /dev/null +++ b/modules/islandora_text_extraction/islandora_text_extraction.install @@ -0,0 +1,23 @@ +getSettings(); + $extensions = $fieldSettings['file_extensions']; + if (!strpos($extensions, 'txt')) { + $fieldSettings['file_extensions'] .= ' txt'; + $field->set('settings', $fieldSettings); + $field->save(); + } +} diff --git a/modules/islandora_text_extraction/islandora_text_extraction.module b/modules/islandora_text_extraction/islandora_text_extraction.module new file mode 100644 index 00000000..2b2c1a5d --- /dev/null +++ b/modules/islandora_text_extraction/islandora_text_extraction.module @@ -0,0 +1,53 @@ +' . t('About') . ''; + $output .= '

' . t('Islandora 8 module to connect to Hypercube microservice') . '

'; + return $output; + + default: + } +} + +/** + * Implements hook_media_presave(). + */ +function islandora_text_extraction_media_presave(MediaInterface $media) { + if ($media->bundle() != 'extracted_text') { + return; + } + $text = $media->get('field_edited_text')->getValue(); + if (!$text) { + $file_id = $media->get('field_media_file')->getValue()[0]['target_id']; + $file = File::load($file_id); + $data = file_get_contents($file->getFileUri()); + $data = nl2br($data); + $media->set('field_edited_text', $data); + $media->field_edited_text->format = 'basic_html'; + } +} + +/** + * Implements hook_form_form_id_alter(). + */ +function islandora_text_extraction_form_block_form_alter(&$form, FormStateInterface $form_state, $form_id) { + unset($form['visibility']['ocr_requested']); + unset($form['visibility']['pdf_text_extraction_requested']); +} diff --git a/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php b/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php new file mode 100644 index 00000000..752d261b --- /dev/null +++ b/modules/islandora_text_extraction/src/Plugin/Action/GenerateOCRDerivative.php @@ -0,0 +1,58 @@ +getValue('mimetype')); + if ($exploded_mime[0] != 'text') { + $form_state->setErrorByName( + 'mimetype', + t('Please enter file mimetype (e.g. text/plain.)') + ); + } + } + +} diff --git a/modules/islandora_text_extraction/src/Plugin/Field/FieldFormatter/OcrTextFormatter.php b/modules/islandora_text_extraction/src/Plugin/Field/FieldFormatter/OcrTextFormatter.php new file mode 100644 index 00000000..d21363fc --- /dev/null +++ b/modules/islandora_text_extraction/src/Plugin/Field/FieldFormatter/OcrTextFormatter.php @@ -0,0 +1,82 @@ + $item) { + $elements[$delta] = ['#markup' => $this->viewValue($item)]; + } + + return $elements; + } + + /** + * Generate the output appropriate for one field item. + * + * @param \Drupal\Core\Field\FieldItemInterface $item + * One field item. + * + * @return string + * The textual output generated. + */ + protected function viewValue(FieldItemInterface $item) { + $fileItem = $item->getValue(); + $file = File::load($fileItem['target_id']); + $contents = file_get_contents($file->getFileUri()); + if (mb_detect_encoding($contents) != 'UTF-8') { + $contents = utf8_encode($contents); + } + $contents = nl2br($contents); + return $contents; + } + +} diff --git a/modules/islandora_text_extraction/tests/src/Functional/LoadTest.php b/modules/islandora_text_extraction/tests/src/Functional/LoadTest.php new file mode 100644 index 00000000..3cdeca91 --- /dev/null +++ b/modules/islandora_text_extraction/tests/src/Functional/LoadTest.php @@ -0,0 +1,46 @@ +user = $this->drupalCreateUser(['administer site configuration']); + $this->drupalLogin($this->user); + } + + /** + * Tests that the home page loads with a 200 response. + */ + public function testLoad() { + $this->drupalGet(Url::fromRoute('')); + $this->assertSession()->statusCodeEquals(200); + } + +} diff --git a/modules/islandora_text_extraction_defaults/config/install/core.entity_form_display.media.extracted_text.default.yml b/modules/islandora_text_extraction_defaults/config/install/core.entity_form_display.media.extracted_text.default.yml new file mode 100644 index 00000000..554646fd --- /dev/null +++ b/modules/islandora_text_extraction_defaults/config/install/core.entity_form_display.media.extracted_text.default.yml @@ -0,0 +1,81 @@ +langcode: en +status: true +dependencies: + config: + - field.field.media.extracted_text.field_edited_text + - field.field.media.extracted_text.field_media_file + - field.field.media.extracted_text.field_media_of + - field.field.media.extracted_text.field_media_use + - field.field.media.extracted_text.field_mime_type + - media.type.extracted_text + module: + - file + - path + - text +id: media.extracted_text.default +targetEntityType: media +bundle: extracted_text +mode: default +content: + created: + type: datetime_timestamp + weight: 3 + region: content + settings: { } + third_party_settings: { } + field_edited_text: + type: text_textarea + weight: 7 + region: content + settings: + rows: 5 + placeholder: '' + third_party_settings: { } + field_media_file: + type: file_generic + weight: 6 + region: content + settings: + progress_indicator: throbber + third_party_settings: { } + langcode: + type: language_select + weight: 1 + region: content + settings: + include_locked: true + third_party_settings: { } + name: + type: string_textfield + weight: 0 + region: content + settings: + size: 60 + placeholder: '' + third_party_settings: { } + path: + type: path + weight: 4 + region: content + settings: { } + third_party_settings: { } + status: + type: boolean_checkbox + settings: + display_label: true + weight: 5 + region: content + third_party_settings: { } + uid: + type: entity_reference_autocomplete + weight: 2 + settings: + match_operator: CONTAINS + size: 60 + placeholder: '' + region: content + third_party_settings: { } +hidden: + field_media_of: true + field_media_use: true + field_mime_type: true diff --git a/modules/islandora_text_extraction_defaults/config/install/core.entity_view_display.media.extracted_text.default.yml b/modules/islandora_text_extraction_defaults/config/install/core.entity_view_display.media.extracted_text.default.yml new file mode 100644 index 00000000..7d0be6f2 --- /dev/null +++ b/modules/islandora_text_extraction_defaults/config/install/core.entity_view_display.media.extracted_text.default.yml @@ -0,0 +1,65 @@ +langcode: en +status: true +dependencies: + config: + - field.field.media.extracted_text.field_edited_text + - field.field.media.extracted_text.field_media_file + - field.field.media.extracted_text.field_media_of + - field.field.media.extracted_text.field_media_use + - field.field.media.extracted_text.field_mime_type + - media.type.extracted_text + module: + - file + - text + - user +id: media.extracted_text.default +targetEntityType: media +bundle: extracted_text +mode: default +content: + created: + label: hidden + type: timestamp + weight: 1 + region: content + settings: + date_format: medium + custom_date_format: '' + timezone: '' + third_party_settings: { } + field_edited_text: + type: text_default + weight: 3 + region: content + label: above + settings: { } + third_party_settings: { } + field_media_file: + type: file_default + weight: 2 + region: content + label: above + settings: + use_description_as_link_text: true + third_party_settings: { } + field_media_of: + type: entity_reference_label + weight: 4 + region: content + label: above + settings: + link: true + third_party_settings: { } + uid: + label: hidden + type: author + weight: 0 + region: content + settings: { } + third_party_settings: { } +hidden: + field_media_use: true + field_mime_type: true + langcode: true + name: true + thumbnail: true diff --git a/modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_edited_text.yml b/modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_edited_text.yml new file mode 100644 index 00000000..dad71376 --- /dev/null +++ b/modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_edited_text.yml @@ -0,0 +1,20 @@ +langcode: en +status: true +dependencies: + config: + - field.storage.media.field_edited_text + - media.type.extracted_text + module: + - text +id: media.extracted_text.field_edited_text +field_name: field_edited_text +entity_type: media +bundle: extracted_text +label: 'Edited Text' +description: '' +required: false +translatable: true +default_value: { } +default_value_callback: '' +settings: { } +field_type: text_long diff --git a/modules/islandora_core_feature/config/install/field.field.media.file.field_media_file.yml b/modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_media_file.yml similarity index 59% rename from modules/islandora_core_feature/config/install/field.field.media.file.field_media_file.yml rename to modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_media_file.yml index 44342544..5e14d8af 100644 --- a/modules/islandora_core_feature/config/install/field.field.media.file.field_media_file.yml +++ b/modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_media_file.yml @@ -3,26 +3,22 @@ status: true dependencies: config: - field.storage.media.field_media_file - - media.type.file - enforced: - module: - - media - - islandora_core_feature + - media.type.extracted_text module: - file -id: media.file.field_media_file +id: media.extracted_text.field_media_file field_name: field_media_file entity_type: media -bundle: file +bundle: extracted_text label: File description: '' required: true -translatable: false +translatable: true default_value: { } default_value_callback: '' settings: + file_extensions: 'txt doc docx pdf' file_directory: '[date:custom:Y]-[date:custom:m]' - file_extensions: 'txt rtf doc docx ppt pptx xls xlsx pdf odf odg odp ods odt fodt fods fodp fodg key numbers pages tiff tif jp2' max_filesize: '' description_field: false handler: 'default:file' diff --git a/modules/islandora_core_feature/config/install/field.field.media.video.field_media_of.yml b/modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_media_of.yml similarity index 58% rename from modules/islandora_core_feature/config/install/field.field.media.video.field_media_of.yml rename to modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_media_of.yml index 2ab7bbbd..a1f8b40b 100644 --- a/modules/islandora_core_feature/config/install/field.field.media.video.field_media_of.yml +++ b/modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_media_of.yml @@ -3,21 +3,22 @@ status: true dependencies: config: - field.storage.media.field_media_of - - media.type.video - enforced: - module: - - islandora_core_feature -id: media.video.field_media_of + - media.type.extracted_text +id: media.extracted_text.field_media_of field_name: field_media_of entity_type: media -bundle: video +bundle: extracted_text label: 'Media of' description: '' required: false -translatable: false +translatable: true default_value: { } default_value_callback: '' settings: handler: 'default:node' - handler_settings: { } + handler_settings: + target_bundles: null + sort: + field: _none + auto_create: false field_type: entity_reference diff --git a/modules/islandora_core_feature/config/install/field.field.media.file.field_media_use.yml b/modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_media_use.yml similarity index 71% rename from modules/islandora_core_feature/config/install/field.field.media.file.field_media_use.yml rename to modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_media_use.yml index ae1b6c31..6a4a1464 100644 --- a/modules/islandora_core_feature/config/install/field.field.media.file.field_media_use.yml +++ b/modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_media_use.yml @@ -3,14 +3,14 @@ status: true dependencies: config: - field.storage.media.field_media_use - - media.type.file + - media.type.extracted_text - taxonomy.vocabulary.islandora_media_use -id: media.file.field_media_use +id: media.extracted_text.field_media_use field_name: field_media_use entity_type: media -bundle: file +bundle: extracted_text label: 'Media Use' -description: 'Defined by Portland Common Data Model: Use Extension https://pcdm.org/2015/05/12/use. ''Original File'' will trigger creation of derivatives.' +description: '' required: false translatable: true default_value: { } diff --git a/modules/islandora_core_feature/config/install/field.field.media.audio.field_mime_type.yml b/modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_mime_type.yml similarity index 60% rename from modules/islandora_core_feature/config/install/field.field.media.audio.field_mime_type.yml rename to modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_mime_type.yml index 466f3f42..5666fb2b 100644 --- a/modules/islandora_core_feature/config/install/field.field.media.audio.field_mime_type.yml +++ b/modules/islandora_text_extraction_defaults/config/install/field.field.media.extracted_text.field_mime_type.yml @@ -3,19 +3,18 @@ status: true dependencies: config: - field.storage.media.field_mime_type - - media.type.audio - enforced: - module: - - islandora_core_feature -id: media.audio.field_mime_type + - media.type.extracted_text +id: media.extracted_text.field_mime_type field_name: field_mime_type entity_type: media -bundle: audio +bundle: extracted_text label: 'MIME type' description: '' required: false -translatable: false -default_value: { } +translatable: true +default_value: + - + value: text/plain default_value_callback: '' settings: { } field_type: string diff --git a/modules/islandora_text_extraction_defaults/config/install/field.storage.media.field_edited_text.yml b/modules/islandora_text_extraction_defaults/config/install/field.storage.media.field_edited_text.yml new file mode 100644 index 00000000..d8025161 --- /dev/null +++ b/modules/islandora_text_extraction_defaults/config/install/field.storage.media.field_edited_text.yml @@ -0,0 +1,18 @@ +langcode: en +status: true +dependencies: + module: + - media + - text +id: media.field_edited_text +field_name: field_edited_text +entity_type: media +type: text_long +settings: { } +module: text +locked: false +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/modules/islandora_text_extraction_defaults/config/install/language.content_settings.media.extracted_text.yml b/modules/islandora_text_extraction_defaults/config/install/language.content_settings.media.extracted_text.yml new file mode 100644 index 00000000..a8d2512c --- /dev/null +++ b/modules/islandora_text_extraction_defaults/config/install/language.content_settings.media.extracted_text.yml @@ -0,0 +1,10 @@ +langcode: en +status: true +dependencies: + config: + - media.type.extracted_text +id: media.extracted_text +target_entity_type_id: media +target_bundle: extracted_text +default_langcode: site_default +language_alterable: false diff --git a/modules/islandora_text_extraction_defaults/config/install/media.type.extracted_text.yml b/modules/islandora_text_extraction_defaults/config/install/media.type.extracted_text.yml new file mode 100644 index 00000000..03c161fb --- /dev/null +++ b/modules/islandora_text_extraction_defaults/config/install/media.type.extracted_text.yml @@ -0,0 +1,12 @@ +langcode: en +status: true +dependencies: { } +id: extracted_text +label: 'Extracted Text' +description: 'Text extracted from Images or PDFs' +source: file +queue_thumbnail_downloads: false +new_revision: false +source_configuration: + source_field: field_media_file +field_map: { } diff --git a/modules/islandora_text_extraction_defaults/config/install/system.action.get_ocr_from_image.yml b/modules/islandora_text_extraction_defaults/config/install/system.action.get_ocr_from_image.yml new file mode 100644 index 00000000..0fc3a640 --- /dev/null +++ b/modules/islandora_text_extraction_defaults/config/install/system.action.get_ocr_from_image.yml @@ -0,0 +1,19 @@ +langcode: en +status: true +dependencies: + module: + - islandora_text_extraction +id: get_ocr_from_image +label: 'Extract Text from Image or PDF' +type: node +plugin: generate_ocr_derivative +configuration: + queue: islandora-connector-ocr + event: 'Generate Derivative' + source_term_uri: 'http://pcdm.org/use#OriginalFile' + derivative_term_uri: 'http://pcdm.org/use#ExtractedText' + mimetype: text/plain + args: null + destination_media_type: extracted_text + scheme: public + path: '[date:custom:Y]-[date:custom:m]/[node:nid]-[term:name].txt' diff --git a/modules/islandora_text_extraction_defaults/islandora_text_extraction_defaults.features.yml b/modules/islandora_text_extraction_defaults/islandora_text_extraction_defaults.features.yml new file mode 100644 index 00000000..9e48e9fd --- /dev/null +++ b/modules/islandora_text_extraction_defaults/islandora_text_extraction_defaults.features.yml @@ -0,0 +1,2 @@ +bundle: islandora +required: true diff --git a/modules/islandora_text_extraction_defaults/islandora_text_extraction_defaults.info.yml b/modules/islandora_text_extraction_defaults/islandora_text_extraction_defaults.info.yml new file mode 100644 index 00000000..5081bb27 --- /dev/null +++ b/modules/islandora_text_extraction_defaults/islandora_text_extraction_defaults.info.yml @@ -0,0 +1,16 @@ +name: 'Islandora Text Extraction Defaults' +type: module +description: 'Default config for the Islandora Text Extraction module.' +core: 8.x +package: Islandora +dependencies: + - field + - file + - islandora_core_feature + - islandora_text_extraction + - language + - media + - path + - system + - text + - user diff --git a/src/Controller/ManageMediaController.php b/src/Controller/ManageMediaController.php index 8ef77dff..776a6808 100644 --- a/src/Controller/ManageMediaController.php +++ b/src/Controller/ManageMediaController.php @@ -2,6 +2,9 @@ namespace Drupal\islandora\Controller; +use Drupal\Core\Access\AccessResult; +use Drupal\Core\Routing\RouteMatch; +use Drupal\node\Entity\Node; use Drupal\node\NodeInterface; /** @@ -14,6 +17,9 @@ class ManageMediaController extends ManageMembersController { * * @param \Drupal\node\NodeInterface $node * Node you want to add a media to. + * + * @return array + * Array of media types to add. */ public function addToNodePage(NodeInterface $node) { return $this->generateTypeList( @@ -26,4 +32,26 @@ class ManageMediaController extends ManageMembersController { ); } + /** + * Check if the object being displayed "is Islandora". + * + * @param \Drupal\Core\Routing\RouteMatch $route_match + * The current routing match. + * + * @return \Drupal\Core\Access\AccessResultAllowed|\Drupal\Core\Access\AccessResultForbidden + * Whether we can or can't show the "thing". + */ + public function access(RouteMatch $route_match) { + if ($route_match->getParameters()->has('node')) { + $node = $route_match->getParameter('node'); + if (!$node instanceof NodeInterface) { + $node = Node::load($node); + } + if ($node->hasField('field_model') && $node->hasField('field_member_of')) { + return AccessResult::allowed(); + } + } + return AccessResult::forbidden(); + } + } diff --git a/src/EventSubscriber/AdminViewsRouteSubscriber.php b/src/EventSubscriber/AdminViewsRouteSubscriber.php index 2d7eb95b..64367673 100644 --- a/src/EventSubscriber/AdminViewsRouteSubscriber.php +++ b/src/EventSubscriber/AdminViewsRouteSubscriber.php @@ -16,9 +16,17 @@ class AdminViewsRouteSubscriber extends RouteSubscriberBase { protected function alterRoutes(RouteCollection $collection) { if ($route = $collection->get('view.media_of.page_1')) { $route->setOption('_admin_route', 'TRUE'); + $route->setRequirement('_permission', 'manage media'); + $route->setRequirement('_custom_access', '\Drupal\islandora\Controller\ManageMediaController::access'); } if ($route = $collection->get('view.manage_members.page_1')) { $route->setOption('_admin_route', 'TRUE'); + $route->setRequirement('_permission', 'manage members'); + $route->setRequirement('_custom_access', '\Drupal\islandora\Controller\ManageMediaController::access'); + } + if ($route = $collection->get('view.reorder_children.page_1')) { + $route->setOption('_admin_route', 'TRUE'); + $route->setRequirement('_permission', 'manage members'); } } diff --git a/src/EventSubscriber/MediaLinkHeaderSubscriber.php b/src/EventSubscriber/MediaLinkHeaderSubscriber.php index 644db872..5df879f0 100644 --- a/src/EventSubscriber/MediaLinkHeaderSubscriber.php +++ b/src/EventSubscriber/MediaLinkHeaderSubscriber.php @@ -71,7 +71,8 @@ class MediaLinkHeaderSubscriber extends LinkHeaderSubscriber implements EventSub $source_field = $type_configuration['source_field']; if (empty($source_field) || - !$media->hasField($source_field) + !$media->hasField($source_field) || + !method_exists($media->get($source_field), 'referencedEntities') ) { return $links; } diff --git a/src/Plugin/Condition/NodeHasTerm.php b/src/Plugin/Condition/NodeHasTerm.php index 774f6d7e..dae52ad0 100644 --- a/src/Plugin/Condition/NodeHasTerm.php +++ b/src/Plugin/Condition/NodeHasTerm.php @@ -83,11 +83,12 @@ class NodeHasTerm extends ConditionPluginBase implements ContainerFactoryPluginI * {@inheritdoc} */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { + $default = []; if (isset($this->configuration['uri']) && !empty($this->configuration['uri'])) { - $default = $this->utils->getTermForUri($this->configuration['uri']); - } - else { - $default = NULL; + $uris = explode(',', $this->configuration['uri']); + foreach ($uris as $uri) { + $default[] = $this->utils->getTermForUri($uri); + } } $form['term'] = [ @@ -96,6 +97,7 @@ class NodeHasTerm extends ConditionPluginBase implements ContainerFactoryPluginI '#tags' => TRUE, '#default_value' => $default, '#target_type' => 'taxonomy_term', + '#required' => TRUE, ]; return parent::buildConfigurationForm($form, $form_state); @@ -108,12 +110,18 @@ class NodeHasTerm extends ConditionPluginBase implements ContainerFactoryPluginI // Set URI for term if possible. $this->configuration['uri'] = NULL; $value = $form_state->getValue('term'); + $uris = []; if (!empty($value)) { - $tid = $value[0]['target_id']; - $term = $this->entityTypeManager->getStorage('taxonomy_term')->load($tid); - $uri = $this->utils->getUriForTerm($term); - if ($uri) { - $this->configuration['uri'] = $uri; + foreach ($value as $target) { + $tid = $target['target_id']; + $term = $this->entityTypeManager->getStorage('taxonomy_term')->load($tid); + $uri = $this->utils->getUriForTerm($term); + if ($uri) { + $uris[] = $uri; + } + } + if (!empty($uris)) { + $this->configuration['uri'] = implode(',', $uris); } } parent::submitConfigurationForm($form, $form_state); @@ -144,18 +152,35 @@ class NodeHasTerm extends ConditionPluginBase implements ContainerFactoryPluginI * TRUE if entity has all the specified term(s), otherwise FALSE. */ protected function evaluateEntity(EntityInterface $entity) { - foreach ($entity->referencedEntities() as $referenced_entity) { - if ($referenced_entity->getEntityTypeId() == 'taxonomy_term' && $referenced_entity->hasField(IslandoraUtils::EXTERNAL_URI_FIELD)) { - $field = $referenced_entity->get(IslandoraUtils::EXTERNAL_URI_FIELD); - if (!$field->isEmpty()) { - $link = $field->first()->getValue(); - if ($link['uri'] == $this->configuration['uri']) { - return $this->isNegated() ? FALSE : TRUE; - } - } - } + // 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(); + }); + + // Get their URIs. + $haystack = array_map(function ($term) { + return $term->get(IslandoraUtils::EXTERNAL_URI_FIELD)->first()->getValue()['uri']; + }, + $terms + ); + + // FALSE if there's no URIs on the node. + if (empty($haystack)) { + return $this->isNegated() ? TRUE : FALSE; + } + + // Get the URIs to look for. It's a required field, so there + // will always be one. + $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; } + // Otherwise, FALSE. return $this->isNegated() ? TRUE : FALSE; } diff --git a/src/Plugin/views/field/IntegerWeightSelector.php b/src/Plugin/views/field/IntegerWeightSelector.php new file mode 100644 index 00000000..141d3567 --- /dev/null +++ b/src/Plugin/views/field/IntegerWeightSelector.php @@ -0,0 +1,114 @@ +options['id'] . '--' . $this->view->row_index . '-->'); + } + + /** + * {@inheritdoc} + */ + public function viewsForm(array &$form, FormStateInterface $form_state) { + // The view is empty, abort. + if (empty($this->view->result)) { + return; + } + + $form[$this->options['id']] = [ + '#tree' => TRUE, + ]; + + // Use the existing values of this result set to populate the options. + $options = []; + foreach ($this->view->result as $row_index => $row) { + $options[$this->getValue($row)] = $this->getValue($row); + } + + // If we were given some blank values we need to fill + // out the option list from 1 through the result count + // to make sure we have enough. (Blanks should only appear + // at the beginning of the results list.) + // Also, blank values will break the selector, remove it. + if (array_key_exists('', $options)) { + unset($options['']); + for ($i = 1; $i <= $this->view->total_rows; $i++) { + $options[$i] = $i; + } + ksort($options); + } + + // Now that we have all the available weight values, populate the forms. + foreach ($this->view->result as $row_index => $row) { + $entity = $row->_entity; + $field_langcode = $entity->getEntityTypeId() . '__' . $this->field . '_langcode'; + + $form[$this->options['id']][$row_index]['weight'] = [ + '#type' => 'select', + '#options' => $options, + '#default_value' => $this->getValue($row), + '#attributes' => ['class' => ['weight-selector']], + ]; + + $form[$this->options['id']][$row_index]['entity'] = [ + '#type' => 'value', + '#value' => $entity, + ]; + + $form[$this->options['id']][$row_index]['langcode'] = [ + '#type' => 'value', + '#value' => $row->{$field_langcode}, + ]; + } + + $form['views_field'] = [ + '#type' => 'value', + '#value' => $this->field, + ]; + + $form['#action'] = \Drupal::request()->getRequestUri(); + } + + /** + * {@inheritdoc} + */ + public function viewsFormSubmit(array &$form, FormStateInterface $form_state) { + $field_name = $form_state->getValue('views_field'); + $rows = $form_state->getValue($field_name); + + foreach ($rows as $row) { + if ($row['langcode']) { + $entity = $row['entity']->getTranslation($row['langcode']); + } + else { + $entity = $row['entity']; + } + if ($entity && $entity->hasField($field_name)) { + $entity->set($field_name, $row['weight']); + $entity->save(); + } + } + } + +} diff --git a/tests/modules/integer_weight_test_views/integer_weight_test_views.info.yml b/tests/modules/integer_weight_test_views/integer_weight_test_views.info.yml new file mode 100644 index 00000000..78c510fc --- /dev/null +++ b/tests/modules/integer_weight_test_views/integer_weight_test_views.info.yml @@ -0,0 +1,9 @@ +name: 'Integer weight test views' +type: module +description: 'Provides default views for integer weight views tests.' +package: Testing +core: 8.x +dependencies: + - drupal:node + - drupal:views + - drupal:language diff --git a/modules/islandora_core_feature/config/install/views.view.members.yml b/tests/modules/integer_weight_test_views/test_views/views.view.test_integer_weight.yml similarity index 65% rename from modules/islandora_core_feature/config/install/views.view.members.yml rename to tests/modules/integer_weight_test_views/test_views/views.view.test_integer_weight.yml index ae7a0d0a..c08b8400 100644 --- a/modules/islandora_core_feature/config/install/views.view.members.yml +++ b/tests/modules/integer_weight_test_views/test_views/views.view.test_integer_weight.yml @@ -2,17 +2,14 @@ langcode: en status: true dependencies: config: - - core.entity_view_mode.node.teaser - enforced: - module: - - islandora_core_feature + - node.type.repo_item module: - node - user -id: members -label: Members +id: test_integer_weight +label: 'test integer weight' module: views -description: 'Displays members for content.' +description: '' tag: '' base_table: node_field_data base_field: nid @@ -68,17 +65,9 @@ display: previous: ‹‹ next: ›› style: - type: default - options: - grouping: { } - row_class: '' - default_row_class: true - uses_fields: false + type: table row: - type: 'entity:node' - options: - relationship: none - view_mode: teaser + type: fields fields: title: id: title @@ -86,7 +75,6 @@ display: field: title entity_type: node entity_field: title - label: '' alter: alter_text: false make_link: false @@ -104,6 +92,7 @@ display: relationship: none group_type: group admin_label: '' + label: Title exclude: false element_type: '' element_class: '' @@ -127,45 +116,77 @@ display: multi_type: separator separator: ', ' field_api_classes: false - filters: - status: - id: status - table: node_field_data - field: status + field_integer_weight: + id: field_integer_weight + table: node__field_integer_weight + field: field_integer_weight relationship: none group_type: group admin_label: '' - operator: '=' + label: 'Integer weight selector (field_integer_weight)' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + range: '20' + plugin_id: integer_weight_selector + filters: + status: value: '1' - group: 1 - exposed: false + table: node_field_data + field: status + plugin_id: boolean + entity_type: node + entity_field: status + id: status expose: - operator_id: '' - label: '' - description: '' - use_operator: false operator: '' - identifier: '' - required: false - remember: false - multiple: false - remember_roles: - authenticated: authenticated - is_grouped: false - group_info: - label: '' - description: '' - identifier: '' - optional: true - widget: select - multiple: false - remember: false - default_group: All - default_group_multiple: { } - group_items: { } + group: 1 + type: + id: type + table: node_field_data + field: type + value: + repo_item:repo_item entity_type: node - entity_field: status - plugin_id: boolean + entity_field: type + plugin_id: bundle sorts: created: id: created @@ -182,74 +203,49 @@ display: expose: label: '' granularity: second + field_integer_weight_value: + id: field_integer_weight_value + table: node__field_integer_weight + field: field_integer_weight_value + relationship: none + group_type: group + admin_label: '' + order: ASC + exposed: false + expose: + label: '' + plugin_id: standard + title: 'test weight' header: { } footer: { } empty: { } relationships: { } - arguments: - field_member_of_target_id: - id: field_member_of_target_id - table: node__field_member_of - field: field_member_of_target_id - relationship: none - group_type: group - admin_label: '' - default_action: default - exception: - value: all - title_enable: false - title: All - title_enable: false - title: '' - default_argument_type: node - default_argument_options: { } - default_argument_skip_url: false - summary_options: - base_path: '' - count: true - items_per_page: 25 - override: false - summary: - sort_order: asc - number_of_records: 0 - format: default_summary - specify_validation: false - validate: - type: none - fail: 'not found' - validate_options: { } - break_phrase: false - not: false - plugin_id: numeric + arguments: { } display_extenders: { } - filter_groups: - operator: AND - groups: { } - title: Members cache_metadata: max-age: -1 contexts: - 'languages:language_content' - 'languages:language_interface' - - url - url.query_args - 'user.node_grants:view' - user.permissions tags: { } - block_1: - display_plugin: block - id: block_1 - display_title: Block - position: 2 + page_1: + display_plugin: page + id: page_1 + display_title: Page + position: 1 display_options: display_extenders: { } + path: test-integer-weight cache_metadata: max-age: -1 contexts: - 'languages:language_content' - 'languages:language_interface' - - url - url.query_args - 'user.node_grants:view' - user.permissions tags: { } + diff --git a/tests/src/Functional/NodeHasTermTest.php b/tests/src/Functional/NodeHasTermTest.php new file mode 100644 index 00000000..a27cf474 --- /dev/null +++ b/tests/src/Functional/NodeHasTermTest.php @@ -0,0 +1,90 @@ +createImageTag(); + $this->createPreservationMasterTag(); + } + + /** + * @covers \Drupal\islandora\Plugin\Condition\NodeHasTerm + */ + public function testNodeHasTerm() { + + // Create a new node with the tag. + $node = $this->container->get('entity_type.manager')->getStorage('node')->create([ + 'type' => 'test_type', + 'title' => 'Test Node', + 'field_tags' => [$this->imageTerm->id()], + ]); + + // Create and execute the condition. + $condition_manager = $this->container->get('plugin.manager.condition'); + $condition = $condition_manager->createInstance( + 'node_has_term', + [ + 'uri' => 'http://purl.org/coar/resource_type/c_c513', + ] + ); + $condition->setContextValue('node', $node); + $this->assertTrue($condition->execute(), "Condition should pass if node has the term"); + + // Create a new node without the tag. + $node = $this->container->get('entity_type.manager')->getStorage('node')->create([ + 'type' => 'test_type', + 'title' => 'Test Node', + ]); + + $condition->setContextValue('node', $node); + $this->assertFalse($condition->execute(), "Condition should fail if the node does not have any terms"); + + // Create a new node with the wrong tag. + $node = $this->container->get('entity_type.manager')->getStorage('node')->create([ + 'type' => 'test_type', + 'title' => 'Test Node', + 'field_tags' => [$this->preservationMasterTerm->id()], + ]); + + $condition->setContextValue('node', $node); + $this->assertFalse($condition->execute(), "Condition should fail if the node has terms, but not the one we want."); + + // 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', + ] + ); + $condition->setContextValue('node', $node); + $this->assertFalse($condition->execute(), "Condition should fail if node does not have both terms"); + + // Create a node with both tags. + $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"); + } + +} diff --git a/tests/src/FunctionalJavascript/IntegerWeightTest.php b/tests/src/FunctionalJavascript/IntegerWeightTest.php new file mode 100644 index 00000000..ba3892e6 --- /dev/null +++ b/tests/src/FunctionalJavascript/IntegerWeightTest.php @@ -0,0 +1,201 @@ +adminUser = $this->drupalCreateUser( + [ + 'administer content types', + 'administer node fields', + 'administer node display', + ] + ); + + // Create dummy repo_item type to sort (since we don't have + // repository_object without islandora_defaults). + $type = $this->container->get('entity_type.manager')->getStorage('node_type') + ->create([ + 'type' => 'repo_item', + 'name' => 'Repository Item', + ]); + $type->save(); + $this->container->get('router.builder')->rebuild(); + + $fieldStorage = FieldStorageConfig::create([ + 'fieldName' => static::$fieldName, + 'entity_type' => 'node', + 'type' => static::$fieldType, + ]); + $fieldStorage->save(); + $field = FieldConfig::create([ + 'field_storage' => $fieldStorage, + 'bundle' => 'repo_item', + 'required' => FALSE, + ]); + $field->save(); + + for ($n = 1; $n <= 3; $n++) { + $node = $this->drupalCreateNode([ + 'type' => 'repo_item', + 'title' => "Item $n", + static::$fieldName => $n, + ]); + $node->save(); + $this->nodes[] = $node; + } + + ViewsTestData::createTestViews(get_class($this), ['integer_weight_test_views']); + } + + /** + * Test integer weight selector. + */ + public function testIntegerWeightSelector() { + $this->drupalGet('test-integer-weight'); + $page = $this->getSession()->getPage(); + + $weight_select1 = $page->findField("field_integer_weight[0][weight]"); + $weight_select2 = $page->findField("field_integer_weight[1][weight]"); + $weight_select3 = $page->findField("field_integer_weight[2][weight]"); + + // Are row weight selects hidden? + $this->assertFalse($weight_select1->isVisible()); + $this->assertFalse($weight_select2->isVisible()); + $this->assertFalse($weight_select3->isVisible()); + + // Check that 'Item 2' is feavier than 'Item 1'. + $this->assertGreaterThan($weight_select1->getValue(), $weight_select2->getValue()); + + // Does 'Item 1' preced 'Item 2'? + $this->assertOrderInPage(['Item 1', 'Item 2']); + + // No changes yet, so no warning... + $this->assertSession()->pageTextNotContains('You have unsaved changes.'); + + // Drag and drop 'Item 1' over 'Item 2'. + $dragged = $this->xpath("//tr[@class='draggable'][1]//a[@class='tabledrag-handle']")[0]; + $target = $this->xpath("//tr[@class='draggable'][2]//a[@class='tabledrag-handle']")[0]; + $dragged->dragTo($target); + + // Pause for javascript to do it's thing. + $this->assertJsCondition('jQuery(".tabledrag-changed-warning").is(":visible")'); + + // Look for unsaved changes warning. + $this->assertSession()->pageTextContains('You have unsaved changes.'); + + // 'Item 2' should now preced 'Item 1'. + $this->assertOrderInPage(['Item 2', 'Item 1']); + + $this->submitForm([], 'Save'); + + // Form refresh should reflect the new order still. + $this->assertOrderInPage(['Item 2', 'Item 1']); + + // Ensure the stored values reflect the new order. + $item1 = Node::load($this->nodes[0]->id()); + $item2 = Node::load($this->nodes[1]->id()); + $this->assertGreaterThan($item2->field_integer_weight->getString(), $item1->field_integer_weight->getString()); + } + + /** + * Asserts that several pieces of markup are in a given order in the page. + * + * Taken verbatim from the weight module. + * + * @param string[] $items + * An ordered list of strings. + * + * @throws \Behat\Mink\Exception\ExpectationException + * When any of the given string is not found. + */ + protected function assertOrderInPage(array $items) { + $session = $this->getSession(); + $text = $session->getPage()->getHtml(); + $strings = []; + foreach ($items as $item) { + if (($pos = strpos($text, $item)) === FALSE) { + throw new ExpectationException("Cannot find '$item' in the page", $session->getDriver()); + } + $strings[$pos] = $item; + } + ksort($strings); + $ordered = implode(', ', array_map(function ($item) { + return "'$item'"; + }, $items)); + $this->assertSame($items, array_values($strings), "Found strings, ordered as: $ordered."); + } + +}