From 080440ce7a8a3f8fdc44b03ba167c2d658474ba6 Mon Sep 17 00:00:00 2001 From: Nigel Banks Date: Thu, 22 Nov 2012 05:50:00 -0400 Subject: [PATCH 01/20] Initial ingest multipage process, also cleanup. --- admin/islandora.admin.inc | 11 - ...landora_dublin_core.inc => DublinCore.inc} | 16 +- includes/{tuque.inc => IslandoraTuque.inc} | 25 +- includes/{mime.detect.inc => MimeDetect.inc} | 0 includes/add_datastream.form.inc | 221 +++++++++ includes/breadcrumb.inc | 37 +- includes/datastream.inc | 462 ++---------------- includes/delete_datastream.form.inc | 63 +++ includes/delete_object.form.inc | 61 +++ includes/globals.inc | 409 ++++++++++++++++ includes/ingest-menu.inc | 47 -- includes/ingest.form.inc | 387 +++++++++++++++ includes/ingest.menu.inc | 62 +++ includes/islandora.ingest.inc | 235 --------- includes/object_properties.form.inc | 116 +++++ includes/object_properties.inc | 125 ----- includes/purge.form.inc | 138 ------ includes/solution_packs.inc | 159 +++--- includes/utilities.inc | 85 +++- islandora.api.php | 12 +- islandora.info | 4 + islandora.install | 7 +- islandora.module | 455 ++++++++--------- theme/islandora-object-edit.tpl.php | 2 +- theme/islandora-object.tpl.php | 22 +- theme/islandora.theme.inc | 7 +- 26 files changed, 1794 insertions(+), 1374 deletions(-) rename includes/{islandora_dublin_core.inc => DublinCore.inc} (94%) rename includes/{tuque.inc => IslandoraTuque.inc} (58%) rename includes/{mime.detect.inc => MimeDetect.inc} (100%) create mode 100644 includes/add_datastream.form.inc create mode 100644 includes/delete_datastream.form.inc create mode 100644 includes/delete_object.form.inc create mode 100644 includes/globals.inc delete mode 100644 includes/ingest-menu.inc create mode 100644 includes/ingest.form.inc create mode 100644 includes/ingest.menu.inc delete mode 100644 includes/islandora.ingest.inc create mode 100644 includes/object_properties.form.inc delete mode 100644 includes/object_properties.inc delete mode 100644 includes/purge.form.inc diff --git a/admin/islandora.admin.inc b/admin/islandora.admin.inc index 46bd06a6..4032c9ac 100644 --- a/admin/islandora.admin.inc +++ b/admin/islandora.admin.inc @@ -11,18 +11,10 @@ * @return array */ function islandora_repository_admin($form, &$form_state) { - module_load_include('inc', 'islandora', 'includes/tuque'); module_load_include('inc', 'islandora', 'includes/utilities'); - // add css drupal_add_css(drupal_get_path('module', 'islandora') . '/css/islandora.admin.css'); - if (!IslandoraTuque::exists()) { - IslandoraTuque::getError(); - return; - } - $form = array(); - if (isset($form_state['values']['islandora_base_url'])) { $url = $form_state['values']['islandora_base_url']; } @@ -30,7 +22,6 @@ function islandora_repository_admin($form, &$form_state) { $url = variable_get('islandora_base_url', 'http://localhost:8080/fedora'); } - module_load_include('inc', 'islandora', 'includes/tuque'); $connection = new IslandoraTuque(NULL, $url); try { $info = $connection->api->a->describeRepository(); @@ -156,7 +147,6 @@ function islandora_repository_admin($form, &$form_state) { function islandora_update_url_div($form, $form_state) { unset($form_state['submit_handlers']); $form_state['rebuild'] = TRUE; - return $form['islandora_tabs']['islandora_general']['wrapper']; } @@ -166,6 +156,5 @@ function islandora_update_url_div($form, $form_state) { function islandora_update_namespace_div($form, $form_state) { unset($form_state['submit_handlers']); $form_state['rebuild'] = TRUE; - return $form['islandora_tabs']['islandora_namespace']['wrapper']; } diff --git a/includes/islandora_dublin_core.inc b/includes/DublinCore.inc similarity index 94% rename from includes/islandora_dublin_core.inc rename to includes/DublinCore.inc index 25580b34..a2baa81f 100644 --- a/includes/islandora_dublin_core.inc +++ b/includes/DublinCore.inc @@ -10,7 +10,7 @@ /** * Dublin Core Class */ -class Dublin_Core { +class DublinCore { public $dc = array( 'dc:title' => array(), @@ -32,11 +32,11 @@ class Dublin_Core { public $owner; /** - * Constructs a Dublin_Core object from a Fedora_Item object and populates - * the $dc array. - * @param $item + * Constructs a DublinCore object from a Fedora_Item object and populates the $dc array. + * + * @param string $dc_xml */ - function Dublin_Core($dc_xml = NULL) { + function DublinCore($dc_xml = NULL) { if (!empty($dc_string)) { $this->dc = self::import_from_xml_string($dc_xml); } @@ -134,14 +134,15 @@ class Dublin_Core { /** * Creates a new instance of the class by parsing dc_xml + * * @param string $dc_xml - * @return Dublin_Core + * @return DublinCore */ static function import_from_xml_string($dc_xml) { $dc_doc = new DomDocument(); if ($dc_doc->loadXML($dc_xml)) { $oai_dc = $dc_doc->getElementsByTagNameNS('http://purl.org/dc/elements/1.1/', '*'); - $new_dc = new Dublin_Core(); + $new_dc = new DublinCore(); foreach ($oai_dc as $child) { array_push($new_dc->dc[$child->nodeName], $child->nodeValue); } @@ -153,4 +154,3 @@ class Dublin_Core { } } - diff --git a/includes/tuque.inc b/includes/IslandoraTuque.inc similarity index 58% rename from includes/tuque.inc rename to includes/IslandoraTuque.inc index 7693a703..22cff732 100644 --- a/includes/tuque.inc +++ b/includes/IslandoraTuque.inc @@ -2,32 +2,10 @@ /** * @file + * * This file contains a class to include the Tuque php library. */ -$islandora_module_path = drupal_get_path('module', 'islandora'); - -//do this until we expost these in a module or library -@include_once 'sites/all/libraries/tuque/Datastream.php'; -@include_once 'sites/all/libraries/tuque/FedoraApi.php'; -@include_once 'sites/all/libraries/tuque/FedoraApiSerializer.php'; -@include_once 'sites/all/libraries/tuque/Object.php'; -@include_once 'sites/all/libraries/tuque/RepositoryConnection.php'; -@include_once 'sites/all/libraries/tuque/Cache.php'; -@include_once 'sites/all/libraries/tuque/RepositoryException.php'; -@include_once 'sites/all/libraries/tuque/Repository.php'; -@include_once 'sites/all/libraries/tuque/FedoraRelationships.php'; - -@include_once "$islandora_module_path/libraries/tuque/Datastream.php"; -@include_once "$islandora_module_path/libraries/tuque/FedoraApi.php"; -@include_once "$islandora_module_path/libraries/tuque/FedoraApiSerializer.php"; -@include_once "$islandora_module_path/libraries/tuque/Object.php"; -@include_once "$islandora_module_path/libraries/tuque/RepositoryConnection.php"; -@include_once "$islandora_module_path/libraries/tuque/Cache.php"; -@include_once "$islandora_module_path/libraries/tuque/RepositoryException.php"; -@include_once "$islandora_module_path/libraries/tuque/Repository.php"; -@include_once "$islandora_module_path/libraries/tuque/FedoraRelationships.php"; - class IslandoraTuque { /** @@ -96,4 +74,3 @@ class IslandoraTuque { drupal_set_message(filter_xss($message), 'error', FALSE); } } - diff --git a/includes/mime.detect.inc b/includes/MimeDetect.inc similarity index 100% rename from includes/mime.detect.inc rename to includes/MimeDetect.inc diff --git a/includes/add_datastream.form.inc b/includes/add_datastream.form.inc new file mode 100644 index 00000000..c9b71e34 --- /dev/null +++ b/includes/add_datastream.form.inc @@ -0,0 +1,221 @@ + "islandora/object/{$object->id}", + '#attributes' => array( + 'enctype' => 'multipart/form-data' + ), + 'fieldset' => array( + '#type' => 'fieldset', + '#title' => 'Add a datastream', + '#collapsible' => FALSE, + '#collapsed' => FALSE, + 'dsid' => array( + '#title' => 'Datastream ID', + '#description' => t('An ID for this stream that is unique to this object.' . + 'Must start with a letter and contain only alphanumeric characters and dashes and underscores.' . + 'Datastreams that are defined by the content model don\'t currently exist: @unused_dsids.', + array('@unused_dsids' => $unused_datastreams) + ), + '#type' => 'textfield', + '#size' => 64, + '#maxlength' => 64, + '#required' => TRUE, + '#element_validate' => array( + 'islandora_add_datastream_form_field_is_not_an_existing_datastream_id', + 'islandora_add_datastream_form_field_starts_with_a_letter', + 'islandora_add_datastream_form_field_is_valid_dsid', + ), + '#autocomplete_path' => "islandora/object/{$object->id}/manage/datastreams/add/autocomplete" + ), + 'label' => array( + '#title' => 'Datastream Label', + '#required' => TRUE, + '#size' => 64, + '#maxlength' => 64, + '#description' => t('A Human readable label'), + '#type' => 'textfield', + '#element_validate' => array('islandora_add_datastream_form_field_does_not_contain_a_forward_slash') + ), + 'file' => array( + '#type' => 'managed_file', + '#required' => TRUE, + '#title' => t('Upload Document'), + '#size' => 48, + '#description' => t('Select a file to upload.
Files must be less than !size MB.', array('!size' => $upload_size)), + '#default_value' => isset($form_state['values']['files']) ? $form_state['values']['files'] : NULL, + '#upload_location' => 'temporary://', + '#upload_validators' => array( + 'file_validate_extensions' => array(NULL), + 'file_validate_size' => array($upload_size * 1024 * 1024), // Assume its specified in MB + ), + ), + 'submit' => array( + '#type' => 'submit', + '#value' => t('Add Datastream') + ), + ) + ); +} + +/** + * Checks if the given form field doesn't already repersent a Datastream ID. + * + * @param array $element + * The form field to check. + * @param array $form_state + * The Drupal form state. + * @param array $form + * The Drupal form. + */ +function islandora_add_datastream_form_field_is_not_an_existing_datastream_id(array $element, array &$form_state, array $form) { + if (isset($form_state['object'][$element['#value']])) { + form_error($element, t("!title already exists in the object.", array('!title' => $element['#title']))); + } +} + +/** + * Checks if the given form field starts with a letter. + * + * @param array $element + * The form field to check. + * @param array $form_state + * The Drupal form state. + * @param array $form + * The Drupal form. + */ +function islandora_add_datastream_form_field_starts_with_a_letter(array $element, array &$form_state, array $form) { + if (!(preg_match("/^[a-zA-Z]/", $element['#value']))) { + form_error($element, t("!title has to start with a letter.", array('!title' => $element['#title']))); + } +} + +/** + * Checks if the given form field contains only valid characters for a datstream id. + * + * @param array $element + * The form field to check. + * @param array $form_state + * The Drupal form state. + * @param array $form + * The Drupal form. + */ +function islandora_add_datastream_form_field_is_valid_dsid(array $element, array &$form_state, array $form) { + module_load_include('inc', 'islandora', 'includes/utilities'); + if (!islandora_is_valid_dsid($element['#value'])) { + form_error($element, t("!title contains invalid characters.", array('!title' => $element['#title']))); + } +} + +/** + * Checks if the given form field contains a "/" character. + * + * @param array $element + * The form field to check. + * @param array $form_state + * The Drupal form state. + * @param array $form + * The Drupal form. + */ +function islandora_add_datastream_form_field_does_not_contain_a_forward_slash(array $element, array &$form_state, array $form) { + if (strpos($element['#value'], '/') !== FALSE) { + form_error($element, t('!title cannot contain a "/" character.', array('!title' => $element['#title']))); + } +} + +/** + * Checks if the given datastream id requires that the upload file be of a certian MIME type. + * + * @param array $form + * The Drupal form. + * @param array $form_state + * The Drupal form state. + */ +function islandora_add_datastream_form_validate(array $form, array &$form_state) { + $file = file_load($form_state['values']['file']); + $dsid = $form_state['values']['dsid']; + if (isset($form_state['datastream_requirements'][$dsid]) && $file) { + $allowed_types = $form_state['datastream_requirements'][$dsid]['mime']; + $mime_detect = new MimeDetect(); + $allowed_extensions = array_map(array($mime_detect, 'getExtension'), $allowed_types); + $errors = file_validate_extensions($file, implode(' ', $allowed_extensions)); + if (count($errors) > 0) { + form_set_error('file', $errors[0]); + } + } +} + +/** + * Adds the new datastream based on the submitted values, only creates managed datastreams at the moment. + * + * @param array $form + * The Drupal form. + * @param array $form_state + * The Drupal form state. + */ +function islandora_add_datastream_form_submit(array $form, array &$form_state) { + $object = $form_state['object']; + $form_state['redirect'] = "islandora/object/{$object->id}"; + $file = file_load($form_state['values']['file']); + try { + $ds = $object->constructDatastream($form_state['values']['dsid'], 'M'); + $ds->label = $form_state['values']['label']; + $ds->mimetype = $file->filemime; + $path = drupal_realpath($file->uri); + $ds->setContentFromFile($path); + $object->ingestDatastream($ds); + file_delete($file); + } catch (exception $e) { + drupal_set_message(t('@message', array('@message' => check_plain($e->getMessage()))), 'error'); + file_delete($file); // Make sure to delete anyways. + return; + } + drupal_set_message(t("Successfully Added Datastream!")); +} + +/** + * Callback for an autocomplete field in the admin add datastream form. It lists the missing required (may be optional) datastreams. + * + * @param FedoraObject $object + * The object used to check for missing required datastreams used to populate the options in this callback. + * @param string $query + * The user query to match against the missing required datastreams. + */ +function islandora_add_datastream_form_autocomplete_callback(FedoraObject $object, $query = '') { + module_load_include('inc', 'islandora', 'includes/content_model'); + $dsids = array_keys(islandora_get_missing_datastreams_requirements($object)); + $dsids = array_combine($dsids, $dsids); + $query = trim($query); + if (!empty($query)) { + $dsids = array_filter($dsids, function($id) use($query) { return stripos($id, $query) !== FALSE; }); + } + drupal_json_output($dsids); +} diff --git a/includes/breadcrumb.inc b/includes/breadcrumb.inc index 5e553277..b7c30c7f 100644 --- a/includes/breadcrumb.inc +++ b/includes/breadcrumb.inc @@ -2,23 +2,31 @@ /** * @file + * * This file contains functions to create breadcrumbs on Islandora object pages. */ /** - * Callback function to get the breadcrumbs for an object page + * Get an array of links to be passed to drupal_set_breadcrumb(). This is used for generating the bread-crumbs for the view object page. + * + * Each link in the bread-crumbs represents a member of the given objects ancestry + * which is identified by any of the following RELS-EXT terms (isMemberOf,isMemberOfCollection,isPartOf). + * + * @param FedoraObject $object + * An object whose ancestry will be mapped to bread-crumbs. + * + * @see drupal_set_breadcrumb() + * + * @return array + * Array of links, starting with most distant ancestor proceeding up to but not including the given object. For use in the function drupal_set_breadcrumb(). */ function islandora_get_breadcrumbs($object) { $breadcrumbs = array(); - islandora_get_breadcrumbs_recursive($object->id, $breadcrumbs, $object->repository); - - if (isset($breadcrumbs[0])) { + if (isset($breadcrumbs[0])) { // Remove the actual object. unset($breadcrumbs[0]); } - $breadcrumbs = array_reverse($breadcrumbs); - return $breadcrumbs; } @@ -27,14 +35,17 @@ function islandora_get_breadcrumbs($object) { * * @todo Make fully recursive... * - * @global type $base_url - * @param type $pid - * @param type $breadcrumbs - * @param type $level + * @todo Could use some clean up, can't be called multiple times safely due to the use of static variables. + * + * @param string $pid + * THe object id whose parent will be fetched for the next link. + * @param array $breadcrumbs + * The list of existing bread-crumb links in reverse order. + * @param FedoraRepository $repository + * The fedora repository. */ -function islandora_get_breadcrumbs_recursive($pid, &$breadcrumbs, $repository) { +function islandora_get_breadcrumbs_recursive($pid, array &$breadcrumbs, FedoraRepository $repository) { // Before executing the query, we hve a base case of accessing the top-level collection - global $base_url; static $max_level = 10; static $level = -1; @@ -81,4 +92,4 @@ function islandora_get_breadcrumbs_recursive($pid, &$breadcrumbs, $repository) { islandora_get_breadcrumbs_recursive($root, $breadcrumbs, $repository); // And render the last two links and break (on the next pass). } } -} \ No newline at end of file +} diff --git a/includes/datastream.inc b/includes/datastream.inc index ba986c12..d1620d5f 100644 --- a/includes/datastream.inc +++ b/includes/datastream.inc @@ -2,454 +2,94 @@ /** * @file + * * This file contains the admin form and callback functions for datastream manipulations. */ -define('DS_COMP_STREAM', 'DS-COMPOSITE-MODEL'); +/** + * Callback to download the given datastream to the users computer. + * + * @param FedoraDatastream $datastream + * The datastream to download. + */ +function islandora_download_datastream(FedoraDatastream $datastream) { + islandora_view_datastream($datastream, TRUE); +} /** * Callback function to view or download a datastream. * - * @global object $user - * @param string $object_id - * @param string $dsid - * @return stream - * prints datastream to browser + * @note + * This function calls exit(). + * + * @param FedoraDatastream $datastream + * The datastream to view/download. + * @param boolean $download + * If TRUE the file is download to the user computer for viewing otherwise it will attempt to display in the browser natively. */ -function islandora_view_datastream($object, $dsid, $method = 'view') { - // if the object exists but the datastream doesn't - if (!isset($object[$dsid])) { - return drupal_not_found(); - } +function islandora_view_datastream(FedoraDatastream $datastream, $download = FALSE) { header_remove('Cache-Control'); header_remove('Expires'); - header('Content-type: ' . $object[$dsid]->mimetype); - if ($object[$dsid]->controlGroup == 'M' || $object[$dsid]->controlGroup == 'X') { - header('Content-length: ' . $object[$dsid]->size); + header('Content-type: ' . $datastream->mimetype); + if ($datastream->controlGroup == 'M' || $datastream->controlGroup == 'X') { + header('Content-length: ' . $datastream->size); } - - if ($method == 'download') { - header("Content-Disposition: attachment; filename=\"" . $object[$dsid]->label); + if ($download) { + header("Content-Disposition: attachment; filename=\"" . $datastream->label); } - - // Disable page caching drupal_page_is_cacheable(FALSE); - - // Try not to load the file into PHP memory + // Try not to load the file into PHP memory! $file = drupal_tempnam(file_directory_temp(), 'islandora'); - $object[$dsid]->getContent($file); + $datastream->getContent($file); readfile($file); drupal_unlink($file); exit(); } /** - * For a given object, return all parent collections. - */ -function islandora_datastream_get_parents($islandora_object) { - $parent_collections = array(); - - try { - $repository = $islandora_object->repository; - $collections1 = $islandora_object->relationships->get(FEDORA_RELS_EXT_URI, 'isMemberOfCollection'); - $collections2 = $islandora_object->relationships->get(FEDORA_RELS_EXT_URI, 'isMemberOf'); - } - catch (RepositoryException $e) { - $collections1 = array(); - $collections2 = array(); - } - $collections = array_merge($collections1, $collections2); - - foreach ($collections as $collection) { - try { - $pid = $collection['object']['value']; - $object = $repository->getObject($collection['object']['value']); - $parent_collections[$pid] = array(); - $parent_collections[$pid]['object'] = $object; - $parent_collections[$pid]['url'] = 'islandora/object/' . $object->id; - $parent_collections[$pid]['label'] = $object->label; - $parent_collections[$pid]['label_link'] = l($parent_collections[$pid]['label'], $parent_collections[$pid]['url']); - } - catch (RepositoryException $e) { - - } - } - - return $parent_collections; -} - -/** + * Get the human readable size of the given datastream. * - * @param array $arr - * an array of dsids that are defined by this objects cmodels - * @param string $ds_comp_stream - * the dscomposite stream as xml - */ -function islandora_get_defined_dsids_array(&$arr, $ds_comp_stream) { - $sxml = new SimpleXMLElement($ds_comp_stream); - foreach ($sxml->dsTypeModel as $ds) { - //$arr[$ds['ID']] - $mimes = array(); - foreach ($ds->form as $form) { - $mimetype = (string) $form['MIME']; - $mimes[] = $mimetype; - } - $dsid = (string) $ds['ID']; - if ($dsid != 'AUDIT') { - $arr[(string) $ds['ID']] = $mimes; - } - } -} - -/** + * @param FedoraDatastream $datastream + * The datastream to check. * - * @global type $user - * @param string $object_id - * @return string|array + * @return string + * A human readable size of the given datastream, or '-' if the size could not be determined. */ -function islandora_get_unused_dsids($object) { - - $defined_dsids = array(); - - if (!$object) { - return $defined_dsids; - } - - $models = $object->models; - if (isset($models)) { - foreach ($models as $model) { - try { - $model_object = $object->repository->getObject($model); - if (isset($model_object[DS_COMP_STREAM])) { - $dscomposite_stream = $model_object[DS_COMP_STREAM]->content; - islandora_get_defined_dsids_array($defined_dsids, $dscomposite_stream); - } - } catch (Exception $e) { - //do nothing as other objects may have a dscompsite stream - } - } - } - foreach ($defined_dsids as $key => $value) { - if (isset($object[$key])) { - unset($defined_dsids[$key]); //ds exists in the object so don't show in the dropdown - } - } - return $defined_dsids; -} - -/** - * buids the default add datastream form - * @param string $object_id - * @param array $form_state - * @return array - * a form ready to be rendered with a call to Drupal render - */ -function islandora_get_add_datastream_form($object, &$form_state) { - $unused_dsids = islandora_get_unused_dsids($object); - $form = array(); - $form['add_fieldset'] = array( - '#type' => 'fieldset', - '#title' => 'Add a datastream', - '#collapsible' => TRUE, - '#collapsed' => TRUE, - ); - $form['add_fieldset']['add_datastream_label'] = array( - '#value' => t('

Add Datastream:

'), - '#weight' => -10, - ); - - $form['pid'] = array( - '#type' => 'hidden', - '#value' => "$object->id" - ); - - $form['add_fieldset']['stream_label'] = array( - '#title' => 'Datastream Label', - '#required' => 'TRUE', - '#description' => t('A Human readable label'), - '#type' => 'textfield' - ); - - $form['#attributes']['enctype'] = 'multipart/form-data'; - $form['add_fieldset']['add-stream-file-location'] = array( - '#type' => 'file', - '#title' => t('Upload Document'), - '#size' => 48, - // '#required'=>'TRUE', - '#description' => t('The file to upload.') - ); - $form['#redirect'] = "islandora/object/$object->id/"; - $form['add_fieldset']['submit'] = array( - '#type' => 'submit', - '#value' => t('Add Datastream') - ); - - if (!empty($unused_dsids)) { - $dsids_for_form = array(); - foreach ($unused_dsids as $key => $value) { - $dsids_for_form[$key] = $key; - } - $form['add_fieldset']['stream_id'] = array( - '#type' => 'select', - '#title' => t('Datastream ID'), - '#default_value' => variable_get('feed_item_length', 'teaser'), - '#weight' => '-1', - '#description' => t('Datastream IDs defined by the content model.'), - ); - $form['add_fieldset']['stream_id']['#options'] = $dsids_for_form; - } - else { - $form['add_fieldset']['stream_id'] = array( - '#title' => 'Datastream ID', - '#required' => 'TRUE', - '#description' => t('An ID for this stream that is unique to this object. Must start with a letter and contain only alphanumeric characters and dashes and underscores.'), - '#type' => 'textfield', - '#weight' => -1, - ); - } - return $form; -} - -/** - * Default implmentation currently only does M (managed datastreams) - * other modules can hook form alter to add other functionality - * @global string $base_url - * @global object $user - * Drupal user - * @param array $form - * @param array $form_state - * @return type - */ -function islandora_add_datastream_form_submit($form, &$form_state) { - global $base_url; - if (!empty($form_state['submit']) && $form_state['submit'] == 'OK') { - $form_state['rebuild'] = TRUE; - return; - } - - module_load_include('inc', 'islandora', 'includes/mime.detect'); - $mimetype = new MimeDetect(); - - $file = $form_state['values']['add-stream-file-location']; - $file = drupal_realpath($file); - - $object_id = $form_state['values']['pid']; - $dsid = $form_state['values']['stream_id']; - $ds_label = $form_state['values']['stream_label']; - $dformat = $mimetype->getMimeType($file); - $control_group = "M"; - - try { - $fedora_object = islandora_object_load($object_id); - $ds = $fedora_object->constructDatastream($dsid, $control_group); - $ds->label = $ds_label; - $ds->mimetype = $dformat; - $ds->setContentFromFile($file); - $fedora_object->ingestDatastream($ds); - $d_file = file_load($form_state['values']['fid']); - file_delete($d_file); - } catch (exception $e) { - drupal_set_message(t('@message', array('@message' => check_plain($e->getMessage()))), 'error'); - return; - } - drupal_set_message(t("Successfully Added Datastream!")); - drupal_goto("islandora/object/$object_id"); +function islandora_datastream_get_human_readable_size(FedoraDatastream $datastream) { + module_load_include('inc', 'islandora', 'includes/utilities'); + $size_is_calculatable = $datastream->controlGroup == 'M' || $datastream->controlGroup == 'X'; + return $size_is_calculatable ? islandora_convert_bytes_to_human_readable($datastream->size) : '-'; } /** - * validates this datastream id against its allowed mimetypes in the dscomposite - * of its content models. - * @param array $form - * @param array $form_state - * @return boolean + * Get either the 'view' or 'download' url for the given datastream if possible. + * + * @param FedoraDatastream $datastream + * The datastream to generated the url to. + * + * @return string + * either the 'view' or 'download' url for the given datastream. */ -function islandora_add_datastream_form_validate($form, &$form_state) { - module_load_include('inc', 'islandora', 'includes/mime.detect'); - $mimetype = new MimeDetect(); - if ($form_state['clicked_button']['#value'] == 'OK') { - $form_state['rebuild'] = TRUE; - return; - } - $dsid = $form_state['values']['stream_id']; - $ds_label = $form_state['values']['stream_label']; - if (drupal_strlen($dsid) > 64) { - form_set_error('', t('Data stream ID cannot be more than 64 characters.')); - return FALSE; - } - if (!(preg_match("/^[a-zA-Z]/", $dsid))) { - form_set_error('', t("Data stream ID (@dsid) has to start with a letter.", array('@dsid' => check_plain($dsid)))); - return FALSE; - } - if (drupal_strlen($ds_label) > 64) { - form_set_error('', t('Data stream Label cannot be more than 64 characters.')); - return FALSE; - } - if (strpos($ds_label, '/')) { - form_set_error('', t('Data stream Label cannot contain a "/".')); - return FALSE; - } - - $object_id = $form_state['values']['pid']; - $fedora_object = islandora_object_load($object_id); - - if (isset($fedora_object[$dsid])) { - form_set_error('', t('Data stream ID already exists in object.')); - return FALSE; - } - - $mimetype = new MimeDetect(); - $object = islandora_object_load($form_state['values']['pid']); - $unused_dsids = islandora_get_unused_dsids($object); - if (isset($unused_dsids[$dsid])) { - $types_allowed = $unused_dsids[$dsid]; - $arr = array(); - foreach ($types_allowed as $type) { - $arr[] = $mimetype->getExtension($type); - } - } - else { - // @TODO: this is unsafe, should probably be fixed see: - // http://api.drupal.org/api/drupal/includes!file.inc/function/file_save_upload/7 - $arr = array(); - } - - - $file = file_save_upload('add-stream-file-location', array('file_validate_extensions' => $arr)); - if ($file) { - $form_state['values']['add-stream-file-location'] = $file->uri; - $form_state['values']['fid'] = $file->fid; //so we can load it to delete later - } - else { - form_set_error('add-stream-file-location', t('There was no file uploaded')); - } +function islandora_datastream_get_url(FedoraDatastream $datastream, $type = 'download') { + return $datastream->controlGroup == 'R' ? $datastream->url : "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/$type"; } - /** - * buids the default add datastream form - * @param string $object_id - * @param array $form_state - * @return array - * a form ready to be rendered with a call to Drupal render + * Gets the delete link. + * + * @param FedoraDatastream $datastream + * The datastream to generated the url to. */ -function islandora_add_datastream_form($form, &$form_state, $object) { - // Ensure we're loaded, in case AJAX stuff is ever added. - form_load_include($form_state, 'inc', 'islandora', 'includes/datastream'); - - $unused_dsids = islandora_get_unused_dsids($object); //$defined_dsids; - $form = array(); - $form['add_fieldset'] = array( - '#type' => 'fieldset', - '#title' => 'Add a datastream', - '#collapsible' => FALSE, - '#collapsed' => FALSE, - ); - $form['add_fieldset']['add_datastream_label'] = array( - '#value' => t('

Add Datastream:

'), - '#weight' => -10, - ); - - $form['pid'] = array( - '#type' => 'hidden', - '#value' => "$object->id" - ); - - $form['add_fieldset']['stream_label'] = array( - '#title' => 'Datastream Label', - '#required' => 'TRUE', - '#description' => t('A Human readable label'), - '#type' => 'textfield' - ); - - $form['#attributes']['enctype'] = 'multipart/form-data'; - $form['add_fieldset']['add-stream-file-location'] = array( - '#type' => 'file', - '#title' => t('Upload Document'), - '#size' => 48, - // '#required'=>'TRUE', - '#description' => t('The file to upload.') - ); - $form['#redirect'] = "islandora/object/$object->id/"; - $form['add_fieldset']['submit'] = array( - '#type' => 'submit', - '#value' => t('Add Datastream') - ); - - $unused_dsids = islandora_get_unused_dsids($object); - $dsids_for_form = ''; - $i = 0; - foreach ($unused_dsids as $key => $value) { - if ($i++) { - $dsids_for_form .= ", "; - } - $dsids_for_form .= "'$key'"; - } - - $form['add_fieldset']['stream_id'] = array( - '#title' => 'Datastream ID', - '#required' => 'TRUE', - '#description' => t('An ID for this stream that is unique to this object. Must start with a letter and contain only alphanumeric characters and dashes and underscores. Datastreams that are defined by the content model don\'t currently exist: @unused_dsids.', array( - '@unused_dsids' => $dsids_for_form, - )), - '#type' => 'textfield', - '#weight' => -1, - '#autocomplete_path' => "islandora/object/$object->id/manage/datastreams/add/autocomplete", - ); - return $form; -} - -function islandora_datastream_autocomplete_callback($object, $string = '') { - $dsids = islandora_get_unused_dsids($object); - $output = array(); - foreach ($dsids as $id => $ds) { - if (trim($string) == '') { - $output[$id] = $id; - } - else { - $ret = stripos($id, $string); - if ($ret !== FALSE) { - $output[$id] = $id; - } - } - } - drupal_json_output($output); -} - -function islandora_datastream_get_human_readable_size($ds) { - module_load_include('inc', 'islandora', 'includes/utilities'); - - // we return - if we don't have a size - if ($ds->controlGroup == 'M' || $ds->controlGroup == 'X') { - return islandora_convert_bytes_to_human_readable($ds->size); - } - else { - return '-'; - } -} - -function islandora_datastream_get_url($ds, $type = 'download') { - if ($ds->controlGroup == 'R') { - return $ds->url; - } - else { - return "islandora/object/{$ds->parent->id}/datastream/{$ds->id}/$type"; - } -} - -function islandora_datastream_get_delete_link($ds) { - $datastreams = module_invoke_all('islandora_undeletable_datastreams', $ds->parent->models); - - if (in_array($ds->id, $datastreams)) { +function islandora_datastream_get_delete_link(FedoraDatastream $datastream) { + $datastreams = module_invoke_all('islandora_undeletable_datastreams', $datastream->parent->models); + if (in_array($datastream->id, $datastreams)) { return ''; } else { - return l(t('delete'), 'islandora/object/' . $ds->parent->id . '/datastream/' . $ds->id . '/delete'); + return l(t('delete'), 'islandora/object/' . $datastream->parent->id . '/datastream/' . $datastream->id . '/delete'); } } -function islandora_islandora_undeletable_datastreams($models) { - return array('DC'); -} function islandora_datastream_edit_get_link($object, $ds_id) { $edit_registry = module_invoke_all('islandora_edit_datastream_registry', $object, $ds_id); diff --git a/includes/delete_datastream.form.inc b/includes/delete_datastream.form.inc new file mode 100644 index 00000000..0bdeb9d5 --- /dev/null +++ b/includes/delete_datastream.form.inc @@ -0,0 +1,63 @@ + $datastream->id)), + "islandora/object/{$datastream->parent->id}", + t('This action cannot be undone.'), + t('Delete'), + t('Cancel') + ); +} + +/** + * Submit handler for the delete datastream form. Purges/Delete's the given FedoraDatastream if possible. + * + * The ISLANDORA_PRE_PURGE_DATASTREAM_HOOK will query other modules as to whether the given FedoraDatastream + * should be: blocked from purging; state set to 'Deleted'; or purged. + * + * @see islanodra_delete_datastream(). + * + * @param string $object_id + * ID of the object + * @param string $datastream_id + * ID of the datastream + */ +function islandora_delete_datastream_form_submit(array $form, array &$form_state) { + $datastream = $form_state['datastream']; + $datastream_id = $datastream->id; + $object = $datastream->parent; + $deleted = FALSE; + try { + $deleted = islandora_delete_datastream($datastream); + } catch (Exception $e) { + drupal_set_message(t('Error deleting %s datastream from object %o %e', array('%s' => $datastream_id, '%o' => $object->label, '%e' => $e->getMessage())), 'error'); + } + if ($deleted) { + drupal_set_message(t('%d datastream sucessfully deleted from Islandora object %o', array('%d' => $datastream_id, '%o' => $object->label))); + } + else { + drupal_set_message(t('Error deleting %s datastream from object %o', array('%s' => $datastream_id, '%o' => $object->label)), 'error'); + } + $form_state['redirect'] = "islandora/object/{$object->id}"; +} diff --git a/includes/delete_object.form.inc b/includes/delete_object.form.inc new file mode 100644 index 00000000..a86b948d --- /dev/null +++ b/includes/delete_object.form.inc @@ -0,0 +1,61 @@ + $object->label)), + "islandora/object/$object->id", + t('This action cannot be undone.'), + t('Delete'), + t('Cancel') + ); +} + +/** + * Gives the option of deleting or purging and object. + * + * @note The description below probably applies to islanodra_object_purge() function... + * + * The default behaviour is to purge the object to reduce maintenance. + * If a solution pack wants to change this behaviour and have the object set to deleted then + * it can respond to the 'islandora_pre_purge_object' hook with an array containing the pair + * 'delete' => TRUE. + * Once the object has been deleted/purged then a second call lets the solution packs know that + * the object has been dealt with. In this call the object id and content models are sent out so + * that the solution packs can act on this news. There is no guarantee that the object still exists + * and so the object object isn't sent. + * + * @todo Clean Up! + * + * @param array $form + * The Drupal form. + * @param array $form_state + * The Drupal form state. + */ +function islandora_delete_object_form_submit(array $form, array &$form_state) { + module_load_include('inc', 'islandora', 'includes/datastream'); + $object = $form_state['object']; + $parents = islandora_get_parents_from_rels_ext($object); + $parent = array_pop($parents); + $form_state['redirect'] = isset($parent) ? "islandora/object/{$parent->id}" : 'islandora'; + islandora_delete_object($object); +} diff --git a/includes/globals.inc b/includes/globals.inc new file mode 100644 index 00000000..e389d87a --- /dev/null +++ b/includes/globals.inc @@ -0,0 +1,409 @@ + $e)), 'error'); + } + } + return $tuque; +} + +/** + * Gets the given object if found, NULL if it is inaccessible and FALSE if it was not found. + * + * @param string $object_id + * The identifier of the object to get. + * + * @return FedoraObject + * The object if found, NULL if it is inaccessible and FALSE if it was not found. + */ +function islandora_get_object_by_id($object_id) { + $tuque = islandora_get_tuque_connection(); + if ($tuque) { + try { + $object = $tuque->repository->getObject($object_id); + drupal_alter('islandora_object', $object); + return $object; + } catch (Exception $e) { + if ($e->getCode() == '404') { + return FALSE; + } else { + return NULL; + } + } + } + else { + IslandoraTuque::getError(); + } + return NULL; // Assuming access denied in all other cases for now. +} + +/** + * Ingest the given object into Fedora calling its pre/post hooks as well. + * + * @param NewFedoraObject $object + * An ingestable FedoraObject. + * + * @return FedoraObject + * The ingested FedoraObject, after running the pre/post ingest hooks. + */ +function islandora_add_object(NewFedoraObject &$object) { + islandora_pre_add_object($object); + $object->repository->ingestObject($object); + islandora_post_add_object($object); + return $object; +} + +/** + * Calls the ISLANDORA_PRE_INGEST_HOOK hooks. + * + * @param NewFedoraObject $object + * An ingestable FedoraObject. + */ +function islandora_pre_add_object(NewFedoraObject $object) { + module_load_include('inc', 'islandora', 'includes/utilities'); + foreach (islandora_build_hook_list(ISLANDORA_PRE_INGEST_HOOK, $object->models) as $hook) { + module_invoke_all($hook, $object); + } +} + +/** + * Calls the ISLANDORA_POST_INGEST_HOOK hooks. + * + * @param FedoraObject $object + * A recently ingestable FedoraObject. + */ +function islandora_post_add_object(FedoraObject $object) { + foreach (islandora_build_hook_list(ISLANDORA_POST_INGEST_HOOK, $object->models) as $hook) { + module_invoke_all($hook, $object); + } +} + +/** + * Deletes the given object into Fedora calling its pre/post hooks as well. + * + * @param FedoraObject $object + * An object to delete. + * + * @return FedoraObject + * The ingested FedoraObject, after running the pre/post ingest hooks. + */ +function islandora_delete_object(FedoraObject &$object) { + $object_id = $object->id; + $models = $object->models; + $action = islandora_pre_delete_object($object); + switch ($action) { + case 'blocked': // Do nothing. + return FALSE; + case 'delete': // Change the state to deleted. + $object->delete(); + islandora_post_delete_object($object, $object_id, $models); + return TRUE; + default: // Purge + $object->repository->purgeObject($object_id); + islandora_post_delete_object($object_id, $models); + $object = NULL; + return TRUE; + } + islandora_post_delete_object($object); + return $object; +} + +/** + * Calls the ISLANDORA_PRE_PURGE_OBJECT_HOOK hooks. + * + * @param FedoraObject $object + * The object that is about to be deleted. + */ +function islandora_pre_delete_object(FedoraObject $object) { + module_load_include('inc', 'islandora', 'includes/utilities'); + $results = array(); + foreach (islandora_build_hook_list(ISLANDORA_PRE_PURGE_OBJECT_HOOK, $object->models) as $hook) { + $results = array_merge_recursive($results, module_invoke_all($hook, $object)); + } + $action = (isset($results['block']) && $results['block']) ? 'block' : FALSE; + $action = (!$action && isset($results['delete']) && $results['delete']) ? 'delete' : $action; + $action = !$action ? 'purge' : $action; + return $action; +} + +/** + * Calls the ISLANDORA_POST_INGEST_HOOK hooks. + * + * @param string $object_id + * The object id of an the recently deleted object. + * @param array $models + * The list of content models the delete object subsribed to. + */ +function islandora_post_delete_object($object_id, array $models) { + module_load_include('inc', 'islandora', 'includes/utilities'); + foreach (islandora_build_hook_list(ISLANDORA_POST_PURGE_OBJECT_HOOK, $models) as $hook) { + module_invoke_all($hook, $object_id, $models); + } +} + +/** + * Delete's/Purges the given datastream. + * + * @throws Exception + * Which types are undefined, but more than likely because of the hooks there will be several kinds. + * + * @param FedoraDatastream $datastream + * The datastream to delete. + * + * @return boolean + * TRUE is returned if the datastream was Deleted/Purged, FALSE if it was blocked. + */ +function islandora_delete_datastream(FedoraDatastream &$datastream) { + $datastream_id = $datastream->id; + $object = $datastream->parent; + $action = islandora_pre_delete_datastream($datastream); + switch ($action) { + case 'blocked': // Do nothing. + return FALSE; + case 'delete': // Change the state to deleted. + $object[$datastream_id]->state = 'D'; + islandora_post_delete_datastream($object, $datastream_id); // @todo Differentiate between delete/purge in the hooks. + return TRUE; + default: // Purge + $object->purgeDatastream($datastream_id); + islandora_post_delete_datastream($object, $datastream_id); + $datastream = NULL; + return TRUE; + } +} + +/** + * The default behaviour is to 'purge' the datastream but this can be overridden by modules that implement + * the 'islandora_pre_purge_datastream' hook. + * + * @todo make this an alter. + * + * The returned array can include a 'block' => TRUE + * pair which will prevent the datastream from being deleted if it particularly needed for + * a certain function. Returning 'delete' => TRUE will cause the datastream to be put into + * a deleted state. + * + * @param FedoraDatastream $datastream + * The datastream to delete. + * + * @return string + * The action to take when deleting the given datastream, either 'purge', 'delete', or 'block'. + */ +function islandora_pre_delete_datastream(FedoraDatastream $datastream) { + module_load_include('inc', 'islandora', 'includes/utilities'); + $results = array(); + foreach (islandora_build_hook_list(ISLANDORA_PRE_PURGE_DATASTREAM_HOOK, $datastream->parent->models) as $hook) { + $results = array_merge_recursive($results, module_invoke_all($hook, $datastream)); // @note Not sure this will work the greatest, probably an alter would be better... + } + $action = (isset($results['block']) && $results['block']) ? 'block' : FALSE; + $action = (!$action && isset($results['delete']) && $results['delete']) ? 'delete' : $action; + $action = !$action ? 'purge' : $action; + return $action; +} + +/** + * Calls the post purge datastream hooks. + * + * @todo Should differentiate between purging/deleting. + * + * @param FedoraObject $object + * The parent object of the deleted datastream. + * @param string $datastream_id + * The datastream id of the deleted datastream. + */ +function islandora_post_delete_datastream(FedoraObject $object, $datastream_id) { + module_load_include('inc', 'islandora', 'includes/utilities'); + foreach (islandora_build_hook_list(ISLANDORA_POST_PURGE_DATASTREAM_HOOK, $object->models) as $hook) { + module_invoke_all($hook, $object, $datastream_id); + } +} + +/** + * Gets any objects that the given object has a (isMemberOf, isMemberOfCollection) relationship with. + * + * This function gets its info from the RELS-EXT directly rather than through an risearch. + * + * @param FedoraObject $object + * The object whose parents will be returned. + * + * @return array + * An array of FedoraObject's that the given object has a (isMemberOf, isMemberOfCollection) relationship with. + */ +function islandora_get_parents_from_rels_ext(FedoraObject $object) { + try { + $collections = array_merge( + $object->relationships->get(FEDORA_RELS_EXT_URI, 'isMemberOfCollection'), + $object->relationships->get(FEDORA_RELS_EXT_URI, 'isMemberOf')); + } + catch (RepositoryException $e) { + return array(); + } // @todo some logging would be nice, not sure what this throws. + $collections = array_map(function($o) { return islandora_get_object_by_id($o['object']['value']); }, $collections); + return array_filter($collections); +} + +/** + * Checks what datastreams the object already has against its required datastreams as defined by its content models, and returns their intersection. + * + * @param FedoraObject $object + * The object which models will be used to determine what datastreams it should have. + * + * @return array + * The DS-COMPOSITE-MODEL defined datastreams that are required for the given object, but not already present. + */ +function islandora_get_missing_datastreams_requirements(FedoraObject $object) { + $datastreams = islandora_get_datastreams_requirements($object); + foreach ($datastreams as $dsid => $requirements) { + if (isset($object[$dsid])) { + unset($datastreams[$dsid]); + } + } + return $datastreams; +} + +/** + * Checks the object's content model's for which datastream are expected to be used with this object, as defined by the DS-COMPOSITE-MODEL datastreams. + * + * For duplicate datastreams in the models, the first model defines the datastreams attributes regardless of what other models define. + * This should be undefined behavior according to the documentation. + * @see https://wiki.duraspace.org/display/FEDORA34/Fedora+Digital+Object+Model#FedoraDigitalObjectModel-ContentModelObjectCMODEL + * + * @param FedoraObject $object + * The object which models will be used to determine what datastreams it should have. + * + * @see islandora_get_required_datastreams_from_content_model() from more details on the return value. + * + * @return array + * The DS-COMPOSITE-MODEL defined datastreams that are required for the given object. + */ +function islandora_get_datastreams_requirements(FedoraObject $object) { + $dsids = array(); + foreach ($object->models as $model) { + $model = islandora_get_object_by_id($model); + $dsids += islandora_get_datastreams_requirements_from_content_model($model); + } + unset($dsids['AUDIT']); // The AUDIT Datastream can not really be added, so it can't really be missing. + return $dsids; +} + +/** + * Checks the given content model for which datastreams are required for subscribing objects, as defined by it's DS-COMPOSITE-MODEL datastream. + * + * @todo Add support for fetching the schema information. + * + * @param FedoraObject $object + * The content model whose DS-COMPOSITE-MODEL datastream will be used to determine what datastreams are required. + * + * @return array + * The DS-COMPOSITE-MODEL defined datastreams that are required for the given object. + * + * @code + * array( + * 'DC' => array( + * 'id' => 'DC', + * 'mime' => 'text/xml', + * 'optional' => FALSE, + * ) + * ) + * @endcode + */ +function islandora_get_datastreams_requirements_from_content_model(FedoraObject $object) { + if (empty($object[DS_COMP_STREAM])) { + return array(); + } + $xml = new SimpleXMLElement($object[DS_COMP_STREAM]->content); + foreach ($xml->dsTypeModel as $ds) { + $dsid = (string) $ds['ID']; + $optional = strtolower((string) $ds['optional']); + $mime = array(); + foreach ($ds->form as $form) { + $mime[] = (string) $form['MIME']; + } + $dsids[$dsid] = array( + 'id' => $dsid, + 'mime' => $mime, + 'optional' => ($optional == 'true') ? TRUE : FALSE + ); + } + return $dsids; +} + + +/** + * Prepare an ingestable object. + * + * @param string $namespace + * The namespace in which the PID for the new object will be created. + * @param string $label + * An optional label to apply to the object. + * @param array $datastreams + * A array of datastreams to add, where each datastream definition is an + * associative array containing: + * - dsid: The datastream ID. + * - label: An optional label for the datastream. + * - mimetype: A MIMEtype for the datastream; defaults to text/xml. + * - control_group: One of X, M, R and E; defaults to M. + * - datastream_file: A web-accessible path, for which we try to get an + * absolute path using url(). + * @param array $content_models + * An array of content model PIDs to which the new object should subscribe. + * @param array $relationships + * An array of relationships, where each relationship is an associative array + * containing: + * - relationship: The predicate for the relationship, from the Fedora + * RELS-EXT namespace. + * - pid: The object for the relationship, to which we are creating the + * relationhsip. + * + * @return NewFedoraObject + * An ingestable NewFedoraObject. + */ +function islandora_prepare_new_object($namespace = NULL, $label = NULL, $datastreams = array(), $content_models = array(), $relationships = array()) { + $tuque = islandora_get_tuque_connection(); + $object = isset($namespace) ? $tuque->repository->constructObject($namespace) : new NewFedoraObject(NULL, $tuque->repository); + $object->owner = isset($user->name) ? $user->name : $object->owner; + $object->label = isset($label) ? $label : $object->label; + foreach ($content_models as $content_model) { + $object->relationships->add(FEDORA_MODEL_URI, 'hasModel', $content_model); + } + foreach ($relationships as $relationship) { + $object->relationships->add(FEDORA_RELS_EXT_URI, $relationship['relationship'], $relationship['pid']); + } + foreach ($datastreams as $ds) { + $dsid = $ds['dsid']; + $label = isset($ds['label']) ? $ds['label'] : ''; + $mimetype = isset($ds['mimetype']) ? $ds['mimetype'] : 'text/xml'; + $control_group = (isset($ds['control_group']) && in_array($ds['control_group'], array('X', 'M', 'R', 'E'))) ? $ds['control_group'] : 'M'; // Default 'Managed' + $datastream_file = url($ds['datastream_file'], array('absolute' => TRUE)); + $datastream = $object->constructDatastream($dsid, $control_group); + $datastream->label = $label; + $datastream->mimetype = $mimetype; + switch ($control_group) { + case 'M': + $datastream->setContentFromUrl($datastream_file); + break; + case 'X': + $datastream->setContentFromString(file_get_contents($datastream_file)); + break; + } + $object->ingestDatastream($datastream); + } + return $object; +} diff --git a/includes/ingest-menu.inc b/includes/ingest-menu.inc deleted file mode 100644 index 5e7d9436..00000000 --- a/includes/ingest-menu.inc +++ /dev/null @@ -1,47 +0,0 @@ -label))); - drupal_goto('islandora/object/' . $collection_object->id); - } - elseif ($registry_count == 1) { - // One registry implementation, go there - drupal_goto($ingest_registry[0]['url']); - } - else { - // Multiple ingest routes registered - return islandora_ingest_registry_render($ingest_registry); - } -} - -// @TODO: theme -function islandora_ingest_registry_render($ingest_registry) { - $output = array( - '#type' => 'markup', - '#markup' => '', - ); - foreach ($ingest_registry AS $ingest_route) { - $output['#markup'] .= l($ingest_route['name'], $ingest_route['url']) . '
'; - } - return $output; -} \ No newline at end of file diff --git a/includes/ingest.form.inc b/includes/ingest.form.inc new file mode 100644 index 00000000..d57c3c15 --- /dev/null +++ b/includes/ingest.form.inc @@ -0,0 +1,387 @@ + 'isMemberOfCollection', 'pid' => $o); }; + $relationships = empty($configuration['collections']) ? array() : array_map($relationship_map, $configuration['collections']); + $object = islandora_prepare_new_object($namespace, $label, array(), array(), $relationships); + $form_state['islandora'] = array( + 'step' => 0, + 'steps' => islandora_ingest_get_steps($configuration), + 'objects' => array($object), + 'configuration' => $configuration + ); + } +} + +/** + * Executes the current step, building the form definition and appending on any additonal elements + * required for the step to function. + * + * @param array $form + * The drupal form. + * @param array $form_state + * The drupal form state. + * + * @return array + * The form definition of the current step. + */ +function islandora_ingest_form_execute_step(array $form, array &$form_state) { + $step_info = islandora_ingest_form_get_step_info($form_state); + switch ($step_info['type']) { + case 'form': + $args = array($form, &$form_state); + $args = isset($step_info['args']) ? array_merge($args, $step_info['args']) : $args; + $form = call_user_func_array($step_info['form_id'], $args); + return islandora_ingest_form_stepify($form, $form_state, $step_info); + case 'batch': // @todo Implement if possible. + break; + } + return array(); +} + +/** + * Append Prev/Next buttons submit/validation handlers etc. + * + * @param array $form + * The drupal form. + * @param array $form_state + * The drupal form state. + * @param array $step_info + * The info for building the current form step. + * + * @return array + * The stepified drupal form definition for the given step. + */ +function islandora_ingest_form_stepify(array $form, array &$form_state, array $step_info) { + $step = islandora_ingest_form_get_step($form_state); + $first_step = $step > 0; + $last_step = $step == (islandora_ingest_form_get_step_count($form_state) - 1); + $form['prev'] = $first_step ? islandora_ingest_form_previous_button() : NULL; + $form['next'] = $last_step ? islandora_ingest_form_ingest_button($step_info) : islandora_ingest_form_next_button($step_info); + return $form; +} + +/** + * Defines the previous button for the ingest form. + * + * @return array + * The previous button for the ingest form. + */ +function islandora_ingest_form_previous_button() { + return array( + '#type' => 'submit', + '#value' => t('Previous'), + '#name' => 'prev', + '#submit' => array('islandora_ingest_form_previous_submit'), + /** + * #limit_validation_errors, is why when the previous button is pressed no values persisted in the form_state, but its also what allows us to go back when validation errors occur. + * To have a better solution going forward we can either limit validation only on required fields, or we can convert all required fields to use #element_validation functions, and + * Remove the need for #limit_validation_errors. Or maybe there is some other solution, regardless of what it is, it won't be standard. + */ + '#limit_validation_errors' => array() + ); +} + +/** + * The submit handler for the ingest form previous button. + * + * Stores the current form steps values in the form storage. + * Moves the focus of the multi-page ingest form back one step. + * Restores the form values for the previous step. + * + * @param array $form + * The drupal form. + * @param array $form_state + * The drupal form state. + */ +function islandora_ingest_form_previous_submit(array $form, array &$form_state) { + $step = &islandora_ingest_form_get_step($form_state); + $step_info = &islandora_ingest_form_get_step_info($form_state, $step); + $step_info['values'] = $form_state['values']; // Store values + $step--; // Goto previous step + $step_info = &islandora_ingest_form_get_step_info($form_state, $step); // Get values + $form_state['values'] = isset($step_info['values']) ? $step_info['values'] : NULL; // Use values + $form_state['rebuild'] = TRUE; +} + +/** + * Defines the next button for the ingest form. + * + * Adds submit/validate handlers for the form step if they exist. + * + * @return array + * The next button for the ingest form. + */ +function islandora_ingest_form_next_button(array $step_info) { + $form_id = $step_info['form_id']; + $validate_callback = $form_id . '_validate'; + $validate = function_exists($validate_callback) ? array($validate_callback) : NULL; + $submit_callback = $form_id . '_submit'; + $submit = function_exists($submit_callback) ? array($submit_callback, 'islandora_ingest_form_next_submit') : array('islandora_ingest_form_next_submit'); + return array( + '#type' => 'submit', + '#value' => t('Next'), + '#name' => 'next', + '#validate' => $validate, + '#submit' => $submit + ); +} + +/** + * The submit handler for the ingest form next button. + * + * Stores the current form steps values in the form storage. + * Moves the focus of the multi-page ingest form forward one step. + * Restores the form values for the next step if present. + * + * @param array $form + * The drupal form. + * @param array $form_state + * The drupal form state. + */ +function islandora_ingest_form_next_submit(array $form, array &$form_state) { + $step = &islandora_ingest_form_get_step($form_state); + $step_info = &islandora_ingest_form_get_step_info($form_state, $step); + $step_info['values'] = $form_state['values']; // Store Values + $step++; // Goto Next Step + $step_info = &islandora_ingest_form_get_step_info($form_state, $step); + $form_state['values'] = isset($step_info['values']) ? $step_info['values'] : array(); // Restore Values if Stored. + $form_state['rebuild'] = TRUE; +} + +/** + * Defines the ingest button for the ingest form. + * + * This button is only shown on the last page of the multi-page ingest form. + * + * @return array + * The ingest button for the ingest form. + */ +function islandora_ingest_form_ingest_button(array $step_info) { + $form_id = $step_info['form_id']; + $validate_callback = $form_id . '_validate'; + $validate = function_exists($validate_callback) ? array($validate_callback) : NULL; + $submit_callback = $form_id . '_submit'; + $submit = function_exists($submit_callback) ? array($submit_callback, 'islandora_ingest_form_submit') : array('islandora_ingest_form_submit'); + return array( + '#type' => 'submit', + '#name' => 'ingest', + '#value' => t('Ingest'), + '#validate' => $validate, + '#submit' => $submit + ); +} + +/** + * The submit handler for the ingest form. + * + * Attempts to ingest every object built by the previous steps. + * + * @param array $form + * The drupal form. + * @param array $form_state + * The drupal form state. + */ +function islandora_ingest_form_submit(array $form, array &$form_state) { + foreach ($form_state['islandora']['objects'] as $object) { + try { + islandora_add_object($object); + } catch (Exception $e) { + watchdog('islandora', $e->getMessage(), NULL, WATCHDOG_ERROR); // If post hooks throws it may already exist at this point but may be invalid, so don't say failed :P + drupal_set_message(t('A problems occured while ingesting "@label" (ID: @pid), please notifiy the administrator.', array('@label' => $object->label, '@pid' => $object->id)), 'error'); + } + } +} + +/** + * Gets the configuration. + * + * @param array $form_state + * The drupal form state. + * + * @return int + * The current step index. + */ +function islandora_ingest_form_get_configuration(array $form_state) { + return $form_state['islandora']['configuration']; +} + +/** + * Gets the stored objects. + * + * @param array $form_state + * The drupal form state. + * + * @return int + * The current step index. + */ +function &islandora_ingest_form_get_objects(array $form_state) { + return $form_state['islandora']['objects']; +} + +/** + * Gets a single object. + * + * @param array $form_state + * The drupal form state. + * + * @return int + * The current step index. + */ +function islandora_ingest_form_get_object(array $form_state) { + $objects = &islandora_ingest_form_get_objects($form_state); + return current($objects); +} + +/** + * Get a reference to the current step index. + * + * @param array $form_state + * The drupal form state. + * + * @return int + * The current step index. + */ +function &islandora_ingest_form_get_step(array &$form_state) { + return $form_state['islandora']['step']; +} + +/** + * Get a reference to the step info of the given step or the current step if none is given. + * + * @param array $form_state + * The drupal form state. + * @param int $step + * The index of the step to get. + * + * @return integer + * The step info of the requested step if found, NULL otherwise. + */ +function &islandora_ingest_form_get_step_info(array &$form_state, $step = NULL) { + $step = isset($step) ? $step : islandora_ingest_form_get_step($form_state); + $steps = &islandora_ingest_form_get_steps($form_state); + if (!empty($steps[$step])) { + return $steps[$step]; + } + return NULL; // @todo deal with unknown case. +} + +/** + * Get a reference to the steps stored in the form state. + * + * @param array $form_state + * The drupal form state. + * + * @return array + * All the steps to be used in the ingest process. + */ +function &islandora_ingest_form_get_steps(array &$form_state) { + return $form_state['islandora']['steps']; +} + +/** + * Call form_load_include, for the current step if it defines a required file. + * + * @param array $form_state + * The drupal form state. + */ +function islandora_ingest_form_step_form_load_include(array &$form_state) { + form_load_include($form_state, 'inc', 'islandora', 'includes/ingest.form'); // Always load this file. + $step_info = islandora_ingest_form_get_step_info($form_state); + if (isset($step_info['file']) && isset($step_info['module'])) { + $matches = array(); + preg_match('/^(.*)\.(.*)$/', $step_info['file'], $matches); + list($file, $name, $type) = $matches; + form_load_include($form_state, $type, $step_info['module'], $name); // Load include files. + } +} + +/** + * Get the number of steps. + * + * @param array $form_state + * The drupal form state. + * + * @return int + * The number of steps. + */ +function islandora_ingest_form_get_step_count(array $form_state) { + $steps = islandora_ingest_form_get_steps($form_state); + return count($steps); +} + +/** + * Buildes the initial list of ingest steps. Sorted by weight expected range between -50 to 50. + * + * The sort order is undefined for steps which have the same weight. + * + * @param array $configuration + * The configuration options used to build the multi-paged ingest process. + * + * @return array + * The initial list of sorted ingest steps as defined by all implementers of ISLANDORA_INGEST_STEP_HOOK. + */ +function islandora_ingest_get_steps(array $configuration) { + module_load_include('inc', 'islandora', 'includes/utilities'); + $steps = array(); + $models = isset($configuration['models']) ? $configuration['models'] : array(); + foreach (islandora_build_hook_list(ISLANDORA_INGEST_STEP_HOOK, $models) as $hook) { + $steps = array_merge($steps, module_invoke_all($hook, $configuration)); + } + usort($steps, 'drupal_sort_weight'); + return $steps; +} diff --git a/includes/ingest.menu.inc b/includes/ingest.menu.inc new file mode 100644 index 00000000..cb61b906 --- /dev/null +++ b/includes/ingest.menu.inc @@ -0,0 +1,62 @@ +'; + drupal_goto($redirect); + } + module_load_include('inc', 'islandora', 'includes/ingest.form'); + return drupal_get_form('islandora_ingest_form', $configuration); +} + +/** + * Fetches/validates the ingest configuration from the $_GET parameters. + * + * Generic parameters as accepted by all ingest processes, other modules may add to this list. + * id -> The pid of the object to create. optional. + * models -> Comma delimited list of all the content models the created object should have. + * collections -> Comma delimited list of all the collections the created object should belong to. + * + * @return array + * The configuration options used to build the multi-paged ingest process. + */ +function islandora_ingest_get_configuration() { + $configuration = $_GET; + unset($configuration['q']); + $convert_to_array_keys = array_intersect(array('models', 'collections'), array_keys($configuration)); + foreach ($convert_to_array_keys as $key) { + $configuration[$key] = explode(',', $configuration[$key]); + } + // @todo add hook for manipulating/validating the configuration. + return islandora_valid_ingest_configuration($configuration) ? $configuration : FALSE; +} + +/** + * Validates the given ingest configuration. + * + * At the moment it requires that models and collections are present. + * + * @param array $configuration + * The key value pairs that are used to build the multi-paged ingest process. + * + * @return boolean + * TRUE if the configuration is valid, FALSE otherwise. + */ +function islandora_valid_ingest_configuration(array $configuration) { + // @todo Add more robust validation, add watchdog logs, etc. + return isset($configuration['models']) && isset($configuration['collections']); +} diff --git a/includes/islandora.ingest.inc b/includes/islandora.ingest.inc deleted file mode 100644 index 9aa4f4f7..00000000 --- a/includes/islandora.ingest.inc +++ /dev/null @@ -1,235 +0,0 @@ -models; - $collection_info = module_invoke_all('islandora_ingest_get_information', $models, $collection_object); - - return $collection_info; -} - -/** - * Get an ingestable object. - * - * @deprecated - * Deprecated in favour of the more flexible - * islandora_ingest_new_object_prepare()--which this function has been made - * to call behind the scenes anyway. - * - * @param array $content_models - * An array of content models to which the new object should subscribe, where - * each content model is described by an associative array containing: - * - pid: The Fedora PID of the content model. - * @param string $collection_pid - * The collection to which the new object should belong. - * @param string $relationship - * The relationship this object will have to the collection. - * @param string $namespace - * The namespace in which the PID for the new object will be created. - * - * @return NewFedoraObject - * A NewFedoraObject which may be adjusted before ingesting. - */ -function islandora_ingest_get_object($content_models, $collection_pid, $relationship, $namespace) { - $models = array(); - foreach ($content_models as $relation) { - $models[] = $relation['pid']; - } - - return islandora_ingest_new_object_prepare($namespace, NULL, array(), $models, array( - array( - 'pid' => $collection_pid, - 'relationship' => $relationship, - ), - ), $collection_pid); -} - -/** - * Prepare an ingestable object. - * - * @param string $namespace - * The namespace in which the PID for the new object will be created. - * @param string $label - * An optional label to apply to the object. - * @param array $datastreams - * A array of datastreams to add, where each datastream definition is an - * associative array containing: - * - dsid: The datastream ID. - * - label: An optional label for the datastream. - * - mimetype: A MIMEtype for the datastream; defaults to text/xml. - * - control_group: One of X, M, R and E; defaults to M. - * - datastream_file: A web-accessible path, for which we try to get an - * absolute path using url(). - * @param array $content_models - * An array of content model PIDs to which the new object should subscribe. - * @param array $relationships - * An array of relationships, where each relationship is an associative array - * containing: - * - relationship: The predicate for the relationship, from the Fedora - * RELS-EXT namespace. - * - pid: The object for the relationship, to which we are creating the - * relationhsip. - * - * @return NewFedoraObject - * An ingestable NewFedoraObject. - */ -function islandora_ingest_new_object_prepare($namespace = NULL, $label = NULL, $datastreams = array(), $content_models = array(), $relationships = array(), $collection_pid = NULL) { - // include Tuque library - module_load_include('inc', 'islandora', 'includes/tuque'); - global $user; - // new connection - try { - $connection = new IslandoraTuque($user); - } catch (Exception $e) { - drupal_set_message(t('Unable to connect to the repository %e', array('%e' => $e)), 'error'); - return; - } - // construct new object - $object = $connection->repository->constructObject($namespace); - - // add label - if (!empty($label)) { - $object->label = $label; - } - // add content model relationship(s) - foreach ($content_models as $content_model) { - $object->relationships->add(FEDORA_MODEL_URI, 'hasModel', $content_model); - } - // add collection relationship(s) - if (!empty($relationships)) { - foreach ($relationships as $relationship) { - $object->relationships->add(FEDORA_RELS_EXT_URI, $relationship['relationship'], $relationship['pid']); - } - } - // add datastreams - foreach ((array) $datastreams as $ds) { - // variables - $ds_id = $ds['dsid']; - $ds_label = isset($ds['label']) ? $ds['label'] : ''; - $ds_mimetype = isset($ds['mimetype']) ? $ds['mimetype'] : 'text/xml'; - $ds_control_group = (isset($ds['control_group']) AND in_array($ds['control_group'], array('X', 'M', 'R', 'E'))) ? $ds['control_group'] : 'M'; - $ds_datastream_file = url($ds['datastream_file'], array('absolute' => TRUE)); - - // datastream object - $datastream = $object->constructDatastream($ds_id, $ds_control_group); - $datastream->label = $ds_label; - $datastream->mimetype = $ds_mimetype; - switch ($ds_control_group) { - case 'M': - $datastream->setContentFromUrl($ds_datastream_file); - break; - case 'X': - $datastream->setContentFromString(file_get_contents($ds_datastream_file)); - break; - } - $object->ingestDatastream($datastream); - } - - module_load_include('inc', 'islandora', 'includes/utilities'); - foreach (islandora_build_hook_list('islandora_ingest_pre_ingest', $content_models) as $hook) { - module_invoke_all($hook, $object, $content_models, $collection_pid); - } - - return $object; -} - -/** - * Ingest the given object into Fedora. - * - * @param NewFedoraObject $object - * An ingestable FedoraObject. - * - * @return FedoraObject - * The ingested FedoraObject, after running the post ingest hooks. - */ -function islandora_ingest_add_object(&$object) { - $object->repository->ingestObject($object); - - module_load_include('inc', 'islandora', 'includes/utilities'); - - foreach (islandora_build_hook_list(ISLANDORA_POST_INGEST_HOOK, $object->models) as $hook) { - module_invoke_all($hook, $object); - } - - return $object; -} - -/** - * Ingest an object. - * - * @param array $object_model - * An associative array containing the necessary parameters to create the - * desired object: - * - pid: The PID with which the object will be created. - * - label: An optional label to apply to the object. - * - datastreams: Same as the "datastreams" array accepted by - * islandora_ingest_new_object_prepare(). - * - cmodel: Either an array of content models as accepted by - * islandora_ingest_new_object_prepare(), or a single content model PID to add - * to the object. - * - parent: Either an array of parents, or a single parent PID to which to - * relate to; uses isMemberOfCollection by default. - * - relationships: An array of relationships as accepted by - * islandora_ingest_new_object_prepare(). - * - * @return FedoraObject - * An FedoraObject which has been ingested into Fedora. - */ -function islandora_ingest_new_object($object_model) { - // prepare variables - // namespace - $namespace = $object_model['pid']; - // label - $label = !empty($object_model['label']) ? $object_model['label'] : NULL; - // datastreams - $datastreams = array(); - if (!empty($object_model['datastreams']) AND is_array($object_model['datastreams'])) { - $datastreams = $object_model['datastreams']; - } - // content models - $content_models = array(); - if (!empty($object_model['cmodel'])) { - if (is_array($object_model['cmodel'])) { - $content_models = $object_model['cmodel']; - } - else { - $content_models[] = $object_model['cmodel']; - } - } - // relationships - $relationships = array(); - // single parent - if (!empty($object_model['parent']) AND !is_array($object_model['parent'])) { - $relationships[] = array('relationship' => 'isMemberOfCollection', 'pid' => $object_model['parent']); - } - // parents array - if (!empty($object_model['parents']) AND is_array($object_model['parents'])) { - foreach ($object_model['parents'] as $parent) { - $relationships[] = array('relationship' => 'isMemberOfCollection', 'pid' => $parent); - } - } - // other relationships - if (!empty($object_model['relationships']) AND is_array($object_model['relationships'])) { - foreach ($object_model['relationships'] as $relationship) { - $relationships[] = array('relationship' => $relationship['relationship'], 'pid' => $relationship['pid']); - } - } - - // build new object - $object = islandora_ingest_new_object_prepare($namespace, $label, $datastreams, $content_models, $relationships); - - // ingest (and return) new object - return islandora_ingest_add_object($object); -} - - - - - diff --git a/includes/object_properties.form.inc b/includes/object_properties.form.inc new file mode 100644 index 00000000..d5e7a978 --- /dev/null +++ b/includes/object_properties.form.inc @@ -0,0 +1,116 @@ +label); + $form_state['object'] = $object; + return array( + 'pid' => array( + '#type' => 'hidden', + '#value' => $object->id + ), + 'object_label' => array( + '#title' => t('Item Label'), + '#default_value' => $object->label, + '#required' => 'TRUE', + '#description' => t('A Human readable label'), + '#size' => 120, // Double the normal length + '#maxlength' => 255, // Max length for a Fedora Label + '#type' => 'textfield' + ), + 'object_owner' => array( // @todo Make this into an autocomplete field that list the users in the system as well. + '#title' => t('Owner'), + '#default_value' => $object->owner, + '#required' => FALSE, + '#description' => t('The owner id'), + '#type' => 'textfield' + ), + 'object_state' => array( + '#title' => t('State'), + '#default_value' => $object->state, + '#required' => TRUE, + '#description' => t('The items state one of active, inactive or deleted'), + '#type' => 'select', + '#options' => array('A' => 'Active', 'I' => 'Inactive', 'D' => 'Deleted') + ), + 'submit' => array( + '#type' => 'submit', + '#value' => 'Update Properties' + ), + 'delete' => array( + '#type' => 'submit', + '#value' => t('Delete'), + '#submit' => array('islandora_object_properties_form_delete'), + '#limit_validation_errors' => array(array('pid')) + ) + ); +} + +/** + * Submit handler for object properties admin form. + * + * @param array $form + * The Drupal form. + * @param array $form_state + * The Drupal form state. + */ +function islandora_object_properties_form_submit(array $form, array &$form_state) { + $object = $form_state['object']; + $owner = $form_state['values']['object_owner']; + $state = $form_state['values']['object_state']; + $label = $form_state['values']['object_label']; + if (isset($owner) && $owner != $object->owner) { + try { + $object->owner = $owner; + 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($state) && $state != $object->state) { + try { + $object->state = $state; + 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()))); + } + } +} + +/** + * Callback function for object properties admin form delete button. + * + * @param array $form + * The Drupal form. + * @param array $form_state + * The Drupal form state. + */ +function islandora_object_properties_form_delete(array $form, array &$form_state) { + drupal_goto("islandora/object/{$form_state['values']['pid']}/delete"); +} diff --git a/includes/object_properties.inc b/includes/object_properties.inc deleted file mode 100644 index d4f7eeca..00000000 --- a/includes/object_properties.inc +++ /dev/null @@ -1,125 +0,0 @@ -owner) { - try { - $islandora_object->owner = $owner; - 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($state) && $state != $islandora_object->state) { - try { - $islandora_object->state = $state; - 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 != $islandora_object->label) { - try { - $islandora_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()))); - } - } -} - -/** - * Callback function for object properties admin form delete button. - */ -function islandora_edit_properties_form_delete($form, &$form_state) { - $islandora_object = $form_state['values']['pid']; - drupal_goto("islandora/object/$islandora_object/delete"); -} - -/** - * Object properties admin form. - * - * @param array $form - * @param array $form_state - * @param string $object_id - * an object id - * @return array - */ -function islandora_edit_properties_form($form, &$form_state, $object) { - $form = array(); - if (!isset($object)) { - return NULL; - } - drupal_set_title($object->label); - $form['pid'] = array( - '#type' => 'hidden', - '#value' => $object->id, - ); - - $form['object_label'] = array( - '#title' => t('Item Label'), - '#default_value' => $object->label, - '#required' => 'TRUE', - '#description' => t('A Human readable label'), - '#type' => 'textfield' - ); - $form['object_owner'] = array( - '#title' => t('Owner'), - '#default_value' => $object->owner, - '#required' => FALSE, - '#description' => t('The owner id'), - '#type' => 'textfield', - ); - $form['object_state'] = array( - '#title' => t('State'), - '#default_value' => $object->state, - '#required' => TRUE, - '#description' => t('The items state one of active, inactive or deleted'), - '#type' => 'select', - '#options' => array('A' => 'Active', 'I' => 'Inactive', 'D' => 'Deleted'), - ); - $form['submit'] = array( - '#type' => 'submit', - '#value' => 'Update Properties', - ); - $form['delete'] = array( - '#type' => 'submit', - '#value' => t('Delete'), - '#submit' => array('islandora_edit_properties_form_delete'), - '#limit_validation_errors' => array(array('pid')), - ); - return $form; -} diff --git a/includes/purge.form.inc b/includes/purge.form.inc deleted file mode 100644 index 32517933..00000000 --- a/includes/purge.form.inc +++ /dev/null @@ -1,138 +0,0 @@ - TRUE. - * Once the object has been deleted/purged then a second call lets the solution packs know that - * the object has been dealt with. In this call the object id and content models are sent out so - * that the solution packs can act on this news. There is no guarantee that the object still exists - * and so the object object isn't sent. - * - * @param string $object_id - * ID of the object - * @return type - */ -function islandora_purge_object_submit($form, &$form_state) { - - $object_id = $form_state['values']['pid']; - $collection = $form_state['values']['col']; - - // purge object - islandora_object_purge($object_id); - - drupal_goto($collection); -} - -function islandora_purge_object($form, &$form_state, $object) { - module_load_include('inc', 'islandora', 'includes/datastream'); - - $parent = islandora_datastream_get_parents($object); - $key = array_keys($parent); - - if (count($key) > 0) { - $redirect = "islandora/object/$key[0]"; - } - else { - $redirect = "islandora"; - } - - $form['pid'] = array('#type' => 'value', '#value' => $object->id); - $form['col'] = array('#type' => 'value', '#value' => $redirect); - - return confirm_form($form, - t('Are you sure you want to delete %title?', array('%title' => $object->label)), - "islandora/object/$object->id", - t('This action cannot be undone.'), - t('Delete'), - t('Cancel') - ); -} - -function islandora_purge_datastream($form, &$form_state, $object, $datastream_id) { - module_load_include('inc', 'islandora', 'includes/datastream'); - - $datastream = $object->getDatastream($datastream_id); - - $redirect = "islandora/object/$object->id"; - - $form['pid'] = array('#type' => 'value', '#value' => $object->id); - $form['dsid'] = array('#type' => 'value', '#value' => $datastream_id); - $form['col'] = array('#type' => 'value', '#value' => $redirect); - - return confirm_form($form, - t('Are you sure you want to delete the %dsid datastream?', array('%dsid' => $datastream->id)), - "islandora/object/$object->id", - t('This action cannot be undone.'), - t('Delete'), - t('Cancel') - ); -} - -/** - * Gives the option of purging or deleting a datastream. - * - * The default behaviour is to purge the datastream but this can be overridden using the - * 'islandora_pre_purge_datastream' hook. The returned array can include a 'block' => TRUE - * pair which will prevent the datastream from being deleted if it particularly needed for - * a certain function. Returning 'delete' => TRUE will cause the datastream to be put into - * a deleted state. - * - * @param string $object_id - * ID of the object - * @param string $datastream_id - * ID of the datastream - * - */ -function islandora_purge_datastream_submit($form, &$form_state) { - $object_id = $form_state['values']['pid']; - $datastream_id = $form_state['values']['dsid']; - - if (!isset($datastream_id)) { - drupal_set_message(t('Cannot remove datastream, datastream id not set')); - return; - } - - $object = islandora_object_load($object_id); - - if (!isset($object)) { - drupal_set_message(t('Could not remove object, object not found')); - return; - } - - //notify modules of pending deletion so we can update rels etc - $arr = module_invoke_all('islandora_pre_purge_datastream', $object[$datastream_id]); - - if (isset($arr['block']) && $arr['block']) { - drupal_set_message(t('Purging of the %d datastream was blocked', array('%d' => $datastream_id)), 'warning'); - return; - } - if (isset($arr['delete']) && $arr['delete']) { - try { - $object[$datastream_id]->state = 'D'; - } catch (Exception $e) { - drupal_set_message(t('Error deleting %s datastream from Islandora object %o %e', array('%s' => $datastream_id, '%o' => $object->id, '%e' => $e)), 'error'); - return; - } - } - else { - try { - $object->purgeDatastream($datastream_id); - } catch (Exception $e) { - drupal_set_message(t('Error purging %s datastream from Islandora object %o %e', array('%s' => $datastream_id, '%o' => $object_id, '%e' => $e)), 'error'); - return; - } - } - //notify modules post deletion - module_invoke_all('islandora_post_purge_datastream', $object, $datastream_id); - drupal_set_message(t('%d datastream sucessfully purged from Islandora object %o', array('%d' => $datastream_id, '%o' => $object->label))); - drupal_goto('islandora/object/' . $object->id); -} diff --git a/includes/solution_packs.inc b/includes/solution_packs.inc index ffc8d31f..ebb9e5f5 100644 --- a/includes/solution_packs.inc +++ b/includes/solution_packs.inc @@ -2,29 +2,24 @@ /** * @file + * * This file contains all admin and callback functions for solution pack management. */ /** - * Solution pack admin page callback + * Solution pack admin page callback. */ function islandora_solution_packs_admin() { - // add css - drupal_add_css(drupal_get_path('module', 'islandora') . '/css/islandora.admin.css'); - // check connection module_load_include('inc', 'islandora', 'includes/utilities'); - $url = variable_get('islandora_base_url', 'http://localhost:8080/fedora'); - $info = islandora_describe_repository($url); - if (!$info) { - $config_url = url('admin/islandora/configure'); - drupal_set_message(t('Could not connect to the repository. Please check the settings on the Islandora configuration page.', array('@config_url' => $config_url)), 'error'); + drupal_add_css(drupal_get_path('module', 'islandora') . '/css/islandora.admin.css'); + if (!islandora_describe_repository()) { + $message = t('Could not connect to the repository. Please check the settings on the ' . + 'Islandora configuration page.', + array('@config_url' => url('admin/islandora/configure'))); + drupal_set_message($message, 'error'); } - - // set variables $enabled_solution_packs = module_invoke_all('islandora_required_objects'); - $output = ''; - foreach ($enabled_solution_packs as $solution_pack_module => $solution_pack_info) { $objects = array(); foreach ($solution_pack_info as $field => $value) { @@ -37,12 +32,9 @@ function islandora_solution_packs_admin() { break; } } - // get form $form_array = drupal_get_form('islandora_solution_pack_form_' . $solution_pack_module, $solution_pack_module, $solution_pack_name, $objects); - // render form $output .= drupal_render($form_array); } - return $output; } @@ -50,10 +42,7 @@ function islandora_solution_packs_admin() { * Solution pack admin page */ function islandora_solution_pack_form($form, &$form_state, $solution_pack_module, $solution_pack_name, $objects = array()) { - - // set variables global $base_url; - global $base_path; $needs_update = FALSE; $needs_install = FALSE; $could_not_connect = FALSE; @@ -120,8 +109,6 @@ function islandora_solution_pack_form($form, &$form_state, $solution_pack_modul $could_not_connect = TRUE; break; } - - // label if ($needs_install OR $could_not_connect) { $label = $object['label'] ? $object['label'] : ''; } @@ -129,11 +116,8 @@ function islandora_solution_pack_form($form, &$form_state, $solution_pack_modul $label = $object['label'] ? l($object['label'], $base_url . '/islandora/object/' . $pid) : ''; } $table_row[] = $label; - // pid $table_row[] = $pid; - // object status $table_row[] = $object_status; - // add row $table_rows[] = $table_row; } } @@ -169,14 +153,12 @@ function islandora_solution_pack_form($form, &$form_state, $solution_pack_modul $submit_button_text = ''; } - // table $form['solution_pack']['table'] = array( '#type' => 'item', '#markup' => theme('table', array('header' => $table_header, 'rows' => $table_rows)), ); } - // submit if (!$could_not_connect) { $form['solution_pack']['submit'] = array( '#value' => $submit_button_text, @@ -185,12 +167,8 @@ function islandora_solution_pack_form($form, &$form_state, $solution_pack_modul '#attributes' => array('class' => array('islandora-solution-pack-submit')), '#weight' => 40, ); - // submit callback - $form['solution_pack']['#submit'] = array( - 'islandora_solution_pack_form_submit', - ); + $form['solution_pack']['#submit'] = array('islandora_solution_pack_form_submit'); } - return $form; } @@ -203,8 +181,6 @@ function islandora_solution_pack_form($form, &$form_state, $solution_pack_modul * The state of the form submited. */ function islandora_solution_pack_form_submit($form, &$form_state) { - - // get variables $solution_pack_module = $form_state['values']['solution_pack_module']; $solution_pack_name = $form_state['values']['solution_pack_name']; $objects = $form_state['values']['objects']; @@ -228,22 +204,16 @@ function islandora_solution_pack_form_submit($form, &$form_state) { } - - - /** * Batch reingest object(s) * - * @param type $object + * @param array $object * @param type $context * @return type */ function islandora_batch_reingest_object($object_model, &$context) { - module_load_include('inc', 'islandora', 'includes/utilities'); - module_load_include('inc', 'islandora', 'includes/islandora.ingest'); - // include Tuque library - module_load_include('inc', 'islandora', 'includes/tuque'); + global $user; global $base_url; // new connection @@ -256,9 +226,8 @@ function islandora_batch_reingest_object($object_model, &$context) { } if (!empty($object_model) && is_array($object_model)) { - // set and validate PID $pid = $object_model['pid']; - if (!islandora_validate_pid($pid)) { + if (!islandora_is_valid_pid($pid)) { return NULL; } @@ -267,13 +236,16 @@ function islandora_batch_reingest_object($object_model, &$context) { $object_query = $connection->api->a->findObjects('query', 'pid=' . $pid); $reinstall = FALSE; if (!empty($object_query['results'])) { - islandora_object_purge($pid); + $object = islandora_get_object_by_id($pid); + if (isset($object)) { + islandora_delete_object($object); + } $reinstall = TRUE; } // build and ingest new object try { - $object = islandora_ingest_new_object($object_model); + $object = islandora_solution_pack_add_object($object_model); $object_name = $object->label; if ($reinstall) { drupal_set_message(t('Successfully reinstalled @object_name.', array('@object_name' => $object_name, '@pid' => $pid))); @@ -299,9 +271,7 @@ function islandora_install_solution_pack($module_name = NULL, $op = 'install') { if (!empty($module_name)) { // include files - module_load_include('inc', 'islandora', 'includes/tuque'); module_load_include('module', 'islandora', 'islandora'); - module_load_include('inc', 'islandora', 'includes/islandora.ingest'); module_load_include('inc', 'islandora', 'includes/utilities'); module_load_include('module', $module_name, $module_name); @@ -381,9 +351,7 @@ function islandora_install_solution_pack($module_name = NULL, $op = 'install') { } } else { - // build and ingest new object - islandora_ingest_new_object($object); - // set message + islandora_solution_pack_add_object($object); drupal_set_message(st('@module_label: installed @label object.', array('@module_label' => $module_label, '@label' => $label, '@pid' => $pid, '@object_url' => $object_url))); } break; @@ -485,6 +453,87 @@ function islandora_check_object_status($object_model = array()) { } } +/** + * Converts the given definition into an object and add's it to the repository. + * + * @param array $object_definition + * An associative array containing the necessary parameters to create the + * desired object: + * - pid: The PID with which the object will be created. + * - label: An optional label to apply to the object. + * - datastreams: Same as the "datastreams" array accepted by + * islandora_prepare_new_object(). + * - cmodel: Either an array of content models as accepted by + * islandora_preprare_new_object(), or a single content model PID to add + * to the object. + * - parent: Either an array of parents, or a single parent PID to which to + * relate to; uses isMemberOfCollection by default. + * - relationships: An array of relationships as accepted by + * islandora_prepare_new_object(). + * + * @return FedoraObject + * The newly created object. + */ +function islandora_solution_pack_add_object(array $object_definition) { + $object = islandora_solution_pack_prepare_new_object($object_definition); + return islandora_add_object($object); +} + +/** + * Prepares a new object based on the solution pack style of declaring them as arrays. + * + * @param array $object_definition + * An associative array containing the necessary parameters to create the + * desired object: + * - pid: The PID with which the object will be created. + * - label: An optional label to apply to the object. + * - datastreams: Same as the "datastreams" array accepted by + * islandora_prepare_new_object(). + * - cmodel: Either an array of content models as accepted by + * islandora_prepare_new_object(), or a single content model PID to add + * to the object. + * - parent: Either an array of parents, or a single parent PID to which to + * relate to; uses isMemberOfCollection by default. + * - relationships: An array of relationships as accepted by + * islandora_prepare_new_object(). + * + * @return NewFedoraObject + * An NewFedoraObject which has been initalized with the given properties. + */ +function islandora_solution_pack_prepare_new_object(array $object_definition) { + $namespace = $object_definition['pid']; + $label = !empty($object_definition['label']) ? $object_definition['label'] : NULL; + $datastreams = array(); + if (!empty($object_definition['datastreams']) AND is_array($object_definition['datastreams'])) { + $datastreams = $object_definition['datastreams']; + } + $content_models = array(); + if (!empty($object_definition['cmodel'])) { + if (is_array($object_definition['cmodel'])) { + $content_models = $object_definition['cmodel']; + } + else { + $content_models[] = $object_definition['cmodel']; + } + } + $relationships = array(); + if (!empty($object_definition['parent']) AND !is_array($object_definition['parent'])) { + $relationships[] = array('relationship' => 'isMemberOfCollection', 'pid' => $object_definition['parent']); + } + if (!empty($object_definition['parents']) AND is_array($object_definition['parents'])) { + foreach ($object_definition['parents'] as $parent) { + $relationships[] = array('relationship' => 'isMemberOfCollection', 'pid' => $parent); + } + } + if (!empty($object_definition['relationships']) AND is_array($object_definition['relationships'])) { + foreach ($object_definition['relationships'] as $relationship) { + $relationships[] = array('relationship' => $relationship['relationship'], 'pid' => $relationship['pid']); + } + } + return islandora_prepare_new_object($namespace, $label, $datastreams, $content_models, $relationships); +} + + /** * @defgroup viewer-functions * @{ @@ -537,7 +586,7 @@ function islandora_viewers_form($variable_id = NULL, $mimetype = NULL) { // table loop foreach ($viewers as $name => $profile) { - + $options[$name] = ''; // machine name $form['viewers'][$variable_id]['name'][$name] = array( @@ -589,9 +638,9 @@ function islandora_viewers_form($variable_id = NULL, $mimetype = NULL) { function islandora_get_viewers($mimetype = NULL) { $viewers = array(); // get all viewers - $defined_viewers = module_invoke_all('islandora_viewer_info'); + $defined_viewers = module_invoke_all('islandora_viewer_info'); // filter viewers by mimetype - foreach($defined_viewers as $key => $value) { + foreach ($defined_viewers as $key => $value) { if (in_array($mimetype, $value['mimetype']) OR $mimetype == NULL) { $viewers[$key] = $value; } @@ -702,11 +751,9 @@ function islandora_get_viewer_id($variable_id) { */ function islandora_get_viewer_callback($viewer_id = NULL) { if ($viewer_id !== NULL) { - // get defined viewers $viewers = module_invoke_all('islandora_viewer_info'); if (isset($viewers[$viewer_id]['callback'])) { - // return callback function - return $viewers[$viewer_id]['callback']; + return $viewers[$viewer_id]['callback']; } } return FALSE; diff --git a/includes/utilities.inc b/includes/utilities.inc index 820e7660..8c6fab0b 100644 --- a/includes/utilities.inc +++ b/includes/utilities.inc @@ -58,45 +58,43 @@ function islandora_control_group_to_human_readable($control_group) { } /** - * valid pid ?? - * @param type $pid + * Checks if the given pid is valid. + * + * @param string $pid + * The object id to check. + * * @return boolean + * TRUE if valid, FALSE otherwise. */ -function islandora_validate_pid($pid) { - $valid = FALSE; - if (drupal_strlen(trim($pid)) <= 64 && preg_match('/^([A-Za-z0-9]|-|\.)+:(([A-Za-z0-9])|-|\.|~|_|(%[0-9A-F]{2}))+$/', trim($pid))) { - $valid = TRUE; - } - - return $valid; +function islandora_is_valid_pid($pid) { + return drupal_strlen(trim($pid)) <= 64 && preg_match('/^([A-Za-z0-9]|-|\.)+:(([A-Za-z0-9])|-|\.|~|_|(%[0-9A-F]{2}))+$/', trim($pid)); } /** - * Valid Dsid ?? - * @param type $dsid + * Checks if the given datastream id is valid. + * + * @param string $dsid + * The datastream id to check. + * * @return boolean + * TRUE if valid, FALSE otherwise. */ -function islandora_validate_dsid($dsid) { - $valid = FALSE; - if (drupal_strlen(trim($dsid)) <= 64 && preg_match('/^[a-zA-Z0-9\_\-\.]+$/', trim($dsid))) { - $valid = TRUE; - } - - return $valid; +function islandora_is_valid_dsid($dsid) { + return drupal_strlen(trim($dsid)) <= 64 && preg_match('/^[a-zA-Z0-9\_\-\.]+$/', trim($dsid)); } /* Helper function to describe a Fedora repository. * * Can be used to check if Fedora is available. * - * @param $url - * A url to a Fedora repository. + * @param string $url + * A url to a Fedora repository, if NULL the default is used. * @return * Returns an array describing the repository. Returns FALSE if Fedora is down * or if the url is incorrect. */ -function islandora_describe_repository($url) { - module_load_include('inc', 'islandora', 'includes/tuque'); +function islandora_describe_repository($url = NULL) { + $url = isset($url) ? $url : variable_get('islandora_base_url', 'http://localhost:8080/fedora'); $connection = new IslandoraTuque(NULL, $url); try { $info = $connection->api->a->describeRepository(); @@ -152,3 +150,46 @@ function islandora_escape_pid_for_function($pid) { $pid ); } + +/** + * Gets the namespace of the given id. + * + * @param string $id + * Either a PID or namespace to check for accessibility. Any string like those below are fine. + * @code + * 'islandora', + * 'islandora:', + * 'islandora:1234', + * @endcode + * + * @return string + * The namespace portion of the given string. + */ +function islandora_get_namespace($id) { + $matches = array(); + preg_match('/^([^:]*)/', $id, $matches); + return $matches[0]; +} + +/** + * Checks the given namespace or PID is/has an accessible namespace as defined by the "islandora_pids_allowed" variable. + * + * @param string $namespace + * Either a PID or namespace to check for accessibility. Any string like those below are fine. + * @code + * 'islandora', + * 'islandora:', + * 'islandora:1234', + * @endcode + * + * @return boolean + * TRUE if accessible, FALSE otherwise. + */ +function islanodra_namespace_accessible($id) { + if (variable_get('islandora_namespace_restriction_enforced', FALSE)) { + $namespace = islandora_get_namespace($id) . ':'; + $allowed_namespaces = explode(" ", variable_get('islandora_pids_allowed', 'default: demo: changeme: islandora: ilives: islandora-book: books: newspapers: ')); + return in_array($namespace, $allowed_namespaces); + } + return TRUE; +} diff --git a/islandora.api.php b/islandora.api.php index 918b5502..7c4cc121 100644 --- a/islandora.api.php +++ b/islandora.api.php @@ -155,17 +155,15 @@ function hook_islandora_object_alter($fedora_object) {} * * @param type $islandora_object * A Tuque FedoraObject - * @param array $content_models - * @param string $collection_pid */ -function hook_islandora_ingest_pre_ingest($islandora_object, $content_models, $collection_pid) {} +function hook_islandora_ingest_pre_ingest($islandora_object) {} /** * Allow modification of objects of a certain content model before ingesting. * * @see hook_islandora_ingest_pre_ingest() */ -function hook_CMODEL_PID_islandora_ingest_pre_ingest($islandora_object, $content_models, $collection_pid) {} +function hook_CMODEL_PID_islandora_ingest_pre_ingest($islandora_object) {} /** * Allow modules to setup for the purge of a datastream. @@ -218,3 +216,9 @@ function hook_islandora_required_objects() {} * @see islandora_get_viewer_callback() */ function hook_islandora_viewer_info() {} + + +/** + * Returns a list of datastreams that are determined to be undeletable. + */ +function hook_islandora_undeletable_datastreams(array $models) {} diff --git a/islandora.info b/islandora.info index 188380f9..c93e0e60 100644 --- a/islandora.info +++ b/islandora.info @@ -1,9 +1,13 @@ name = Islandora description = "View and manage Fedora objects" package = Islandora +dependencies[] = tuque version = 7.x-dev core = 7.x configure = admin/islandora/configure stylesheets[all][] = css/islandora.base.css stylesheets[all][] = css/islandora.theme.css +files[] = includes/MimeDetect.inc +files[] = includes/DublinCore.inc +files[] = includes/IslandoraTuque.inc php = 5.3 diff --git a/islandora.install b/islandora.install index c44c6418..88549ce5 100644 --- a/islandora.install +++ b/islandora.install @@ -2,7 +2,8 @@ /** * @file - * This file contains all install functions. + * + * This file contains all install related hooks. */ /** @@ -12,7 +13,6 @@ */ function islandora_install() { module_load_include('inc', 'islandora', 'includes/solution_packs'); - // install object(s) islandora_install_solution_pack('islandora'); } @@ -23,6 +23,5 @@ function islandora_install() { */ function islandora_uninstall() { module_load_include('inc', 'islandora', 'includes/solution_packs'); - // uninstall callback islandora_install_solution_pack('islandora', 'uninstall'); -} \ No newline at end of file +} diff --git a/islandora.module b/islandora.module index c12b034b..8edf81f0 100644 --- a/islandora.module +++ b/islandora.module @@ -1,6 +1,6 @@ . */ +module_load_include('inc', 'islandora', 'includes/globals'); +// Common datastreams +define('DS_COMP_STREAM', 'DS-COMPOSITE-MODEL'); // Permissions define('FEDORA_VIEW', 'view fedora repository'); @@ -34,16 +37,21 @@ define('FEDORA_MANAGE', 'manage fedora items'); // Hooks define('ISLANDORA_VIEW_HOOK', 'islandora_view_object'); define('ISLANDORA_EDIT_HOOK', 'islandora_edit_object'); +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_INGEST_STEP_HOOK', 'islandora_ingest_steps'); +define('ISLANDORA_PRE_PURGE_DATASTREAM_HOOK', 'islandora_pre_purge_datastream'); +define('ISLANDORA_POST_PURGE_DATASTREAM_HOOK', 'islandora_post_purge_datastream'); /** * Implements hook_menu(). - * we need some standard entry points so we can have consistent urls for different Object actions + * + * We need some standard entry points so we can have consistent urls for different Object actions */ function islandora_menu() { $items = array(); - $items['admin/islandora'] = array( 'title' => 'Islandora', 'description' => "Configure settings associated with Islandora.", @@ -60,7 +68,6 @@ function islandora_menu() { 'type' => MENU_NORMAL_ITEM, 'weight' => -1, ); - $items['admin/islandora/solution_packs'] = array( 'title' => 'Solution packs', 'description' => 'Install content models and collections required by installed solution packs.', @@ -68,147 +75,131 @@ function islandora_menu() { 'access arguments' => array(FEDORA_ADD_DS), 'file' => 'includes/solution_packs.inc', 'type' => MENU_NORMAL_ITEM, - ); - - $items['islandora/object/%islandora_object/manage/ingest'] = array( - 'title' => 'Add an object', - 'page callback' => 'islandora_ingest_callback', - 'page arguments' => array(2), - 'file' => 'includes/ingest-menu.inc', - 'type' => MENU_LOCAL_ACTION, - 'access callback' => 'islandora_ingest_access_callback', - 'access arguments' => array(2, FEDORA_INGEST), - ); - + ); $items['islandora'] = array( 'title' => 'Islandora Repository', 'page callback' => 'islandora_view_default_object', 'type' => MENU_NORMAL_ITEM, 'access arguments' => array(FEDORA_VIEW), ); - $items['islandora/object/%islandora_object'] = array( 'title' => 'Repository', 'page callback' => 'islandora_view_object', 'page arguments' => array(2), 'type' => MENU_NORMAL_ITEM, - 'access callback' => 'islandora_access_callback', - 'access arguments' => array(2, FEDORA_VIEW), + 'access callback' => 'islandora_object_access_callback', + 'access arguments' => array(FEDORA_VIEW, 2), ); - - $items['islandora/object/%islandora_object/view'] = array( 'title' => 'View', 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -1, ); - $items['islandora/object/%islandora_object/view/default'] = array( 'title' => 'View', 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -1, ); - $items['islandora/object/%islandora_object/manage'] = array( 'title' => 'Manage', 'page callback' => 'islandora_edit_object', 'page arguments' => array(2), 'type' => MENU_LOCAL_TASK, - 'access callback' => 'islandora_access_callback', - 'access arguments' => array(2, FEDORA_MODIFY_STATE), + 'access callback' => 'islandora_object_access_callback', + 'access arguments' => array(FEDORA_MODIFY_STATE, 2), ); - $items['islandora/object/%islandora_object/manage/datastreams'] = array( 'title' => 'Datastreams', 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10, ); - $items['islandora/object/%islandora_object/manage/properties'] = array( 'title' => 'Properties', 'page callback' => 'drupal_get_form', - 'file' => 'includes/object_properties.inc', - 'page arguments' => array('islandora_edit_properties_form', 2), + 'file' => 'includes/object_properties.form.inc', + 'page arguments' => array('islandora_object_properties_form', 2), 'type' => MENU_LOCAL_TASK, - 'access callback' => 'islandora_access_callback', - 'access arguments' => array(2, FEDORA_MODIFY_STATE), + 'access callback' => 'islandora_object_access_callback', + 'access arguments' => array(FEDORA_MODIFY_STATE, 2), 'weight' => -5, ); - $items['islandora/object/%islandora_object/delete'] = array( 'title' => 'Delete object', - 'file' => 'includes/purge.form.inc', + 'file' => 'includes/delete_object.form.inc', 'page callback' => 'drupal_get_form', - 'page arguments' => array('islandora_purge_object', 2), + 'page arguments' => array('islandora_delete_object_form', 2), 'type' => MENU_CALLBACK, - 'access callback' => 'islandora_access_callback', - 'access arguments' => array(2, FEDORA_PURGE), + 'access callback' => 'islandora_object_access_callback', + 'access arguments' => array(FEDORA_PURGE, 2), ); - $items['islandora/object/%islandora_object/manage/datastreams/add'] = array( 'title' => 'Add a datastream', - 'file' => 'includes/datastream.inc', + 'file' => 'includes/add_datastream.form.inc', 'page callback' => 'drupal_get_form', 'page arguments' => array('islandora_add_datastream_form', 2), 'type' => MENU_LOCAL_ACTION, - 'access callback' => 'islandora_access_callback', - 'access arguments' => array(2, FEDORA_ADD_DS) + 'access callback' => 'islandora_object_access_callback', + 'access arguments' => array(FEDORA_ADD_DS, 2) ); - $items['islandora/object/%islandora_object/manage/datastreams/add/autocomplete'] = array( - 'file' => 'includes/datastream.inc', - 'page callback' => 'islandora_datastream_autocomplete_callback', + 'file' => 'includes/add_datastream.form.inc', + 'page callback' => 'islandora_add_datastream_form_autocomplete_callback', 'page arguments' => array(2), 'type' => MENU_CALLBACK, - 'access callback' => 'islandora_access_callback', - 'access arguments' => array(2, FEDORA_ADD_DS) + 'access callback' => 'islandora_object_access_callback', + 'access arguments' => array(FEDORA_ADD_DS, 2) ); - - $items['islandora/object/%islandora_object/datastream/%'] = array( + $items['islandora/object/%islandora_object/datastream/%islandora_datastream'] = array( 'title' => 'View datastream', 'page callback' => 'islandora_view_datastream', - 'page arguments' => array(2, 4), + 'page arguments' => array(4), 'type' => MENU_CALLBACK, 'file' => 'includes/datastream.inc', - 'access callback' => 'islandora_access_callback', - 'access arguments' => array(2, FEDORA_VIEW), + 'access callback' => 'islandora_object_datastream_access_callback', + 'access arguments' => array(FEDORA_VIEW, 2, 4), + 'load arguments' => array('%map'), ); - - $items['islandora/object/%islandora_object/datastream/%/view'] = array( + $items['islandora/object/%islandora_object/datastream/%islandora_datastream/view'] = array( 'title' => 'View datastream', 'type' => MENU_DEFAULT_LOCAL_TASK, ); - - $items['islandora/object/%islandora_object/datastream/%/download'] = array( + $items['islandora/object/%islandora_object/datastream/%islandora_datastream/download'] = array( 'title' => 'Download datastream', - 'page callback' => 'islandora_view_datastream', - 'page arguments' => array(2, 4, 5), + 'page callback' => 'islandora_download_datastream', + 'page arguments' => array(4), 'type' => MENU_CALLBACK, 'file' => 'includes/datastream.inc', - 'access callback' => 'islandora_access_callback', - 'access arguments' => array(2, FEDORA_VIEW), + 'access callback' => 'islandora_object_datastream_access_callback', + 'access arguments' => array(FEDORA_VIEW, 2, 4), + 'load arguments' => array('%map'), ); - - $items['islandora/object/%islandora_object/datastream/%/edit'] = array( + $items['islandora/object/%islandora_object/datastream/%islandora_datastreams/edit'] = array( 'title' => 'Edit datastream', 'page callback' => 'islandora_edit_datastream', 'page arguments' => array(2, 4), 'type' => MENU_CALLBACK, 'file' => 'includes/datastream.inc', - 'access callback' => 'islandora_access_callback', - 'access arguments' => array(2, FEDORA_METADATA_EDIT), + 'access callback' => 'islandora_object_datastream_access_callback', + 'access arguments' => array(FEDORA_METADATA_EDIT, 2, 4), + 'load arguments' => array('%map'), ); - - $items['islandora/object/%islandora_object/datastream/%/delete'] = array( - 'title' => 'Purge data stream', + $items['islandora/object/%islandora_object/datastream/%islandora_datastream/delete'] = array( + 'title' => 'Delete data stream', 'page callback' => 'drupal_get_form', - 'page arguments' => array('islandora_purge_datastream', 2, 4), - 'file' => 'includes/purge.form.inc', + 'page arguments' => array('islandora_delete_datastream_form', 4), + 'file' => 'includes/delete_datastream.form.inc', 'type' => MENU_CALLBACK, - 'access callback' => 'islandora_access_callback', - 'access arguments' => array(2, FEDORA_PURGE), + 'access callback' => 'islandora_object_datastream_access_callback', + 'access arguments' => array(FEDORA_PURGE, 2, 4), + 'load arguments' => array('%map'), + ); + $items['islandora/ingest'] = array( + 'title' => 'Add an Object', + 'page callback' => 'islandora_ingest_callback', + 'file' => 'includes/ingest.menu.inc', + 'type' => MENU_SUGGESTED_ITEM, + 'access arguments' => array(FEDORA_INGEST), ); - return $items; } @@ -225,8 +216,6 @@ function islandora_admin_paths() { /** * Implements hook_theme(). - * - * @return array */ function islandora_theme() { return array( @@ -252,8 +241,6 @@ function islandora_theme() { /** * Implements hook_permission(). - * - * @return array */ function islandora_permission() { return array( @@ -302,105 +289,94 @@ function islandora_forms($form_id) { } /** - * determines whether we can see the object or not - * checks PID namespace permissions, and user permissions - * @global object $user - * @param string $op - * @param string $pid + * Checks whether the user can access the given object with the given permission. + * + * Checks for object existance, accessiblitly, namespace permissions, and user permissions * - * @return boolean + * @see islandora_object_load() To find potential solutions to enable page not found errors. + * + * @param string $perm + * The user permission to test for. + * @param FedoraObject $object + * The object to test, if NULL given the object doesn't exist or is inaccessible. + * + * @return boolean + * TRUE if the user is allowed to access this object, FALSE otherwise. */ -function islandora_access_callback($object = NULL, $perm = NULL) { - if (!$object || !$perm) { - return FALSE; - } - - $is_restricted = variable_get('islandora_namespace_restriction_enforced', FALSE); - - if (!$is_restricted) { - $namespace_access = TRUE; - } - else { - $pid_namespace = substr($object->id, 0, strpos($object->id, ':') + 1); // Get the namespace (with colon) - $allowed_namespaces = explode(" ", variable_get('islandora_pids_allowed', 'default: demo: changeme: islandora: ilives: islandora-book: books: newspapers: ')); - $namespace_access = in_array($pid_namespace, $allowed_namespaces); - } +function islandora_object_access_callback($perm, $object = NULL) { + module_load_include('inc', 'islandora', 'includes/utilities'); + return user_access($perm) && is_object($object) && islanodra_namespace_accessible($object->id); +} - return ($namespace_access && user_access($perm)); +/** + * Checks whether the user can access the given object and datastream with the given permission. + * + * Checks for object existance, accessiblitly, namespace permissions, and user permissions + * + * @see islandora_object_load() To find potential solutions to enable page not found errors. + * + * @param string $perm + * The user permission to test for. + * @param FedoraObject $object + * The object to test, if NULL given the object doesn't exist or is inaccessible. + * @param FedoraDatastream $datastream + * The datastream to test, if NULL given the datastream doesn't exist or is inaccessible. + * + * @return boolean + * TRUE if the user is allowed to access this object, FALSE otherwise. + */ +function islandora_object_datastream_access_callback($perm, $object = NULL, $datastream = NULL) { + module_load_include('inc', 'islandora', 'includes/utilities'); + return user_access($perm) && is_object($object) && islanodra_namespace_accessible($object->id) && is_object($datastream); } /** - * a function to call other modules edit page. If there are not any modules - * that handle this function this module will build a default page. - * @global object $user - * @param string $object_id + * Renders the given objects manage page. Its possible to modify the output of this function if 'ISLANDORA_EDIT_HOOK' is + * implemented in other modules. + * + * If no modules implement 'ISLANDORA_EDIT_HOOK' then this function returns the default manage view. + * + * @param FedoraObject $object + * The object to manage. + * * @return string + * The HTML repersentation of the manage object page. */ -function islandora_edit_object($object) { - if (!$object) { - return drupal_not_found(); - } - +function islandora_edit_object(FedoraObject $object) { module_load_include('inc', 'islandora', 'includes/utilities'); - - // Accumulate the output. $output = array(); - - // Call cmodel oriented variants first. foreach (islandora_build_hook_list(ISLANDORA_EDIT_HOOK, $object->models) as $hook) { $temp = module_invoke_all($hook, $object); if (!empty($temp)) { $output = array_merge_recursive($output, $temp); } } - - // Add in the default, if we did not get any results. if (empty($output)) { - $output = islandora_default_islandora_edit_object($object); + $output = islandora_default_islandora_edit_object($object); // Add in the default, if we did not get any results. } - arsort($output); - drupal_alter(ISLANDORA_EDIT_HOOK, $object, $output); - return implode('', $output); } /** - * edit properties form - * @param type $object_id - * @return string - */ -function islandora_edit_properties($object_id) { - $object = islandora_object_load($object_id); - if (isset($object)) { - module_load_include('inc', 'islandora', 'includes/object_properties'); - $form = drupal_get_form('islandora_edit_properties_form', $object); - drupal_set_title($object->label); - return drupal_render($form); - } - return ""; -} - -/** - * Builds a default page for the edit tab. + * Renders the default manage object page for the given object. * - * @param object $fedora_object - * A tuque Fedora Object + * @param FedoraObject $object + * The object used to render the manage object page. + * + * @return array + * The default rendering of the object manage page, indexed at 'Default Edit output'. */ -function islandora_default_islandora_edit_object($fedora_object) { - $output = theme('islandora_default_edit', array( - 'islandora_object' => $fedora_object, - )); - +function islandora_default_islandora_edit_object(FedoraObject $object) { + $output = theme('islandora_default_edit', array('islandora_object' => $object)); return array('Default Edit output' => $output); } /** * Page callback for the path "islandora". * - * Redirects to the view of the object indicated by the Drupal variable - * islandora_repository_pid. + * Redirects to the view of the object indicated by the Drupal variable 'islandora_repository_pid'. */ function islandora_view_default_object() { $pid = variable_get('islandora_repository_pid', 'islandora:root'); @@ -408,59 +384,49 @@ function islandora_view_default_object() { } /** - * The view entry point. modules should implement hook_islandora_view_object for the Fedora Content models that + * Renders the default view object page for the given object. + * + * Modules should implement ISLANDORA_VIEW_HOOK for the Fedora Content models that * their modules want to provide a view for. - * @global object $user - * @param string $object_id + * + * If no modules implement the hook then the default view object page will be rendered. + * + * @param FedoraObject $object + * The object to view. * * @return string + * The html repersentation of this object. */ -function islandora_view_object($fedora_object = NULL) { +function islandora_view_object(FedoraObject $object) { module_load_include('inc', 'islandora', 'includes/breadcrumb'); module_load_include('inc', 'islandora', 'includes/utilities'); - - global $user; - - if (!$fedora_object) { - return drupal_not_found(); - } - - // set breadcrumbs - drupal_set_breadcrumb(islandora_get_breadcrumbs($fedora_object)); - // optional pager parameters + drupal_set_breadcrumb(islandora_get_breadcrumbs($object)); + // Optional pager parameters $page_number = (empty($_GET['page'])) ? '1' : $_GET['page']; $page_size = (empty($_GET['pagesize'])) ? '10' : $_GET['pagesize']; - - // Accumulate the output. $output = array(); - - // Call cmodel oriented variants first. - foreach (islandora_build_hook_list(ISLANDORA_VIEW_HOOK, $fedora_object->models) as $hook) { - $temp = module_invoke_all($hook, $fedora_object, $page_number, $page_size); + foreach (islandora_build_hook_list(ISLANDORA_VIEW_HOOK, $object->models) as $hook) { + $temp = module_invoke_all($hook, $object, $page_number, $page_size); // @todo Remove page number and size from this hook, implementers of the hook should use drupal page handling directly. if (!empty($temp)) { $output = array_merge_recursive($output, $temp); } } - - // Add in the default, if we did not get any results. if (empty($output)) { - $output = islandora_default_islandora_view_object($fedora_object); + $output = islandora_default_islandora_view_object($object); // No results, use the default view. } - arsort($output); - - drupal_alter(ISLANDORA_VIEW_HOOK, $fedora_object, $output); - + drupal_alter(ISLANDORA_VIEW_HOOK, $object, $output); return implode('', $output); } /** - * If there are no modules registered to handle this objects cmodels or there are - * not any cmodels specified this will create a default display. + * Renders the default view object page for the given object. * * @param FedoraObject $object - * The object whose display we are to render. + * The object used to render the view object page. + * * @return array + * The default rendering of the object view page, indexed at 'Default output'. */ function islandora_default_islandora_view_object($object) { $output = theme('islandora_default', array('islandora_object' => $object)); @@ -468,106 +434,73 @@ function islandora_default_islandora_view_object($object) { } /** - * A helper function to get a connection and return an object + * A helper function to get a connection and return an object for objects specified in the menu path as '%islandora_object'. + * + * This should only be used by the Drupal menu wildcard system! As for non existing objects this will return page not found. + * + * After some research drupal_not_found(), drupal_access_denied() and others can not be safetly used at this level. Nor can + * They be used at the "access callback" level. Not without hacking core, also it seems roling our own versions of these + * functions will be fruitless. We can still use drupal_goto() though, if we redirect to our own pages for 404, 500 etc. we + * Will be able to deliever the correct message to users. + * + * @todo For non accessible objects to the user this should return access denied. + * @todo When the repository down this should return a 500 error or a site offline notice. * - * @global object $user * @param string $object_id + * The pid of an object in the menu path identified by '%islandora_object'. + * * @return FedoraObject + * If the given object id exists in the repository then this returns a FedoraObject, if no object was found it returns FALSE which triggers a drupal_page_not_found(), if the + * object was inaccessible then NULL is returned, and the access callback will catch that case, triggering an access denied. */ function islandora_object_load($object_id) { - module_load_include('inc', 'islandora', 'includes/tuque'); - $islandora_tuque = &drupal_static(__FUNCTION__); - - if (!$islandora_tuque) { - $islandora_tuque = new IslandoraTuque(); + static $object = NULL, $load_failed = FALSE; // Assume inaccessible. + if ($load_failed || isset($object)) { + return $object; } - - if (IslandoraTuque::exists()) { - try { - $fedora_object = $islandora_tuque->repository->getObject($object_id); - } catch (Exception $e) { - return NULL; - } - - drupal_alter('islandora_object', $fedora_object); - return $fedora_object; - } - else { - IslandoraTuque::getError(); - return NULL; + $object = islandora_get_object_by_id($object_id); // Either NULL or FALSE. + if (!isset($object)) { + $load_failed = TRUE; } + return $object; } /** - * A helper function to get a connection and purge an object + * A helper function to get an datastream specified as '%islandora_datastream' for the object specified in the menu path as '%islandora_object'. * - * @global object $user - * @param string $object_id - * @return FedoraObject + * This should only be used by the Drupal menu wildcard system! As for non existing datastreams this will return page not found. + * + * The following settings are required for any menu paths which intent to use this auto loader. + * + * @code + * 'load arguments' => array('%map'), + * @endcode + * + * @see islandora_object_load() for solutions to access/not found problems. + * + * @todo For non accessible datastreams to the user this should return access denied. + * @todo Is there anything we can do to enhance caching? + * + * @param string $datastream_id + * The dsid of the datastream specified as '%islandora_datastream' to fetch from the given object in the menu path identified by '%islandora_object'. + * + * @return FedoraDatastream + * If the given datastream id exists in the object then this returns a FedoraDatastream, in other cases this aborts. */ -function islandora_object_purge($object_id) { - if (!$object_id) { - drupal_set_message(t('Cannot remove object, object id not set')); - return; - } - - // load object - $object = islandora_object_load($object_id); - - if (!$object) { - drupal_set_message(t('Could not remove object, object not found')); - return; - } - - module_load_include('inc', 'islandora', 'includes/utilities'); - - $content_models = $object->models; - - $arr = array(); - foreach (islandora_build_hook_list(ISLANDORA_PRE_PURGE_OBJECT_HOOK, $object->models) as $hook) { - $temp = module_invoke_all($hook, $object); - if (!empty($temp)) { - $arr = array_merge_recursive($arr, $temp); - } +function islandora_datastream_load($datastream_id, $map) { + static $datastream = NULL, $load_failed = FALSE; // @hack for bug in drupal_not_found() when used before the menu callback. Infinite recursion bug. + if ($load_failed || isset($datastream)) { + return $datastream; } - - if (isset($arr['delete']) && $arr['delete']) { - try { - $object->delete(); - } catch (Exception $e) { - drupal_set_message(t('Error deleting Islandora object %s %e', array('%s' => $object_id, '%e' => $e)), 'error'); - return ""; - } - } - else { - try { - $object->repository->purgeObject($object_id); - } catch (Exception $e) { - drupal_set_message(t('Error purging Islandora object %s %e', array('%s' => $object_id, '%e' => $e)), 'error'); - return ""; + foreach ($map as $element) { + $is_fedora_object = is_object($element) && strtolower(get_class($element)) == 'fedoraobject'; // @todo Probably a better way to check types by now. + if ($is_fedora_object && isset($element[$datastream_id])) { // @todo check for access denied to this datastream so we can show the access denied page instead. + $datastream = $element[$datastream_id]; + return $datastream; } } - - module_invoke_all('islandora_post_purge_object', $object_id, $content_models); // notify modules post deletion -} - - -/** - * Ingest access callback - */ -function islandora_ingest_access_callback($object, $perm) { - if (islandora_access_callback($object, $perm) === FALSE) { - return FALSE; - } - - $ingest_registry = module_invoke_all('islandora_ingest_registry', $object); - - if (count($ingest_registry) > 0) { - return TRUE; - } - else { - return FALSE; - } + $load_failed = TRUE; + return $datastream; // @todo Test } /** @@ -634,7 +567,9 @@ function islandora_islandora_required_objects() { ); } - - - - +/** + * Implements islandora_undeleteable_datastreams(). + */ +function islandora_islandora_undeletable_datastreams(array $models) { + return array('DC'); +} diff --git a/theme/islandora-object-edit.tpl.php b/theme/islandora-object-edit.tpl.php index f0005083..559ffd8c 100644 --- a/theme/islandora-object-edit.tpl.php +++ b/theme/islandora-object-edit.tpl.php @@ -11,7 +11,7 @@ * to get the contents of a datastream * $object['dsid']->content * - * $dublin_core is a Dublin_Core object + * $dublin_core is a DublinCore object * which is an array of elements, such as dc.title * and each element has an array of values. dc.title can have none, one or many titles * this is the case for all dc elements. diff --git a/theme/islandora-object.tpl.php b/theme/islandora-object.tpl.php index e876f679..f10bb745 100644 --- a/theme/islandora-object.tpl.php +++ b/theme/islandora-object.tpl.php @@ -3,7 +3,7 @@ /* * @file * This is a template for objects that do not have a module to registered to build their display. - * + * * islandora_object is a fedora tuque Object * $object->label - The label for this object. * $object->id - The identifier of the object. @@ -17,7 +17,7 @@ * to test if a datastream exists isset($object['dsid']) * * to iterate over datastreams: - * foreach($object as $ds) { + * foreach ($object as $ds) { * $ds->label, etc * } * @@ -37,20 +37,20 @@ * $ds->checksumType - The type of checksum for the datastream. * $ds->createdDate->format("Y-m-d") - The created date with an option to use a format of your choice * $ds->content - The content of the datastream - * $ds->url - The URL. This is only valid for R and E datastreams. - * - * $dublin_core is a Dublin_Core object + * $ds->url - The URL. This is only valid for R and E datastreams. + * + * $dublin_core is a DublinCore object * which is an array of elements, such as dc.title * and each element has an array of values. dc.title can have none, one or many titles * this is the case for all dc elements. * * - * + * * we can get a list of datastreams by doing - * foreach ($object as $ds){ + * foreach ($object as $ds) { * do something here * } - * + * */ ?> @@ -80,8 +80,8 @@
Collections
- $value): ?> -
+ +
label, "islandora/object/{$collection->id}"); ?>
@@ -96,7 +96,7 @@ - + $value): ?> diff --git a/theme/islandora.theme.inc b/theme/islandora.theme.inc index 7999e0d0..f92091fc 100644 --- a/theme/islandora.theme.inc +++ b/theme/islandora.theme.inc @@ -59,11 +59,10 @@ function islandora_preprocess_islandora_default(&$variables) { drupal_add_js('misc/form.js'); drupal_add_js('misc/collapse.js'); $islandora_object = $variables['islandora_object']; - module_load_include('inc', 'islandora', 'includes/islandora_dublin_core'); module_load_include('inc', 'islandora', 'includes/utilities'); module_load_include('inc', 'islandora', 'includes/datastream'); - $variables['parent_collections'] = islandora_datastream_get_parents($islandora_object); + $variables['parent_collections'] = islandora_get_parents_from_rels_ext($islandora_object); $datastreams = array(); foreach ($islandora_object as $ds) { @@ -89,7 +88,7 @@ function islandora_preprocess_islandora_default(&$variables) { try { $dc = $islandora_object['DC']->content; //$dc_xml = simplexml_load_string($dc); - $dc_object = Dublin_Core::import_from_xml_string($dc); + $dc_object = DublinCore::import_from_xml_string($dc); $dc_array = $dc_object->as_formatted_array(); } catch (Exception $e) { drupal_set_message(t('Error retrieving object %s %t', array('%s' => $islandora_object->id, '%t' => $e->getMessage())), 'error', FALSE); @@ -101,4 +100,4 @@ function islandora_preprocess_islandora_default(&$variables) { if (isset($islandora_object['TN'])) { $variables['islandora_thumbnail_url'] = $base_url . '/islandora/object/' . $islandora_object->id . '/datastream/TN/view'; } -} \ No newline at end of file +} From 0db865a8af8e1cffc629ba61e2ce94e41cd14475 Mon Sep 17 00:00:00 2001 From: Nigel Banks Date: Thu, 22 Nov 2012 07:46:13 -0400 Subject: [PATCH 02/20] Downloaded labels now have the proper labels, redirect the user on ingest to the last ingested object. --- includes/datastream.inc | 2 +- includes/ingest.form.inc | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/includes/datastream.inc b/includes/datastream.inc index d1620d5f..bff346b3 100644 --- a/includes/datastream.inc +++ b/includes/datastream.inc @@ -35,7 +35,7 @@ function islandora_view_datastream(FedoraDatastream $datastream, $download = FAL header('Content-length: ' . $datastream->size); } if ($download) { - header("Content-Disposition: attachment; filename=\"" . $datastream->label); + header("Content-Disposition: attachment; filename=\"{$datastream->label}\""); } drupal_page_is_cacheable(FALSE); // Try not to load the file into PHP memory! diff --git a/includes/ingest.form.inc b/includes/ingest.form.inc index d57c3c15..524b27f1 100644 --- a/includes/ingest.form.inc +++ b/includes/ingest.form.inc @@ -240,6 +240,7 @@ function islandora_ingest_form_submit(array $form, array &$form_state) { foreach ($form_state['islandora']['objects'] as $object) { try { islandora_add_object($object); + $form_state['redirect'] = "islandora/object/{$object->id}"; } catch (Exception $e) { watchdog('islandora', $e->getMessage(), NULL, WATCHDOG_ERROR); // If post hooks throws it may already exist at this point but may be invalid, so don't say failed :P drupal_set_message(t('A problems occured while ingesting "@label" (ID: @pid), please notifiy the administrator.', array('@label' => $object->label, '@pid' => $object->id)), 'error'); From 6b181c1f48ba015c37bee1af2ea3da68394cbd92 Mon Sep 17 00:00:00 2001 From: Nigel Banks Date: Sun, 25 Nov 2012 19:09:17 -0400 Subject: [PATCH 03/20] Notifiy the user when the repository is down. --- includes/utilities.inc | 3 ++- islandora.module | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/includes/utilities.inc b/includes/utilities.inc index 8c6fab0b..a1aefa70 100644 --- a/includes/utilities.inc +++ b/includes/utilities.inc @@ -83,7 +83,8 @@ function islandora_is_valid_dsid($dsid) { return drupal_strlen(trim($dsid)) <= 64 && preg_match('/^[a-zA-Z0-9\_\-\.]+$/', trim($dsid)); } -/* Helper function to describe a Fedora repository. +/** + * Helper function to describe a Fedora repository. * * Can be used to check if Fedora is available. * diff --git a/islandora.module b/islandora.module index 8edf81f0..1216e9ed 100644 --- a/islandora.module +++ b/islandora.module @@ -460,6 +460,10 @@ function islandora_object_load($object_id) { } $object = islandora_get_object_by_id($object_id); // Either NULL or FALSE. if (!isset($object)) { + module_load_include('inc', 'islandora', 'includes/utilities'); + if (islandora_describe_repository() === FALSE) { + drupal_set_message(t('The repository is not availible please contact the administrator.'), 'error'); + } $load_failed = TRUE; } return $object; From 662209ef1a2ba62ae9bc58f2c981418ad376977e Mon Sep 17 00:00:00 2001 From: Nigel Banks Date: Mon, 26 Nov 2012 14:48:32 +0000 Subject: [PATCH 04/20] Fixed logical error in islandora_delete_object. --- includes/globals.inc | 2 -- includes/ingest.form.inc | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/includes/globals.inc b/includes/globals.inc index e389d87a..33a50c58 100644 --- a/includes/globals.inc +++ b/includes/globals.inc @@ -121,8 +121,6 @@ function islandora_delete_object(FedoraObject &$object) { $object = NULL; return TRUE; } - islandora_post_delete_object($object); - return $object; } /** diff --git a/includes/ingest.form.inc b/includes/ingest.form.inc index 524b27f1..d6381436 100644 --- a/includes/ingest.form.inc +++ b/includes/ingest.form.inc @@ -243,7 +243,7 @@ function islandora_ingest_form_submit(array $form, array &$form_state) { $form_state['redirect'] = "islandora/object/{$object->id}"; } catch (Exception $e) { watchdog('islandora', $e->getMessage(), NULL, WATCHDOG_ERROR); // If post hooks throws it may already exist at this point but may be invalid, so don't say failed :P - drupal_set_message(t('A problems occured while ingesting "@label" (ID: @pid), please notifiy the administrator.', array('@label' => $object->label, '@pid' => $object->id)), 'error'); + drupal_set_message(t('A problem occured while ingesting "@label" (ID: @pid), please notifiy the administrator.', array('@label' => $object->label, '@pid' => $object->id)), 'error'); } } } From f9041ee4fa213adf3ea2375f2c4e86f4acb42b7e Mon Sep 17 00:00:00 2001 From: Nigel Banks Date: Mon, 26 Nov 2012 15:56:52 +0000 Subject: [PATCH 05/20] Removed module_load_include in global space, corrected parameters in function call to islandora_post_delete. Fixed documentation error. --- includes/globals.inc | 4 ++-- islandora.module | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/includes/globals.inc b/includes/globals.inc index 33a50c58..30659e60 100644 --- a/includes/globals.inc +++ b/includes/globals.inc @@ -113,7 +113,7 @@ function islandora_delete_object(FedoraObject &$object) { return FALSE; case 'delete': // Change the state to deleted. $object->delete(); - islandora_post_delete_object($object, $object_id, $models); + islandora_post_delete_object($object_id, $models); return TRUE; default: // Purge $object->repository->purgeObject($object_id); @@ -142,7 +142,7 @@ function islandora_pre_delete_object(FedoraObject $object) { } /** - * Calls the ISLANDORA_POST_INGEST_HOOK hooks. + * Calls the ISLANDORA_POST_PURGE_OBJECT_HOOK hooks. * * @param string $object_id * The object id of an the recently deleted object. diff --git a/islandora.module b/islandora.module index 1216e9ed..3f649f74 100644 --- a/islandora.module +++ b/islandora.module @@ -20,7 +20,7 @@ * You should have received a copy of the GNU General Public License * along with the program. If not, see . */ -module_load_include('inc', 'islandora', 'includes/globals'); +require_once __DIR__ . "/includes/globals.inc"; // Common datastreams define('DS_COMP_STREAM', 'DS-COMPOSITE-MODEL'); From 56b816a2984c350c35caa5b292bdbbcec8b6cdf8 Mon Sep 17 00:00:00 2001 From: Nigel Banks Date: Mon, 26 Nov 2012 16:54:55 +0000 Subject: [PATCH 06/20] Fixed documentation errors --- includes/ingest.form.inc | 23 ++++++++++++++--------- islandora.module | 18 +++++++++--------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/includes/ingest.form.inc b/includes/ingest.form.inc index d6381436..77717257 100644 --- a/includes/ingest.form.inc +++ b/includes/ingest.form.inc @@ -249,39 +249,44 @@ function islandora_ingest_form_submit(array $form, array &$form_state) { } /** - * Gets the configuration. + * Gets the configuration used to create the multi-page ingest form. * * @param array $form_state * The drupal form state. * - * @return int - * The current step index. + * @return array + * The configuration used to generate the multi-page ingest forms. */ function islandora_ingest_form_get_configuration(array $form_state) { return $form_state['islandora']['configuration']; } /** - * Gets the stored objects. + * Gets a reference to the stored NewFedoraObject's which are to be ingested when the final step submits. * * @param array $form_state * The drupal form state. * - * @return int - * The current step index. + * @return array + * A reference to the stored NewFedoraObjects to be ingested when the final step submits. */ function &islandora_ingest_form_get_objects(array $form_state) { return $form_state['islandora']['objects']; } /** - * Gets a single object. + * Gets a single object from the stored NewFedoraObject's. + * + * @note - In our current use case we are only dealing with a single object ingest, this makes it convenient to access it. + * Ideally the steps implementations will be abstracted to be indifferent to what object it's currently working on. This will act as + * a placeholder for such functionality. * * @param array $form_state * The drupal form state. * - * @return int - * The current step index. + * @return array + * Returns the 'current' object in the array of NewFedoraObjects, generally this is only used + * when there is one object in the list of objects. */ function islandora_ingest_form_get_object(array $form_state) { $objects = &islandora_ingest_form_get_objects($form_state); diff --git a/islandora.module b/islandora.module index 3f649f74..e2d280e5 100644 --- a/islandora.module +++ b/islandora.module @@ -436,22 +436,22 @@ function islandora_default_islandora_view_object($object) { /** * A helper function to get a connection and return an object for objects specified in the menu path as '%islandora_object'. * - * This should only be used by the Drupal menu wildcard system! As for non existing objects this will return page not found. + * This should only be used by the Drupal menu wildcard system! * - * After some research drupal_not_found(), drupal_access_denied() and others can not be safetly used at this level. Nor can - * They be used at the "access callback" level. Not without hacking core, also it seems roling our own versions of these - * functions will be fruitless. We can still use drupal_goto() though, if we redirect to our own pages for 404, 500 etc. we - * Will be able to deliever the correct message to users. + * When this function returns FALSE the Drupal menu system will issues a "page not found" error, when this function returns NULL, + * the access function is expected to check for the given object and return false generating a "accesss denied" error. * - * @todo For non accessible objects to the user this should return access denied. - * @todo When the repository down this should return a 500 error or a site offline notice. + * This will currently display a message if the repository is inaccessable, ideally this would redirect to another page in such a case, + * as the access function will not be aware of this fact and will trigger the display of the "access denied" page. + * + * @todo When the repository down this should return a 500 error or a site offline notice. Currently only displays a message. * * @param string $object_id * The pid of an object in the menu path identified by '%islandora_object'. * * @return FedoraObject - * If the given object id exists in the repository then this returns a FedoraObject, if no object was found it returns FALSE which triggers a drupal_page_not_found(), if the - * object was inaccessible then NULL is returned, and the access callback will catch that case, triggering an access denied. + * If the given object id exists in the repository then this returns a FedoraObject, if no object was found it returns FALSE which triggers drupal_page_not_found(), if the + * object was inaccessible then NULL is returned, and the access callback is expected to catch that case, triggering drupal_access_denied(). */ function islandora_object_load($object_id) { static $object = NULL, $load_failed = FALSE; // Assume inaccessible. From 8aecdb722f90340722460a00d7c1e4c9054ce617 Mon Sep 17 00:00:00 2001 From: Nigel Banks Date: Mon, 26 Nov 2012 20:12:09 +0000 Subject: [PATCH 07/20] Typo fixes. --- includes/utilities.inc | 2 +- islandora.module | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/includes/utilities.inc b/includes/utilities.inc index a1aefa70..ab41af1e 100644 --- a/includes/utilities.inc +++ b/includes/utilities.inc @@ -186,7 +186,7 @@ function islandora_get_namespace($id) { * @return boolean * TRUE if accessible, FALSE otherwise. */ -function islanodra_namespace_accessible($id) { +function islandora_namespace_accessible($id) { if (variable_get('islandora_namespace_restriction_enforced', FALSE)) { $namespace = islandora_get_namespace($id) . ':'; $allowed_namespaces = explode(" ", variable_get('islandora_pids_allowed', 'default: demo: changeme: islandora: ilives: islandora-book: books: newspapers: ')); diff --git a/islandora.module b/islandora.module index e2d280e5..4859f5b2 100644 --- a/islandora.module +++ b/islandora.module @@ -44,6 +44,7 @@ define('ISLANDORA_POST_PURGE_OBJECT_HOOK', 'islandora_post_purge_object'); define('ISLANDORA_INGEST_STEP_HOOK', 'islandora_ingest_steps'); define('ISLANDORA_PRE_PURGE_DATASTREAM_HOOK', 'islandora_pre_purge_datastream'); define('ISLANDORA_POST_PURGE_DATASTREAM_HOOK', 'islandora_post_purge_datastream'); +define('ISLANDORA_EDIT_DATASTREAM_HOOK', 'islandora_edit_datastream'); /** * Implements hook_menu(). @@ -75,7 +76,7 @@ function islandora_menu() { 'access arguments' => array(FEDORA_ADD_DS), 'file' => 'includes/solution_packs.inc', 'type' => MENU_NORMAL_ITEM, - ); + ); $items['islandora'] = array( 'title' => 'Islandora Repository', 'page callback' => 'islandora_view_default_object', @@ -305,7 +306,7 @@ function islandora_forms($form_id) { */ function islandora_object_access_callback($perm, $object = NULL) { module_load_include('inc', 'islandora', 'includes/utilities'); - return user_access($perm) && is_object($object) && islanodra_namespace_accessible($object->id); + return user_access($perm) && is_object($object) && islandora_namespace_accessible($object->id); } /** @@ -327,7 +328,7 @@ function islandora_object_access_callback($perm, $object = NULL) { */ function islandora_object_datastream_access_callback($perm, $object = NULL, $datastream = NULL) { module_load_include('inc', 'islandora', 'includes/utilities'); - return user_access($perm) && is_object($object) && islanodra_namespace_accessible($object->id) && is_object($datastream); + return user_access($perm) && is_object($object) && islandora_namespace_accessible($object->id) && is_object($datastream); } /** From 595cbb43f47830f6be816ab99f71e909b9edf288 Mon Sep 17 00:00:00 2001 From: Nigel Banks Date: Mon, 26 Nov 2012 20:46:02 +0000 Subject: [PATCH 08/20] Fix for spelling mistakes and coder recommendations. --- includes/add_datastream.form.inc | 10 +++++----- includes/delete_datastream.form.inc | 2 +- includes/delete_object.form.inc | 2 +- includes/globals.inc | 3 ++- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/includes/add_datastream.form.inc b/includes/add_datastream.form.inc index c9b71e34..820a0399 100644 --- a/includes/add_datastream.form.inc +++ b/includes/add_datastream.form.inc @@ -70,7 +70,7 @@ function islandora_add_datastream_form(array $form, array &$form_state, FedoraOb '#required' => TRUE, '#title' => t('Upload Document'), '#size' => 48, - '#description' => t('Select a file to upload.
Files must be less than !size MB.', array('!size' => $upload_size)), + '#description' => t('Select a file to upload.
Files must be less than @size MB.', array('@size' => $upload_size)), '#default_value' => isset($form_state['values']['files']) ? $form_state['values']['files'] : NULL, '#upload_location' => 'temporary://', '#upload_validators' => array( @@ -98,7 +98,7 @@ function islandora_add_datastream_form(array $form, array &$form_state, FedoraOb */ function islandora_add_datastream_form_field_is_not_an_existing_datastream_id(array $element, array &$form_state, array $form) { if (isset($form_state['object'][$element['#value']])) { - form_error($element, t("!title already exists in the object.", array('!title' => $element['#title']))); + form_error($element, t("@title already exists in the object.", array('@title' => $element['#title']))); } } @@ -114,7 +114,7 @@ function islandora_add_datastream_form_field_is_not_an_existing_datastream_id(ar */ function islandora_add_datastream_form_field_starts_with_a_letter(array $element, array &$form_state, array $form) { if (!(preg_match("/^[a-zA-Z]/", $element['#value']))) { - form_error($element, t("!title has to start with a letter.", array('!title' => $element['#title']))); + form_error($element, t("@title has to start with a letter.", array('@title' => $element['#title']))); } } @@ -131,7 +131,7 @@ function islandora_add_datastream_form_field_starts_with_a_letter(array $element function islandora_add_datastream_form_field_is_valid_dsid(array $element, array &$form_state, array $form) { module_load_include('inc', 'islandora', 'includes/utilities'); if (!islandora_is_valid_dsid($element['#value'])) { - form_error($element, t("!title contains invalid characters.", array('!title' => $element['#title']))); + form_error($element, t("@title contains invalid characters.", array('@title' => $element['#title']))); } } @@ -147,7 +147,7 @@ function islandora_add_datastream_form_field_is_valid_dsid(array $element, array */ function islandora_add_datastream_form_field_does_not_contain_a_forward_slash(array $element, array &$form_state, array $form) { if (strpos($element['#value'], '/') !== FALSE) { - form_error($element, t('!title cannot contain a "/" character.', array('!title' => $element['#title']))); + form_error($element, t('@title cannot contain a "/" character.', array('@title' => $element['#title']))); } } diff --git a/includes/delete_datastream.form.inc b/includes/delete_datastream.form.inc index 0bdeb9d5..2ca7c673 100644 --- a/includes/delete_datastream.form.inc +++ b/includes/delete_datastream.form.inc @@ -36,7 +36,7 @@ function islandora_delete_datastream_form(array $form, array &$form_state, Fedor * The ISLANDORA_PRE_PURGE_DATASTREAM_HOOK will query other modules as to whether the given FedoraDatastream * should be: blocked from purging; state set to 'Deleted'; or purged. * - * @see islanodra_delete_datastream(). + * @see islandora_delete_datastream(). * * @param string $object_id * ID of the object diff --git a/includes/delete_object.form.inc b/includes/delete_object.form.inc index a86b948d..df0c40b9 100644 --- a/includes/delete_object.form.inc +++ b/includes/delete_object.form.inc @@ -33,7 +33,7 @@ function islandora_delete_object_form(array $form, array &$form_state, FedoraObj /** * Gives the option of deleting or purging and object. * - * @note The description below probably applies to islanodra_object_purge() function... + * @note The description below probably applies to islandora_object_purge() function... * * The default behaviour is to purge the object to reduce maintenance. * If a solution pack wants to change this behaviour and have the object set to deleted then diff --git a/includes/globals.inc b/includes/globals.inc index 30659e60..c97cdb3f 100644 --- a/includes/globals.inc +++ b/includes/globals.inc @@ -43,7 +43,8 @@ function islandora_get_object_by_id($object_id) { } catch (Exception $e) { if ($e->getCode() == '404') { return FALSE; - } else { + } + else { return NULL; } } From 92915bdd7cf0394e91756368f4655805088fe0a2 Mon Sep 17 00:00:00 2001 From: Nigel Banks Date: Mon, 26 Nov 2012 22:30:07 +0000 Subject: [PATCH 09/20] Remove inline comments, make comments 80 characters or less in length. --- README | 54 +++++++++++- admin/islandora.admin.inc | 4 +- includes/DublinCore.inc | 4 +- includes/add_datastream.form.inc | 26 ++++-- includes/breadcrumb.inc | 25 ++++-- includes/datastream.inc | 9 +- includes/delete_datastream.form.inc | 9 +- includes/delete_object.form.inc | 18 +--- includes/globals.inc | 109 +++++++++++++++--------- includes/ingest.form.inc | 103 ++++++++++++++--------- includes/ingest.menu.inc | 12 ++- includes/object_properties.form.inc | 10 ++- includes/solution_packs.inc | 29 +++---- includes/utilities.inc | 11 ++- islandora.module | 126 ++++++++++++++++++---------- theme/islandora-object-edit.tpl.php | 10 ++- theme/islandora-object.tpl.php | 17 ++-- theme/islandora.theme.inc | 6 +- 18 files changed, 374 insertions(+), 208 deletions(-) diff --git a/README b/README index 7a642cc4..1a3479e8 100644 --- a/README +++ b/README @@ -1,9 +1,59 @@ +CONTENTS OF THIS FILE +--------------------- + + * summary + * requirements + * installation + * configuration + * customization + * troubleshooting + * faq + * contact + * sponsors + + +SUMMARY +------- + Islandora Fedora Repository Module -For installation and customization instructions please see the documentation and the DuraSpace Wiki: +For installation and customization instructions please see the documentation +and the DuraSpace Wiki: https://wiki.duraspace.org/display/ISLANDORA/Islandora -All bugs, feature requests and improvement suggestions are tracked at the DuraSpace JIRA: +All bugs, feature requests and improvement suggestions are tracked at the +DuraSpace JIRA: https://jira.duraspace.org/browse/ISLANDORA + +REQUIREMENTS +------------ + + +INSTALLATION +------------ + + +CONFIGURATION +------------- + + +CUSTOMIZATION +------------- + + +TROUBLESHOOTING +--------------- + + +F.A.Q. +------ + + +CONTACT +------- + + +SPONSORS +-------- \ No newline at end of file diff --git a/admin/islandora.admin.inc b/admin/islandora.admin.inc index 4032c9ac..0308cc3f 100644 --- a/admin/islandora.admin.inc +++ b/admin/islandora.admin.inc @@ -2,7 +2,9 @@ /** * @file - * islandora.admin.inc: This file contains the general islandora admin form and callback functions. + * + * islandora.admin.inc: This file contains the general islandora admin form and + * callback functions. */ /** diff --git a/includes/DublinCore.inc b/includes/DublinCore.inc index a2baa81f..7c2b094c 100644 --- a/includes/DublinCore.inc +++ b/includes/DublinCore.inc @@ -2,6 +2,7 @@ /** * @file + * * Implements a simple class for working with Dublin Core data and exporting it * back to XML. Inspiration and design shamelessly stolen from the pyfedora * project at http://pypi.python.org/pypi/pyfedora/0.1.0 @@ -32,7 +33,8 @@ class DublinCore { public $owner; /** - * Constructs a DublinCore object from a Fedora_Item object and populates the $dc array. + * Constructs a DublinCore object from a Fedora_Item object and populates the + * $dc array. * * @param string $dc_xml */ diff --git a/includes/add_datastream.form.inc b/includes/add_datastream.form.inc index 820a0399..fa998d54 100644 --- a/includes/add_datastream.form.inc +++ b/includes/add_datastream.form.inc @@ -41,8 +41,10 @@ function islandora_add_datastream_form(array $form, array &$form_state, FedoraOb 'dsid' => array( '#title' => 'Datastream ID', '#description' => t('An ID for this stream that is unique to this object.' . - 'Must start with a letter and contain only alphanumeric characters and dashes and underscores.' . - 'Datastreams that are defined by the content model don\'t currently exist: @unused_dsids.', + 'Must start with a letter and contain only alphanumeric ' . + 'characters and dashes and underscores. Datastreams that ' . + 'are defined by the content model don\'t currently exist: ' . + '@unused_dsids.', array('@unused_dsids' => $unused_datastreams) ), '#type' => 'textfield', @@ -75,7 +77,8 @@ function islandora_add_datastream_form(array $form, array &$form_state, FedoraOb '#upload_location' => 'temporary://', '#upload_validators' => array( 'file_validate_extensions' => array(NULL), - 'file_validate_size' => array($upload_size * 1024 * 1024), // Assume its specified in MB + // Assume its specified in MB + 'file_validate_size' => array($upload_size * 1024 * 1024), ), ), 'submit' => array( @@ -119,7 +122,8 @@ function islandora_add_datastream_form_field_starts_with_a_letter(array $element } /** - * Checks if the given form field contains only valid characters for a datstream id. + * Checks if the given form field contains only valid characters for a + * datastream id. * * @param array $element * The form field to check. @@ -152,7 +156,8 @@ function islandora_add_datastream_form_field_does_not_contain_a_forward_slash(ar } /** - * Checks if the given datastream id requires that the upload file be of a certian MIME type. + * Checks if the given datastream id requires that the upload file be of a + * certian MIME type. * * @param array $form * The Drupal form. @@ -174,7 +179,8 @@ function islandora_add_datastream_form_validate(array $form, array &$form_state) } /** - * Adds the new datastream based on the submitted values, only creates managed datastreams at the moment. + * Adds the new datastream based on the submitted values, only creates managed + * datastreams at the moment. * * @param array $form * The Drupal form. @@ -202,12 +208,14 @@ function islandora_add_datastream_form_submit(array $form, array &$form_state) { } /** - * Callback for an autocomplete field in the admin add datastream form. It lists the missing required (may be optional) datastreams. + * Callback for an autocomplete field in the admin add datastream form. + * It lists the missing required (may be optional) datastreams. * * @param FedoraObject $object - * The object used to check for missing required datastreams used to populate the options in this callback. + * The object used to check for missing required datastreams used to populate + * the options in this callback. * @param string $query - * The user query to match against the missing required datastreams. + * vThe user query to match against the missing required datastreams. */ function islandora_add_datastream_form_autocomplete_callback(FedoraObject $object, $query = '') { module_load_include('inc', 'islandora', 'includes/content_model'); diff --git a/includes/breadcrumb.inc b/includes/breadcrumb.inc index b7c30c7f..6abb480c 100644 --- a/includes/breadcrumb.inc +++ b/includes/breadcrumb.inc @@ -7,10 +7,12 @@ */ /** - * Get an array of links to be passed to drupal_set_breadcrumb(). This is used for generating the bread-crumbs for the view object page. + * Get an array of links to be passed to drupal_set_breadcrumb(). This is used + * for generating the bread-crumbs for the view object page. * * Each link in the bread-crumbs represents a member of the given objects ancestry - * which is identified by any of the following RELS-EXT terms (isMemberOf,isMemberOfCollection,isPartOf). + * which is identified by any of the following RELS-EXT terms + * (isMemberOf,isMemberOfCollection,isPartOf). * * @param FedoraObject $object * An object whose ancestry will be mapped to bread-crumbs. @@ -18,12 +20,15 @@ * @see drupal_set_breadcrumb() * * @return array - * Array of links, starting with most distant ancestor proceeding up to but not including the given object. For use in the function drupal_set_breadcrumb(). + * Array of links, starting with most distant ancestor proceeding up to but + * not including the given object. For use in the function + * drupal_set_breadcrumb(). */ function islandora_get_breadcrumbs($object) { $breadcrumbs = array(); islandora_get_breadcrumbs_recursive($object->id, $breadcrumbs, $object->repository); - if (isset($breadcrumbs[0])) { // Remove the actual object. + if (isset($breadcrumbs[0])) { + // Remove the actual object. unset($breadcrumbs[0]); } $breadcrumbs = array_reverse($breadcrumbs); @@ -35,7 +40,8 @@ function islandora_get_breadcrumbs($object) { * * @todo Make fully recursive... * - * @todo Could use some clean up, can't be called multiple times safely due to the use of static variables. + * @todo Could use some clean up, can't be called multiple times safely due to + * the use of static variables. * * @param string $pid * THe object id whose parent will be fetched for the next link. @@ -45,7 +51,8 @@ function islandora_get_breadcrumbs($object) { * The fedora repository. */ function islandora_get_breadcrumbs_recursive($pid, array &$breadcrumbs, FedoraRepository $repository) { - // Before executing the query, we hve a base case of accessing the top-level collection + // Before executing the query, we hve a base case of accessing the + // top-level collection static $max_level = 10; static $level = -1; @@ -88,8 +95,10 @@ function islandora_get_breadcrumbs_recursive($pid, array &$breadcrumbs, FedoraRe islandora_get_breadcrumbs_recursive($parent, $breadcrumbs, $repository); } else { - $breadcrumbs[] = '...'; // Add an non-link, as we don't know how to get back to the root. - islandora_get_breadcrumbs_recursive($root, $breadcrumbs, $repository); // And render the last two links and break (on the next pass). + // Add an non-link, as we don't know how to get back to the root. + $breadcrumbs[] = '...'; + // And render the last two links and break (on the next pass). + islandora_get_breadcrumbs_recursive($root, $breadcrumbs, $repository); } } } diff --git a/includes/datastream.inc b/includes/datastream.inc index bff346b3..1c67f9ac 100644 --- a/includes/datastream.inc +++ b/includes/datastream.inc @@ -3,7 +3,8 @@ /** * @file * - * This file contains the admin form and callback functions for datastream manipulations. + * This file contains the admin form and callback functions for datastream + * manipulations. */ /** @@ -25,7 +26,8 @@ function islandora_download_datastream(FedoraDatastream $datastream) { * @param FedoraDatastream $datastream * The datastream to view/download. * @param boolean $download - * If TRUE the file is download to the user computer for viewing otherwise it will attempt to display in the browser natively. + * If TRUE the file is download to the user computer for viewing otherwise it + * will attempt to display in the browser natively. */ function islandora_view_datastream(FedoraDatastream $datastream, $download = FALSE) { header_remove('Cache-Control'); @@ -53,7 +55,8 @@ function islandora_view_datastream(FedoraDatastream $datastream, $download = FAL * The datastream to check. * * @return string - * A human readable size of the given datastream, or '-' if the size could not be determined. + * A human readable size of the given datastream, or '-' if the size could not + * be determined. */ function islandora_datastream_get_human_readable_size(FedoraDatastream $datastream) { module_load_include('inc', 'islandora', 'includes/utilities'); diff --git a/includes/delete_datastream.form.inc b/includes/delete_datastream.form.inc index 2ca7c673..9c3cd368 100644 --- a/includes/delete_datastream.form.inc +++ b/includes/delete_datastream.form.inc @@ -3,7 +3,8 @@ /** * @file * - * This file contains the admin (confirmation) form and callback functions to delete/purge a datastream. + * This file contains the admin (confirmation) form and callback functions to + * delete/purge a datastream. */ /** @@ -31,9 +32,11 @@ function islandora_delete_datastream_form(array $form, array &$form_state, Fedor } /** - * Submit handler for the delete datastream form. Purges/Delete's the given FedoraDatastream if possible. + * Submit handler for the delete datastream form. Purges/Delete's the given + * FedoraDatastream if possible. * - * The ISLANDORA_PRE_PURGE_DATASTREAM_HOOK will query other modules as to whether the given FedoraDatastream + * The ISLANDORA_PRE_PURGE_DATASTREAM_HOOK will query other modules as to + * whether the given FedoraDatastream * should be: blocked from purging; state set to 'Deleted'; or purged. * * @see islandora_delete_datastream(). diff --git a/includes/delete_object.form.inc b/includes/delete_object.form.inc index df0c40b9..159b4aed 100644 --- a/includes/delete_object.form.inc +++ b/includes/delete_object.form.inc @@ -3,7 +3,8 @@ /** * @file * - * This file contains the admin (confirmation) form and callback functions to purge an object. + * This file contains the admin (confirmation) form and callback functions to + * purge an object. */ /** @@ -31,20 +32,7 @@ function islandora_delete_object_form(array $form, array &$form_state, FedoraObj } /** - * Gives the option of deleting or purging and object. - * - * @note The description below probably applies to islandora_object_purge() function... - * - * The default behaviour is to purge the object to reduce maintenance. - * If a solution pack wants to change this behaviour and have the object set to deleted then - * it can respond to the 'islandora_pre_purge_object' hook with an array containing the pair - * 'delete' => TRUE. - * Once the object has been deleted/purged then a second call lets the solution packs know that - * the object has been dealt with. In this call the object id and content models are sent out so - * that the solution packs can act on this news. There is no guarantee that the object still exists - * and so the object object isn't sent. - * - * @todo Clean Up! + * Delete's the object in questionGives deloption of deleting or purging and object. * * @param array $form * The Drupal form. diff --git a/includes/globals.inc b/includes/globals.inc index c97cdb3f..e85a71bc 100644 --- a/includes/globals.inc +++ b/includes/globals.inc @@ -3,11 +3,13 @@ /** * @file * - * This file contains any functions meant to be part of the global space, ie. functions that and other modules will use without including a module file. + * This file contains any functions meant to be part of the global space, ie. + * functions that and other modules will use without including a module file. */ /** - * Just a wrapper around fetchings the IslandoraTuque object, with some very basic error logging. + * Just a wrapper around fetchings the IslandoraTuque object, with some very + * basic error logging. * * @return IslandoraTuque * A IslandoraTuque instance @@ -25,13 +27,15 @@ function islandora_get_tuque_connection() { } /** - * Gets the given object if found, NULL if it is inaccessible and FALSE if it was not found. + * Gets the given object if found, NULL if it is inaccessible and FALSE if it + * was not found. * * @param string $object_id * The identifier of the object to get. * * @return FedoraObject - * The object if found, NULL if it is inaccessible and FALSE if it was not found. + * The object if found, NULL if it is inaccessible and FALSE if it was not + * found. */ function islandora_get_object_by_id($object_id) { $tuque = islandora_get_tuque_connection(); @@ -52,7 +56,8 @@ function islandora_get_object_by_id($object_id) { else { IslandoraTuque::getError(); } - return NULL; // Assuming access denied in all other cases for now. + // Assuming access denied in all other cases for now. + return NULL; } /** @@ -110,13 +115,16 @@ function islandora_delete_object(FedoraObject &$object) { $models = $object->models; $action = islandora_pre_delete_object($object); switch ($action) { - case 'blocked': // Do nothing. + case 'blocked': + // Do nothing. return FALSE; - case 'delete': // Change the state to deleted. + case 'delete': + // Change the state to deleted. $object->delete(); islandora_post_delete_object($object_id, $models); return TRUE; - default: // Purge + default: + // Purge $object->repository->purgeObject($object_id); islandora_post_delete_object($object_id, $models); $object = NULL; @@ -161,26 +169,32 @@ function islandora_post_delete_object($object_id, array $models) { * Delete's/Purges the given datastream. * * @throws Exception - * Which types are undefined, but more than likely because of the hooks there will be several kinds. + * Which types are undefined, but more than likely because of the hooks + * there will be several kinds. * * @param FedoraDatastream $datastream * The datastream to delete. * * @return boolean - * TRUE is returned if the datastream was Deleted/Purged, FALSE if it was blocked. + * TRUE is returned if the datastream was Deleted/Purged, FALSE if it was + * blocked. */ function islandora_delete_datastream(FedoraDatastream &$datastream) { $datastream_id = $datastream->id; $object = $datastream->parent; $action = islandora_pre_delete_datastream($datastream); switch ($action) { - case 'blocked': // Do nothing. + case 'blocked': + // Do nothing. return FALSE; - case 'delete': // Change the state to deleted. + case 'delete': + // Change the state to deleted. $object[$datastream_id]->state = 'D'; - islandora_post_delete_datastream($object, $datastream_id); // @todo Differentiate between delete/purge in the hooks. + // @todo Differentiate between delete/purge in the hooks. + islandora_post_delete_datastream($object, $datastream_id); return TRUE; - default: // Purge + default: + // Purge $object->purgeDatastream($datastream_id); islandora_post_delete_datastream($object, $datastream_id); $datastream = NULL; @@ -189,27 +203,29 @@ function islandora_delete_datastream(FedoraDatastream &$datastream) { } /** - * The default behaviour is to 'purge' the datastream but this can be overridden by modules that implement - * the 'islandora_pre_purge_datastream' hook. + * The default behaviour is to 'purge' the datastream but this can be overridden + * by modules that implement the 'islandora_pre_purge_datastream' hook. * * @todo make this an alter. * * The returned array can include a 'block' => TRUE - * pair which will prevent the datastream from being deleted if it particularly needed for - * a certain function. Returning 'delete' => TRUE will cause the datastream to be put into - * a deleted state. + * pair which will prevent the datastream from being deleted if it particularly + * needed for a certain function. Returning 'delete' => TRUE will cause the + * datastream to be put into a deleted state. * * @param FedoraDatastream $datastream * The datastream to delete. * * @return string - * The action to take when deleting the given datastream, either 'purge', 'delete', or 'block'. + * The action to take when deleting the given datastream, either 'purge', + * 'delete', or 'block'. */ function islandora_pre_delete_datastream(FedoraDatastream $datastream) { module_load_include('inc', 'islandora', 'includes/utilities'); $results = array(); foreach (islandora_build_hook_list(ISLANDORA_PRE_PURGE_DATASTREAM_HOOK, $datastream->parent->models) as $hook) { - $results = array_merge_recursive($results, module_invoke_all($hook, $datastream)); // @note Not sure this will work the greatest, probably an alter would be better... + // Not sure this will work the greatest, probably an alter would be better.. + $results = array_merge_recursive($results, module_invoke_all($hook, $datastream)); } $action = (isset($results['block']) && $results['block']) ? 'block' : FALSE; $action = (!$action && isset($results['delete']) && $results['delete']) ? 'delete' : $action; @@ -235,15 +251,18 @@ function islandora_post_delete_datastream(FedoraObject $object, $datastream_id) } /** - * Gets any objects that the given object has a (isMemberOf, isMemberOfCollection) relationship with. + * Gets any objects that the given object has a + * (isMemberOf, isMemberOfCollection) relationship with. * - * This function gets its info from the RELS-EXT directly rather than through an risearch. + * This function gets its info from the RELS-EXT directly rather than through an + * risearch. * * @param FedoraObject $object * The object whose parents will be returned. * * @return array - * An array of FedoraObject's that the given object has a (isMemberOf, isMemberOfCollection) relationship with. + * An array of FedoraObject's that the given object has a + * (isMemberOf, isMemberOfCollection) relationship with. */ function islandora_get_parents_from_rels_ext(FedoraObject $object) { try { @@ -252,20 +271,24 @@ function islandora_get_parents_from_rels_ext(FedoraObject $object) { $object->relationships->get(FEDORA_RELS_EXT_URI, 'isMemberOf')); } catch (RepositoryException $e) { + // @todo some logging would be nice, not sure what this throws. return array(); - } // @todo some logging would be nice, not sure what this throws. + } $collections = array_map(function($o) { return islandora_get_object_by_id($o['object']['value']); }, $collections); return array_filter($collections); } /** - * Checks what datastreams the object already has against its required datastreams as defined by its content models, and returns their intersection. + * Checks what datastreams the object already has against its required + * datastreams as defined by its content models, and returns their intersection. * * @param FedoraObject $object - * The object which models will be used to determine what datastreams it should have. + * The object which models will be used to determine what datastreams it + * should have. * * @return array - * The DS-COMPOSITE-MODEL defined datastreams that are required for the given object, but not already present. + * The DS-COMPOSITE-MODEL defined datastreams that are required for the given + * object, but not already present. */ function islandora_get_missing_datastreams_requirements(FedoraObject $object) { $datastreams = islandora_get_datastreams_requirements($object); @@ -278,19 +301,24 @@ function islandora_get_missing_datastreams_requirements(FedoraObject $object) { } /** - * Checks the object's content model's for which datastream are expected to be used with this object, as defined by the DS-COMPOSITE-MODEL datastreams. + * Checks the object's content model's for which datastream are expected to be + * used with this object, as defined by the DS-COMPOSITE-MODEL datastreams. * - * For duplicate datastreams in the models, the first model defines the datastreams attributes regardless of what other models define. + * For duplicate datastreams in the models, the first model defines the + * datastreams attributes regardless of what other models define. * This should be undefined behavior according to the documentation. * @see https://wiki.duraspace.org/display/FEDORA34/Fedora+Digital+Object+Model#FedoraDigitalObjectModel-ContentModelObjectCMODEL * * @param FedoraObject $object - * The object which models will be used to determine what datastreams it should have. + * The object which models will be used to determine what datastreams it + * should have. * - * @see islandora_get_required_datastreams_from_content_model() from more details on the return value. + * @see islandora_get_required_datastreams_from_content_model() from more + * details on the return value. * * @return array - * The DS-COMPOSITE-MODEL defined datastreams that are required for the given object. + * The DS-COMPOSITE-MODEL defined datastreams that are required for the given + * object. */ function islandora_get_datastreams_requirements(FedoraObject $object) { $dsids = array(); @@ -298,20 +326,24 @@ function islandora_get_datastreams_requirements(FedoraObject $object) { $model = islandora_get_object_by_id($model); $dsids += islandora_get_datastreams_requirements_from_content_model($model); } - unset($dsids['AUDIT']); // The AUDIT Datastream can not really be added, so it can't really be missing. + // The AUDIT Datastream can not really be added, so it can't really be missing. + unset($dsids['AUDIT']); return $dsids; } /** - * Checks the given content model for which datastreams are required for subscribing objects, as defined by it's DS-COMPOSITE-MODEL datastream. + * Checks the given content model for which datastreams are required for + * subscribing objects, as defined by it's DS-COMPOSITE-MODEL datastream. * * @todo Add support for fetching the schema information. * * @param FedoraObject $object - * The content model whose DS-COMPOSITE-MODEL datastream will be used to determine what datastreams are required. + * The content model whose DS-COMPOSITE-MODEL datastream will be used to + * determine what datastreams are required. * * @return array - * The DS-COMPOSITE-MODEL defined datastreams that are required for the given object. + * The DS-COMPOSITE-MODEL defined datastreams that are required for the given + * object. * * @code * array( @@ -389,7 +421,8 @@ function islandora_prepare_new_object($namespace = NULL, $label = NULL, $datastr $dsid = $ds['dsid']; $label = isset($ds['label']) ? $ds['label'] : ''; $mimetype = isset($ds['mimetype']) ? $ds['mimetype'] : 'text/xml'; - $control_group = (isset($ds['control_group']) && in_array($ds['control_group'], array('X', 'M', 'R', 'E'))) ? $ds['control_group'] : 'M'; // Default 'Managed' + // Default 'Managed' + $control_group = (isset($ds['control_group']) && in_array($ds['control_group'], array('X', 'M', 'R', 'E'))) ? $ds['control_group'] : 'M'; $datastream_file = url($ds['datastream_file'], array('absolute' => TRUE)); $datastream = $object->constructDatastream($dsid, $control_group); $datastream->label = $label; diff --git a/includes/ingest.form.inc b/includes/ingest.form.inc index 77717257..ba2f30d9 100644 --- a/includes/ingest.form.inc +++ b/includes/ingest.form.inc @@ -3,19 +3,21 @@ /** * @file * - * Defines the multi-page ingest form and any relevant hooks and functions for defining the multi-page ingest forms. + * Defines the multi-page ingest form and any relevant hooks and functions for + * defining the multi-page ingest forms. */ /** - * Ingest form build function. Initializes the form state, and builds the initial list of steps, - * excutes the current step. + * Ingest form build function. Initializes the form state, and builds the + * initial list of steps, excutes the current step. * * @param array $form * The drupal form. * @param array $form_state * The drupal form state. * @param array $configuration - * A list of key value pairs that are used to build the list of steps to be executed. + * A list of key value pairs that are used to build the list of steps to be + * executed. * * @return array * The form definition of the current step. @@ -33,13 +35,17 @@ function islandora_ingest_form(array $form, array &$form_state, array $configura * @param array $form_state * The drupal form state. * @param array $configuration - * A list of key value pairs that are used to build the list of steps to be executed. + * A list of key value pairs that are used to build the list of steps to be + * executed. */ function islandora_ingest_form_init_form_state(array &$form_state, array $configuration) { - islandora_ingest_form_init_form_state_storage($form_state, $configuration); // First time initialization of storage. + // First time initialization of storage. + islandora_ingest_form_init_form_state_storage($form_state, $configuration); $steps = &islandora_ingest_form_get_steps($form_state); - usort($steps, 'drupal_sort_weight'); // Always re-sort the steps just incase any build/submit handlers have appended new steps. - islandora_ingest_form_step_form_load_include($form_state); // Load any required files for the current step. + // Always re-sort the steps just incase any build/submit handlers have appended new steps. + usort($steps, 'drupal_sort_weight'); + // Load any required files for the current step. + islandora_ingest_form_step_form_load_include($form_state); } /** @@ -48,12 +54,15 @@ function islandora_ingest_form_init_form_state(array &$form_state, array $config * @param array $form_state * The drupal form state. * @param array $configuration - * A list of key value pairs that are used to build the list of steps to be executed. + * A list of key value pairs that are used to build the list of steps to be + * executed. */ function islandora_ingest_form_init_form_state_storage(array &$form_state, array $configuration) { if (empty($form_state['islandora'])) { - $id = isset($configuration['id']) ? $configuration['id'] : NULL; // Use ID if given. - $namespace = isset($configuration['namespace']) && !isset($id) ? $configuration['namespace'] : $id; // Use namespace if ID not given. + // Use ID if given. + $id = isset($configuration['id']) ? $configuration['id'] : NULL; + // Use namespace if ID not given. + $namespace = isset($configuration['namespace']) && !isset($id) ? $configuration['namespace'] : $id; $label = isset($configuration['label']) ? $configuration['label'] : 'New Object'; $relationship_map = function($o) { return array('relationship' => 'isMemberOfCollection', 'pid' => $o); }; $relationships = empty($configuration['collections']) ? array() : array_map($relationship_map, $configuration['collections']); @@ -68,8 +77,8 @@ function islandora_ingest_form_init_form_state_storage(array &$form_state, array } /** - * Executes the current step, building the form definition and appending on any additonal elements - * required for the step to function. + * Executes the current step, building the form definition and appending on any + * additonal elements required for the step to function. * * @param array $form * The drupal form. @@ -87,7 +96,8 @@ function islandora_ingest_form_execute_step(array $form, array &$form_state) { $args = isset($step_info['args']) ? array_merge($args, $step_info['args']) : $args; $form = call_user_func_array($step_info['form_id'], $args); return islandora_ingest_form_stepify($form, $form_state, $step_info); - case 'batch': // @todo Implement if possible. + case 'batch': + // @todo Implement if possible. break; } return array(); @@ -127,11 +137,13 @@ function islandora_ingest_form_previous_button() { '#value' => t('Previous'), '#name' => 'prev', '#submit' => array('islandora_ingest_form_previous_submit'), - /** - * #limit_validation_errors, is why when the previous button is pressed no values persisted in the form_state, but its also what allows us to go back when validation errors occur. - * To have a better solution going forward we can either limit validation only on required fields, or we can convert all required fields to use #element_validation functions, and - * Remove the need for #limit_validation_errors. Or maybe there is some other solution, regardless of what it is, it won't be standard. - */ + // #limit_validation_errors, is why when the previous button is pressed no + // values persisted in the form_state, but its also what allows us to go + // back when validation errors occur. To have a better solution going + // forward we can either limit validation only on required fields, or we can + // convert all required fields to use #element_validation functions, and + // Remove the need for #limit_validation_errors. Or maybe there is some + // other solution, regardless of what it is, it won't be standard. '#limit_validation_errors' => array() ); } @@ -151,10 +163,10 @@ function islandora_ingest_form_previous_button() { function islandora_ingest_form_previous_submit(array $form, array &$form_state) { $step = &islandora_ingest_form_get_step($form_state); $step_info = &islandora_ingest_form_get_step_info($form_state, $step); - $step_info['values'] = $form_state['values']; // Store values - $step--; // Goto previous step - $step_info = &islandora_ingest_form_get_step_info($form_state, $step); // Get values - $form_state['values'] = isset($step_info['values']) ? $step_info['values'] : NULL; // Use values + $step_info['values'] = $form_state['values']; + $step--; + $step_info = &islandora_ingest_form_get_step_info($form_state, $step); + $form_state['values'] = isset($step_info['values']) ? $step_info['values'] : NULL; $form_state['rebuild'] = TRUE; } @@ -196,10 +208,10 @@ function islandora_ingest_form_next_button(array $step_info) { function islandora_ingest_form_next_submit(array $form, array &$form_state) { $step = &islandora_ingest_form_get_step($form_state); $step_info = &islandora_ingest_form_get_step_info($form_state, $step); - $step_info['values'] = $form_state['values']; // Store Values - $step++; // Goto Next Step + $step_info['values'] = $form_state['values']; + $step++; $step_info = &islandora_ingest_form_get_step_info($form_state, $step); - $form_state['values'] = isset($step_info['values']) ? $step_info['values'] : array(); // Restore Values if Stored. + $form_state['values'] = isset($step_info['values']) ? $step_info['values'] : array(); $form_state['rebuild'] = TRUE; } @@ -242,7 +254,8 @@ function islandora_ingest_form_submit(array $form, array &$form_state) { islandora_add_object($object); $form_state['redirect'] = "islandora/object/{$object->id}"; } catch (Exception $e) { - watchdog('islandora', $e->getMessage(), NULL, WATCHDOG_ERROR); // If post hooks throws it may already exist at this point but may be invalid, so don't say failed :P + // If post hooks throws it may already exist at this point but may be invalid, so don't say failed :P + watchdog('islandora', $e->getMessage(), NULL, WATCHDOG_ERROR); drupal_set_message(t('A problem occured while ingesting "@label" (ID: @pid), please notifiy the administrator.', array('@label' => $object->label, '@pid' => $object->id)), 'error'); } } @@ -262,13 +275,15 @@ function islandora_ingest_form_get_configuration(array $form_state) { } /** - * Gets a reference to the stored NewFedoraObject's which are to be ingested when the final step submits. + * Gets a reference to the stored NewFedoraObject's which are to be ingested + * when the final step submits. * * @param array $form_state * The drupal form state. * * @return array - * A reference to the stored NewFedoraObjects to be ingested when the final step submits. + * A reference to the stored NewFedoraObjects to be ingested when the final + * step submits. */ function &islandora_ingest_form_get_objects(array $form_state) { return $form_state['islandora']['objects']; @@ -277,16 +292,18 @@ function &islandora_ingest_form_get_objects(array $form_state) { /** * Gets a single object from the stored NewFedoraObject's. * - * @note - In our current use case we are only dealing with a single object ingest, this makes it convenient to access it. - * Ideally the steps implementations will be abstracted to be indifferent to what object it's currently working on. This will act as - * a placeholder for such functionality. + * @note - In our current use case we are only dealing with a single object + * ingest, this makes it convenient to access it. Ideally the steps + * implementations will be abstracted to be indifferent to what object it's + * currently working on. This will act as a placeholder for such + * functionality. * * @param array $form_state * The drupal form state. * * @return array - * Returns the 'current' object in the array of NewFedoraObjects, generally this is only used - * when there is one object in the list of objects. + * Returns the 'current' object in the array of NewFedoraObjects, generally + * this is only used when there is one object in the list of objects. */ function islandora_ingest_form_get_object(array $form_state) { $objects = &islandora_ingest_form_get_objects($form_state); @@ -307,7 +324,8 @@ function &islandora_ingest_form_get_step(array &$form_state) { } /** - * Get a reference to the step info of the given step or the current step if none is given. + * Get a reference to the step info of the given step or the current step if + * none is given. * * @param array $form_state * The drupal form state. @@ -323,7 +341,8 @@ function &islandora_ingest_form_get_step_info(array &$form_state, $step = NULL) if (!empty($steps[$step])) { return $steps[$step]; } - return NULL; // @todo deal with unknown case. + // @todo deal with unknown case. + return NULL; } /** @@ -346,13 +365,14 @@ function &islandora_ingest_form_get_steps(array &$form_state) { * The drupal form state. */ function islandora_ingest_form_step_form_load_include(array &$form_state) { - form_load_include($form_state, 'inc', 'islandora', 'includes/ingest.form'); // Always load this file. + form_load_include($form_state, 'inc', 'islandora', 'includes/ingest.form'); $step_info = islandora_ingest_form_get_step_info($form_state); + // Load include files if (isset($step_info['file']) && isset($step_info['module'])) { $matches = array(); preg_match('/^(.*)\.(.*)$/', $step_info['file'], $matches); list($file, $name, $type) = $matches; - form_load_include($form_state, $type, $step_info['module'], $name); // Load include files. + form_load_include($form_state, $type, $step_info['module'], $name); } } @@ -371,7 +391,9 @@ function islandora_ingest_form_get_step_count(array $form_state) { } /** - * Buildes the initial list of ingest steps. Sorted by weight expected range between -50 to 50. + * Buildes the initial list of ingest steps. + * + * Sorted by weight expected range between -50 to 50. * * The sort order is undefined for steps which have the same weight. * @@ -379,7 +401,8 @@ function islandora_ingest_form_get_step_count(array $form_state) { * The configuration options used to build the multi-paged ingest process. * * @return array - * The initial list of sorted ingest steps as defined by all implementers of ISLANDORA_INGEST_STEP_HOOK. + * The initial list of sorted ingest steps as defined by all implementers + * of ISLANDORA_INGEST_STEP_HOOK. */ function islandora_ingest_get_steps(array $configuration) { module_load_include('inc', 'islandora', 'includes/utilities'); diff --git a/includes/ingest.menu.inc b/includes/ingest.menu.inc index cb61b906..ac551014 100644 --- a/includes/ingest.menu.inc +++ b/includes/ingest.menu.inc @@ -14,9 +14,10 @@ */ function islandora_ingest_callback() { $configuration = islandora_ingest_get_configuration(); - if ($configuration === FALSE) { // Redirect back to referer or top level collection. + if ($configuration === FALSE) { drupal_set_message(t('Invalid ingest configuration.'), 'error'); $redirect = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''; + // Redirect back to referer or top level collection. drupal_goto($redirect); } module_load_include('inc', 'islandora', 'includes/ingest.form'); @@ -26,10 +27,13 @@ function islandora_ingest_callback() { /** * Fetches/validates the ingest configuration from the $_GET parameters. * - * Generic parameters as accepted by all ingest processes, other modules may add to this list. + * Generic parameters as accepted by all ingest processes, other modules may + * add to this list. * id -> The pid of the object to create. optional. - * models -> Comma delimited list of all the content models the created object should have. - * collections -> Comma delimited list of all the collections the created object should belong to. + * models -> Comma delimited list of all the content models the created object + * should have. + * collections -> Comma delimited list of all the collections the created + * object should belong to. * * @return array * The configuration options used to build the multi-paged ingest process. diff --git a/includes/object_properties.form.inc b/includes/object_properties.form.inc index d5e7a978..4cafd36c 100644 --- a/includes/object_properties.form.inc +++ b/includes/object_properties.form.inc @@ -32,11 +32,15 @@ function islandora_object_properties_form(array $form, array &$form_state, Fedor '#default_value' => $object->label, '#required' => 'TRUE', '#description' => t('A Human readable label'), - '#size' => 120, // Double the normal length - '#maxlength' => 255, // Max length for a Fedora Label + // Double the normal length + '#size' => 120, + // Max length for a Fedora Label + '#maxlength' => 255, '#type' => 'textfield' ), - 'object_owner' => array( // @todo Make this into an autocomplete field that list the users in the system as well. + // @todo Make this into an autocomplete field that list the users in the + // system as well. + 'object_owner' => array( '#title' => t('Owner'), '#default_value' => $object->owner, '#required' => FALSE, diff --git a/includes/solution_packs.inc b/includes/solution_packs.inc index ebb9e5f5..a54b2fb4 100644 --- a/includes/solution_packs.inc +++ b/includes/solution_packs.inc @@ -3,7 +3,8 @@ /** * @file * - * This file contains all admin and callback functions for solution pack management. + * This file contains all admin and callback functions for solution pack + * management. */ /** @@ -69,25 +70,15 @@ function islandora_solution_pack_form($form, &$form_state, $solution_pack_modul '#value' => $objects, ); - // table - // header $table_header = array(t('Label'), t('PID'), t('Status')); $table_rows = array(); - // loop over defined objects foreach ($objects as $object) { $datastreams = NULL; if (isset($object['pid'])) { - // set variables $pid = $object['pid']; - - // table row $table_row = array(); - - // check object status $object_status = islandora_check_object_status($object); - - // set status labels switch ($object_status) { case 'up_to_date': $object_status = t('Up-to-date'); @@ -130,7 +121,6 @@ function islandora_solution_pack_form($form, &$form_state, $solution_pack_modul '#suffix' => '', ); - // install status $form['solution_pack']['install_status'] = array( '#markup' => '' . t('Object status:') . ' ', '#prefix' => '
', @@ -269,8 +259,6 @@ function islandora_batch_reingest_object($object_model, &$context) { function islandora_install_solution_pack($module_name = NULL, $op = 'install') { // check if a module name is given. // @TODO: check module name for existance if (!empty($module_name)) { - - // include files module_load_include('module', 'islandora', 'islandora'); module_load_include('inc', 'islandora', 'includes/utilities'); module_load_include('module', $module_name, $module_name); @@ -382,7 +370,8 @@ function islandora_install_solution_pack($module_name = NULL, $op = 'install') { * * @see islandora_solution_pack_form() * @see islandora_install_solution_pack() - * @TODO: should this function live in islandora.module so it can be called easier without having to include the solution_packs.inc file? + * @todo: Should this function live in islandora.module so it can be called + * easier without having to include the solution_packs.inc file? */ function islandora_check_object_status($object_model = array()) { if (!empty($object_model)) { @@ -409,7 +398,8 @@ function islandora_check_object_status($object_model = array()) { $object_status = 'missing'; } else { - // object defined with single datastream file // @TODO: should dsversion be mandatory for the check to valid? + // object defined with single datastream file + // @TODO: should dsversion be mandatory for the check to valid? if (isset($object_model['dsid']) && isset($object_model['datastream_file']) && isset($object_model['dsversion'])) { $datastreams = array( array( @@ -580,7 +570,9 @@ function islandora_viewers_form($variable_id = NULL, $mimetype = NULL) { '#type' => 'item', '#title' => t('Select a viewer'), '#description' => t('Preferred viewer for your solution pack. These may be provided by third-party modules.'), - '#tree' => TRUE, // this attribute is important to return the submitted values in a deeper nested arrays in + // This attribute is important to return the submitted values in a deeper + // nested arrays in + '#tree' => TRUE, '#theme' => 'islandora_viewers_table', ); @@ -631,7 +623,8 @@ function islandora_viewers_form($variable_id = NULL, $mimetype = NULL) { * Returns all defined viewers. * * @param string $mimetype - * specify a mimetype to return only viewers that support this certain mimetype. + * specify a mimetype to return only viewers that support this certain + * mimetype. * @return * array of viewer definitions, or FALSE if none are found. */ diff --git a/includes/utilities.inc b/includes/utilities.inc index ab41af1e..b9cea493 100644 --- a/includes/utilities.inc +++ b/includes/utilities.inc @@ -156,7 +156,9 @@ function islandora_escape_pid_for_function($pid) { * Gets the namespace of the given id. * * @param string $id - * Either a PID or namespace to check for accessibility. Any string like those below are fine. + * Either a PID or namespace to check for accessibility. Any string like those + * below are fine. + * * @code * 'islandora', * 'islandora:', @@ -173,10 +175,13 @@ function islandora_get_namespace($id) { } /** - * Checks the given namespace or PID is/has an accessible namespace as defined by the "islandora_pids_allowed" variable. + * Checks the given namespace or PID is/has an accessible namespace as defined + * by the "islandora_pids_allowed" variable. * * @param string $namespace - * Either a PID or namespace to check for accessibility. Any string like those below are fine. + * Either a PID or namespace to check for accessibility. Any string like those + * below are fine. + * * @code * 'islandora', * 'islandora:', diff --git a/islandora.module b/islandora.module index 4859f5b2..f60627c1 100644 --- a/islandora.module +++ b/islandora.module @@ -3,7 +3,8 @@ /** * @file * - * islandora.module: defines paths (drupal menu items) as entry points and acts as a hub for dispatching tasks to other modules. + * islandora.module: defines paths (drupal menu items) as entry points and acts + * as a hub for dispatching tasks to other modules. * * This file is part of Islandora. * @@ -49,7 +50,8 @@ define('ISLANDORA_EDIT_DATASTREAM_HOOK', 'islandora_edit_datastream'); /** * Implements hook_menu(). * - * We need some standard entry points so we can have consistent urls for different Object actions + * We need some standard entry points so we can have consistent urls for + * different Object actions */ function islandora_menu() { $items = array(); @@ -290,16 +292,20 @@ function islandora_forms($form_id) { } /** - * Checks whether the user can access the given object with the given permission. + * Checks whether the user can access the given object with the given + * permission. * - * Checks for object existance, accessiblitly, namespace permissions, and user permissions + * Checks for object existance, accessiblitly, namespace permissions, + * and user permissions * - * @see islandora_object_load() To find potential solutions to enable page not found errors. + * @see islandora_object_load() To find potential solutions to enable + * page not found errors. * * @param string $perm * The user permission to test for. * @param FedoraObject $object - * The object to test, if NULL given the object doesn't exist or is inaccessible. + * The object to test, if NULL given the object doesn't exist or is + * inaccessible. * * @return boolean * TRUE if the user is allowed to access this object, FALSE otherwise. @@ -310,18 +316,23 @@ function islandora_object_access_callback($perm, $object = NULL) { } /** - * Checks whether the user can access the given object and datastream with the given permission. + * Checks whether the user can access the given object and datastream with + * the given permission. * - * Checks for object existance, accessiblitly, namespace permissions, and user permissions + * Checks for object existance, accessiblitly, namespace permissions, + * and user permissions * - * @see islandora_object_load() To find potential solutions to enable page not found errors. + * @see islandora_object_load() To find potential solutions to enable page + * not found errors. * * @param string $perm * The user permission to test for. * @param FedoraObject $object - * The object to test, if NULL given the object doesn't exist or is inaccessible. + * The object to test, if NULL given the object doesn't exist or is + * inaccessible. * @param FedoraDatastream $datastream - * The datastream to test, if NULL given the datastream doesn't exist or is inaccessible. + * The datastream to test, if NULL given the datastream doesn't exist + * or is inaccessible. * * @return boolean * TRUE if the user is allowed to access this object, FALSE otherwise. @@ -332,10 +343,13 @@ function islandora_object_datastream_access_callback($perm, $object = NULL, $dat } /** - * Renders the given objects manage page. Its possible to modify the output of this function if 'ISLANDORA_EDIT_HOOK' is - * implemented in other modules. + * Renders the given objects manage page. * - * If no modules implement 'ISLANDORA_EDIT_HOOK' then this function returns the default manage view. + * Its possible to modify the output of this function if 'ISLANDORA_EDIT_HOOK' + * is implemented in other modules. + * + * If no modules implement 'ISLANDORA_EDIT_HOOK' then this function returns the + * default manage view. * * @param FedoraObject $object * The object to manage. @@ -353,7 +367,8 @@ function islandora_edit_object(FedoraObject $object) { } } if (empty($output)) { - $output = islandora_default_islandora_edit_object($object); // Add in the default, if we did not get any results. + // Add in the default, if we did not get any results. + $output = islandora_default_islandora_edit_object($object); } arsort($output); drupal_alter(ISLANDORA_EDIT_HOOK, $object, $output); @@ -367,7 +382,8 @@ function islandora_edit_object(FedoraObject $object) { * The object used to render the manage object page. * * @return array - * The default rendering of the object manage page, indexed at 'Default Edit output'. + * The default rendering of the object manage page, indexed at + * 'Default Edit output'. */ function islandora_default_islandora_edit_object(FedoraObject $object) { $output = theme('islandora_default_edit', array('islandora_object' => $object)); @@ -377,7 +393,8 @@ function islandora_default_islandora_edit_object(FedoraObject $object) { /** * Page callback for the path "islandora". * - * Redirects to the view of the object indicated by the Drupal variable 'islandora_repository_pid'. + * Redirects to the view of the object indicated by the Drupal variable + * 'islandora_repository_pid'. */ function islandora_view_default_object() { $pid = variable_get('islandora_repository_pid', 'islandora:root'); @@ -387,10 +404,11 @@ function islandora_view_default_object() { /** * Renders the default view object page for the given object. * - * Modules should implement ISLANDORA_VIEW_HOOK for the Fedora Content models that - * their modules want to provide a view for. + * Modules should implement ISLANDORA_VIEW_HOOK for the Fedora Content + * models that their modules want to provide a view for. * - * If no modules implement the hook then the default view object page will be rendered. + * If no modules implement the hook then the default view object page + * will be rendered. * * @param FedoraObject $object * The object to view. @@ -407,13 +425,16 @@ function islandora_view_object(FedoraObject $object) { $page_size = (empty($_GET['pagesize'])) ? '10' : $_GET['pagesize']; $output = array(); foreach (islandora_build_hook_list(ISLANDORA_VIEW_HOOK, $object->models) as $hook) { - $temp = module_invoke_all($hook, $object, $page_number, $page_size); // @todo Remove page number and size from this hook, implementers of the hook should use drupal page handling directly. + // @todo Remove page number and size from this hook, implementers of the + // hook should use drupal page handling directly. + $temp = module_invoke_all($hook, $object, $page_number, $page_size); if (!empty($temp)) { $output = array_merge_recursive($output, $temp); } } if (empty($output)) { - $output = islandora_default_islandora_view_object($object); // No results, use the default view. + // No results, use the default view. + $output = islandora_default_islandora_view_object($object); } arsort($output); drupal_alter(ISLANDORA_VIEW_HOOK, $object, $output); @@ -435,24 +456,35 @@ function islandora_default_islandora_view_object($object) { } /** - * A helper function to get a connection and return an object for objects specified in the menu path as '%islandora_object'. + * A helper function to get a connection and return an object for objects + * specified in the menu path as '%islandora_object'. * * This should only be used by the Drupal menu wildcard system! * - * When this function returns FALSE the Drupal menu system will issues a "page not found" error, when this function returns NULL, - * the access function is expected to check for the given object and return false generating a "accesss denied" error. + * When this function returns FALSE the Drupal menu system will issues a + * "page not found" error, when this function returns NULL, the access function + * is expected to check for the given object and return false generating a + * "accesss denied" error. * - * This will currently display a message if the repository is inaccessable, ideally this would redirect to another page in such a case, - * as the access function will not be aware of this fact and will trigger the display of the "access denied" page. + * This will currently display a message if the repository is inaccessable, + * ideally this would redirect to another page in such a case, + * as the access function will not be aware of this fact and will trigger + * the display of the "access denied" page. * - * @todo When the repository down this should return a 500 error or a site offline notice. Currently only displays a message. + * @todo When the repository down this should return a 500 error or a + * site offline notice. Currently only displays a message. * * @param string $object_id * The pid of an object in the menu path identified by '%islandora_object'. * * @return FedoraObject - * If the given object id exists in the repository then this returns a FedoraObject, if no object was found it returns FALSE which triggers drupal_page_not_found(), if the - * object was inaccessible then NULL is returned, and the access callback is expected to catch that case, triggering drupal_access_denied(). + * If the given object id exists in the repository then this returns a + * FedoraObject. + * If no object was found it returns FALSE which triggers + * drupal_page_not_found(). + * If the object was inaccessible then NULL is returned, and the + * access callback is expected to catch that case, triggering + * drupal_access_denied(). */ function islandora_object_load($object_id) { static $object = NULL, $load_failed = FALSE; // Assume inaccessible. @@ -471,46 +503,49 @@ function islandora_object_load($object_id) { } /** - * A helper function to get an datastream specified as '%islandora_datastream' for the object specified in the menu path as '%islandora_object'. + * A helper function to get an datastream specified as '%islandora_datastream' + * for the object specified in the menu path as '%islandora_object'. * - * This should only be used by the Drupal menu wildcard system! As for non existing datastreams this will return page not found. + * This should only be used by the Drupal menu wildcard system! * - * The following settings are required for any menu paths which intent to use this auto loader. + * The following settings are required for any menu paths which intent to use + * this auto loader. * * @code * 'load arguments' => array('%map'), * @endcode * - * @see islandora_object_load() for solutions to access/not found problems. - * - * @todo For non accessible datastreams to the user this should return access denied. - * @todo Is there anything we can do to enhance caching? + * Its up to the access callbacks and menu callbacks to trigger + * drupal_access_denied() when appropriate. * * @param string $datastream_id - * The dsid of the datastream specified as '%islandora_datastream' to fetch from the given object in the menu path identified by '%islandora_object'. + * The dsid of the datastream specified as '%islandora_datastream' to fetch + * from the given object in the menu path identified by '%islandora_object'. * * @return FedoraDatastream - * If the given datastream id exists in the object then this returns a FedoraDatastream, in other cases this aborts. + * If the given datastream ID exists then this returns a FedoraDatastream + * object, otherwise it returns NULL which triggers drupal_page_not_found(). */ function islandora_datastream_load($datastream_id, $map) { - static $datastream = NULL, $load_failed = FALSE; // @hack for bug in drupal_not_found() when used before the menu callback. Infinite recursion bug. + static $datastream = NULL, $load_failed = FALSE; if ($load_failed || isset($datastream)) { return $datastream; } foreach ($map as $element) { - $is_fedora_object = is_object($element) && strtolower(get_class($element)) == 'fedoraobject'; // @todo Probably a better way to check types by now. - if ($is_fedora_object && isset($element[$datastream_id])) { // @todo check for access denied to this datastream so we can show the access denied page instead. + $is_fedora_object = is_object($element) && strtolower(get_class($element)) == 'fedoraobject'; + if ($is_fedora_object && isset($element[$datastream_id])) { $datastream = $element[$datastream_id]; return $datastream; } } $load_failed = TRUE; - return $datastream; // @todo Test + return $datastream; } /** - * Content model, collection view and collection policy datastreams may now optionally define a version - * number in their top-level XML element as an attribute, as in: + * Content model, collection view and collection policy datastreams may now + * optionally define a version number in their top-level XML element as an + * attribute, as in: * array( diff --git a/theme/islandora-object-edit.tpl.php b/theme/islandora-object-edit.tpl.php index 559ffd8c..0772a899 100644 --- a/theme/islandora-object-edit.tpl.php +++ b/theme/islandora-object-edit.tpl.php @@ -2,8 +2,9 @@ /** * @file - * islandora-object-edit.tpl.php: This is a template for objects that do not have - * a module to registered to build their display. + * + * islandora-object-edit.tpl.php: This is a template for objects that do not + * have a module to registered to build their display. * * islandora_object is a fedora tuque Object * $object->label @@ -13,7 +14,8 @@ * * $dublin_core is a DublinCore object * which is an array of elements, such as dc.title - * and each element has an array of values. dc.title can have none, one or many titles + * and each element has an array of values. + * dc.title can have none, one or many titles * this is the case for all dc elements. * */ @@ -21,4 +23,4 @@ label); ?> - \ No newline at end of file + diff --git a/theme/islandora-object.tpl.php b/theme/islandora-object.tpl.php index f10bb745..9062098c 100644 --- a/theme/islandora-object.tpl.php +++ b/theme/islandora-object.tpl.php @@ -1,8 +1,10 @@ label - The label for this object. @@ -35,13 +37,16 @@ * $ds->size - The size of the datastream * $ds->checksum - The checksum of the datastream * $ds->checksumType - The type of checksum for the datastream. - * $ds->createdDate->format("Y-m-d") - The created date with an option to use a format of your choice + * $ds->createdDate->format("Y-m-d") - The created date with an option to use + * a format of your choice * $ds->content - The content of the datastream - * $ds->url - The URL. This is only valid for R and E datastreams. + * $ds->url - The URL. This is only valid for R and E + * datastreams. * * $dublin_core is a DublinCore object * which is an array of elements, such as dc.title - * and each element has an array of values. dc.title can have none, one or many titles + * and each element has an array of values. + * dc.title can have none, one or many titles * this is the case for all dc elements. * * @@ -81,7 +86,7 @@
Collections
-
label, "islandora/object/{$collection->id}"); ?>
+
label, "islandora/object/{$collection->id}"); ?>
diff --git a/theme/islandora.theme.inc b/theme/islandora.theme.inc index f92091fc..eaef7b60 100644 --- a/theme/islandora.theme.inc +++ b/theme/islandora.theme.inc @@ -2,6 +2,7 @@ /** * @file + * * This file contains all theme and preprocess functions. */ @@ -13,13 +14,12 @@ * theme variables for the edit template */ function islandora_preprocess_islandora_default_edit(&$variables) { - $islandora_object = $variables['islandora_object']; global $base_url; + $islandora_object = $variables['islandora_object']; $datastreams = array(); $variables['islandora_editmetadata_url'] = $base_url . '/islandora/edit_form/' . $islandora_object->id; module_load_include('inc', 'islandora', 'includes/datastream'); module_load_include('inc', 'islandora', 'includes/utilities'); - // $variables['add_datastream_form'] = drupal_get_form('islandora_add_datastream_form', $islandora_object->id); $header = array( array('data' => t('ID')), array('data' => t('Label')), @@ -27,7 +27,6 @@ function islandora_preprocess_islandora_default_edit(&$variables) { array('data' => t('Mime type')), array('data' => t('Size')), array('data' => t('Operations'), 'colspan' => '3'), - //array('data' => t('Delete')), ); $table_attributes = array('class' => array('manage-datastreams')); $rows = array(); @@ -87,7 +86,6 @@ function islandora_preprocess_islandora_default(&$variables) { $variables['datastreams'] = $datastreams; try { $dc = $islandora_object['DC']->content; - //$dc_xml = simplexml_load_string($dc); $dc_object = DublinCore::import_from_xml_string($dc); $dc_array = $dc_object->as_formatted_array(); } catch (Exception $e) { From dd700b16c8682a612003a6fb698d3842d8cb8078 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Mon, 26 Nov 2012 18:35:41 -0400 Subject: [PATCH 10/20] Build out documentation. --- includes/ingest.form.inc | 11 ++++++++++- islandora.api.php | 30 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/includes/ingest.form.inc b/includes/ingest.form.inc index 77717257..f00af036 100644 --- a/includes/ingest.form.inc +++ b/includes/ingest.form.inc @@ -15,7 +15,16 @@ * @param array $form_state * The drupal form state. * @param array $configuration - * A list of key value pairs that are used to build the list of steps to be executed. + * An associative array of configuration values that are used to build the + * list of steps to be executed, including: + * - id: The PID with which the object should be created. + * - namespace: The PID namespace in which the object should be created. + * (id is used first, if it is given). + * - label: The initial label for the object. Defaults to "New Object". + * - collections: An array of collection PIDs, to which the new object should + * be related. + * - models: An array of content model PIDs, to which the new object should + * subscribe * * @return array * The form definition of the current step. diff --git a/islandora.api.php b/islandora.api.php index 7c4cc121..9f1e1e5c 100644 --- a/islandora.api.php +++ b/islandora.api.php @@ -222,3 +222,33 @@ function hook_islandora_viewer_info() {} * Returns a list of datastreams that are determined to be undeletable. */ function hook_islandora_undeletable_datastreams(array $models) {} + +/** + * Define steps used in the islandora_ingest_form() ingest process. + * + * @return array + * An array of associative arrays which define each step in the ingest + * process. Steps are defined by by a number of properties (keys) including: + * - type: The type of step. Currently, only "form" is implemented. + * - weight: The "weight" of this step--heavier(/"larger") values sink to the + * end of the process while smaller(/"lighter") values are executed first. + * - form_id: The form building function to call to get the form structure + * for this step. + * - args: An array of arguments to pass to the form building function. + */ +function hook_islandora_ingest_steps(array $configuration) { + return array( + array( + 'type' => 'form', + 'weight' => 1, + 'form_id' => 'my_cool_form', + 'args' => array('arg_one', 'numero deux'), + ), + ); +} +/** + * Content model specific version of hook_islandora_ingest_steps(). + * + * @see hook_islandora_ingest_steps() + */ +function hook_CMODEL_PID_islandora_ingest_steps(array $configuration) {} From aab988f1946583938b1f671ef612c4682d048347 Mon Sep 17 00:00:00 2001 From: Nigel Banks Date: Mon, 26 Nov 2012 22:36:32 +0000 Subject: [PATCH 11/20] Comment to long --- includes/ingest.form.inc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/includes/ingest.form.inc b/includes/ingest.form.inc index b4f2eb2f..5651ad19 100644 --- a/includes/ingest.form.inc +++ b/includes/ingest.form.inc @@ -50,7 +50,8 @@ function islandora_ingest_form_init_form_state(array &$form_state, array $config // First time initialization of storage. islandora_ingest_form_init_form_state_storage($form_state, $configuration); $steps = &islandora_ingest_form_get_steps($form_state); - // Always re-sort the steps just incase any build/submit handlers have appended new steps. + // Always re-sort the steps just incase any build/submit handlers have + // appended new steps. usort($steps, 'drupal_sort_weight'); // Load any required files for the current step. islandora_ingest_form_step_form_load_include($form_state); From 8c0ce49cff71b45fed83eb6b3e85e260d2231062 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Mon, 26 Nov 2012 18:43:54 -0400 Subject: [PATCH 12/20] Bit more. --- islandora.api.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/islandora.api.php b/islandora.api.php index 9f1e1e5c..337814fa 100644 --- a/islandora.api.php +++ b/islandora.api.php @@ -235,6 +235,10 @@ function hook_islandora_undeletable_datastreams(array $models) {} * - form_id: The form building function to call to get the form structure * for this step. * - args: An array of arguments to pass to the form building function. + * And may optionally include both: + * - module: A module from which we want to load an include. + * - file: A file to include (relative to the module's path, including the + * file's extension). */ function hook_islandora_ingest_steps(array $configuration) { return array( From 47dfae24c03a58cbc3e55e33a866d29a81aa1e62 Mon Sep 17 00:00:00 2001 From: Nigel Banks Date: Tue, 27 Nov 2012 14:29:57 +0000 Subject: [PATCH 13/20] Changes needed for form builder. --- includes/datastream.inc | 84 +++++++++++++++++++++------------------ islandora.module | 6 +-- theme/islandora.theme.inc | 2 +- 3 files changed, 50 insertions(+), 42 deletions(-) diff --git a/includes/datastream.inc b/includes/datastream.inc index 1c67f9ac..c6cb2780 100644 --- a/includes/datastream.inc +++ b/includes/datastream.inc @@ -85,52 +85,60 @@ function islandora_datastream_get_url(FedoraDatastream $datastream, $type = 'dow */ function islandora_datastream_get_delete_link(FedoraDatastream $datastream) { $datastreams = module_invoke_all('islandora_undeletable_datastreams', $datastream->parent->models); - if (in_array($datastream->id, $datastreams)) { - return ''; - } - else { - return l(t('delete'), 'islandora/object/' . $datastream->parent->id . '/datastream/' . $datastream->id . '/delete'); - } + $can_delete = !in_array($datastream->id, $datastreams); + return $can_delete ? l(t('delete'), "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/delete") : ''; } - -function islandora_datastream_edit_get_link($object, $ds_id) { - $edit_registry = module_invoke_all('islandora_edit_datastream_registry', $object, $ds_id); - if (count($edit_registry) > 0 && user_access(FEDORA_METADATA_EDIT)) { - return l(t('edit'), 'islandora/object/' . $object->id . '/datastream/' . $ds_id . '/edit'); - } - else { - return ''; - } +/** + * Gets the edit link. + * + * @param FedoraDatastream $datastream + * The datastream to generated the url to. + */ +function islandora_datastream_edit_get_link(FedoraDatastream $datastream) { + $edit_registry = module_invoke_all('islandora_edit_datastream_registry', $datastream->parent, $datastream); + $can_edit = count($edit_registry) > 0 && user_access(FEDORA_METADATA_EDIT); + return $can_edit ? l(t('edit'), "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/edit") : ''; } -function islandora_edit_datastream($object, $ds_id) { - $edit_registry = module_invoke_all('islandora_edit_datastream_registry', $object, $ds_id); +/** + * Display the edit datastream page. + * + * @param FedoraDatastream $datastream + * The datastream to edit. + */ +function islandora_edit_datastream(FedoraDatastream $datastream) { + $edit_registry = module_invoke_all('islandora_edit_datastream_registry', $datastream->parent, $datastream); $edit_count = count($edit_registry); - - if ($edit_count == 0) { - // No edit implementations. - drupal_set_message(t('There are no edit methods specified for this datastream.')); - drupal_goto('islandora/object/' . $object->id . '/manage/datastreams'); - } - elseif ($edit_count == 1) { - // One registry implementation, go there - drupal_goto($edit_registry[0]['url']); - } - else { - // Multiple edit routes registered - return islandora_edit_datastream_registry_render($edit_registry); + switch ($edit_count) { + case 0: + // No edit implementations. + drupal_set_message(t('There are no edit methods specified for this datastream.')); + drupal_goto("islandora/object/{$object->id}/manage/datastreams"); + break; + case 1: + // One registry implementation, go there + drupal_goto($edit_registry[0]['url']); + break; + default: + // Multiple edit routes registered + return islandora_edit_datastream_registry_render($edit_registry); } } -// @TODO: theme / preprocess -function islandora_edit_datastream_registry_render($edit_registry) { - $output = array( +/** + * Displays links to all the edit datastream registry items. + * + * @param array $edit_registry + * A list of 'islandora_edit_datastream_registry' values. + */ +function islandora_edit_datastream_registry_render(array $edit_registry) { + $markup = ''; + foreach ($edit_registry as $edit_route) { + $markup .= l($edit_route['name'], $edit_route['url']) . '
'; + } + return array( '#type' => 'markup', - '#markup' => '', + '#markup' => $markup, ); - foreach ($edit_registry AS $edit_route) { - $output['#markup'] .= l($edit_route['name'], $edit_route['url']) . '
'; - } - return $output; } diff --git a/islandora.module b/islandora.module index f60627c1..171c03e1 100644 --- a/islandora.module +++ b/islandora.module @@ -155,7 +155,7 @@ function islandora_menu() { $items['islandora/object/%islandora_object/datastream/%islandora_datastream'] = array( 'title' => 'View datastream', 'page callback' => 'islandora_view_datastream', - 'page arguments' => array(4), + 'page arguments' => array(4, FALSE), 'type' => MENU_CALLBACK, 'file' => 'includes/datastream.inc', 'access callback' => 'islandora_object_datastream_access_callback', @@ -176,10 +176,10 @@ function islandora_menu() { 'access arguments' => array(FEDORA_VIEW, 2, 4), 'load arguments' => array('%map'), ); - $items['islandora/object/%islandora_object/datastream/%islandora_datastreams/edit'] = array( + $items['islandora/object/%islandora_object/datastream/%islandora_datastream/edit'] = array( 'title' => 'Edit datastream', 'page callback' => 'islandora_edit_datastream', - 'page arguments' => array(2, 4), + 'page arguments' => array(4), 'type' => MENU_CALLBACK, 'file' => 'includes/datastream.inc', 'access callback' => 'islandora_object_datastream_access_callback', diff --git a/theme/islandora.theme.inc b/theme/islandora.theme.inc index eaef7b60..7cac4d1a 100644 --- a/theme/islandora.theme.inc +++ b/theme/islandora.theme.inc @@ -38,7 +38,7 @@ function islandora_preprocess_islandora_default_edit(&$variables) { array('class' => 'datastream-mime', 'data' => $ds->mimeType), array('class' => 'datastream-size', 'data' => islandora_datastream_get_human_readable_size($ds)), array('class' => 'datastream-download', 'data' => l(t('download'), islandora_datastream_get_url($ds, 'download'))), - array('class' => 'datstream-edit', 'data' => islandora_datastream_edit_get_link($islandora_object, $ds->id)), + array('class' => 'datstream-edit', 'data' => islandora_datastream_edit_get_link($ds)), array('class' => 'datastream-delete', 'data' => islandora_datastream_get_delete_link($ds)), ); } From 76167df6c8286cd1885817d28d3a81f9eeceda7a Mon Sep 17 00:00:00 2001 From: Nigel Banks Date: Tue, 27 Nov 2012 15:09:16 +0000 Subject: [PATCH 14/20] islandora_ingest_get_steps no longer returns NULL values --- includes/ingest.form.inc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/includes/ingest.form.inc b/includes/ingest.form.inc index 5651ad19..856f196b 100644 --- a/includes/ingest.form.inc +++ b/includes/ingest.form.inc @@ -420,6 +420,8 @@ function islandora_ingest_get_steps(array $configuration) { foreach (islandora_build_hook_list(ISLANDORA_INGEST_STEP_HOOK, $models) as $hook) { $steps = array_merge($steps, module_invoke_all($hook, $configuration)); } + // Remove NULL values. + $steps = array_filter($steps); usort($steps, 'drupal_sort_weight'); return $steps; } From cda9f25ae7e2ad4cd5344218b5eec38bfa842152 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Wed, 28 Nov 2012 13:57:12 -0400 Subject: [PATCH 15/20] Break out acquisition of datastream info. --- includes/globals.inc | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/includes/globals.inc b/includes/globals.inc index e85a71bc..3cece340 100644 --- a/includes/globals.inc +++ b/includes/globals.inc @@ -321,8 +321,23 @@ function islandora_get_missing_datastreams_requirements(FedoraObject $object) { * object. */ function islandora_get_datastreams_requirements(FedoraObject $object) { + return islandora_get_datastreams_requirements_from_models($object->models); +} + +/** + * Get the list of which datastreams are valid in the given set of models. + * + * @param array $models + * An array of content models PIDs from which to parse the DS-COMPOSITE-MODEL + * stream. + * + * @return array + * An associative array of associative arrays, merged from calls to + * islandora_get_datastreams_requirements_from_content_model(). + */ +function islandora_get_datastreams_requirements_from_models(array $models) { $dsids = array(); - foreach ($object->models as $model) { + foreach ($models as $model) { $model = islandora_get_object_by_id($model); $dsids += islandora_get_datastreams_requirements_from_content_model($model); } From cf1beabd5c6ef1b68f1ca0b4d28ababb62220cf7 Mon Sep 17 00:00:00 2001 From: jonathangreen Date: Wed, 28 Nov 2012 16:17:16 -0400 Subject: [PATCH 16/20] Updated the wildcard load functions Updated the wildcard load functions to work more like core drupal does, reversing some previous changes. --- includes/IslandoraTuque.inc | 19 +++++++++ includes/globals.inc | 40 ++---------------- includes/solution_packs.inc | 2 +- islandora.module | 84 ++++++++++++++----------------------- 4 files changed, 55 insertions(+), 90 deletions(-) diff --git a/includes/IslandoraTuque.inc b/includes/IslandoraTuque.inc index 22cff732..12cc462b 100644 --- a/includes/IslandoraTuque.inc +++ b/includes/IslandoraTuque.inc @@ -74,3 +74,22 @@ class IslandoraTuque { drupal_set_message(filter_xss($message), 'error', FALSE); } } + +/** + * Just a wrapper around fetchings the IslandoraTuque object, with some very + * basic error logging. + * + * @return IslandoraTuque + * A IslandoraTuque instance + */ +function islandora_get_tuque_connection() { + $tuque = &drupal_static(__FUNCTION__); + if (!$tuque) { + try { + $tuque = new IslandoraTuque(); + } catch (Exception $e) { + drupal_set_message(t('Unable to connect to the repository %e', array('%e' => $e)), 'error'); + } + } + return $tuque; +} \ No newline at end of file diff --git a/includes/globals.inc b/includes/globals.inc index 3cece340..5404d789 100644 --- a/includes/globals.inc +++ b/includes/globals.inc @@ -26,40 +26,6 @@ function islandora_get_tuque_connection() { return $tuque; } -/** - * Gets the given object if found, NULL if it is inaccessible and FALSE if it - * was not found. - * - * @param string $object_id - * The identifier of the object to get. - * - * @return FedoraObject - * The object if found, NULL if it is inaccessible and FALSE if it was not - * found. - */ -function islandora_get_object_by_id($object_id) { - $tuque = islandora_get_tuque_connection(); - if ($tuque) { - try { - $object = $tuque->repository->getObject($object_id); - drupal_alter('islandora_object', $object); - return $object; - } catch (Exception $e) { - if ($e->getCode() == '404') { - return FALSE; - } - else { - return NULL; - } - } - } - else { - IslandoraTuque::getError(); - } - // Assuming access denied in all other cases for now. - return NULL; -} - /** * Ingest the given object into Fedora calling its pre/post hooks as well. * @@ -274,7 +240,7 @@ function islandora_get_parents_from_rels_ext(FedoraObject $object) { // @todo some logging would be nice, not sure what this throws. return array(); } - $collections = array_map(function($o) { return islandora_get_object_by_id($o['object']['value']); }, $collections); + $collections = array_map(function($o) { return islandora_object_load($o['object']['value']); }, $collections); return array_filter($collections); } @@ -333,12 +299,12 @@ function islandora_get_datastreams_requirements(FedoraObject $object) { * * @return array * An associative array of associative arrays, merged from calls to - * islandora_get_datastreams_requirements_from_content_model(). + * islandora_get_datastreams_requirements_from_content_model(). */ function islandora_get_datastreams_requirements_from_models(array $models) { $dsids = array(); foreach ($models as $model) { - $model = islandora_get_object_by_id($model); + $model = islandora_object_load($model); $dsids += islandora_get_datastreams_requirements_from_content_model($model); } // The AUDIT Datastream can not really be added, so it can't really be missing. diff --git a/includes/solution_packs.inc b/includes/solution_packs.inc index a54b2fb4..8dfca853 100644 --- a/includes/solution_packs.inc +++ b/includes/solution_packs.inc @@ -226,7 +226,7 @@ function islandora_batch_reingest_object($object_model, &$context) { $object_query = $connection->api->a->findObjects('query', 'pid=' . $pid); $reinstall = FALSE; if (!empty($object_query['results'])) { - $object = islandora_get_object_by_id($pid); + $object = islandora_object_load($pid); if (isset($object)) { islandora_delete_object($object); } diff --git a/islandora.module b/islandora.module index 171c03e1..2d4d67f4 100644 --- a/islandora.module +++ b/islandora.module @@ -160,7 +160,7 @@ function islandora_menu() { 'file' => 'includes/datastream.inc', 'access callback' => 'islandora_object_datastream_access_callback', 'access arguments' => array(FEDORA_VIEW, 2, 4), - 'load arguments' => array('%map'), + 'load arguments' => array(2), ); $items['islandora/object/%islandora_object/datastream/%islandora_datastream/view'] = array( 'title' => 'View datastream', @@ -174,7 +174,7 @@ function islandora_menu() { 'file' => 'includes/datastream.inc', 'access callback' => 'islandora_object_datastream_access_callback', 'access arguments' => array(FEDORA_VIEW, 2, 4), - 'load arguments' => array('%map'), + 'load arguments' => array(2), ); $items['islandora/object/%islandora_object/datastream/%islandora_datastream/edit'] = array( 'title' => 'Edit datastream', @@ -184,7 +184,7 @@ function islandora_menu() { 'file' => 'includes/datastream.inc', 'access callback' => 'islandora_object_datastream_access_callback', 'access arguments' => array(FEDORA_METADATA_EDIT, 2, 4), - 'load arguments' => array('%map'), + 'load arguments' => array(2), ); $items['islandora/object/%islandora_object/datastream/%islandora_datastream/delete'] = array( 'title' => 'Delete data stream', @@ -194,7 +194,7 @@ function islandora_menu() { 'type' => MENU_CALLBACK, 'access callback' => 'islandora_object_datastream_access_callback', 'access arguments' => array(FEDORA_PURGE, 2, 4), - 'load arguments' => array('%map'), + 'load arguments' => array(2), ); $items['islandora/ingest'] = array( 'title' => 'Add an Object', @@ -459,21 +459,6 @@ function islandora_default_islandora_view_object($object) { * A helper function to get a connection and return an object for objects * specified in the menu path as '%islandora_object'. * - * This should only be used by the Drupal menu wildcard system! - * - * When this function returns FALSE the Drupal menu system will issues a - * "page not found" error, when this function returns NULL, the access function - * is expected to check for the given object and return false generating a - * "accesss denied" error. - * - * This will currently display a message if the repository is inaccessable, - * ideally this would redirect to another page in such a case, - * as the access function will not be aware of this fact and will trigger - * the display of the "access denied" page. - * - * @todo When the repository down this should return a 500 error or a - * site offline notice. Currently only displays a message. - * * @param string $object_id * The pid of an object in the menu path identified by '%islandora_object'. * @@ -487,34 +472,32 @@ function islandora_default_islandora_view_object($object) { * drupal_access_denied(). */ function islandora_object_load($object_id) { - static $object = NULL, $load_failed = FALSE; // Assume inaccessible. - if ($load_failed || isset($object)) { - return $object; - } - $object = islandora_get_object_by_id($object_id); // Either NULL or FALSE. - if (!isset($object)) { - module_load_include('inc', 'islandora', 'includes/utilities'); - if (islandora_describe_repository() === FALSE) { - drupal_set_message(t('The repository is not availible please contact the administrator.'), 'error'); + $tuque = islandora_get_tuque_connection(); + if ($tuque) { + try { + $object = $tuque->repository->getObject($object_id); + drupal_alter('islandora_object', $object); + return $object; + } catch (Exception $e) { + if ($e->getCode() == '404') { + return FALSE; + } + else { + return NULL; + } } - $load_failed = TRUE; } - return $object; + else { + IslandoraTuque::getError(); + } + // Assuming access denied in all other cases for now. + return NULL; } /** * A helper function to get an datastream specified as '%islandora_datastream' * for the object specified in the menu path as '%islandora_object'. * - * This should only be used by the Drupal menu wildcard system! - * - * The following settings are required for any menu paths which intent to use - * this auto loader. - * - * @code - * 'load arguments' => array('%map'), - * @endcode - * * Its up to the access callbacks and menu callbacks to trigger * drupal_access_denied() when appropriate. * @@ -522,24 +505,21 @@ function islandora_object_load($object_id) { * The dsid of the datastream specified as '%islandora_datastream' to fetch * from the given object in the menu path identified by '%islandora_object'. * + * $param string $object_id + * The object to load the datastream from. + * * @return FedoraDatastream * If the given datastream ID exists then this returns a FedoraDatastream * object, otherwise it returns NULL which triggers drupal_page_not_found(). */ -function islandora_datastream_load($datastream_id, $map) { - static $datastream = NULL, $load_failed = FALSE; - if ($load_failed || isset($datastream)) { - return $datastream; - } - foreach ($map as $element) { - $is_fedora_object = is_object($element) && strtolower(get_class($element)) == 'fedoraobject'; - if ($is_fedora_object && isset($element[$datastream_id])) { - $datastream = $element[$datastream_id]; - return $datastream; - } +function islandora_datastream_load($datastream_id, $object_id) { + $object = islandora_object_load($object_id); + + if(!$object) { + return NULL; } - $load_failed = TRUE; - return $datastream; + + return $object[$datastream_id]; } /** From b25d00a25f5d4fcb4aca6840662d24058681d1e7 Mon Sep 17 00:00:00 2001 From: jonathangreen Date: Wed, 28 Nov 2012 16:45:15 -0400 Subject: [PATCH 17/20] Remove the globals Remove the globals.inc file. --- includes/add_datastream.form.inc | 2 + includes/delete_object.form.inc | 1 + includes/globals.inc | 422 ------------------------------- includes/ingest.form.inc | 1 + includes/solution_packs.inc | 1 + includes/utilities.inc | 209 +++++++++++++++ islandora.module | 195 +++++++++++++- 7 files changed, 408 insertions(+), 423 deletions(-) delete mode 100644 includes/globals.inc diff --git a/includes/add_datastream.form.inc b/includes/add_datastream.form.inc index fa998d54..f4506424 100644 --- a/includes/add_datastream.form.inc +++ b/includes/add_datastream.form.inc @@ -21,6 +21,7 @@ */ function islandora_add_datastream_form(array $form, array &$form_state, FedoraObject $object) { module_load_include('inc', 'islandora', 'includes/content_model'); + module_load_include('inc', 'islandora', 'includes/utilities'); form_load_include($form_state, 'inc', 'islandora', 'includes/add_datastream.form'); $form_state['object'] = $object; $form_state['datastream_requirements'] = islandora_get_missing_datastreams_requirements($object); @@ -219,6 +220,7 @@ function islandora_add_datastream_form_submit(array $form, array &$form_state) { */ function islandora_add_datastream_form_autocomplete_callback(FedoraObject $object, $query = '') { module_load_include('inc', 'islandora', 'includes/content_model'); + module_load_include('inc', 'islandora', 'includes/utilities'); $dsids = array_keys(islandora_get_missing_datastreams_requirements($object)); $dsids = array_combine($dsids, $dsids); $query = trim($query); diff --git a/includes/delete_object.form.inc b/includes/delete_object.form.inc index 159b4aed..07cc2c21 100644 --- a/includes/delete_object.form.inc +++ b/includes/delete_object.form.inc @@ -41,6 +41,7 @@ function islandora_delete_object_form(array $form, array &$form_state, FedoraObj */ function islandora_delete_object_form_submit(array $form, array &$form_state) { module_load_include('inc', 'islandora', 'includes/datastream'); + module_load_include('inc', 'islandora', 'includes/utilities'); $object = $form_state['object']; $parents = islandora_get_parents_from_rels_ext($object); $parent = array_pop($parents); diff --git a/includes/globals.inc b/includes/globals.inc deleted file mode 100644 index 5404d789..00000000 --- a/includes/globals.inc +++ /dev/null @@ -1,422 +0,0 @@ - $e)), 'error'); - } - } - return $tuque; -} - -/** - * Ingest the given object into Fedora calling its pre/post hooks as well. - * - * @param NewFedoraObject $object - * An ingestable FedoraObject. - * - * @return FedoraObject - * The ingested FedoraObject, after running the pre/post ingest hooks. - */ -function islandora_add_object(NewFedoraObject &$object) { - islandora_pre_add_object($object); - $object->repository->ingestObject($object); - islandora_post_add_object($object); - return $object; -} - -/** - * Calls the ISLANDORA_PRE_INGEST_HOOK hooks. - * - * @param NewFedoraObject $object - * An ingestable FedoraObject. - */ -function islandora_pre_add_object(NewFedoraObject $object) { - module_load_include('inc', 'islandora', 'includes/utilities'); - foreach (islandora_build_hook_list(ISLANDORA_PRE_INGEST_HOOK, $object->models) as $hook) { - module_invoke_all($hook, $object); - } -} - -/** - * Calls the ISLANDORA_POST_INGEST_HOOK hooks. - * - * @param FedoraObject $object - * A recently ingestable FedoraObject. - */ -function islandora_post_add_object(FedoraObject $object) { - foreach (islandora_build_hook_list(ISLANDORA_POST_INGEST_HOOK, $object->models) as $hook) { - module_invoke_all($hook, $object); - } -} - -/** - * Deletes the given object into Fedora calling its pre/post hooks as well. - * - * @param FedoraObject $object - * An object to delete. - * - * @return FedoraObject - * The ingested FedoraObject, after running the pre/post ingest hooks. - */ -function islandora_delete_object(FedoraObject &$object) { - $object_id = $object->id; - $models = $object->models; - $action = islandora_pre_delete_object($object); - switch ($action) { - case 'blocked': - // Do nothing. - return FALSE; - case 'delete': - // Change the state to deleted. - $object->delete(); - islandora_post_delete_object($object_id, $models); - return TRUE; - default: - // Purge - $object->repository->purgeObject($object_id); - islandora_post_delete_object($object_id, $models); - $object = NULL; - return TRUE; - } -} - -/** - * Calls the ISLANDORA_PRE_PURGE_OBJECT_HOOK hooks. - * - * @param FedoraObject $object - * The object that is about to be deleted. - */ -function islandora_pre_delete_object(FedoraObject $object) { - module_load_include('inc', 'islandora', 'includes/utilities'); - $results = array(); - foreach (islandora_build_hook_list(ISLANDORA_PRE_PURGE_OBJECT_HOOK, $object->models) as $hook) { - $results = array_merge_recursive($results, module_invoke_all($hook, $object)); - } - $action = (isset($results['block']) && $results['block']) ? 'block' : FALSE; - $action = (!$action && isset($results['delete']) && $results['delete']) ? 'delete' : $action; - $action = !$action ? 'purge' : $action; - return $action; -} - -/** - * Calls the ISLANDORA_POST_PURGE_OBJECT_HOOK hooks. - * - * @param string $object_id - * The object id of an the recently deleted object. - * @param array $models - * The list of content models the delete object subsribed to. - */ -function islandora_post_delete_object($object_id, array $models) { - module_load_include('inc', 'islandora', 'includes/utilities'); - foreach (islandora_build_hook_list(ISLANDORA_POST_PURGE_OBJECT_HOOK, $models) as $hook) { - module_invoke_all($hook, $object_id, $models); - } -} - -/** - * Delete's/Purges the given datastream. - * - * @throws Exception - * Which types are undefined, but more than likely because of the hooks - * there will be several kinds. - * - * @param FedoraDatastream $datastream - * The datastream to delete. - * - * @return boolean - * TRUE is returned if the datastream was Deleted/Purged, FALSE if it was - * blocked. - */ -function islandora_delete_datastream(FedoraDatastream &$datastream) { - $datastream_id = $datastream->id; - $object = $datastream->parent; - $action = islandora_pre_delete_datastream($datastream); - switch ($action) { - case 'blocked': - // Do nothing. - return FALSE; - case 'delete': - // Change the state to deleted. - $object[$datastream_id]->state = 'D'; - // @todo Differentiate between delete/purge in the hooks. - islandora_post_delete_datastream($object, $datastream_id); - return TRUE; - default: - // Purge - $object->purgeDatastream($datastream_id); - islandora_post_delete_datastream($object, $datastream_id); - $datastream = NULL; - return TRUE; - } -} - -/** - * The default behaviour is to 'purge' the datastream but this can be overridden - * by modules that implement the 'islandora_pre_purge_datastream' hook. - * - * @todo make this an alter. - * - * The returned array can include a 'block' => TRUE - * pair which will prevent the datastream from being deleted if it particularly - * needed for a certain function. Returning 'delete' => TRUE will cause the - * datastream to be put into a deleted state. - * - * @param FedoraDatastream $datastream - * The datastream to delete. - * - * @return string - * The action to take when deleting the given datastream, either 'purge', - * 'delete', or 'block'. - */ -function islandora_pre_delete_datastream(FedoraDatastream $datastream) { - module_load_include('inc', 'islandora', 'includes/utilities'); - $results = array(); - foreach (islandora_build_hook_list(ISLANDORA_PRE_PURGE_DATASTREAM_HOOK, $datastream->parent->models) as $hook) { - // Not sure this will work the greatest, probably an alter would be better.. - $results = array_merge_recursive($results, module_invoke_all($hook, $datastream)); - } - $action = (isset($results['block']) && $results['block']) ? 'block' : FALSE; - $action = (!$action && isset($results['delete']) && $results['delete']) ? 'delete' : $action; - $action = !$action ? 'purge' : $action; - return $action; -} - -/** - * Calls the post purge datastream hooks. - * - * @todo Should differentiate between purging/deleting. - * - * @param FedoraObject $object - * The parent object of the deleted datastream. - * @param string $datastream_id - * The datastream id of the deleted datastream. - */ -function islandora_post_delete_datastream(FedoraObject $object, $datastream_id) { - module_load_include('inc', 'islandora', 'includes/utilities'); - foreach (islandora_build_hook_list(ISLANDORA_POST_PURGE_DATASTREAM_HOOK, $object->models) as $hook) { - module_invoke_all($hook, $object, $datastream_id); - } -} - -/** - * Gets any objects that the given object has a - * (isMemberOf, isMemberOfCollection) relationship with. - * - * This function gets its info from the RELS-EXT directly rather than through an - * risearch. - * - * @param FedoraObject $object - * The object whose parents will be returned. - * - * @return array - * An array of FedoraObject's that the given object has a - * (isMemberOf, isMemberOfCollection) relationship with. - */ -function islandora_get_parents_from_rels_ext(FedoraObject $object) { - try { - $collections = array_merge( - $object->relationships->get(FEDORA_RELS_EXT_URI, 'isMemberOfCollection'), - $object->relationships->get(FEDORA_RELS_EXT_URI, 'isMemberOf')); - } - catch (RepositoryException $e) { - // @todo some logging would be nice, not sure what this throws. - return array(); - } - $collections = array_map(function($o) { return islandora_object_load($o['object']['value']); }, $collections); - return array_filter($collections); -} - -/** - * Checks what datastreams the object already has against its required - * datastreams as defined by its content models, and returns their intersection. - * - * @param FedoraObject $object - * The object which models will be used to determine what datastreams it - * should have. - * - * @return array - * The DS-COMPOSITE-MODEL defined datastreams that are required for the given - * object, but not already present. - */ -function islandora_get_missing_datastreams_requirements(FedoraObject $object) { - $datastreams = islandora_get_datastreams_requirements($object); - foreach ($datastreams as $dsid => $requirements) { - if (isset($object[$dsid])) { - unset($datastreams[$dsid]); - } - } - return $datastreams; -} - -/** - * Checks the object's content model's for which datastream are expected to be - * used with this object, as defined by the DS-COMPOSITE-MODEL datastreams. - * - * For duplicate datastreams in the models, the first model defines the - * datastreams attributes regardless of what other models define. - * This should be undefined behavior according to the documentation. - * @see https://wiki.duraspace.org/display/FEDORA34/Fedora+Digital+Object+Model#FedoraDigitalObjectModel-ContentModelObjectCMODEL - * - * @param FedoraObject $object - * The object which models will be used to determine what datastreams it - * should have. - * - * @see islandora_get_required_datastreams_from_content_model() from more - * details on the return value. - * - * @return array - * The DS-COMPOSITE-MODEL defined datastreams that are required for the given - * object. - */ -function islandora_get_datastreams_requirements(FedoraObject $object) { - return islandora_get_datastreams_requirements_from_models($object->models); -} - -/** - * Get the list of which datastreams are valid in the given set of models. - * - * @param array $models - * An array of content models PIDs from which to parse the DS-COMPOSITE-MODEL - * stream. - * - * @return array - * An associative array of associative arrays, merged from calls to - * islandora_get_datastreams_requirements_from_content_model(). - */ -function islandora_get_datastreams_requirements_from_models(array $models) { - $dsids = array(); - foreach ($models as $model) { - $model = islandora_object_load($model); - $dsids += islandora_get_datastreams_requirements_from_content_model($model); - } - // The AUDIT Datastream can not really be added, so it can't really be missing. - unset($dsids['AUDIT']); - return $dsids; -} - -/** - * Checks the given content model for which datastreams are required for - * subscribing objects, as defined by it's DS-COMPOSITE-MODEL datastream. - * - * @todo Add support for fetching the schema information. - * - * @param FedoraObject $object - * The content model whose DS-COMPOSITE-MODEL datastream will be used to - * determine what datastreams are required. - * - * @return array - * The DS-COMPOSITE-MODEL defined datastreams that are required for the given - * object. - * - * @code - * array( - * 'DC' => array( - * 'id' => 'DC', - * 'mime' => 'text/xml', - * 'optional' => FALSE, - * ) - * ) - * @endcode - */ -function islandora_get_datastreams_requirements_from_content_model(FedoraObject $object) { - if (empty($object[DS_COMP_STREAM])) { - return array(); - } - $xml = new SimpleXMLElement($object[DS_COMP_STREAM]->content); - foreach ($xml->dsTypeModel as $ds) { - $dsid = (string) $ds['ID']; - $optional = strtolower((string) $ds['optional']); - $mime = array(); - foreach ($ds->form as $form) { - $mime[] = (string) $form['MIME']; - } - $dsids[$dsid] = array( - 'id' => $dsid, - 'mime' => $mime, - 'optional' => ($optional == 'true') ? TRUE : FALSE - ); - } - return $dsids; -} - - -/** - * Prepare an ingestable object. - * - * @param string $namespace - * The namespace in which the PID for the new object will be created. - * @param string $label - * An optional label to apply to the object. - * @param array $datastreams - * A array of datastreams to add, where each datastream definition is an - * associative array containing: - * - dsid: The datastream ID. - * - label: An optional label for the datastream. - * - mimetype: A MIMEtype for the datastream; defaults to text/xml. - * - control_group: One of X, M, R and E; defaults to M. - * - datastream_file: A web-accessible path, for which we try to get an - * absolute path using url(). - * @param array $content_models - * An array of content model PIDs to which the new object should subscribe. - * @param array $relationships - * An array of relationships, where each relationship is an associative array - * containing: - * - relationship: The predicate for the relationship, from the Fedora - * RELS-EXT namespace. - * - pid: The object for the relationship, to which we are creating the - * relationhsip. - * - * @return NewFedoraObject - * An ingestable NewFedoraObject. - */ -function islandora_prepare_new_object($namespace = NULL, $label = NULL, $datastreams = array(), $content_models = array(), $relationships = array()) { - $tuque = islandora_get_tuque_connection(); - $object = isset($namespace) ? $tuque->repository->constructObject($namespace) : new NewFedoraObject(NULL, $tuque->repository); - $object->owner = isset($user->name) ? $user->name : $object->owner; - $object->label = isset($label) ? $label : $object->label; - foreach ($content_models as $content_model) { - $object->relationships->add(FEDORA_MODEL_URI, 'hasModel', $content_model); - } - foreach ($relationships as $relationship) { - $object->relationships->add(FEDORA_RELS_EXT_URI, $relationship['relationship'], $relationship['pid']); - } - foreach ($datastreams as $ds) { - $dsid = $ds['dsid']; - $label = isset($ds['label']) ? $ds['label'] : ''; - $mimetype = isset($ds['mimetype']) ? $ds['mimetype'] : 'text/xml'; - // Default 'Managed' - $control_group = (isset($ds['control_group']) && in_array($ds['control_group'], array('X', 'M', 'R', 'E'))) ? $ds['control_group'] : 'M'; - $datastream_file = url($ds['datastream_file'], array('absolute' => TRUE)); - $datastream = $object->constructDatastream($dsid, $control_group); - $datastream->label = $label; - $datastream->mimetype = $mimetype; - switch ($control_group) { - case 'M': - $datastream->setContentFromUrl($datastream_file); - break; - case 'X': - $datastream->setContentFromString(file_get_contents($datastream_file)); - break; - } - $object->ingestDatastream($datastream); - } - return $object; -} diff --git a/includes/ingest.form.inc b/includes/ingest.form.inc index 856f196b..ad4fc308 100644 --- a/includes/ingest.form.inc +++ b/includes/ingest.form.inc @@ -67,6 +67,7 @@ function islandora_ingest_form_init_form_state(array &$form_state, array $config * executed. */ function islandora_ingest_form_init_form_state_storage(array &$form_state, array $configuration) { + module_load_include('inc', 'islandora', 'includes/utilities'); if (empty($form_state['islandora'])) { // Use ID if given. $id = isset($configuration['id']) ? $configuration['id'] : NULL; diff --git a/includes/solution_packs.inc b/includes/solution_packs.inc index 8dfca853..8c8cb3e0 100644 --- a/includes/solution_packs.inc +++ b/includes/solution_packs.inc @@ -491,6 +491,7 @@ function islandora_solution_pack_add_object(array $object_definition) { * An NewFedoraObject which has been initalized with the given properties. */ function islandora_solution_pack_prepare_new_object(array $object_definition) { + module_load_include('inc', 'islandora', 'includes/utilities'); $namespace = $object_definition['pid']; $label = !empty($object_definition['label']) ? $object_definition['label'] : NULL; $datastreams = array(); diff --git a/includes/utilities.inc b/includes/utilities.inc index b9cea493..2f32eb0c 100644 --- a/includes/utilities.inc +++ b/includes/utilities.inc @@ -3,6 +3,8 @@ /** * @file * Contains islandora utility functions + * + * @todo this file should be broken out into other files. */ /** @@ -199,3 +201,210 @@ function islandora_namespace_accessible($id) { } return TRUE; } + +/** + * Gets any objects that the given object has a + * (isMemberOf, isMemberOfCollection) relationship with. + * + * This function gets its info from the RELS-EXT directly rather than through an + * risearch. + * + * @param FedoraObject $object + * The object whose parents will be returned. + * + * @return array + * An array of FedoraObject's that the given object has a + * (isMemberOf, isMemberOfCollection) relationship with. + */ +function islandora_get_parents_from_rels_ext(FedoraObject $object) { + try { + $collections = array_merge( + $object->relationships->get(FEDORA_RELS_EXT_URI, 'isMemberOfCollection'), + $object->relationships->get(FEDORA_RELS_EXT_URI, 'isMemberOf')); + } + catch (RepositoryException $e) { + // @todo some logging would be nice, not sure what this throws. + return array(); + } + $collections = array_map(function($o) { return islandora_object_load($o['object']['value']); }, $collections); + return array_filter($collections); +} + +/** + * Checks what datastreams the object already has against its required + * datastreams as defined by its content models, and returns their intersection. + * + * @param FedoraObject $object + * The object which models will be used to determine what datastreams it + * should have. + * + * @return array + * The DS-COMPOSITE-MODEL defined datastreams that are required for the given + * object, but not already present. + */ +function islandora_get_missing_datastreams_requirements(FedoraObject $object) { + module_load_include('inc', 'islandora', 'includes/utilities'); + $datastreams = islandora_get_datastreams_requirements($object); + foreach ($datastreams as $dsid => $requirements) { + if (isset($object[$dsid])) { + unset($datastreams[$dsid]); + } + } + return $datastreams; +} + +/** + * Checks the object's content model's for which datastream are expected to be + * used with this object, as defined by the DS-COMPOSITE-MODEL datastreams. + * + * For duplicate datastreams in the models, the first model defines the + * datastreams attributes regardless of what other models define. + * This should be undefined behavior according to the documentation. + * @see https://wiki.duraspace.org/display/FEDORA34/Fedora+Digital+Object+Model#FedoraDigitalObjectModel-ContentModelObjectCMODEL + * + * @param FedoraObject $object + * The object which models will be used to determine what datastreams it + * should have. + * + * @see islandora_get_required_datastreams_from_content_model() from more + * details on the return value. + * + * @return array + * The DS-COMPOSITE-MODEL defined datastreams that are required for the given + * object. + */ +function islandora_get_datastreams_requirements(FedoraObject $object) { + return islandora_get_datastreams_requirements_from_models($object->models); +} + +/** + * Get the list of which datastreams are valid in the given set of models. + * + * @param array $models + * An array of content models PIDs from which to parse the DS-COMPOSITE-MODEL + * stream. + * + * @return array + * An associative array of associative arrays, merged from calls to + * islandora_get_datastreams_requirements_from_content_model(). + */ +function islandora_get_datastreams_requirements_from_models(array $models) { + $dsids = array(); + foreach ($models as $model) { + $model = islandora_object_load($model); + $dsids += islandora_get_datastreams_requirements_from_content_model($model); + } + // The AUDIT Datastream can not really be added, so it can't really be missing. + unset($dsids['AUDIT']); + return $dsids; +} + +/** + * Checks the given content model for which datastreams are required for + * subscribing objects, as defined by it's DS-COMPOSITE-MODEL datastream. + * + * @todo Add support for fetching the schema information. + * + * @param FedoraObject $object + * The content model whose DS-COMPOSITE-MODEL datastream will be used to + * determine what datastreams are required. + * + * @return array + * The DS-COMPOSITE-MODEL defined datastreams that are required for the given + * object. + * + * @code + * array( + * 'DC' => array( + * 'id' => 'DC', + * 'mime' => 'text/xml', + * 'optional' => FALSE, + * ) + * ) + * @endcode + */ +function islandora_get_datastreams_requirements_from_content_model(FedoraObject $object) { + if (empty($object[DS_COMP_STREAM])) { + return array(); + } + $xml = new SimpleXMLElement($object[DS_COMP_STREAM]->content); + foreach ($xml->dsTypeModel as $ds) { + $dsid = (string) $ds['ID']; + $optional = strtolower((string) $ds['optional']); + $mime = array(); + foreach ($ds->form as $form) { + $mime[] = (string) $form['MIME']; + } + $dsids[$dsid] = array( + 'id' => $dsid, + 'mime' => $mime, + 'optional' => ($optional == 'true') ? TRUE : FALSE + ); + } + return $dsids; +} + +/** + * Prepare an ingestable object. + * + * @param string $namespace + * The namespace in which the PID for the new object will be created. + * @param string $label + * An optional label to apply to the object. + * @param array $datastreams + * A array of datastreams to add, where each datastream definition is an + * associative array containing: + * - dsid: The datastream ID. + * - label: An optional label for the datastream. + * - mimetype: A MIMEtype for the datastream; defaults to text/xml. + * - control_group: One of X, M, R and E; defaults to M. + * - datastream_file: A web-accessible path, for which we try to get an + * absolute path using url(). + * @param array $content_models + * An array of content model PIDs to which the new object should subscribe. + * @param array $relationships + * An array of relationships, where each relationship is an associative array + * containing: + * - relationship: The predicate for the relationship, from the Fedora + * RELS-EXT namespace. + * - pid: The object for the relationship, to which we are creating the + * relationhsip. + * + * @return NewFedoraObject + * An ingestable NewFedoraObject. + */ +function islandora_prepare_new_object($namespace = NULL, $label = NULL, $datastreams = array(), $content_models = array(), $relationships = array()) { + module_load_include('inc', 'islandora', 'includes/IslandoraTuque'); + global $user; + $tuque = islandora_get_tuque_connection(); + $object = isset($namespace) ? $tuque->repository->constructObject($namespace) : new NewFedoraObject(NULL, $tuque->repository); + $object->owner = isset($user->name) ? $user->name : $object->owner; + $object->label = isset($label) ? $label : $object->label; + foreach ($content_models as $content_model) { + $object->relationships->add(FEDORA_MODEL_URI, 'hasModel', $content_model); + } + foreach ($relationships as $relationship) { + $object->relationships->add(FEDORA_RELS_EXT_URI, $relationship['relationship'], $relationship['pid']); + } + foreach ($datastreams as $ds) { + $dsid = $ds['dsid']; + $label = isset($ds['label']) ? $ds['label'] : ''; + $mimetype = isset($ds['mimetype']) ? $ds['mimetype'] : 'text/xml'; + // Default 'Managed' + $control_group = (isset($ds['control_group']) && in_array($ds['control_group'], array('X', 'M', 'R', 'E'))) ? $ds['control_group'] : 'M'; + $datastream_file = url($ds['datastream_file'], array('absolute' => TRUE)); + $datastream = $object->constructDatastream($dsid, $control_group); + $datastream->label = $label; + $datastream->mimetype = $mimetype; + switch ($control_group) { + case 'M': + $datastream->setContentFromUrl($datastream_file); + break; + case 'X': + $datastream->setContentFromString(file_get_contents($datastream_file)); + break; + } + $object->ingestDatastream($datastream); + } + return $object; +} diff --git a/islandora.module b/islandora.module index 2d4d67f4..86db7444 100644 --- a/islandora.module +++ b/islandora.module @@ -21,7 +21,6 @@ * You should have received a copy of the GNU General Public License * along with the program. If not, see . */ -require_once __DIR__ . "/includes/globals.inc"; // Common datastreams define('DS_COMP_STREAM', 'DS-COMPOSITE-MODEL'); @@ -472,6 +471,7 @@ function islandora_default_islandora_view_object($object) { * drupal_access_denied(). */ function islandora_object_load($object_id) { + module_load_include('inc', 'islandora', 'includes/IslandoraTuque'); $tuque = islandora_get_tuque_connection(); if ($tuque) { try { @@ -592,3 +592,196 @@ function islandora_islandora_required_objects() { function islandora_islandora_undeletable_datastreams(array $models) { return array('DC'); } + +/** + * Ingest the given object into Fedora calling its pre/post hooks as well. + * + * @todo will be cleaned up in the future + * + * @param NewFedoraObject $object + * An ingestable FedoraObject. + * + * @return FedoraObject + * The ingested FedoraObject, after running the pre/post ingest hooks. + */ +function islandora_add_object(NewFedoraObject &$object) { + islandora_pre_add_object($object); + $object->repository->ingestObject($object); + islandora_post_add_object($object); + return $object; +} + +/** + * Calls the ISLANDORA_PRE_INGEST_HOOK hooks. + * + * @param NewFedoraObject $object + * An ingestable FedoraObject. + */ +function islandora_pre_add_object(NewFedoraObject $object) { + module_load_include('inc', 'islandora', 'includes/utilities'); + foreach (islandora_build_hook_list(ISLANDORA_PRE_INGEST_HOOK, $object->models) as $hook) { + module_invoke_all($hook, $object); + } +} + + +/** + * Calls the ISLANDORA_POST_INGEST_HOOK hooks. + * + * @param FedoraObject $object + * A recently ingestable FedoraObject. + */ +function islandora_post_add_object(FedoraObject $object) { + foreach (islandora_build_hook_list(ISLANDORA_POST_INGEST_HOOK, $object->models) as $hook) { + module_invoke_all($hook, $object); + } +} + +/** + * Deletes the given object into Fedora calling its pre/post hooks as well. + * + * @param FedoraObject $object + * An object to delete. + * + * @return FedoraObject + * The ingested FedoraObject, after running the pre/post ingest hooks. + */ +function islandora_delete_object(FedoraObject &$object) { + $object_id = $object->id; + $models = $object->models; + $action = islandora_pre_delete_object($object); + switch ($action) { + case 'blocked': + // Do nothing. + return FALSE; + case 'delete': + // Change the state to deleted. + $object->delete(); + islandora_post_delete_object($object_id, $models); + return TRUE; + default: + // Purge + $object->repository->purgeObject($object_id); + islandora_post_delete_object($object_id, $models); + $object = NULL; + return TRUE; + } +} + +/** + * Calls the ISLANDORA_PRE_PURGE_OBJECT_HOOK hooks. + * + * @param FedoraObject $object + * The object that is about to be deleted. + */ +function islandora_pre_delete_object(FedoraObject $object) { + module_load_include('inc', 'islandora', 'includes/utilities'); + $results = array(); + foreach (islandora_build_hook_list(ISLANDORA_PRE_PURGE_OBJECT_HOOK, $object->models) as $hook) { + $results = array_merge_recursive($results, module_invoke_all($hook, $object)); + } + $action = (isset($results['block']) && $results['block']) ? 'block' : FALSE; + $action = (!$action && isset($results['delete']) && $results['delete']) ? 'delete' : $action; + $action = !$action ? 'purge' : $action; + return $action; +} + +/** + * Calls the ISLANDORA_POST_PURGE_OBJECT_HOOK hooks. + * + * @param string $object_id + * The object id of an the recently deleted object. + * @param array $models + * The list of content models the delete object subsribed to. + */ +function islandora_post_delete_object($object_id, array $models) { + module_load_include('inc', 'islandora', 'includes/utilities'); + foreach (islandora_build_hook_list(ISLANDORA_POST_PURGE_OBJECT_HOOK, $models) as $hook) { + module_invoke_all($hook, $object_id, $models); + } +} + +/** + * Delete's/Purges the given datastream. + * + * @throws Exception + * Which types are undefined, but more than likely because of the hooks + * there will be several kinds. + * + * @param FedoraDatastream $datastream + * The datastream to delete. + * + * @return boolean + * TRUE is returned if the datastream was Deleted/Purged, FALSE if it was + * blocked. + */ +function islandora_delete_datastream(FedoraDatastream &$datastream) { + $datastream_id = $datastream->id; + $object = $datastream->parent; + $action = islandora_pre_delete_datastream($datastream); + switch ($action) { + case 'blocked': + // Do nothing. + return FALSE; + case 'delete': + // Change the state to deleted. + $object[$datastream_id]->state = 'D'; + // @todo Differentiate between delete/purge in the hooks. + islandora_post_delete_datastream($object, $datastream_id); + return TRUE; + default: + // Purge + $object->purgeDatastream($datastream_id); + islandora_post_delete_datastream($object, $datastream_id); + $datastream = NULL; + return TRUE; + } +} + +/** + * The default behaviour is to 'purge' the datastream but this can be overridden + * by modules that implement the 'islandora_pre_purge_datastream' hook. + * + * @todo make this an alter. + * + * The returned array can include a 'block' => TRUE + * pair which will prevent the datastream from being deleted if it particularly + * needed for a certain function. Returning 'delete' => TRUE will cause the + * datastream to be put into a deleted state. + * + * @param FedoraDatastream $datastream + * The datastream to delete. + * + * @return string + * The action to take when deleting the given datastream, either 'purge', + * 'delete', or 'block'. + */ +function islandora_pre_delete_datastream(FedoraDatastream $datastream) { + module_load_include('inc', 'islandora', 'includes/utilities'); + $results = array(); + foreach (islandora_build_hook_list(ISLANDORA_PRE_PURGE_DATASTREAM_HOOK, $datastream->parent->models) as $hook) { + // Not sure this will work the greatest, probably an alter would be better.. + $results = array_merge_recursive($results, module_invoke_all($hook, $datastream)); + } + $action = (isset($results['block']) && $results['block']) ? 'block' : FALSE; + $action = (!$action && isset($results['delete']) && $results['delete']) ? 'delete' : $action; + $action = !$action ? 'purge' : $action; + return $action; +} + +/** + * Calls the post purge datastream hooks. + * + * @todo Should differentiate between purging/deleting. + * + * @param FedoraObject $object + * The parent object of the deleted datastream. + * @param string $datastream_id + * The datastream id of the deleted datastream. + */ +function islandora_post_delete_datastream(FedoraObject $object, $datastream_id) { + module_load_include('inc', 'islandora', 'includes/utilities'); + foreach (islandora_build_hook_list(ISLANDORA_POST_PURGE_DATASTREAM_HOOK, $object->models) as $hook) { + module_invoke_all($hook, $object, $datastream_id); + } +} \ No newline at end of file From baa8d6ed580e11ceb69e7054e19dfbd6d413bead Mon Sep 17 00:00:00 2001 From: jonathangreen Date: Wed, 28 Nov 2012 20:17:15 -0400 Subject: [PATCH 18/20] Make modifications to turn tuque back into a library. Tuque is a library again. And all of the functions are overriden in islandora for the sake of object loading. --- admin/islandora.admin.inc | 5 ++ includes/IslandoraTuque.inc | 91 +++++++++++++++++++++++++++++++++---- islandora.info | 1 - 3 files changed, 87 insertions(+), 10 deletions(-) diff --git a/admin/islandora.admin.inc b/admin/islandora.admin.inc index 0308cc3f..3a71c652 100644 --- a/admin/islandora.admin.inc +++ b/admin/islandora.admin.inc @@ -16,6 +16,11 @@ function islandora_repository_admin($form, &$form_state) { module_load_include('inc', 'islandora', 'includes/utilities'); drupal_add_css(drupal_get_path('module', 'islandora') . '/css/islandora.admin.css'); + if (!IslandoraTuque::exists()) { + IslandoraTuque::getError(); + return; + } + $form = array(); if (isset($form_state['values']['islandora_base_url'])) { $url = $form_state['values']['islandora_base_url']; diff --git a/includes/IslandoraTuque.inc b/includes/IslandoraTuque.inc index 12cc462b..0fccc0f9 100644 --- a/includes/IslandoraTuque.inc +++ b/includes/IslandoraTuque.inc @@ -6,6 +6,29 @@ * This file contains a class to include the Tuque php library. */ +$islandora_module_path = drupal_get_path('module', 'islandora'); + +//do this until we expost these in a module or library +@include_once 'sites/all/libraries/tuque/Datastream.php'; +@include_once 'sites/all/libraries/tuque/FedoraApi.php'; +@include_once 'sites/all/libraries/tuque/FedoraApiSerializer.php'; +@include_once 'sites/all/libraries/tuque/Object.php'; +@include_once 'sites/all/libraries/tuque/RepositoryConnection.php'; +@include_once 'sites/all/libraries/tuque/Cache.php'; +@include_once 'sites/all/libraries/tuque/RepositoryException.php'; +@include_once 'sites/all/libraries/tuque/Repository.php'; +@include_once 'sites/all/libraries/tuque/FedoraRelationships.php'; + +@include_once "$islandora_module_path/libraries/tuque/Datastream.php"; +@include_once "$islandora_module_path/libraries/tuque/FedoraApi.php"; +@include_once "$islandora_module_path/libraries/tuque/FedoraApiSerializer.php"; +@include_once "$islandora_module_path/libraries/tuque/Object.php"; +@include_once "$islandora_module_path/libraries/tuque/RepositoryConnection.php"; +@include_once "$islandora_module_path/libraries/tuque/Cache.php"; +@include_once "$islandora_module_path/libraries/tuque/RepositoryException.php"; +@include_once "$islandora_module_path/libraries/tuque/Repository.php"; +@include_once "$islandora_module_path/libraries/tuque/FedoraRelationships.php"; + class IslandoraTuque { /** @@ -55,11 +78,11 @@ class IslandoraTuque { } if (self::exists()) { - $this->connection = new RepositoryConnection($url, $user_string, $pass_string); + $this->connection = new IslandoraRepositoryConnection($url, $user_string, $pass_string); $this->connection->reuseConnection = TRUE; - $this->api = new FedoraApi($this->connection); - $this->cache = new SimpleCache(); - $this->repository = new FedoraRepository($this->api, $this->cache); + $this->api = new IslandoraFedoraApi($this->connection); + $this->cache = new IslandoraSimpleCache(); + $this->repository = new IslandoraFedoraRepository($this->api, $this->cache); } } @@ -85,11 +108,61 @@ class IslandoraTuque { function islandora_get_tuque_connection() { $tuque = &drupal_static(__FUNCTION__); if (!$tuque) { - try { - $tuque = new IslandoraTuque(); - } catch (Exception $e) { - drupal_set_message(t('Unable to connect to the repository %e', array('%e' => $e)), 'error'); + if(IslandoraTuque::exists()) { + try { + $tuque = new IslandoraTuque(); + } catch (Exception $e) { + drupal_set_message(t('Unable to connect to the repository %e', array('%e' => $e)), 'error'); + } + } + else { + return NULL; } } return $tuque; -} \ No newline at end of file +} + +class IslandoraFedoraRepository extends FedoraRepository { + protected $queryClass = 'IslandoraRepositoryQuery'; + protected $newObjectClass = 'IslandoraNewFedoraObject'; + protected $objectClass = 'IslandoraFedoraObject'; +} + +class IslandoraRepositoryQuery extends RepositoryQuery {} + +class IslandoraNewFedoraObject extends NewFedoraObject { + protected $newFedoraDatastreamClass = 'IslandoraNewFedoraDatastream'; + protected $fedoraDatastreamClass = 'IslandoraFedoraDatastream'; + protected $fedoraRelsExtClass = 'IslandoraFedoraRelsExt'; +} + +class IslandoraFedoraObject extends FedoraObject { + protected $newFedoraDatastreamClass = 'IslandoraNewFedoraDatastream'; + protected $fedoraDatastreamClass = 'IslandoraFedoraDatastream'; + protected $fedoraRelsExtClass = 'IslandoraFedoraRelsExt'; +} + +class IslandoraRepositoryConnection extends RepositoryConnection {} + +class IslandoraFedoraApi extends FedoraApi {} + +class IslandoraSimpleCache extends SimpleCache {} + +class IslandoraNewFedoraDatastream extends NewFedoraDatastream { + protected $fedoraRelsIntClass = 'IslandoraFedoraRelsInt'; + protected $fedoraDatastreamVersionClass = 'IslandoraFedoraDatastreamVersion'; +} + +class IslandoraFedoraDatastream extends FedoraDatastream { + protected $fedoraRelsIntClass = 'IslandoraFedoraRelsInt'; + protected $fedoraDatastreamVersionClass = 'IslandoraFedoraDatastreamVersion'; +} + +class IslandoraFedoraDatastreamVersion extends FedoraDatastreamVersion { + protected $fedoraRelsIntClass = 'IslandoraFedoraRelsInt'; + protected $fedoraDatastreamVersionClass = 'IslandoraFedoraDatastreamVersion'; +} + +class IslandoraFedoraRelsExt extends FedoraRelsExt {} + +class IslandoraFedoraRelsInt extends FedoraRelsInt {} diff --git a/islandora.info b/islandora.info index c93e0e60..d43d5c3a 100644 --- a/islandora.info +++ b/islandora.info @@ -1,7 +1,6 @@ name = Islandora description = "View and manage Fedora objects" package = Islandora -dependencies[] = tuque version = 7.x-dev core = 7.x configure = admin/islandora/configure From dd0178305080209c3da06e2efe34b9d774a3012d Mon Sep 17 00:00:00 2001 From: Nigel Banks Date: Thu, 29 Nov 2012 22:18:50 +0000 Subject: [PATCH 19/20] Prevent hooks from being called multiple times. --- includes/utilities.inc | 5 +++-- islandora.module | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/includes/utilities.inc b/includes/utilities.inc index 2f32eb0c..2e36e7bd 100644 --- a/includes/utilities.inc +++ b/includes/utilities.inc @@ -126,8 +126,9 @@ function islandora_describe_repository($url = NULL) { function islandora_build_hook_list($hook, $pids = array()) { $hooks = array(); - foreach ($pids as $model) { - $hooks[] = islandora_escape_pid_for_function($model) . '_' . $hook; + $pids = array_unique($pids); + foreach ($pids as $pid) { + $hooks[] = islandora_escape_pid_for_function($pid) . '_' . $hook; } $hooks[] = $hook; diff --git a/islandora.module b/islandora.module index 86db7444..f2d49ebb 100644 --- a/islandora.module +++ b/islandora.module @@ -515,7 +515,7 @@ function islandora_object_load($object_id) { function islandora_datastream_load($datastream_id, $object_id) { $object = islandora_object_load($object_id); - if(!$object) { + if (!$object) { return NULL; } @@ -784,4 +784,4 @@ function islandora_post_delete_datastream(FedoraObject $object, $datastream_id) foreach (islandora_build_hook_list(ISLANDORA_POST_PURGE_DATASTREAM_HOOK, $object->models) as $hook) { module_invoke_all($hook, $object, $datastream_id); } -} \ No newline at end of file +} From 84e5c543f47e522969465a074a8f94a9a1fb2f3d Mon Sep 17 00:00:00 2001 From: Nigel Banks Date: Thu, 29 Nov 2012 22:30:32 +0000 Subject: [PATCH 20/20] Prevent white screen when tuque is not accessible. --- includes/IslandoraTuque.inc | 48 ++------------------------ includes/IslandoraTuqueWrapper.inc | 55 ++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 46 deletions(-) create mode 100644 includes/IslandoraTuqueWrapper.inc diff --git a/includes/IslandoraTuque.inc b/includes/IslandoraTuque.inc index 0fccc0f9..89086829 100644 --- a/includes/IslandoraTuque.inc +++ b/includes/IslandoraTuque.inc @@ -108,7 +108,8 @@ class IslandoraTuque { function islandora_get_tuque_connection() { $tuque = &drupal_static(__FUNCTION__); if (!$tuque) { - if(IslandoraTuque::exists()) { + if (IslandoraTuque::exists()) { + require_once(__DIR__ . '/IslandoraTuqueWrapper.inc'); try { $tuque = new IslandoraTuque(); } catch (Exception $e) { @@ -121,48 +122,3 @@ function islandora_get_tuque_connection() { } return $tuque; } - -class IslandoraFedoraRepository extends FedoraRepository { - protected $queryClass = 'IslandoraRepositoryQuery'; - protected $newObjectClass = 'IslandoraNewFedoraObject'; - protected $objectClass = 'IslandoraFedoraObject'; -} - -class IslandoraRepositoryQuery extends RepositoryQuery {} - -class IslandoraNewFedoraObject extends NewFedoraObject { - protected $newFedoraDatastreamClass = 'IslandoraNewFedoraDatastream'; - protected $fedoraDatastreamClass = 'IslandoraFedoraDatastream'; - protected $fedoraRelsExtClass = 'IslandoraFedoraRelsExt'; -} - -class IslandoraFedoraObject extends FedoraObject { - protected $newFedoraDatastreamClass = 'IslandoraNewFedoraDatastream'; - protected $fedoraDatastreamClass = 'IslandoraFedoraDatastream'; - protected $fedoraRelsExtClass = 'IslandoraFedoraRelsExt'; -} - -class IslandoraRepositoryConnection extends RepositoryConnection {} - -class IslandoraFedoraApi extends FedoraApi {} - -class IslandoraSimpleCache extends SimpleCache {} - -class IslandoraNewFedoraDatastream extends NewFedoraDatastream { - protected $fedoraRelsIntClass = 'IslandoraFedoraRelsInt'; - protected $fedoraDatastreamVersionClass = 'IslandoraFedoraDatastreamVersion'; -} - -class IslandoraFedoraDatastream extends FedoraDatastream { - protected $fedoraRelsIntClass = 'IslandoraFedoraRelsInt'; - protected $fedoraDatastreamVersionClass = 'IslandoraFedoraDatastreamVersion'; -} - -class IslandoraFedoraDatastreamVersion extends FedoraDatastreamVersion { - protected $fedoraRelsIntClass = 'IslandoraFedoraRelsInt'; - protected $fedoraDatastreamVersionClass = 'IslandoraFedoraDatastreamVersion'; -} - -class IslandoraFedoraRelsExt extends FedoraRelsExt {} - -class IslandoraFedoraRelsInt extends FedoraRelsInt {} diff --git a/includes/IslandoraTuqueWrapper.inc b/includes/IslandoraTuqueWrapper.inc new file mode 100644 index 00000000..ff109c1b --- /dev/null +++ b/includes/IslandoraTuqueWrapper.inc @@ -0,0 +1,55 @@ +