diff --git a/css/islandora.theme.css b/css/islandora.theme.css index 29f14e66..4ac4fddc 100644 --- a/css/islandora.theme.css +++ b/css/islandora.theme.css @@ -1,4 +1,4 @@ -/* +/* Document : islandora_basic_collection.theme Created on : May 23, 2012, 11:23:56 AM Description: @@ -11,16 +11,16 @@ dl.islandora-object-tn { float: left; - width: 20.8333%; - padding: 0 10px 0 0; margin: 1.5em 0; + padding: 0 10px 0 0; + width: 20.8333%; } dl.islandora-object-fields { + border-top: 0px solid #ddd; float: right; - width:79.1666%; - border-top:0px solid #ddd; margin: 1.5em 0; + width: 79.1666%; } .islandora-object-fields dt { @@ -28,16 +28,16 @@ dl.islandora-object-fields { } .islandora-object-fields dt.first { - border-top:0; + border-top: 0; } .islandora-object-fields dt, .islandora-object-fields dd { - padding:6px 2% 4px; - border-top:1px solid #ddd; + border-top: 1px solid #ddd; + padding: 6px 2% 4px; } .islandora-object-fields dt.first, .islandora-object-fields dd.first { border-top: 0; -} \ No newline at end of file +} diff --git a/includes/manage_deleted_objects.inc b/includes/manage_deleted_objects.inc new file mode 100644 index 00000000..2708efe3 --- /dev/null +++ b/includes/manage_deleted_objects.inc @@ -0,0 +1,340 @@ + 'markup', + '#markup' => t("There are no deleted objects in this repository."), + ); + return $form; + } + $form['message'] = array( + '#type' => 'markup', + '#markup' => t("Select content models of deleted objects."), + ); + $form['mapped_contentmodels'] = array( + '#type' => 'hidden', + '#value' => $contentmodels_with_deleted_members, + ); + $table_element = islandora_content_model_select_table_form_element(NULL); + + foreach ($table_element['#options'] as $option) { + if (!in_array($option['pid'], $elegible_contentmodels)) { + unset($table_element['#options'][$option['pid']]); + } + if (array_key_exists($option['pid'], $chosen_contentmodels)) { + $table_element['#default_value'][$option['pid']] = TRUE; + } + } + + $form['contentmodels'] = $table_element; + $form['next'] = array( + '#type' => 'submit', + '#value' => t('Next'), + ); + + return $form; +} + +/** + * Submit handler for deletion management prep form. + * + * @param array $form + * The form. + * @param array $form_state + * The form state. + */ +function islandora_deleted_objects_prep_form_submit($form, $form_state) { + $content_models = $form_state['values']['contentmodels']; + $chosen = function($element) { + return $element; + }; + $serialized_contentmodels = serialize(array_filter($content_models, $chosen)); + drupal_goto("admin/islandora/restore/manage/$serialized_contentmodels"); +} + +/** + * The deletion management prep form. + * + * @param array $form + * The Drupal form definition. + * @param array $form_state + * The Drupal form state. + * + * @return array + * The Drupal form definition. + */ +function islandora_deleted_objects_manage_form($form, $form_state, $serialized_chosen = NULL) { + $form['previous'] = array( + '#type' => 'submit', + '#value' => t('Previous'), + '#attributes' => array('source' => 'previous'), + ); + + $chosen_contentmodels = unserialize($serialized_chosen); + $content_models_with_deleted = islandora_get_contentmodels_with_deleted_members(); + foreach ($chosen_contentmodels as $contentmodel) { + if (!array_key_exists($contentmodel, $content_models_with_deleted)) { + unset($chosen_contentmodels[$contentmodel]); + } + } + + if (empty($chosen_contentmodels)) { + $form['message'] = array( + '#type' => 'markup', + '#markup' => t("There are no deleted objects with the selected content models in this repository."), + ); + return $form; + } + + if (is_array($chosen_contentmodels)) { + foreach ($chosen_contentmodels as $key => $value) { + if (in_array($key, $content_models_with_deleted)) { + $chosen_contentmodels[$key] = $content_models_with_deleted[$key]; + } + } + } + + $tuque = islandora_get_tuque_connection(); + $repository = $tuque->repository; + // Query brings back fedora-system:FedoraObject-3.0, doubling the results. + $total = $repository->ri->countQuery(islandora_get_deleted_query($chosen_contentmodels), 'sparql') / 2; + $limit = 25; + if ($total < 28) { + $limit = $total; + } + $current_page = pager_default_initialize($total, $limit); + $query_limit = $limit * 2; + $offset = $current_page * $query_limit; + $options = islandora_get_deleted_objects($chosen_contentmodels, $query_limit, $offset); + + foreach ($options as &$option) { + $option['content_model'] = $content_models_with_deleted[$option['content_model']]; + } + $form['serialized_chosen'] = array( + '#type' => 'hidden', + '#value' => $serialized_chosen, + ); + $form['pager'] = array( + '#type' => 'markup', + '#markup' => theme('pager', array('quantity', count($options))), + ); + $form['propogate'] = array( + '#title' => t('Apply changes to related objects?'), + '#default_value' => TRUE, + '#description' => t("Objects associated with selected objects will also be purged/restored. ie page objects associated with a book object."), + '#type' => 'checkbox', + ); + $form['chosen'] = array( + '#type' => 'hidden', + '#value' => $chosen_contentmodels, + ); + $form['objects_to_process'] = array( + '#type' => 'tableselect', + '#header' => array( + 'title' => t('Name'), + 'pid' => t('PID'), + 'content_model' => t('Content Model'), + ), + '#multiple' => TRUE, + '#options' => $options, + ); + + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Restore selected objects'), + '#attributes' => array('source' => 'restore'), + ); + if (user_access(ISLANDORA_PURGE)) { + $form['purge'] = array( + '#type' => 'submit', + '#value' => t('Irrevocably purge selected objects'), + '#attributes' => array('source' => 'purge'), + ); + } + return $form; +} + +/** + * Submit handler for deletion management form. + * + * @param array $form + * The form. + * @param array $form_state + * The form state. + */ +function islandora_deleted_objects_manage_form_submit($form, $form_state) { + module_load_include('inc', 'islandora', 'includes/utilities'); + $serialized_chosen = isset($form_state['values']['serialized_chosen']) ? $form_state['values']['serialized_chosen'] : NULL; + + if (isset($form_state['clicked_button']['#attributes']['source']) && $form_state['clicked_button']['#attributes']['source'] == 'previous') { + drupal_goto("admin/islandora/restore/prep/$serialized_chosen"); + } + if ($form_state['clicked_button']['#attributes']['source'] == 'restore') { + $descriptor = "Restoring"; + $action = 'islandora_restore_object_by_pid'; + } + if ($form_state['clicked_button']['#attributes']['source'] == 'purge') { + $descriptor = "Purging"; + $action = 'islandora_purge_object_by_pid'; + } + $objects_to_process = array_filter($form_state['values']['objects_to_process']); + $pids_to_restore = $objects_to_process; + if ($form_state['values']['propogate']) { + foreach ($objects_to_process as $pid) { + $fedora_object = islandora_object_load($pid); + $temp = islandora_invoke_hook_list(ISLANDORA_UPDATE_RELATED_OBJECTS_PROPERTIES_HOOK, $fedora_object->models, array($fedora_object)); + if (!empty($temp)) { + $pids_to_restore = array_merge_recursive($pids_to_restore, $temp); + } + } + } + $batch = array( + 'title' => t('@descriptor selected objects', array('@descriptor' => $descriptor)), + 'file' => drupal_get_path('module', 'islandora') . '/includes/manage_deleted_objects.inc', + 'operations' => array(), + ); + + foreach ($pids_to_restore as $pid) { + $batch['operations'][] = array( + $action, + array($pid), + ); + } + batch_set($batch); + batch_process("admin/islandora/restore/manage/$serialized_chosen"); +} + +/** + * Gets PIDS of all deleted objects. + * + * @return array + * PIDS of deleted objects + */ +function islandora_get_deleted_objects($content_models, $limit, $offset) { + $tuque = islandora_get_tuque_connection(); + $repository = $tuque->repository; + $query = islandora_get_deleted_query($content_models, $offset); + $objects = $repository->ri->sparqlQuery($query, $limit); + $deleted_objects = array(); + foreach ($objects as $object) { + if ($object['object']['value'] != "fedora-system:FedoraObject-3.0") { + $pid = $object['subject']['value']; + $cm_pid = $object['object']['value']; + $title = $object['label']['value']; + $deleted_objects[$pid] = array( + 'title' => $title, 'pid' => $pid, + 'content_model' => $content_models[$cm_pid], + ); + } + } + return $deleted_objects; +} + +/** + * Gets PIDS of all content models associated with deleted objects. + * + * @return array + * array of content model pids + */ +function islandora_get_contentmodels_with_deleted_members() { + $tuque = new IslandoraTuque(); + $repository = $tuque->repository; + $query = "PREFIX fm: + SELECT DISTINCT ?object ?label FROM <#ri> + WHERE { + {?subject fm:state fm:Deleted; + fm:hasModel ?object; + } + OPTIONAL{ + ?object fm:label ?label + } + }"; + + $objects = $repository->ri->sparqlQuery($query, -1); + $content_models = array(); + foreach ($objects as $object) { + if ($object['object']['value'] != "fedora-system:FedoraObject-3.0") { + $content_models[$object['object']['value']] = $object['label']['value']; + } + } + return $content_models; +} + +/** + * Restores deleted object. + * + * @param String $pid + * PID of object to be restored + */ +function islandora_restore_object_by_pid($pid) { + $fedora_object = islandora_object_load($pid); + $fedora_object->state = 'A'; +} + +/** + * Purges deleted object. + * + * @param String $pid + * PID of object to be restored + */ +function islandora_purge_object_by_pid($pid) { + $fedora_object = islandora_object_load($pid); + $fedora_object->repository->purgeObject($pid); +} + +/** + * Get query to find all deleted objects by content type. + * + * @param array $content_models + * Content models to restrict search + * @param int $offset + * offset to be added to search + * + * @return String + * Sparql query + */ +function islandora_get_deleted_query($content_models, $offset = 0) { + $candidates = array_keys($content_models); + $first_contentmodel = array_shift($candidates); + $prefix = "PREFIX fm: <" . FEDORA_MODEL_URI . "> "; + $select = "SELECT DISTINCT ?subject ?label ?object FROM <#ri> WHERE { "; + $where_clause = "{?subject fm:hasModel ; + fm:state fm:Deleted; + fm:hasModel ?object; + }"; + $suffix = "} ORDER BY ?subject OFFSET $offset"; + $unions = ''; + foreach ($candidates as $contentmodel) { + $unions .= "UNION {?subject fm:hasModel ; + fm:state fm:Deleted; + fm:hasModel ?object; + } + "; + } + $optional = "OPTIONAL{?subject fm:label ?label}"; + return "$prefix $select $where_clause $unions $optional $suffix"; +} diff --git a/includes/mime_detect.inc b/includes/mime_detect.inc index 13b66cc8..4035afe5 100644 --- a/includes/mime_detect.inc +++ b/includes/mime_detect.inc @@ -162,6 +162,7 @@ class MimeDetect { "xpm" => "image/x-xpixmap", "xwd" => "image/x-windowdump", // videos: + "mkv" => "video/x-matroska", "mpeg" => "video/mpeg", "mpe" => "video/mpeg", "mpg" => "video/mpeg", diff --git a/includes/object_properties.form.inc b/includes/object_properties.form.inc index 51e48a5f..5295f067 100644 --- a/includes/object_properties.form.inc +++ b/includes/object_properties.form.inc @@ -21,6 +21,11 @@ function islandora_object_properties_form(array $form, array &$form_state, AbstractObject $object) { drupal_set_title($object->label); $form_state['object'] = $object; + $temp = islandora_invoke_hook_list(ISLANDORA_UPDATE_RELATED_OBJECTS_PROPERTIES_HOOK, $object->models, array($object)); + $related_objects_pids = array(); + if (!empty($temp)) { + $related_objects_pids = array_merge_recursive($related_objects_pids, $temp); + } return array( 'pid' => array( '#type' => 'hidden', @@ -54,6 +59,18 @@ function islandora_object_properties_form(array $form, array &$form_state, Abstr '#type' => 'select', '#options' => array('A' => 'Active', 'I' => 'Inactive', 'D' => 'Deleted'), ), + 'propogate' => array( + '#title' => t('Apply changes to related objects?'), + '#default_value' => TRUE, + '#description' => t("Changes to owner and state will applied to associated objects. ie page objects associated with a book object."), + '#type' => 'checkbox', + '#access' => count($related_objects_pids), + ), + 'related_pids' => array( + '#value' => $related_objects_pids, + '#type' => 'hidden', + '#access' => count($related_objects_pids), + ), 'submit' => array( '#type' => 'submit', '#value' => 'Update Properties', @@ -61,7 +78,9 @@ function islandora_object_properties_form(array $form, array &$form_state, Abstr 'delete' => array( '#type' => 'submit', '#access' => islandora_object_access(ISLANDORA_PURGE, $object), - '#value' => t('Delete'), + '#value' => t("Permanently remove '@label' from repository", array( + '@label' => truncate_utf8($object->label, 32, TRUE, TRUE)) + ), '#submit' => array('islandora_object_properties_form_delete'), '#limit_validation_errors' => array(array('pid')), ), @@ -81,32 +100,54 @@ function islandora_object_properties_form_submit(array $form, array &$form_state $owner = $form_state['values']['object_owner']; $state = $form_state['values']['object_state']; $label = $form_state['values']['object_label']; + $propogate = $form_state['values']['propogate']; + $update_owners = FALSE; + $update_states = FALSE; if (isset($owner) && $owner != $object->owner) { try { $object->owner = $owner; + $update_owners = TRUE; drupal_set_message(t('Successfully updated owner %s', array('%s' => $owner))); } catch (Exception $e) { form_set_error('object_owner', t('Error updating owner %s', array('%s' => $e->getMessage()))); } } + + if (isset($label) && $label != $object->label) { + try { + $object->label = $label; + drupal_set_message(t('Successfully updated label %s', array('%s' => check_plain($label)))); + } + catch (Exception $e) { + form_set_error(t('Error updating label %s', array('%s' => $e->getMessage()))); + } + } if (isset($state) && $state != $object->state) { try { $object->state = $state; + $update_states = TRUE; drupal_set_message(t('Successfully updated state %s', array('%s' => $state))); } catch (Exception $e) { form_set_error('object_state', t('Error updating state %s', array('%s' => $e->getMessage()))); } } - if (isset($label) && $label != $object->label) { - try { - $object->label = $label; - drupal_set_message(t('Successfully updated label %s', array('%s' => check_plain($label)))); - } - catch (Exception $e) { - form_set_error(t('Error updating label %s', array('%s' => $e->getMessage()))); + if ($propogate && ($update_states || $update_owners)) { + $related_objects_pids = $form_state['values']['related_pids']; + $batch = array( + 'title' => t('Updating related objects'), + 'file' => drupal_get_path('module', 'islandora') . '/includes/object_properties.form.inc', + 'operations' => array(), + ); + + foreach ($related_objects_pids as $pid) { + $batch['operations'][] = array( + 'islandora_update_object_properties', + array($pid, $update_states, $state, $update_owners, $owner), + ); } + batch_set($batch); } } @@ -121,3 +162,29 @@ function islandora_object_properties_form_submit(array $form, array &$form_state function islandora_object_properties_form_delete(array $form, array &$form_state) { drupal_goto("islandora/object/{$form_state['values']['pid']}/delete"); } + +/** + * Updates object state. + * + * @param String $pid + * PID of object to be updated + * @param Boolean $update_states + * If TRUE, update object state + * @param String $state + * Desired object state + * @param Boolean $update_owners + * If TRUE, update Owner + * @param String $owner + * New Owner + */ +function islandora_update_object_properties($pid, $update_states, $state, $update_owners, $owner) { + $fedora_object = islandora_object_load($pid); + if ($fedora_object) { + if ($update_states) { + $fedora_object->state = $state; + } + if ($update_owners) { + $fedora_object->owner = $owner; + } + } +} diff --git a/includes/utilities.inc b/includes/utilities.inc index 91988918..6366305e 100644 --- a/includes/utilities.inc +++ b/includes/utilities.inc @@ -889,9 +889,7 @@ function islandora_as_renderable_array(&$markup_array) { if (!is_array($value)) { // Not a renderable array, just a string. Let's convert it to a // renderable '#markup' element. - $value = array( - '#markup' => $value, - ); + $value = array('#markup' => $value); } elseif (!isset($value['#type']) && !isset($value['#markup'])) { // A simple array--possibly the result of a recursive merge? Let's @@ -902,9 +900,7 @@ function islandora_as_renderable_array(&$markup_array) { // If it is an array at this level, we can assume that it is a // renderable array. If it is not an array, convert to a renderable // '#markup' element. - $inner = array( - '#markup' => $inner, - ); + $inner = array('#markup' => $inner); } } unset($inner); diff --git a/islandora.api.php b/islandora.api.php index 2cdf5d73..39c6e454 100644 --- a/islandora.api.php +++ b/islandora.api.php @@ -649,6 +649,21 @@ function hook_CMODEL_PID_islandora_derivative() { } +/** + + * Retrieves PIDS of related objects for property updating. + * + * @param AbstractObject $object + * AbstractObject representing deleted object + */ +function hook_islandora_update_related_objects_properties(AbstractObject $object) { + $related_objects = get_all_children_siblings_and_friends($object); + $pids_to_return = array(); + foreach($related_objects as $related_object) { + $pids_to_return[] = $related_object->id; + } + return $pids_to_return; +} /** * Alters breadcrumbs used on Solr search results and within Islandora views. * diff --git a/islandora.module b/islandora.module index 8fa20898..45458665 100644 --- a/islandora.module +++ b/islandora.module @@ -34,8 +34,10 @@ define('ISLANDORA_INGEST', 'ingest fedora objects'); define('ISLANDORA_PURGE', 'delete fedora objects and datastreams'); define('ISLANDORA_MANAGE_PROPERTIES', 'manage object properties'); define('ISLANDORA_VIEW_DATASTREAM_HISTORY', 'view old datastream versions'); +define('ISLANDORA_MANAGE_DELETED_OBJECTS', 'manage deleted objects'); define('ISLANDORA_REVERT_DATASTREAM', 'revert to old datastream'); + // Hooks. define('ISLANDORA_VIEW_HOOK', 'islandora_view_object'); define('ISLANDORA_PRINT_HOOK', 'islandora_view_print_object'); @@ -45,6 +47,7 @@ define('ISLANDORA_PRE_INGEST_HOOK', 'islandora_ingest_pre_ingest'); define('ISLANDORA_POST_INGEST_HOOK', 'islandora_ingest_post_ingest'); define('ISLANDORA_PRE_PURGE_OBJECT_HOOK', 'islandora_pre_purge_object'); define('ISLANDORA_POST_PURGE_OBJECT_HOOK', 'islandora_post_purge_object'); +define('ISLANDORA_UPDATE_RELATED_OBJECTS_PROPERTIES_HOOK', 'islandora_update_related_objects_properties'); // @todo Add Documentation. define('ISLANDORA_OBJECT_INGESTED_HOOK', 'islandora_object_ingested'); @@ -320,6 +323,26 @@ function islandora_menu() { 'access arguments' => array('administer site configuration'), 'type' => MENU_CALLBACK, ); + $items['admin/islandora/restore/prep'] = array( + 'description' => 'Restore or permanantly remove objects with Deleted status', + 'title' => 'Manage Deleted Objects', + 'file' => 'includes/manage_deleted_objects.inc', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('islandora_deleted_objects_prep_form'), + 'type' => MENU_NORMAL_ITEM, + 'access arguments' => array(ISLANDORA_MANAGE_DELETED_OBJECTS), + ); + + $items['admin/islandora/restore/manage'] = array( + 'description' => 'Restore or permanantly remove objects with Deleted status', + 'title' => 'Manage Deleted Objects', + 'file' => 'includes/manage_deleted_objects.inc', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('islandora_deleted_objects_manage_form'), + 'type' => MENU_SUGGESTED_ITEM, + 'access arguments' => array(ISLANDORA_MANAGE_DELETED_OBJECTS), + ); + return $items; } @@ -462,6 +485,10 @@ function islandora_permission() { 'title' => t('Revert datastream history'), 'description' => t('Revert to a previous version of a datastream.'), ), + ISLANDORA_MANAGE_DELETED_OBJECTS => array( + 'title' => t('Manage deleted objects'), + 'description' => t('Purge or revert deleted objects.'), + ), ); } @@ -481,15 +508,14 @@ function islandora_print_object(AbstractObject $object) { drupal_set_title($object->label); return theme('islandora_object_print', array('object' => $object)); } + /** * Implements hook_forms(). */ function islandora_forms($form_id) { $forms = array(); if (strpos($form_id, 'islandora_solution_pack_form_') !== FALSE) { - $forms[$form_id] = array( - 'callback' => 'islandora_solution_pack_form', - ); + $forms[$form_id] = array('callback' => 'islandora_solution_pack_form'); } return $forms; } @@ -758,11 +784,7 @@ function islandora_manage_overview_object(AbstractObject $object) { */ function islandora_default_islandora_manage_overview_object(AbstractObject $object) { $output = theme('islandora_default_overview', array('islandora_object' => $object)); - return array( - 'Default overview output' => array( - '#markup' => $output, - ), - ); + return array('Default overview output' => array('#markup' => $output)); } /** @@ -815,11 +837,7 @@ function islandora_edit_object(AbstractObject $object) { */ function islandora_default_islandora_edit_object(AbstractObject $object) { $output = theme('islandora_default_edit', array('islandora_object' => $object)); - return array( - 'Default Edit output' => array( - '#markup' => $output, - ), - ); + return array('Default Edit output' => array('#markup' => $output)); } /** @@ -857,13 +875,10 @@ function islandora_view_object(AbstractObject $object) { drupal_add_js(array( 'islandora' => array( 'print_img' => $path . '/images/print-icon.png'), - ), array( - 'type' => 'setting')); + ), array( + 'type' => 'setting')); - drupal_add_js(array( - 'islandora' => array( - 'print_link' => 'islandora/object/' . $object->id . '/print_object')), - array('type' => 'setting')); + drupal_add_js(array('islandora' => array('print_link' => 'islandora/object/' . $object->id . '/print')), array('type' => 'setting')); drupal_add_js($path . '/js/add_print.js'); drupal_set_title($object->label); @@ -947,6 +962,7 @@ function islandora_drupal_title(AbstractObject $object) { return $object->label; } + /** * Renders the default view object page for the given object. * @@ -958,11 +974,7 @@ function islandora_drupal_title(AbstractObject $object) { */ function islandora_default_islandora_view_object($object) { $output = theme('islandora_default', array('islandora_object' => $object)); - return array( - 'Default output' => array( - '#markup' => $output, - ), - ); + return array('Default output' => array('#markup' => $output)); } /** @@ -1000,11 +1012,7 @@ function islandora_default_islandora_printer_object($object, $alter) { 'dc_array' => $variables, 'islandora_content' => $alter)); - return array( - 'Default output' => array( - '#markup' => $output, - ), - ); + return array('Default output' => array('#markup' => $output)); } /** @@ -1223,9 +1231,7 @@ function islandora_islandora_required_objects(IslandoraTuque $connection) { return array( 'islandora' => array( 'title' => 'Islandora', - 'objects' => array( - $root_collection, - ), + 'objects' => array($root_collection), ), ); } @@ -1401,6 +1407,7 @@ function islandora_entity_property_info() { return $info; } + /** * Menu callback downloads the given clip. */ @@ -1531,9 +1538,9 @@ function islandora_datastream_access($op, $datastream, $user = NULL) { // The datastream check returned FALSE, and one in the object or datastream // checks returned TRUE. $cache[$op][$datastream->parent->id][$datastream->id][$user->uid] = ( - !in_array(FALSE, $datastream_results, TRUE) && - (in_array(TRUE, $object_results, TRUE) || in_array(TRUE, $datastream_results, TRUE)) - ); + !in_array(FALSE, $datastream_results, TRUE) && + (in_array(TRUE, $object_results, TRUE) || in_array(TRUE, $datastream_results, TRUE)) + ); } return $cache[$op][$datastream->parent->id][$datastream->id][$user->uid]; @@ -1547,13 +1554,10 @@ function islandora_islandora_basic_collection_get_query_filters() { if ($enforced) { $namespace_array = islandora_get_allowed_namespaces(); $namespace_sparql = implode('|', $namespace_array); - return format_string('regex(str(?object), "info:fedora/(!namespaces):")', array( - '!namespaces' => $namespace_sparql, - )); + return format_string('regex(str(?object), "info:fedora/(!namespaces):")', array('!namespaces' => $namespace_sparql)); } } - /** * Implements hook_islandora_object_ingested(). *