Nigel Banks
12 years ago
26 changed files with 1794 additions and 1374 deletions
@ -0,0 +1,221 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
/** |
||||||
|
* @file |
||||||
|
* |
||||||
|
* Functions for generating/validating/submitting the add datastream form. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* The admin add datastream form. |
||||||
|
* |
||||||
|
* @param array $form |
||||||
|
* The Drupal form. |
||||||
|
* @param array $form_state |
||||||
|
* The Drupal form state. |
||||||
|
* @param FedoraObject $object |
||||||
|
* The object to be deleted. |
||||||
|
* |
||||||
|
* @return array |
||||||
|
* The drupal form definition. |
||||||
|
*/ |
||||||
|
function islandora_add_datastream_form(array $form, array &$form_state, FedoraObject $object) { |
||||||
|
module_load_include('inc', 'islandora', 'includes/content_model'); |
||||||
|
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); |
||||||
|
$unused_datastreams = array_keys($form_state['datastream_requirements']); |
||||||
|
$unused_datastreams = array_map(function($o) { return "'$o'"; }, $unused_datastreams); |
||||||
|
$unused_datastreams = implode(', ', $unused_datastreams); |
||||||
|
$upload_size = min((int)ini_get('post_max_size'), (int)ini_get('upload_max_filesize')); |
||||||
|
return array( |
||||||
|
'#redirect' => "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: <b>@unused_dsids</b>.', |
||||||
|
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.<br/>Files must be less than <b>!size MB.</b>', 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); |
||||||
|
} |
@ -0,0 +1,63 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
/** |
||||||
|
* @file |
||||||
|
* |
||||||
|
* This file contains the admin (confirmation) form and callback functions to delete/purge a datastream. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* The admin delete datastream form. |
||||||
|
* |
||||||
|
* @param array $form |
||||||
|
* The Drupal form. |
||||||
|
* @param array $form_state |
||||||
|
* The Drupal form state. |
||||||
|
* @param FedoraDatastream $datastream |
||||||
|
* The datastream to be deleted. |
||||||
|
* |
||||||
|
* @return array |
||||||
|
* The drupal form definition. |
||||||
|
*/ |
||||||
|
function islandora_delete_datastream_form(array $form, array &$form_state, FedoraDatastream $datastream) { |
||||||
|
$form_state['datastream'] = $datastream; |
||||||
|
return confirm_form($form, |
||||||
|
t('Are you sure you want to delete the %dsid datastream?', array('%dsid' => $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}"; |
||||||
|
} |
@ -0,0 +1,61 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
/** |
||||||
|
* @file |
||||||
|
* |
||||||
|
* This file contains the admin (confirmation) form and callback functions to purge an object. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* The admin delete object form. |
||||||
|
* |
||||||
|
* @param array $form |
||||||
|
* The Drupal form. |
||||||
|
* @param array $form_state |
||||||
|
* The Drupal form state. |
||||||
|
* @param FedoraObject $object |
||||||
|
* The object to be deleted. |
||||||
|
* |
||||||
|
* @return array |
||||||
|
* The drupal form definition. |
||||||
|
*/ |
||||||
|
function islandora_delete_object_form(array $form, array &$form_state, FedoraObject $object) { |
||||||
|
$form_state['object'] = $object; |
||||||
|
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') |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 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); |
||||||
|
} |
@ -0,0 +1,409 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
/** |
||||||
|
* @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. |
||||||
|
* |
||||||
|
* @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; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 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; |
||||||
|
} |
@ -1,47 +0,0 @@ |
|||||||
<?php |
|
||||||
|
|
||||||
/** |
|
||||||
* @file |
|
||||||
* Menu callback functionality for islandora/ingest |
|
||||||
*/ |
|
||||||
|
|
||||||
/** |
|
||||||
* Callback function for islandora/ingest/%collection_pid |
|
||||||
* |
|
||||||
* @TODO: validate?: pid, registry return |
|
||||||
* @param string $pid |
|
||||||
*/ |
|
||||||
function islandora_ingest_callback($collection_object) { |
|
||||||
if (!$collection_object) { |
|
||||||
return drupal_not_found(); |
|
||||||
} |
|
||||||
|
|
||||||
$ingest_registry = module_invoke_all('islandora_ingest_registry', $collection_object); |
|
||||||
$registry_count = count($ingest_registry); |
|
||||||
|
|
||||||
if ($registry_count == 0) { |
|
||||||
// No ingest implementations. |
|
||||||
drupal_set_message(t('There are no ingest methods specified for @name.', array('@name', $collection_object->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']) . '<br/>'; |
|
||||||
} |
|
||||||
return $output; |
|
||||||
} |
|
@ -0,0 +1,387 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
/** |
||||||
|
* @file |
||||||
|
* |
||||||
|
* 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. |
||||||
|
* |
||||||
|
* @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. |
||||||
|
* |
||||||
|
* @return array |
||||||
|
* The form definition of the current step. |
||||||
|
*/ |
||||||
|
function islandora_ingest_form(array $form, array &$form_state, array $configuration) { |
||||||
|
islandora_ingest_form_init_form_state($form_state, $configuration); |
||||||
|
return islandora_ingest_form_execute_step($form, $form_state); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Prepares/Initializes the form state for use. |
||||||
|
* |
||||||
|
* Also cleans up or loads any data required. |
||||||
|
* |
||||||
|
* @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. |
||||||
|
*/ |
||||||
|
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. |
||||||
|
$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. |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Initializes the form_state storage for use in the ingest multi-page forms. |
||||||
|
* |
||||||
|
* @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. |
||||||
|
*/ |
||||||
|
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. |
||||||
|
$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']); |
||||||
|
$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; |
||||||
|
} |
@ -0,0 +1,62 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
/** |
||||||
|
* @file |
||||||
|
* |
||||||
|
* Ingest Menu callback hooks. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* Menu callback, Renders the multi-page ingest form if possible. |
||||||
|
* |
||||||
|
* @return string |
||||||
|
* HTML representing the mult-page ingest form. |
||||||
|
*/ |
||||||
|
function islandora_ingest_callback() { |
||||||
|
$configuration = islandora_ingest_get_configuration(); |
||||||
|
if ($configuration === FALSE) { // Redirect back to referer or top level collection. |
||||||
|
drupal_set_message(t('Invalid ingest configuration.'), 'error'); |
||||||
|
$redirect = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '<front>'; |
||||||
|
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']); |
||||||
|
} |
@ -1,235 +0,0 @@ |
|||||||
<?php |
|
||||||
|
|
||||||
/** |
|
||||||
* @file |
|
||||||
* This file contains ingest callback functions. |
|
||||||
*/ |
|
||||||
|
|
||||||
/** |
|
||||||
* @TODO: needs documentation |
|
||||||
*/ |
|
||||||
function islandora_ingest_get_information(AbstractFedoraObject $collection_object) { |
|
||||||
$models = $collection_object->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); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,116 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
/** |
||||||
|
* @file |
||||||
|
* |
||||||
|
* Contains admin form functions for editing an object's properties. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* Object properties admin form. |
||||||
|
* |
||||||
|
* @param array $form |
||||||
|
* The Drupal form. |
||||||
|
* @param array $form_state |
||||||
|
* The Drupal form state. |
||||||
|
* @param FedoraObject $object |
||||||
|
* The object whose properties this form will modify. |
||||||
|
* |
||||||
|
* @return array |
||||||
|
* The drupal form definition. |
||||||
|
*/ |
||||||
|
function islandora_object_properties_form(array $form, array &$form_state, FedoraObject $object) { |
||||||
|
drupal_set_title($object->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"); |
||||||
|
} |
@ -1,125 +0,0 @@ |
|||||||
<?php |
|
||||||
|
|
||||||
/** |
|
||||||
* @file |
|
||||||
* Contains admin form functions for object properties |
|
||||||
*/ |
|
||||||
|
|
||||||
/** |
|
||||||
* Validate function for object properties admin form. |
|
||||||
* |
|
||||||
* @TODO: may want more validation here the only restrictions i see on |
|
||||||
* the object label and owner is the foxml schema says they should be |
|
||||||
* an xsd:string there maybe further restrictions such as length but they aren't |
|
||||||
* defined in the schema. |
|
||||||
* @param array $form |
|
||||||
* @param array $form_state |
|
||||||
* @return boolean |
|
||||||
*/ |
|
||||||
function islandora_edit_properties_form_validate($form, &$form_state) { |
|
||||||
$islandora_object = islandora_object_load($form_state['values']['pid']); |
|
||||||
if (!isset($islandora_object)) { |
|
||||||
form_set_error('', t('Could not update properties object not found.')); |
|
||||||
return FALSE; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Submit function for object properties admin form. |
|
||||||
* |
|
||||||
* @param array $form |
|
||||||
* @param array $form_state |
|
||||||
*/ |
|
||||||
function islandora_edit_properties_form_submit($form, &$form_state) { |
|
||||||
$islandora_object = islandora_object_load($form_state['values']['pid']); |
|
||||||
$owner = $form_state['values']['object_owner']; |
|
||||||
$state = $form_state['values']['object_state']; |
|
||||||
$label = $form_state['values']['object_label']; |
|
||||||
if (isset($owner) && $owner != $islandora_object->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; |
|
||||||
} |
|
@ -1,138 +0,0 @@ |
|||||||
<?php |
|
||||||
|
|
||||||
/** |
|
||||||
* @file |
|
||||||
* This file contains the admin (confirmation) form and callback functions to purge an object. |
|
||||||
*/ |
|
||||||
|
|
||||||
/** |
|
||||||
* Gives the option of deleting or purging and object. |
|
||||||
* |
|
||||||
* 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. |
|
||||||
* |
|
||||||
* @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); |
|
||||||
} |
|
@ -1,9 +1,13 @@ |
|||||||
name = Islandora |
name = Islandora |
||||||
description = "View and manage Fedora objects" |
description = "View and manage Fedora objects" |
||||||
package = Islandora |
package = Islandora |
||||||
|
dependencies[] = tuque |
||||||
version = 7.x-dev |
version = 7.x-dev |
||||||
core = 7.x |
core = 7.x |
||||||
configure = admin/islandora/configure |
configure = admin/islandora/configure |
||||||
stylesheets[all][] = css/islandora.base.css |
stylesheets[all][] = css/islandora.base.css |
||||||
stylesheets[all][] = css/islandora.theme.css |
stylesheets[all][] = css/islandora.theme.css |
||||||
|
files[] = includes/MimeDetect.inc |
||||||
|
files[] = includes/DublinCore.inc |
||||||
|
files[] = includes/IslandoraTuque.inc |
||||||
php = 5.3 |
php = 5.3 |
||||||
|
Loading…
Reference in new issue