diff --git a/islandora.links.menu.yml b/islandora.links.menu.yml
index 36024a194..7d69b3d65 100644
--- a/islandora.links.menu.yml
+++ b/islandora.links.menu.yml
@@ -11,3 +11,10 @@ system.islandora_settings:
parent: system.admin_config_islandora
route_name: system.islandora_settings
description: 'Confgure core Islandora settings'
+
+# RDF property mappings
+system.islandora_rdf_mappings:
+ title: 'Field and term RDF mappings'
+ parent: system.admin_reports
+ description: 'List of configured Drupal field to RDF property mappings and taxonomy term linked data URIs.'
+ route_name: system.islandora_rdf_mappings
diff --git a/islandora.routing.yml b/islandora.routing.yml
index 3bdfdf536..b91c1051c 100644
--- a/islandora.routing.yml
+++ b/islandora.routing.yml
@@ -16,6 +16,15 @@ system.islandora_settings:
requirements:
_permission: 'administer site configuration'
+# RDF properties report
+system.islandora_rdf_mappings:
+ path: '/admin/reports/islandora/rdf_mappings'
+ defaults:
+ _controller: '\Drupal\islandora\Controller\RdfMappingsReportController::main'
+ _title: 'Field and term RDF mappings'
+ requirements:
+ _permission: 'administer site configuration'
+
islandora.add_member_to_node_page:
path: '/node/{node}/members/add'
defaults:
diff --git a/src/Controller/RdfMappingsReportController.php b/src/Controller/RdfMappingsReportController.php
new file mode 100644
index 000000000..d275043ed
--- /dev/null
+++ b/src/Controller/RdfMappingsReportController.php
@@ -0,0 +1,236 @@
+renderer = $renderer;
+ $this->entityFieldManager = $entity_field_manager;
+ $this->entityTypeBundleInfo = $entity_type_bundle_info;
+ $this->utils = $utils;
+ }
+
+ /**
+ * Controller's create method for dependecy injection.
+ *
+ * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
+ * The App Container.
+ *
+ * @return \Drupal\islandora\Controller\RdfMappingsReportController
+ * Controller instance.
+ */
+ public static function create(ContainerInterface $container) {
+ return new static(
+ $container->get('renderer'),
+ $container->get('entity_field.manager'),
+ $container->get('entity_type.bundle.info'),
+ $container->get('islandora.utils')
+ );
+ }
+
+ /**
+ * Output the RDF mappings report.
+ *
+ * @return string
+ * Markup of the tables.
+ */
+ public function main() {
+ $markup = '';
+
+ // Configured namespaces.
+ $namespaces = rdf_get_namespaces();
+ $namespaces_table_rows = [];
+ foreach ($namespaces as $alias => $namespace_uri) {
+ $namespaces_table_rows[] = [$alias, $namespace_uri];
+ }
+ $namespaces_table_header = [t('Namespace alias'), t('Namespace URI')];
+ $namespaces_table = [
+ '#theme' => 'table',
+ '#header' => $namespaces_table_header,
+ '#rows' => $namespaces_table_rows,
+ ];
+ $namespaces_table_markup = $this->renderer->render($namespaces_table);
+
+ $markup .= '' . t('RDF namespaces used in field mappings') .
+ '
' . $namespaces_table_markup . '
';
+
+ // Node and media field to RDF property mappings.
+ $entity_types = ['node', 'media'];
+ $markup .= '
' . t('Field mappings') . '
';
+ foreach ($entity_types as $entity_type) {
+ $bundles = $this->entityTypeBundleInfo->getBundleInfo($entity_type);
+ foreach ($bundles as $name => $attr) {
+ $rdf_mappings = rdf_get_mapping($entity_type, $name);
+ $rdf_types = $rdf_mappings->getPreparedBundleMapping();
+ if (array_key_exists('types', $rdf_types) && count($rdf_types['types']) > 0) {
+ $rdf_types = implode(', ', $rdf_types['types']);
+ $markup .= '' . $attr['label'] . ' (' . $entity_type . ')' . ', mapped to RDF type ' . $rdf_types . '
';
+ }
+ else {
+ $markup .= '' . $attr['label'] . ' (' . $entity_type . ') - no RDF type mapping
';
+ }
+ $fields = $this->entityFieldManager->getFieldDefinitions($entity_type, $name);
+ $mappings_table_rows = [];
+ foreach ($fields as $field_name => $field_object) {
+ $field_mappings = $rdf_mappings->getPreparedFieldMapping($field_name);
+ if (array_key_exists('properties', $field_mappings)) {
+ $properties = implode(', ', $field_mappings['properties']);
+ $mappings_table_rows[] = [
+ $field_object->getLabel() .
+ ' (' . $field_name . ')',
+ $properties,
+ ];
+ }
+ }
+
+ $mappings_header = [t('Drupal field'), t('RDF property')];
+
+ if (count($mappings_table_rows) == 0) {
+ $mappings_header = [];
+ $mappings_table_rows[] = [t('No RDF mappings configured for @bundle.', ['@bundle' => $attr['label']])];
+ }
+
+ $mappings_table = [
+ '#theme' => 'table',
+ '#header' => $mappings_header,
+ '#rows' => $mappings_table_rows,
+ ];
+ $mappings_table_markup = $this->renderer->render($mappings_table);
+ $markup .= $mappings_table_markup;
+ }
+ }
+
+ // Taxonomy terms with external URIs or authority links.
+ $markup .= '' . t('Taxonomy terms with external URIs or authority links') . '
';
+ $uri_fields = $this->utils->getUriFieldNamesForTerms();
+
+ $vocabs = Vocabulary::loadMultiple();
+ foreach ($vocabs as $vid => $vocab) {
+ $rdf_mappings = rdf_get_mapping('taxonomy_term', $vid);
+ $rdf_types = $rdf_mappings->getPreparedBundleMapping();
+ $vocab_table_header = [];
+ $vocab_table_rows = [];
+ if (array_key_exists('types', $rdf_types) && count($rdf_types['types']) > 0) {
+ $rdf_types = implode(', ', $rdf_types['types']);
+ $markup .= '' . $vocab->label() . ' (' . $vid . ')' . ', mapped to RDF type ' . $rdf_types . '
';
+ }
+ else {
+ $markup .= '' . $vocab->label() . ' (' . $vid . ') - no RDF type mapping
';
+ }
+ $terms = $this->entityTypeManager()->getStorage('taxonomy_term')->loadTree($vid);
+ if (count($terms) == 0) {
+ $vocab_table_rows[] = [t('No terms in this vocabulary.')];
+ $vocab_table = [
+ '#theme' => 'table',
+ '#header' => $vocab_table_header,
+ '#rows' => $vocab_table_rows,
+ ];
+ $vocab_table_markup = $this->renderer->render($vocab_table);
+ $markup .= $vocab_table_markup;
+ }
+ else {
+ $vocab_table_header = [
+ t('Term'),
+ t('Term ID'),
+ t('External URI or Authority link'),
+ ];
+ $vocab_table_rows = [];
+ foreach ($terms as $t) {
+ $ld_uri = NULL;
+ $term = Term::load($t->tid);
+ foreach ($uri_fields as $uri_field) {
+ if ($term->hasField($uri_field) && !$term->get($uri_field)->isEmpty()) {
+ $ld_uri = $term->get($uri_field)->first()->getValue();
+ continue;
+ }
+ }
+ if (is_array($ld_uri) && array_key_exists('uri', $ld_uri)) {
+ $term_link = Link::fromTextAndUrl($term->getName(), Url::fromUri('internal:/taxonomy/term/' . $term->id()));
+ $vocab_table_rows[] = [
+ $term_link,
+ $term->id(),
+ $ld_uri['uri'],
+ ];
+ }
+ else {
+ $term_link = Link::fromTextAndUrl($term->getName(), Url::fromUri('internal:/taxonomy/term/' . $term->id()));
+ $vocab_table_rows[] = [$term_link, $term->id(), t('None')];
+ }
+ }
+ $vocab_table = [
+ '#theme' => 'table',
+ '#header' => $vocab_table_header,
+ '#rows' => $vocab_table_rows,
+ ];
+ }
+ $vocab_table_markup = $this->renderer->render($vocab_table);
+ $markup .= $vocab_table_markup;
+ }
+
+ return ['#markup' => $markup];
+ }
+
+}
diff --git a/src/IslandoraUtils.php b/src/IslandoraUtils.php
index 99088ddd1..46108d459 100644
--- a/src/IslandoraUtils.php
+++ b/src/IslandoraUtils.php
@@ -299,7 +299,8 @@ public function getUriFieldNamesForTerms() {
$field_map = $this->entityFieldManager->getFieldMap();
$fields = [];
foreach ($field_map['taxonomy_term'] as $field_name => $field_data) {
- if ($field_data['type'] == 'authority_link') {
+ $data_types = ['authority_link', 'field_external_authority_link'];
+ if (in_array($field_data['type'], $data_types)) {
$fields[] = $field_name;
}
}