Browse Source

Manage Collections Page

pull/744/head
dannylamb 5 years ago
parent
commit
7338f9ff9e
  1. 26
      islandora.links.action.yml
  2. 45
      islandora.routing.yml
  3. 481
      modules/islandora_core_feature/config/install/views.view.collections.yml
  4. 1
      modules/islandora_core_feature/islandora_core_feature.features.yml
  5. 1
      modules/islandora_core_feature/islandora_core_feature.info.yml
  6. 47
      src/Controller/AddCollectionController.php
  7. 9
      src/Controller/ManageMediaController.php
  8. 26
      src/Controller/ManageMembersController.php
  9. 21
      src/Form/AddChildrenForm.php
  10. 55
      src/Form/AddMediaForm.php
  11. 33
      src/IslandoraUtils.php
  12. 60
      tests/src/Functional/AddChildTest.php
  13. 62
      tests/src/Functional/AddCollectionTest.php
  14. 46
      tests/src/Functional/AddMediaTest.php
  15. 2
      tests/src/Functional/GenerateDerivativeTestBase.php
  16. 4
      tests/src/Functional/IslandoraFunctionalTestBase.php
  17. 4
      tests/src/Functional/LinkHeaderTest.php
  18. 6
      tests/src/Functional/NodeHasTermTest.php

26
islandora.links.action.yml

@ -1,12 +1,24 @@
islandora.upload_media:
route_name: islandora.upload_media
title: Upload Media
appears_on:
- view.media_of.page_1
islandora.add_media_to_node: islandora.add_media_to_node:
route_name: islandora.add_media_form route_name: islandora.add_media_to_node_page
title: Add Media title: Add Media
appears_on: appears_on:
- view.media_of.page_1 - view.media_of.page_1
islandora.add_children_to_node: islandora.upload_children:
route_name: islandora.add_children_form route_name: islandora.upload_children
title: Add Children title: Upload Children
appears_on:
- view.manage_members.page_1
islandora.add_member_to_node:
route_name: islandora.add_member_to_node_page
title: Add Child
appears_on: appears_on:
- view.manage_members.page_1 - view.manage_members.page_1
@ -15,3 +27,9 @@ islandora.reorder_children:
title: Reorder Children title: Reorder Children
appears_on: appears_on:
- view.manage_members.page_1 - view.manage_members.page_1
islandora.add_collection:
route_name: islandora.add_collection
title: Add Collection
appears_on:
- view.collections.page_1

45
islandora.routing.yml

@ -16,24 +16,58 @@ system.islandora_settings:
requirements: requirements:
_permission: 'administer site configuration' _permission: 'administer site configuration'
islandora.add_children_form: islandora.add_member_to_node_page:
path: '/node/{node}/members/add' path: '/node/{node}/members/add'
defaults:
_controller: '\Drupal\islandora\Controller\ManageMembersController::addToNodePage'
_title_callback: '\Drupal\islandora\Controller\ManageMembersController::addTitle'
entity_type_id: node
options:
_admin_route: 'true'
requirements:
_entity_create_any_access: 'node'
islandora.upload_children:
path: '/node/{node}/members/upload'
defaults: defaults:
_form: '\Drupal\islandora\Form\AddChildrenForm' _form: '\Drupal\islandora\Form\AddChildrenForm'
_title: 'Add children' _title: 'Upload Children'
options: options:
_admin_route: 'TRUE' _admin_route: 'TRUE'
requirements: requirements:
_permssion: 'create node,create media' _access: 'TRUE'
#_permssion: 'create node,create media'
islandora.add_media_form: islandora.add_media_to_node_page:
path: '/node/{node}/media/add' path: '/node/{node}/media/add'
defaults:
_controller: '\Drupal\islandora\Controller\ManageMediaController::addToNodePage'
_title_callback: '\Drupal\islandora\Controller\ManageMediaController::addTitle'
entity_type_id: media
options:
_admin_route: 'true'
requirements:
_entity_create_any_access: 'media'
islandora.upload_media:
path: '/node/{node}/media/upload'
defaults:
_form: '\Drupal\islandora\Form\AddMediaForm' _form: '\Drupal\islandora\Form\AddMediaForm'
_title: 'Add media' _title: 'Add media'
options: options:
_admin_route: 'TRUE' _admin_route: 'TRUE'
requirements: requirements:
_permssion: 'create media' _custom_access: '\Drupal\islandora\Form\AddMediaForm::access'
islandora.add_collection:
path: '/collection/add'
defaults:
_controller: '\Drupal\islandora\Controller\AddCollectionController::addCollectionPage'
_title: 'Add Collection'
options:
_admin_route: 'true'
requirements:
_custom_access: '\Drupal\islandora\Controller\AddCollectionController::access'
islandora.media_source_update: islandora.media_source_update:
path: '/media/{media}/source' path: '/media/{media}/source'
@ -49,6 +83,7 @@ islandora.media_source_put_to_node:
path: '/node/{node}/media/{media_type}/{taxonomy_term}' path: '/node/{node}/media/{media_type}/{taxonomy_term}'
defaults: defaults:
_controller: '\Drupal\islandora\Controller\MediaSourceController::putToNode' _controller: '\Drupal\islandora\Controller\MediaSourceController::putToNode'
methods: [PUT] methods: [PUT]
requirements: requirements:
_custom_access: '\Drupal\islandora\Controller\MediaSourceController::putToNodeAccess' _custom_access: '\Drupal\islandora\Controller\MediaSourceController::putToNodeAccess'

481
modules/islandora_core_feature/config/install/views.view.collections.yml

@ -0,0 +1,481 @@
langcode: en
status: true
dependencies:
config:
- core.entity_view_mode.node.teaser
module:
- media
- node
- taxonomy
- user
id: collections
label: Collections
module: views
description: 'All collections in the repository'
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: 'access content'
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: mini
options:
items_per_page: 10
offset: 0
id: 0
total_pages: null
expose:
items_per_page: false
items_per_page_label: 'Items per page'
items_per_page_options: '5, 10, 25, 50'
items_per_page_options_all: false
items_per_page_options_all_label: '- All -'
offset: false
offset_label: Offset
tags:
previous: ‹‹
next: ››
style:
type: table
options:
grouping: { }
row_class: ''
default_row_class: true
override: true
sticky: false
caption: ''
summary: ''
description: ''
columns:
title: title
info:
title:
sortable: false
default_sort_order: asc
align: ''
separator: ''
empty_column: false
responsive: ''
default: '-1'
empty_table: false
row:
type: 'entity:node'
options:
view_mode: teaser
fields:
title:
id: title
table: node_field_data
field: title
relationship: none
group_type: group
admin_label: ''
label: Title
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: false
ellipsis: false
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
click_sort_column: value
type: string
settings:
link_to_entity: true
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
entity_type: node
entity_field: title
plugin_id: field
field_member_of:
id: field_member_of
table: node__field_member_of
field: field_member_of
relationship: reverse__node__field_member_of
group_type: count
admin_label: ''
label: Children
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
set_precision: false
precision: 0
decimal: .
separator: ', '
format_plural: 0
format_plural_string: !!binary MQNAY291bnQ=
prefix: ''
suffix: ''
click_sort_column: target_id
type: entity_reference_label
settings: { }
group_column: entity_id
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
field_api_classes: false
plugin_id: field
field_file_size:
id: field_file_size
table: media__field_file_size
field: field_file_size
relationship: reverse__media__field_media_of
group_type: sum
admin_label: ''
label: 'Disk Usage'
exclude: false
alter:
alter_text: true
text: "{% if field_file_size > (1024 ** 5) %}\r\n {% set size = field_file_size / (1024 ** 5) %}\r\n {% set abbreviation = 'PB' %}\r\n{% elseif field_file_size > (1024 ** 4) %}\r\n {% set size = field_file_size / (1024 ** 4) %}\r\n {% set abbreviation = 'TB' %}\r\n{% elseif field_file_size > (1024 ** 3) %}\r\n {% set size = field_file_size / (1024 ** 3) %}\r\n {% set abbreviation = 'GB' %}\r\n{% elseif field_file_size > (1024 ** 2) %}\r\n {% set size = field_file_size / (1024 ** 2) %}\r\n {% set abbreviation = 'MB' %}\r\n{% elseif field_file_size > 1024 %}\r\n {% set size = field_file_size / 1024 %}\r\n {% set abbreviation = 'KB' %}\r\n{% else %}\r\n {% set size = field_file_size %}\r\n {% set abbreviation = 'B' %}\r\n{% endif %}\r\n\r\n{{ size|round(2, 'common') }} {{ abbreviation }}"
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
set_precision: false
precision: 0
decimal: .
separator: ''
format_plural: 0
format_plural_string: !!binary MQNAY291bnQ=
prefix: ''
suffix: ''
click_sort_column: value
type: number_integer
settings: { }
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
field_api_classes: false
plugin_id: field
operations:
id: operations
table: node
field: operations
relationship: none
group_type: group
admin_label: ''
label: 'Operations links'
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
destination: true
entity_type: node
plugin_id: entity_operations
filters:
status:
value: '1'
table: node_field_data
field: status
plugin_id: boolean
entity_type: node
entity_field: status
id: status
expose:
operator: ''
group: 1
field_external_uri_uri:
id: field_external_uri_uri
table: taxonomy_term__field_external_uri
field: field_external_uri_uri
relationship: field_model
group_type: group
admin_label: ''
operator: '='
value: 'http://purl.org/dc/dcmitype/Collection'
group: 1
exposed: false
expose:
operator_id: ''
label: ''
description: ''
use_operator: false
operator: ''
identifier: ''
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
placeholder: ''
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
plugin_id: string
sorts: { }
title: Collections
header: { }
footer: { }
empty: { }
relationships:
field_model:
id: field_model
table: node__field_model
field: field_model
relationship: none
group_type: group
admin_label: 'field_model: Taxonomy term'
required: true
plugin_id: standard
reverse__node__field_member_of:
id: reverse__node__field_member_of
table: node_field_data
field: reverse__node__field_member_of
relationship: none
group_type: group
admin_label: field_member_of
required: false
entity_type: node
plugin_id: entity_reverse
reverse__media__field_media_of:
id: reverse__media__field_media_of
table: node_field_data
field: reverse__media__field_media_of
relationship: none
group_type: group
admin_label: field_media_of
required: false
entity_type: node
plugin_id: entity_reverse
arguments: { }
display_extenders: { }
filter_groups:
operator: AND
groups:
1: AND
group_by: true
cache_metadata:
max-age: -1
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- 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: admin/content/collections
menu:
type: tab
title: Collections
description: ''
expanded: false
parent: ''
weight: -100
context: '0'
menu_name: admin
tab_options:
type: normal
title: Collections
description: ''
weight: 0
cache_metadata:
max-age: -1
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url.query_args
- 'user.node_grants:view'
- user.permissions
tags: { }

1
modules/islandora_core_feature/islandora_core_feature.features.yml

@ -14,3 +14,4 @@ required:
- field.storage.node.field_model - field.storage.node.field_model
- field.storage.node.field_weight - field.storage.node.field_weight
- field.storage.taxonomy_term.field_external_uri - field.storage.taxonomy_term.field_external_uri
- views.view.collections

1
modules/islandora_core_feature/islandora_core_feature.info.yml

@ -12,6 +12,7 @@ dependencies:
- filehash - filehash
- image - image
- islandora - islandora
- islandora_defaults
- jsonld - jsonld
- jwt - jwt
- language - language

47
src/Controller/AddCollectionController.php

@ -0,0 +1,47 @@
<?php
namespace Drupal\islandora\Controller;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Routing\RouteMatch;
use Drupal\islandora\IslandoraUtils;
/**
* Page to select new type to add as member.
*/
class AddCollectionController extends ManageMembersController {
/**
* Renders a list of types to add as a collection.
*/
public function addCollectionPage() {
$term = $this->utils->getTermForUri('http://purl.org/dc/dcmitype/Collection');
$field = IslandoraUtils::MODEL_FIELD;
return $this->generateTypeList(
'node',
'node_type',
'node.add',
'node.type_add',
$field,
['query' => ["edit[$field][widget]" => $term->id()]]
);
}
/**
* 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 ($this->utils->canCreateIslandoraEntity('node', 'node_type')) {
return AccessResult::allowed();
}
return AccessResult::forbidden();
}
}

9
src/Controller/ManageMediaController.php

@ -2,6 +2,7 @@
namespace Drupal\islandora\Controller; namespace Drupal\islandora\Controller;
use Drupal\islandora\IslandoraUtils;
use Drupal\Core\Access\AccessResult; use Drupal\Core\Access\AccessResult;
use Drupal\Core\Routing\RouteMatch; use Drupal\Core\Routing\RouteMatch;
use Drupal\node\Entity\Node; use Drupal\node\Entity\Node;
@ -22,13 +23,15 @@ class ManageMediaController extends ManageMembersController {
* Array of media types to add. * Array of media types to add.
*/ */
public function addToNodePage(NodeInterface $node) { public function addToNodePage(NodeInterface $node) {
$field = IslandoraUtils::MEDIA_OF_FIELD;
return $this->generateTypeList( return $this->generateTypeList(
'media', 'media',
'media_type', 'media_type',
'entity.media.add_form', 'entity.media.add_form',
'entity.media_type.add_form', 'entity.media_type.add_form',
$node, $field,
'field_media_of' ['query' => ["edit[$field][widget][0][target_id]" => $node->id()]]
); );
} }
@ -47,7 +50,7 @@ class ManageMediaController extends ManageMembersController {
if (!$node instanceof NodeInterface) { if (!$node instanceof NodeInterface) {
$node = Node::load($node); $node = Node::load($node);
} }
if ($node->hasField('field_model') && $node->hasField('field_member_of')) { if ($this->utils->isIslandoraType($node->getEntityTypeId(), $node->bundle())) {
return AccessResult::allowed(); return AccessResult::allowed();
} }
} }

26
src/Controller/ManageMembersController.php

@ -7,6 +7,7 @@ use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Entity\Controller\EntityController; use Drupal\Core\Entity\Controller\EntityController;
use Drupal\Core\Entity\EntityFieldManager; use Drupal\Core\Entity\EntityFieldManager;
use Drupal\Core\Link; use Drupal\Core\Link;
use Drupal\islandora\IslandoraUtils;
use Drupal\node\NodeInterface; use Drupal\node\NodeInterface;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
@ -36,6 +37,13 @@ class ManageMembersController extends EntityController {
*/ */
protected $renderer; protected $renderer;
/**
* Islandora Utils.
*
* @var \Drupal\islandora\IslandoraUtils
*/
protected $utils;
/** /**
* Constructor. * Constructor.
* *
@ -45,15 +53,19 @@ class ManageMembersController extends EntityController {
* The entity field manager. * The entity field manager.
* @param \Drupal\Core\Render\RendererInterface $renderer * @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer. * The renderer.
* @param \Drupal\islandora\IslandoraUtils $utils
* Islandora utils.
*/ */
public function __construct( public function __construct(
EntityTypeManagerInterface $entity_type_manager, EntityTypeManagerInterface $entity_type_manager,
EntityFieldManager $entity_field_manager, EntityFieldManager $entity_field_manager,
RendererInterface $renderer RendererInterface $renderer,
IslandoraUtils $utils
) { ) {
$this->entityTypeManager = $entity_type_manager; $this->entityTypeManager = $entity_type_manager;
$this->entityFieldManager = $entity_field_manager; $this->entityFieldManager = $entity_field_manager;
$this->renderer = $renderer; $this->renderer = $renderer;
$this->utils = $utils;
} }
/** /**
@ -63,7 +75,8 @@ class ManageMembersController extends EntityController {
return new static( return new static(
$container->get('entity_type.manager'), $container->get('entity_type.manager'),
$container->get('entity_field.manager'), $container->get('entity_field.manager'),
$container->get('renderer') $container->get('renderer'),
$container->get('islandora.utils')
); );
} }
@ -74,20 +87,21 @@ class ManageMembersController extends EntityController {
* Node you want to add a member to. * Node you want to add a member to.
*/ */
public function addToNodePage(NodeInterface $node) { public function addToNodePage(NodeInterface $node) {
$field = IslandoraUtils::MEMBER_OF_FIELD;
return $this->generateTypeList( return $this->generateTypeList(
'node', 'node',
'node_type', 'node_type',
'node.add', 'node.add',
'node.type_add', 'node.type_add',
$node, $field,
'field_member_of' ['query' => ["edit[$field][widget][0][target_id]" => $node->id()]]
); );
} }
/** /**
* Renders a list of content types to add as members. * Renders a list of content types to add as members.
*/ */
protected function generateTypeList($entity_type, $bundle_type, $entity_add_form, $bundle_add_form, NodeInterface $node, $field) { protected function generateTypeList($entity_type, $bundle_type, $entity_add_form, $bundle_add_form, $field, array $url_options) {
$type_definition = $this->entityTypeManager->getDefinition($bundle_type); $type_definition = $this->entityTypeManager->getDefinition($bundle_type);
$build = [ $build = [
@ -115,7 +129,7 @@ class ManageMembersController extends EntityController {
$bundle->label(), $bundle->label(),
$entity_add_form, $entity_add_form,
[$bundle_type => $bundle->id()], [$bundle_type => $bundle->id()],
['query' => ["edit[$field][widget][0][target_id]" => $node->id()]] $url_options
), ),
]; ];
} }

21
src/Form/AddChildrenForm.php

@ -4,6 +4,7 @@ namespace Drupal\islandora\Form;
use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url; use Drupal\Core\Url;
use Drupal\Core\Routing\RouteMatch;
use Drupal\islandora\IslandoraUtils; use Drupal\islandora\IslandoraUtils;
use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\Exception\HttpException;
@ -176,4 +177,24 @@ class AddChildrenForm extends AddMediaForm {
); );
} }
/**
* Check if the user can create any "Islandora" nodes and media.
*
* @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) {
$can_create_media = $this->utils->canCreateIslandoraEntity('media', 'media_type');
$can_create_node = $this->utils->canCreateIslandoraEntity('node', 'node_type');
if ($can_create_media && $can_create_node) {
return AccessResult::allowed();
}
return AccessResult::forbidden();
}
} }

55
src/Form/AddMediaForm.php

@ -2,11 +2,13 @@
namespace Drupal\islandora\Form; namespace Drupal\islandora\Form;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Config\ImmutableConfig; use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\Database\Connection; use Drupal\Core\Database\Connection;
use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Session\AccountInterface; use Drupal\Core\Session\AccountInterface;
use Drupal\islandora\IslandoraUtils; use Drupal\islandora\IslandoraUtils;
use Drupal\islandora\MediaSource\MediaSourceService; use Drupal\islandora\MediaSource\MediaSourceService;
@ -14,6 +16,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\Exception\HttpException;
use Drupal\Core\Utility\Token; use Drupal\Core\Utility\Token;
use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Routing\RouteMatch;
/** /**
* Form that lets users upload one or more files as children to a resource node. * Form that lets users upload one or more files as children to a resource node.
@ -27,6 +30,13 @@ class AddMediaForm extends FormBase {
*/ */
protected $entityTypeManager; protected $entityTypeManager;
/**
* Entity field manager.
*
* @var \Drupal\Core\Entity\EntityFieldManagerInterface
*/
protected $entityFieldManager;
/** /**
* Media source service. * Media source service.
* *
@ -88,6 +98,7 @@ class AddMediaForm extends FormBase {
*/ */
public function __construct( public function __construct(
EntityTypeManagerInterface $entity_type_manager, EntityTypeManagerInterface $entity_type_manager,
EntityFieldManagerInterface $entity_field_manager,
IslandoraUtils $utils, IslandoraUtils $utils,
MediaSourceService $media_source, MediaSourceService $media_source,
ImmutableConfig $config, ImmutableConfig $config,
@ -97,6 +108,7 @@ class AddMediaForm extends FormBase {
Connection $database Connection $database
) { ) {
$this->entityTypeManager = $entity_type_manager; $this->entityTypeManager = $entity_type_manager;
$this->entityFieldManager = $entity_field_manager;
$this->utils = $utils; $this->utils = $utils;
$this->mediaSource = $media_source; $this->mediaSource = $media_source;
$this->config = $config; $this->config = $config;
@ -112,6 +124,7 @@ class AddMediaForm extends FormBase {
public static function create(ContainerInterface $container) { public static function create(ContainerInterface $container) {
return new static( return new static(
$container->get('entity_type.manager'), $container->get('entity_type.manager'),
$container->get('entity_field.manager'),
$container->get('islandora.utils'), $container->get('islandora.utils'),
$container->get('islandora.media_source_service'), $container->get('islandora.media_source_service'),
$container->get('config.factory')->get('islandora.settings'), $container->get('config.factory')->get('islandora.settings'),
@ -243,4 +256,46 @@ class AddMediaForm extends FormBase {
} }
} }
/**
* Check if the user can create any "Islandora" media.
*
* @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 ($this->utils->canCreateIslandoraEntity('media', 'media_type')) {
return AccessResult::allowed();
}
return AccessResult::forbidden();
}
/**
* Utility function to check if user can create 'Islandora' entity types.
*/
protected function canCreateIslandoraEntity($entity_type, $bundle_type) {
$bundles = $this->entityTypeManager->getStorage($bundle_type)->loadMultiple();
$access_control_handler = $this->entityTypeManager->getAccessControlHandler($entity_type);
$allowed = [];
foreach (array_keys($bundles) as $bundle) {
// Skip bundles that aren't 'Islandora' types.
if (!$this->utils->isIslandoraType($entity_type, $bundle)) {
continue;
}
$access = $access_control_handler->createAccess($bundle, NULL, [], TRUE);
if (!$access->isAllowed()) {
continue;
}
return TRUE;
}
return FALSE;
}
} }

33
src/IslandoraUtils.php

@ -597,4 +597,37 @@ class IslandoraUtils {
} }
} }
/**
* Util function for access handlers .
*
* @param string $entity_type
* Entity type such as 'node', 'media', 'taxonomy_term', etc..
* @param string $bundle_type
* Bundle type such as 'node_type', 'media_type', 'vocabulary', etc...
*
* @return bool
* If user can create _at least one_ of the 'Islandora' types requested.
*/
public function canCreateIslandoraEntity($entity_type, $bundle_type) {
$bundles = $this->entityTypeManager->getStorage($bundle_type)->loadMultiple();
$access_control_handler = $this->entityTypeManager->getAccessControlHandler($entity_type);
$allowed = [];
foreach (array_keys($bundles) as $bundle) {
// Skip bundles that aren't 'Islandora' types.
if (!$this->isIslandoraType($entity_type, $bundle)) {
continue;
}
$access = $access_control_handler->createAccess($bundle, NULL, [], TRUE);
if (!$access->isAllowed()) {
continue;
}
return TRUE;
}
return FALSE;
}
} }

60
tests/src/Functional/AddChildTest.php

@ -0,0 +1,60 @@
<?php
namespace Drupal\Tests\islandora\Functional;
/**
* Tests the ManageMembersController.
*
* @group islandora
*/
class AddChildTest extends IslandoraFunctionalTestBase {
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp();
$this->parent =
$this->collectionTerm = $this->container->get('entity_type.manager')->getStorage('taxonomy_term')->create([
'name' => 'Collection',
'vid' => $this->testVocabulary->id(),
'field_external_uri' => [['uri' => "http://purl.org/dc/dcmitype/Collection"]],
]);
$this->collectionTerm->save();
}
/**
* @covers \Drupal\islandora\Controller\AddCollectionController::addToNodePage
* @covers \Drupal\islandora\Controller\AddCollectionController::access
* @covers \Drupal\islandora\IslandoraUtils::isIslandoraType
*/
public function testAddChild() {
$account = $this->drupalCreateUser([
'bypass node access',
]);
$this->drupalLogin($account);
$parent = $this->container->get('entity_type.manager')->getStorage('node')->create([
'type' => 'test_type',
'title' => 'Parent',
]);
$parent->save();
// Visit the add member page.
$this->drupalGet("/node/{$parent->id()}/members/add");
// Assert that test_type is on the list.
$this->assertSession()->pageTextContains($this->testType->label());
$this->clickLink($this->testType->label());
$url = $this->getUrl();
// Assert that the link creates the correct prepopulate query param.
$substring = 'node/add/test_type?edit%5Bfield_member_of%5D%5Bwidget%5D%5B0%5D%5Btarget_id%5D=1';
$this->assertTrue(
strpos($url, $substring) !== FALSE,
"Malformed URL, could not find $substring in $url."
);
}
}

62
tests/src/Functional/AddCollectionTest.php

@ -0,0 +1,62 @@
<?php
namespace Drupal\Tests\islandora\Functional;
/**
* Tests the AddCollectionController.
*
* @group islandora
*/
class AddCollectionTest extends IslandoraFunctionalTestBase {
/**
* Term to belong to the media.
*
* @var \Drupal\taxonomy\TermInterface
*/
protected $collectionTerm;
/**
* {@inheritdoc}
*/
public function setUp() {
parent::setUp();
$this->collectionTerm = $this->container->get('entity_type.manager')->getStorage('taxonomy_term')->create([
'name' => 'Collection',
'vid' => $this->testVocabulary->id(),
'field_external_uri' => [['uri' => "http://purl.org/dc/dcmitype/Collection"]],
]);
$this->collectionTerm->save();
}
/**
* @covers \Drupal\islandora\Controller\AddCollectionController::addCollectionPage
* @covers \Drupal\islandora\Controller\AddCollectionController::access
* @covers \Drupal\islandora\IslandoraUtils::isIslandoraType
*/
public function testAddCollection() {
$account = $this->drupalCreateUser([
'bypass node access',
]);
$this->drupalLogin($account);
// Visit the add collection page.
$this->drupalGet('/collection/add');
// Assert the test type is in the list of available types.
$this->assertSession()->pageTextContains($this->testType->label());
// Click the test type and make sure you get sent to the right form.
$this->clickLink($this->testType->label());
$url = $this->getUrl();
// Assert that the link creates the correct prepopulate query param.
$substring = 'node/add/test_type?edit%5Bfield_model%5D%5Bwidget%5D=1';
$this->assertTrue(
strpos($url, 'node/add/test_type?edit%5Bfield_model%5D%5Bwidget%5D=1') !== FALSE,
"Malformed URL, could not find $substring in $url."
);
}
}

46
tests/src/Functional/AddMediaTest.php

@ -0,0 +1,46 @@
<?php
namespace Drupal\Tests\islandora\Functional;
/**
* Tests the ManageMembersController.
*
* @group islandora
*/
class AddMediaTest extends IslandoraFunctionalTestBase {
/**
* @covers \Drupal\islandora\Controller\AddCollectionController::addToNodePage
* @covers \Drupal\islandora\Controller\AddCollectionController::access
* @covers \Drupal\islandora\IslandoraUtils::isIslandoraType
*/
public function testAddMedia() {
$account = $this->drupalCreateUser([
'bypass node access',
'create media',
]);
$this->drupalLogin($account);
$parent = $this->container->get('entity_type.manager')->getStorage('node')->create([
'type' => 'test_type',
'title' => 'Parent',
]);
$parent->save();
// Visit the add media page.
$this->drupalGet("/node/{$parent->id()}/media/add");
// Assert that test_meida_type is on the list.
$this->assertSession()->pageTextContains($this->testMediaType->label());
$this->clickLink($this->testMediaType->label());
$url = $this->getUrl();
// Assert that the link creates the correct prepopulate query param.
$substring = 'media/add/test_media_type?edit%5Bfield_media_of%5D%5Bwidget%5D%5B0%5D%5Btarget_id%5D=1';
$this->assertTrue(
strpos($url, $substring) !== FALSE,
"Malformed URL, could not find $substring in $url."
);
}
}

2
tests/src/Functional/GenerateDerivativeTestBase.php

@ -48,7 +48,7 @@ abstract class GenerateDerivativeTestBase extends IslandoraFunctionalTestBase {
$this->node = $this->container->get('entity_type.manager')->getStorage('node')->create([ $this->node = $this->container->get('entity_type.manager')->getStorage('node')->create([
'type' => $this->testType->id(), 'type' => $this->testType->id(),
'title' => 'Test Node', 'title' => 'Test Node',
'field_tags' => [$this->imageTerm->id()], 'field_model' => [$this->imageTerm->id()],
]); ]);
$this->node->save(); $this->node->save();
} }

4
tests/src/Functional/IslandoraFunctionalTestBase.php

@ -176,13 +176,13 @@ EOD;
]); ]);
$this->testType->save(); $this->testType->save();
$this->createEntityReferenceField('node', 'test_type', 'field_member_of', 'Member Of', 'node', 'default', [], 2); $this->createEntityReferenceField('node', 'test_type', 'field_member_of', 'Member Of', 'node', 'default', [], 2);
$this->createEntityReferenceField('node', 'test_type', 'field_tags', 'Tags', 'taxonomy_term', 'default', [], 2); $this->createEntityReferenceField('node', 'test_type', 'field_model', 'Model', 'taxonomy_term', 'default', [], 2);
// Create a media type. // Create a media type.
$this->testMediaType = $this->createMediaType('file', ['id' => 'test_media_type']); $this->testMediaType = $this->createMediaType('file', ['id' => 'test_media_type']);
$this->testMediaType->save(); $this->testMediaType->save();
$this->createEntityReferenceField('media', $this->testMediaType->id(), 'field_media_of', 'Media Of', 'node', 'default', [], 2); $this->createEntityReferenceField('media', $this->testMediaType->id(), 'field_media_of', 'Media Of', 'node', 'default', [], 2);
$this->createEntityReferenceField('media', $this->testMediaType->id(), 'field_tags', 'Tags', 'taxonomy_term', 'default', [], 2); $this->createEntityReferenceField('media', $this->testMediaType->id(), 'field_media_use', 'Tags', 'taxonomy_term', 'default', [], 2);
// Copy over the rest of the config from yml files. // Copy over the rest of the config from yml files.
$source = new FileStorage(__DIR__ . '/../../fixtures/config'); $source = new FileStorage(__DIR__ . '/../../fixtures/config');

4
tests/src/Functional/LinkHeaderTest.php

@ -61,13 +61,13 @@ class LinkHeaderTest extends IslandoraFunctionalTestBase {
'type' => $this->testType->id(), 'type' => $this->testType->id(),
'title' => 'Referencer', 'title' => 'Referencer',
'field_member_of' => [$this->referenced->id()], 'field_member_of' => [$this->referenced->id()],
'field_tags' => [$this->imageTerm->id()], 'field_model' => [$this->imageTerm->id()],
]); ]);
$this->referencer->save(); $this->referencer->save();
list($this->file, $this->media) = $this->makeMediaAndFile($account); list($this->file, $this->media) = $this->makeMediaAndFile($account);
$this->media->set('field_media_of', $this->referencer); $this->media->set('field_media_of', $this->referencer);
$this->media->set('field_tags', $this->preservationMasterTerm); $this->media->set('field_media_use', $this->preservationMasterTerm);
$this->media->save(); $this->media->save();
} }

6
tests/src/Functional/NodeHasTermTest.php

@ -33,7 +33,7 @@ class NodeHasTermTest extends IslandoraFunctionalTestBase {
$node = $this->container->get('entity_type.manager')->getStorage('node')->create([ $node = $this->container->get('entity_type.manager')->getStorage('node')->create([
'type' => 'test_type', 'type' => 'test_type',
'title' => 'Test Node', 'title' => 'Test Node',
'field_tags' => [$this->imageTerm->id()], 'field_model' => [$this->imageTerm->id()],
]); ]);
// Create and execute the condition. // Create and execute the condition.
@ -60,7 +60,7 @@ class NodeHasTermTest extends IslandoraFunctionalTestBase {
$node = $this->container->get('entity_type.manager')->getStorage('node')->create([ $node = $this->container->get('entity_type.manager')->getStorage('node')->create([
'type' => 'test_type', 'type' => 'test_type',
'title' => 'Test Node', 'title' => 'Test Node',
'field_tags' => [$this->preservationMasterTerm->id()], 'field_model' => [$this->preservationMasterTerm->id()],
]); ]);
$condition->setContextValue('node', $node); $condition->setContextValue('node', $node);
@ -81,7 +81,7 @@ class NodeHasTermTest extends IslandoraFunctionalTestBase {
$node = $this->container->get('entity_type.manager')->getStorage('node')->create([ $node = $this->container->get('entity_type.manager')->getStorage('node')->create([
'type' => 'test_type', 'type' => 'test_type',
'title' => 'Test Node', 'title' => 'Test Node',
'field_tags' => [$this->imageTerm->id(), $this->preservationMasterTerm->id()], 'field_model' => [$this->imageTerm->id(), $this->preservationMasterTerm->id()],
]); ]);
$condition->setContextValue('node', $node); $condition->setContextValue('node', $node);
$this->assertTrue($condition->execute(), "Condition should pass if node has both terms"); $this->assertTrue($condition->execute(), "Condition should pass if node has both terms");

Loading…
Cancel
Save