From b9745499587ec2522e17f0bed5685e3cafca6103 Mon Sep 17 00:00:00 2001 From: Jared Whiklo Date: Thu, 1 Dec 2016 10:02:25 -0600 Subject: [PATCH] 7.x islandora 1724 (#651) * Make breadcrumb creation a hookable process. * Forgot to add selection to admin page. * Add more attribution and remove unused path. * Fix admin form and coding standards. * Add the new variable to be removed on uninstall * Code review * Code review * Fix code style and add some docs to README * Stop using Mulgara prefixes --- README.md | 3 +++ includes/admin.form.inc | 23 +++++++++++++++++++++++ includes/breadcrumb.inc | 32 +++++++++++++++++++++++++++++--- islandora.api.php | 38 ++++++++++++++++++++++++++++++++++++++ islandora.install | 1 + islandora.module | 21 ++++++++++++++++++--- 6 files changed, 112 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 2fa632846..337bacd35 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,9 @@ The `islandora_drupal_filter` passes the username of 'anonymous' through to Fedo Drupal's cron can be run to remove expired authentication tokens. +**Breadcrumb Generation** on the configuration page, allows you to choose the default breadcrumb generation + or a custom method (if implemented). + ### Customization [Customize ingest forms](http://github.com/Islandora/islandora/wiki/Multi-paged-Ingest-Forms) diff --git a/includes/admin.form.inc b/includes/admin.form.inc index 19c4544e0..3293c3430 100644 --- a/includes/admin.form.inc +++ b/includes/admin.form.inc @@ -22,6 +22,17 @@ function islandora_repository_admin(array $form, array &$form_state) { $url = islandora_system_settings_form_default_value('islandora_base_url', 'http://localhost:8080/fedora', $form_state); $restrict_namespaces = islandora_system_settings_form_default_value('islandora_namespace_restriction_enforced', FALSE, $form_state); $confirmation_message = islandora_admin_settings_form_repository_access_message($url); + + $breadcrumb_backend_options = module_invoke_all('islandora_breadcrumbs_backends'); + $map_to_title = function ($backend) { + return $backend['title']; + }; + // In case the selected breadcrumb backend is no longer available. + $breadcrumb_backend = variable_get('islandora_breadcrumbs_backends', ISLANDORA_BREADCRUMB_LEGACY_BACKEND); + if (!isset($breadcrumb_backend_options[$breadcrumb_backend])) { + $breadcrumb_backend = ISLANDORA_BREADCRUMB_LEGACY_BACKEND; + } + $form = array( 'islandora_tabs' => array( '#type' => 'vertical_tabs', @@ -97,6 +108,18 @@ function islandora_repository_admin(array $form, array &$form_state) { '#description' => t('Larger sites may experience a notable performance improvement when disabled due to how breadcrumbs are constructed.'), '#default_value' => variable_get('islandora_render_drupal_breadcrumbs', TRUE), ), + 'islandora_breadcrumbs_backends' => array( + '#type' => 'radios', + '#title' => t('Breadcrumb generation'), + '#description' => t('How breadcrumbs for Islandora objects are generated for display.'), + '#default_value' => $breadcrumb_backend, + '#options' => array_map($map_to_title, $breadcrumb_backend_options), + '#states' => array( + 'visible' => array( + ':input[name="islandora_render_drupal_breadcrumbs"]' => array('checked' => TRUE), + ), + ), + ), 'islandora_risearch_use_itql_when_necessary' => array( '#type' => 'checkbox', '#title' => t('Use iTQL for particular queries'), diff --git a/includes/breadcrumb.inc b/includes/breadcrumb.inc index a8dc3169d..afba4c4b6 100644 --- a/includes/breadcrumb.inc +++ b/includes/breadcrumb.inc @@ -24,17 +24,43 @@ * not including the given object. For use in the function * drupal_set_breadcrumb(). */ -function islandora_get_breadcrumbs($object) { +function islandora_get_breadcrumbs(AbstractObject $object) { $breadcrumbs = array(); if (variable_get('islandora_render_drupal_breadcrumbs', TRUE)) { - $breadcrumbs = islandora_get_breadcrumbs_recursive($object->id, $object->repository); - array_pop($breadcrumbs); + $backend = variable_get('islandora_breadcrumbs_backends', ISLANDORA_BREADCRUMB_LEGACY_BACKEND); + $backends = module_invoke_all('islandora_breadcrumbs_backends'); + if ($backend === ISLANDORA_BREADCRUMB_LEGACY_BACKEND || !isset($backends[$backend])) { + $breadcrumbs = islandora_get_breadcrumbs_legacy($object->id, $object->repository); + } + else { + if (isset($backends[$backend]['file'])) { + require_once $backends[$backend]['file']; + } + $breadcrumbs = call_user_func($backends[$backend]['callable'], $object); + } $context = 'islandora'; drupal_alter('islandora_breadcrumbs', $breadcrumbs, $context, $object); } return $breadcrumbs; } +/** + * Call the legacy SPARQL recursive function and return the correct breadcrumbs. + * + * @param string $pid + * The object id whose parent will be fetched for the next link. + * @param \IslandoraFedoraRepository $repository + * The fedora repository. + * + * @return array + * An array of links representing the breadcrumb trail, "root" first. + */ +function islandora_get_breadcrumbs_legacy($pid, IslandoraFedoraRepository $repository) { + $breadcrumbs = islandora_get_breadcrumbs_recursive($pid, $repository); + array_pop($breadcrumbs); + return $breadcrumbs; +} + /** * Builds an array of drupal links for use in breadcrumbs. * diff --git a/islandora.api.php b/islandora.api.php index a50a0c24d..cdf301291 100644 --- a/islandora.api.php +++ b/islandora.api.php @@ -907,3 +907,41 @@ function hook_islandora_edit_datastream_registry_alter(&$edit_registry, $context function hook_islandora_repository_connection_construction_alter(RepositoryConnection $instance) { $instance->userAgent = "Tuque/cURL"; } + +/** + * Allow a overridable backend for generating breadcrumbs. + * + * Stolen shamelessly from @adam-vessey. + * + * @return array + * Should return an associative array mapping unique (module-prefixed, + * preferably) keys to associative arrays containing: + * - title: A human-readable title for the backend. + * - callable: A PHP callable to call for this backend, implementing + * callback_islandora_basic_collection_query_backends(). + * - file: An optional file to load before attempting to call the callable. + */ +function hook_islandora_breadcrumbs_backends() { + return array( + 'awesome_backend' => array( + 'title' => t('Awesome Backend'), + 'callable' => 'callback_islandora_breadcrumbs_backends', + ), + ); +} + +/** + * Generate an array of links for breadcrumbs leading to $object, root first. + * + * Stolen shamelessly from @adam-vessey. + * + * @param AbstractObject $object + * The object to generate breadcrumbs for. + * + * @return array + * Array of links from root to the parent of $object. + */ +function callback_islandora_breadcrumbs_backends(AbstractObject $object) { + // Do something to get an array of breadcrumb links for $object, root first. + return array($root_link, $collection_link, $object_link); +} diff --git a/islandora.install b/islandora.install index fe04c0e2a..d993f80cf 100644 --- a/islandora.install +++ b/islandora.install @@ -58,6 +58,7 @@ function islandora_uninstall() { 'islandora_use_object_semaphores', 'islandora_semaphore_period', 'islandora_require_obj_upload', + 'islandora_breadcrumbs_backends', ); array_walk($variables, 'variable_del'); } diff --git a/islandora.module b/islandora.module index 21fbccfda..e060ce12f 100644 --- a/islandora.module +++ b/islandora.module @@ -68,6 +68,8 @@ define('ISLANDORA_DERIVATIVE_CREATION_HOOK', 'islandora_derivative'); define('ISLANDORA_CONTENT_MODELS_AUTOCOMPLETE', 'islandora/autocomplete/content-models'); define('ISLANDORA_MIME_TYPES_AUTOCOMPLETE', 'islandora/autocomplete/mime-types'); +const ISLANDORA_BREADCRUMB_LEGACY_BACKEND = 'islandora_breadcrumbs_legacy_sparql'; + /** * Implements hook_menu(). * @@ -2152,9 +2154,9 @@ function islandora_schedule_cache_clear_for_batch() { */ function islandora_islandora_get_breadcrumb_query_predicates(AbstractObject $object) { return array( - 'fedora-rels-ext:isPartOf', - 'fedora-rels-ext:isMemberOfCollection', - 'fedora-rels-ext:isMemberOf', + 'info:fedora/fedora-system:def/relations-external#isPartOf', + 'info:fedora/fedora-system:def/relations-external#isMemberOfCollection', + 'info:fedora/fedora-system:def/relations-external#isMemberOf', ); } @@ -2171,3 +2173,16 @@ function islandora_create_manage_overview(AbstractObject $object) { $output = theme('islandora_object_overview', array('islandora_object' => $object)); return array('cmodels' => $output); } + +/** + * Implements hook_islandora_breadcrumbs_backends(). + */ +function islandora_islandora_breadcrumbs_backends() { + return array( + ISLANDORA_BREADCRUMB_LEGACY_BACKEND => array( + 'title' => t('Resource Index - Default'), + // Callback not needed as this is our legacy process and the + // default incase anything goes wrong. + ), + ); +}