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