Browse Source

Resolved merge conflict.

pull/371/head
MorganDawe 12 years ago
parent
commit
a384900fa5
  1. 74
      includes/add_datastream.form.inc
  2. 45
      includes/datastream.inc
  3. 127
      includes/datastream.version.inc
  4. 27
      includes/ingest.form.inc
  5. 3
      includes/object.entity_controller.inc
  6. 3
      includes/tuque_wrapper.inc
  7. 2
      includes/utilities.inc
  8. 1
      islandora.info
  9. 62
      islandora.module
  10. 198
      tests/datastream_versions.test
  11. 12
      tests/islandora_ingest_test.module
  12. 62
      tests/islandora_web_test_case.inc
  13. 191
      theme/theme.inc

74
includes/add_datastream.form.inc

@ -32,7 +32,7 @@ function islandora_add_datastream_form(array $form, array &$form_state, Abstract
'#attributes' => array( '#attributes' => array(
'enctype' => 'multipart/form-data', 'enctype' => 'multipart/form-data',
), ),
'dsid' => array( 'dsid_fieldset' => array(
'#type' => 'fieldset', '#type' => 'fieldset',
'#title' => 'Add a datastream', '#title' => 'Add a datastream',
'#collapsible' => FALSE, '#collapsible' => FALSE,
@ -40,44 +40,44 @@ function islandora_add_datastream_form(array $form, array &$form_state, Abstract
'dsid' => array( 'dsid' => array(
'#title' => 'Datastream ID', '#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, dashes and underscores. The following datastreams are defined by this content model but don't currently exist: <b>@unused_dsids</b>.", array('@unused_dsids' => $unused_datastreams)), '#description' => t("An ID for this stream that is unique to this object. Must start with a letter and contain only alphanumeric characters, dashes and underscores. The following datastreams are defined by this content model but 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",
), ),
'#type' => 'textfield', 'label' => array(
'#size' => 64, '#title' => 'Datastream Label',
'#maxlength' => 64, '#required' => TRUE,
'#required' => TRUE, '#size' => 64,
'#element_validate' => array( '#maxlength' => 64,
'islandora_add_datastream_form_field_is_not_an_existing_datastream_id', '#description' => t('A human-readable label'),
'islandora_add_datastream_form_field_starts_with_a_letter', '#type' => 'textfield',
'islandora_add_datastream_form_field_is_valid_dsid', '#element_validate' => array('islandora_add_datastream_form_field_does_not_contain_a_forward_slash'),
), ),
'#autocomplete_path' => "islandora/object/{$object->id}/manage/datastreams/add/autocomplete", 'file' => array(
), '#type' => 'managed_file',
'label' => array( '#required' => TRUE,
'#title' => 'Datastream Label', '#title' => t('Upload Document'),
'#required' => TRUE, '#size' => 48,
'#size' => 64, '#description' => t('Select a file to upload.<br/>Files must be less than <b>@size MB.</b>', array('@size' => $upload_size)),
'#maxlength' => 64, '#default_value' => isset($form_state['values']['files']) ? $form_state['values']['files'] : NULL,
'#description' => t('A human-readable label'), '#upload_location' => 'temporary://',
'#type' => 'textfield', '#upload_validators' => array(
'#element_validate' => array('islandora_add_datastream_form_field_does_not_contain_a_forward_slash'), 'file_validate_extensions' => array(NULL),
), // Assume its specified in MB.
'file' => array( 'file_validate_size' => array($upload_size * 1024 * 1024),
'#type' => 'managed_file', ),
'#required' => TRUE, ),
'#title' => t('Upload Document'), 'submit' => array(
'#size' => 48, '#type' => 'submit',
'#description' => t('Select a file to upload.<br/>Files must be less than <b>@size MB.</b>', array('@size' => $upload_size)), '#value' => t('Add Datastream'),
'#default_value' => isset($form_state['values']['files']) ? $form_state['values']['files'] : NULL,
'#upload_location' => 'temporary://',
'#upload_validators' => array(
'file_validate_extensions' => array(NULL),
// Assume its specified in MB.
'file_validate_size' => array($upload_size * 1024 * 1024),
), ),
),
'submit' => array(
'#type' => 'submit',
'#value' => t('Add Datastream'),
), ),
); );
} }
@ -148,7 +148,7 @@ function islandora_add_datastream_form_field_does_not_contain_a_forward_slash(ar
} }
/** /**
* Checks if the given datastream requires the upload to be a certian MIME type. * Checks if the given datastream requires the upload to be a certain MIME type.
* *
* @param array $form * @param array $form
* The Drupal form. * The Drupal form.

45
includes/datastream.inc

@ -26,8 +26,19 @@ function islandora_download_datastream(AbstractDatastream $datastream) {
* @param bool $download * @param bool $download
* If TRUE the file is download to the user computer for viewing otherwise it * If TRUE the file is download to the user computer for viewing otherwise it
* will attempt to display in the browser natively. * will attempt to display in the browser natively.
* @param int $version
* The version of the datastream to display
*/ */
function islandora_view_datastream(AbstractDatastream $datastream, $download = FALSE) { function islandora_view_datastream(AbstractDatastream $datastream, $download = FALSE, $version = NULL) {
if ($version !== NULL) {
if (isset($datastream[$version])) {
$datastream = $datastream[$version];
}
else {
return drupal_not_found();
}
}
header_remove('Cache-Control'); header_remove('Cache-Control');
header_remove('Expires'); header_remove('Expires');
header('Content-type: ' . $datastream->mimetype); header('Content-type: ' . $datastream->mimetype);
@ -69,12 +80,31 @@ function islandora_datastream_get_human_readable_size(AbstractDatastream $datast
* *
* @param AbstractDatastream $datastream * @param AbstractDatastream $datastream
* The datastream to generated the url to. * The datastream to generated the url to.
* @param string $type
* One of:
* - download
* - view
* @param int $version
* (Optional) The version of the datastream to get a URL for.
* *
* @return string * @return string
* either the 'view' or 'download' url for the given datastream. * either the 'view' or 'download' url for the given datastream.
*/ */
function islandora_datastream_get_url(AbstractDatastream $datastream, $type = 'download') { function islandora_datastream_get_url(AbstractDatastream $datastream, $type = 'download', $version = NULL) {
return $datastream->controlGroup == 'R' ? $datastream->url : "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/$type"; if ($version === NULL) {
$link = "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/$type";
}
else {
$link = "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/version/$version/$type";
$datastream = $datastream[$version];
}
if ($datastream->controlGroup == 'R') {
return $datastream->url;
}
else {
return $link;
}
} }
/** /**
@ -82,6 +112,9 @@ function islandora_datastream_get_url(AbstractDatastream $datastream, $type = 'd
* *
* @param AbstractDatastream $datastream * @param AbstractDatastream $datastream
* The datastream to generated the url to. * The datastream to generated the url to.
*
* @return string
* Markup containing the link to the confirm form to delete the datastream.
*/ */
function islandora_datastream_get_delete_link(AbstractDatastream $datastream) { function islandora_datastream_get_delete_link(AbstractDatastream $datastream) {
$message = islandora_deprecated('7.x-1.2', 'Use the "islandora_datastream_delete_link" theme implementation.'); $message = islandora_deprecated('7.x-1.2', 'Use the "islandora_datastream_delete_link" theme implementation.');
@ -97,6 +130,9 @@ function islandora_datastream_get_delete_link(AbstractDatastream $datastream) {
* *
* @param AbstractDatastream $datastream * @param AbstractDatastream $datastream
* The datastream to generated the url to. * The datastream to generated the url to.
*
* @return string
* Markup containing the link to edit the datastream.
*/ */
function islandora_datastream_edit_get_link(AbstractDatastream $datastream) { function islandora_datastream_edit_get_link(AbstractDatastream $datastream) {
$message = islandora_deprecated('7.x-1.2', 'Use the "islandora_datastream_edit_link" theme implementation.'); $message = islandora_deprecated('7.x-1.2', 'Use the "islandora_datastream_edit_link" theme implementation.');
@ -139,6 +175,9 @@ function islandora_edit_datastream(AbstractDatastream $datastream) {
* *
* @param array $edit_registry * @param array $edit_registry
* A list of 'islandora_edit_datastream_registry' values. * A list of 'islandora_edit_datastream_registry' values.
*
* @return array
* A Drupal renderable array containing the "edit" markup.
*/ */
function islandora_edit_datastream_registry_render(array $edit_registry) { function islandora_edit_datastream_registry_render(array $edit_registry) {
$markup = ''; $markup = '';

127
includes/datastream.version.inc

@ -0,0 +1,127 @@
<?php
/**
* @file
* The form displayed that shows the datastream version history.
*/
/**
* Function that returns markup for the datastream versions page.
*/
function islandora_datastream_version_table($datastream) {
module_load_include('inc', 'islandora', 'includes/datastream');
module_load_include('inc', 'islandora', 'includes/utilities');
drupal_set_title(t("@dsid Previous Versions", array('@dsid' => $datastream->id)));
$header = array();
$header[] = array('data' => t('Created Date'));
$header[] = array('data' => t('Size'));
$header[] = array('data' => t('Label'));
$header[] = array('data' => t('Mime type'));
$header[] = array('data' => t('Operations'));
$rows = array();
foreach ($datastream as $version => $datastream_version) {
$row = array();
$row[] = array(
'class' => 'datastream-date',
'data' => theme('islandora_datastream_view_link', array(
'datastream' => $datastream,
'label' => $datastream_version->createdDate->format(DATE_RFC850),
'version' => $version,
)),
);
$row[] = array(
'class' => 'datastream-size',
'data' => islandora_datastream_get_human_readable_size($datastream_version),
);
$row[] = array(
'class' => 'datastream-label',
'data' => $datastream_version->label,
);
$row[] = array(
'class' => 'datastream-mime',
'data' => $datastream_version->mimeType,
);
$row[] = array(
'class' => 'datastream-delete',
'data' => theme('islandora_datastream_delete_link', array(
'datastream' => $datastream,
'version' => $version,
)),
);
$rows[] = $row;
}
return theme('table', array('header' => $header, 'rows' => $rows));
}
/**
* The admin delete datastream form.
*
* @param array $form
* The Drupal form.
* @param array $form_state
* The Drupal form state.
* @param AbstractDatastream $datastream
* The datastream to be deleted.
* @param string $version
* The version number of the datastream we are trying to delete.
*
* @return array
* The drupal form definition.
*/
function islandora_delete_datastream_version_form(array $form, array &$form_state, AbstractDatastream $datastream, $version) {
if (!isset($datastream[$version]) || count($datastream) < 2) {
return drupal_not_found();
}
$form_state['datastream'] = $datastream;
$form_state['version'] = $version;
return confirm_form($form,
t('Are you sure you want to delete version @version of the @dsid datastream?', array('@dsid' => $datastream->id, '@version' => $version)),
"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 AbstractDatastream 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.
*
* @param array $form
* The Drupal form.
* @param array $form_state
* The Drupal form state.
*/
function islandora_delete_datastream_version_form_submit(array $form, array &$form_state) {
$datastream = $form_state['datastream'];
$version = $form_state['version'];
$datastream_id = $datastream->id;
$object = $datastream->parent;
try {
unset($datastream[$version]);
}
catch (Exception $e) {
drupal_set_message(t('Error deleting version %v of %s datastream from object %o %e', array(
'%v' => $version,
'%s' => $datastream_id,
'%o' => $object->label,
'%e' => $e->getMessage())), 'error');
}
drupal_set_message(t('%d datastream version successfully deleted from Islandora object %o', array(
'%d' => $datastream_id,
'%o' => $object->label)));
$form_state['redirect'] = "islandora/object/{$object->id}/datastream/{$datastream->id}/version";
}

27
includes/ingest.form.inc

@ -186,10 +186,10 @@ function islandora_ingest_form_get_step(array &$form_state, $step_id = NULL) {
* *
* @param array $form_state * @param array $form_state
* The Drupal form state. * The Drupal form state.
* @param string $step * @param array $step
* The step relative to the result, if not provided the current step is used. * The step relative to the result, if not provided the current step is used.
* *
* @return string * @return array|null
* The next step if found, NULL otherwise. * The next step if found, NULL otherwise.
*/ */
function islandora_ingest_form_get_next_step(array &$form_state, array $step = NULL) { function islandora_ingest_form_get_next_step(array &$form_state, array $step = NULL) {
@ -205,10 +205,10 @@ function islandora_ingest_form_get_next_step(array &$form_state, array $step = N
* *
* @param array $form_state * @param array $form_state
* The Drupal form state. * The Drupal form state.
* @param string $step * @param array $step
* The step relative to the result, if not provided the current step is used. * The step relative to the result, if not provided the current step is used.
* *
* @return string * @return array|null
* The next step if found, NULL otherwise. * The next step if found, NULL otherwise.
*/ */
function islandora_ingest_form_get_previous_step(array &$form_state, array $step = NULL) { function islandora_ingest_form_get_previous_step(array &$form_state, array $step = NULL) {
@ -329,6 +329,9 @@ function islandora_ingest_form_decrement_step(array &$form_state) {
* The Drupal form. * The Drupal form.
* @param array $form_state * @param array $form_state
* The Drupal form state. * The Drupal form state.
* @param string $step_id
* The ID of the step relative to the result, if not provided the current
* step_id is used.
* *
* @return array * @return array
* The form definition of the current step. * The form definition of the current step.
@ -363,6 +366,8 @@ function islandora_ingest_form_execute_step(array $form, array &$form_state, $st
* The Drupal form. * The Drupal form.
* @param array $form_state * @param array $form_state
* The Drupal form state. * The Drupal form state.
* @param array $step
* The step we are executing.
* *
* @return array * @return array
* The form definition of the given step. * The form definition of the given step.
@ -391,6 +396,8 @@ function islandora_ingest_form_execute_form_step(array $form, array &$form_state
* The Drupal form. * The Drupal form.
* @param array $form_state * @param array $form_state
* The Drupal form state. * The Drupal form state.
* @param array $step
* The step that execution begins from.
*/ */
function islandora_ingest_form_execute_consecutive_callback_steps(array $form, array &$form_state, array $step) { function islandora_ingest_form_execute_consecutive_callback_steps(array $form, array &$form_state, array $step) {
do { do {
@ -409,6 +416,8 @@ function islandora_ingest_form_execute_consecutive_callback_steps(array $form, a
* The Drupal form. * The Drupal form.
* @param array $form_state * @param array $form_state
* The Drupal form state. * The Drupal form state.
* @param array $step
* The step currently being executed.
*/ */
function islandora_ingest_form_execute_callback_step(array $form, array &$form_state, array $step) { function islandora_ingest_form_execute_callback_step(array $form, array &$form_state, array $step) {
$args = array(&$form_state); $args = array(&$form_state);
@ -425,6 +434,8 @@ function islandora_ingest_form_execute_callback_step(array $form, array &$form_s
* The Drupal form. * The Drupal form.
* @param array $form_state * @param array $form_state
* The Drupal form state. * The Drupal form state.
* @param array $step
* The step that execution begins from.
*/ */
function islandora_ingest_form_undo_consecutive_callback_steps(array $form, array &$form_state, array $step) { function islandora_ingest_form_undo_consecutive_callback_steps(array $form, array &$form_state, array $step) {
do { do {
@ -443,6 +454,8 @@ function islandora_ingest_form_undo_consecutive_callback_steps(array $form, arra
* The Drupal form. * The Drupal form.
* @param array $form_state * @param array $form_state
* The Drupal form state. * The Drupal form state.
* @param array $step
* The step which the undo callback is being called on.
*/ */
function islandora_ingest_form_undo_callback_step(array $form, array &$form_state, array $step) { function islandora_ingest_form_undo_callback_step(array $form, array &$form_state, array $step) {
$args = array(&$form_state); $args = array(&$form_state);
@ -457,11 +470,13 @@ function islandora_ingest_form_undo_callback_step(array $form, array &$form_stat
* The Drupal form. * The Drupal form.
* @param array $form_state * @param array $form_state
* The Drupal form state. * The Drupal form state.
* @param array $step
* An array defining a ingest step.
* *
* @return array * @return array
* The stepified Drupal form definition for the given step. * The stepified Drupal form definition for the given step.
*/ */
function islandora_ingest_form_stepify(array $form, array &$form_state, $step) { function islandora_ingest_form_stepify(array $form, array &$form_state, array $step) {
$first_form_step = islandora_ingest_form_on_first_form_step($form_state); $first_form_step = islandora_ingest_form_on_first_form_step($form_state);
$last_form_step = islandora_ingest_form_on_last_form_step($form_state); $last_form_step = islandora_ingest_form_on_last_form_step($form_state);
$form['form_step_id'] = array( $form['form_step_id'] = array(
@ -692,6 +707,8 @@ function islandora_ingest_form_ingest_button(array &$form_state) {
* *
* Attempts to ingest every object built by the previous steps. * Attempts to ingest every object built by the previous steps.
* *
* @param array $form
* The Drupal form.
* @param array $form_state * @param array $form_state
* The Drupal form state. * The Drupal form state.
*/ */

3
includes/object.entity_controller.inc

@ -24,6 +24,9 @@ class IslandoraObjectEntityController implements DrupalEntityControllerInterface
* The ID's of the entities. * The ID's of the entities.
* @param array $conditions * @param array $conditions
* The conditions to apply. * The conditions to apply.
*
* @return array
* An array of loaded objects.
*/ */
public function load($ids = array(), $conditions = array()) { public function load($ids = array(), $conditions = array()) {
if (!empty($conditions)) { if (!empty($conditions)) {

3
includes/tuque_wrapper.inc

@ -207,6 +207,9 @@ class IslandoraFedoraApiM extends FedoraApiM {
'params' => $params, 'params' => $params,
); );
islandora_alter_datastream($object, $datastream, $context); islandora_alter_datastream($object, $datastream, $context);
if (isset($params['lastModifiedDate'])) {
$params['lastModifiedDate'] = (string) $object[$dsid]->createdDate;
}
try { try {
if ($context['block']) { if ($context['block']) {
throw new Exception('Modify Datastream was blocked.'); throw new Exception('Modify Datastream was blocked.');

2
includes/utilities.inc

@ -14,6 +14,8 @@
* *
* @param int $bytes * @param int $bytes
* Size in bytes to convert * Size in bytes to convert
* @param int $precision
* The amount of decimal precision to show.
* *
* @return string * @return string
* Human readable size. * Human readable size.

1
islandora.info

@ -17,4 +17,5 @@ files[] = tests/hooks.test
files[] = tests/ingest.test files[] = tests/ingest.test
files[] = tests/hooked_access.test files[] = tests/hooked_access.test
files[] = tests/islandora_manage_permissions.test files[] = tests/islandora_manage_permissions.test
files[] = tests/datastream_versions.test
php = 5.3 php = 5.3

62
islandora.module

@ -33,6 +33,7 @@ define('FEDORA_ADD_DS', 'add fedora datastreams');
define('FEDORA_INGEST', 'ingest fedora objects'); define('FEDORA_INGEST', 'ingest fedora objects');
define('FEDORA_PURGE', 'delete fedora objects and datastreams'); define('FEDORA_PURGE', 'delete fedora objects and datastreams');
define('FEDORA_MANAGE_PROPERTIES', 'manage object properties'); define('FEDORA_MANAGE_PROPERTIES', 'manage object properties');
define('ISLANDORA_VIEW_DATASTREAM_HISTORY', 'view old datastream versions');
// Hooks. // Hooks.
define('ISLANDORA_VIEW_HOOK', 'islandora_view_object'); define('ISLANDORA_VIEW_HOOK', 'islandora_view_object');
@ -241,6 +242,48 @@ function islandora_menu() {
'access arguments' => array(FEDORA_PURGE, 4), 'access arguments' => array(FEDORA_PURGE, 4),
'load arguments' => array(2), 'load arguments' => array(2),
); );
<<<<<<< HEAD
=======
$items['islandora/object/%islandora_object/datastream/%islandora_datastream/version'] = array(
'title' => 'Datastream Versions',
'page arguments' => array(4),
'page callback' => 'islandora_datastream_version_table',
'file' => 'includes/datastream.version.inc',
'type' => MENU_CALLBACK,
'access callback' => 'islandora_datastream_access',
'access arguments' => array(ISLANDORA_VIEW_DATASTREAM_HISTORY, 4),
'load arguments' => array(2),
);
$items['islandora/object/%islandora_object/datastream/%islandora_datastream/version/%/delete'] = array(
'title' => 'Delete datastream version',
'page arguments' => array('islandora_delete_datastream_version_form', 4, 6),
'page callback' => 'drupal_get_form',
'file' => 'includes/datastream.version.inc',
'type' => MENU_CALLBACK,
'access callback' => 'islandora_datastream_access',
'access arguments' => array(FEDORA_PURGE, 4),
'load arguments' => array(2),
);
$items['islandora/object/%islandora_object/datastream/%islandora_datastream/version/%/view'] = array(
'title' => 'View datastream version',
'page callback' => 'islandora_view_datastream',
'page arguments' => array(4, FALSE, 6),
'type' => MENU_CALLBACK,
'file' => 'includes/datastream.inc',
'access callback' => 'islandora_datastream_access',
'access arguments' => array(ISLANDORA_VIEW_DATASTREAM_HISTORY, 4),
'load arguments' => array(2),
);
$items['islandora/object/%islandora_object/print'] = array(
'title' => 'Print Object',
'page callback' => 'islandora_print_object',
'page arguments' => array(2),
'type' => MENU_CALLBACK,
'access callback' => 'islandora_object_access',
'access arguments' => array(FEDORA_VIEW_OBJECTS, 2),
'load arguments' => array(2),
);
>>>>>>> 73e09a9d0d9f0f91f2cbca4d6a204a96c9695fa1
$items['islandora/object/%islandora_object/download_clip'] = array( $items['islandora/object/%islandora_object/download_clip'] = array(
'page callback' => 'islandora_download_clip', 'page callback' => 'islandora_download_clip',
'page arguments' => array(2), 'page arguments' => array(2),
@ -267,8 +310,9 @@ function islandora_menu() {
function islandora_admin_paths() { function islandora_admin_paths() {
$paths = array(); $paths = array();
$paths['islandora/object/*/manage*'] = TRUE; $paths['islandora/object/*/manage*'] = TRUE;
$paths['islandora/object/*/delete'] = TRUE; $paths['islandora/object/*/delete*'] = TRUE;
$paths['islandora/object/*/datastream/*/edit'] = TRUE; $paths['islandora/object/*/datastream/*/edit'] = TRUE;
$paths['islandora/object/*/datastream/*/versions'] = TRUE;
return $paths; return $paths;
} }
@ -338,16 +382,24 @@ function islandora_theme() {
), ),
'islandora_datastream_delete_link' => array( 'islandora_datastream_delete_link' => array(
'file' => 'theme/theme.inc', 'file' => 'theme/theme.inc',
'variables' => array('datastream' => NULL), 'variables' => array('datastream' => NULL, 'version' => NULL),
), ),
'islandora_datastream_view_link' => array( 'islandora_datastream_view_link' => array(
'file' => 'theme/theme.inc', 'file' => 'theme/theme.inc',
'variables' => array('datastream' => NULL), 'variables' => array(
'datastream' => NULL,
'version' => NULL,
'label' => NULL,
),
), ),
'islandora_datastream_download_link' => array( 'islandora_datastream_download_link' => array(
'file' => 'theme/theme.inc', 'file' => 'theme/theme.inc',
'variables' => array('datastream' => NULL), 'variables' => array('datastream' => NULL),
), ),
'islandora_datastream_version_link' => array(
'file' => 'theme/theme.inc',
'variables' => array('datastream' => NULL),
),
); );
} }
@ -380,6 +432,10 @@ function islandora_permission() {
'title' => t('Manage object properties'), 'title' => t('Manage object properties'),
'description' => t('Modify object labels, owner IDs, and states.'), 'description' => t('Modify object labels, owner IDs, and states.'),
), ),
ISLANDORA_VIEW_DATASTREAM_HISTORY => array(
'title' => t('View datastream history'),
'description' => t('View all previous versions of a datastream.'),
),
); );
} }

198
tests/datastream_versions.test

@ -0,0 +1,198 @@
<?php
/**
* @file
* Tests that datastream versions code works as intended
*/
class IslandoraDatastreamVersionTestCase extends IslandoraWebTestCase {
/**
* Gets info to display to describe this test.
*
* @see IslandoraWebTestCase::getInfo()
*/
public static function getInfo() {
return array(
'name' => 'Islandora Datastream Versions',
'description' => 'Tests the functionality related to datastream versions in Islandora.',
'group' => 'Islandora',
);
}
/**
* Create an object with many datastram versions.
*
* @see IslandoraWebTestCase::setUp()
*/
public function setUp() {
parent::setUp();
$this->pid = $this->randomName() . ":" . $this->randomName();
$tuque = islandora_get_tuque_connection();
$object = $tuque->repository->constructObject($this->pid);
$object = $tuque->repository->ingestObject($object);
$this->dsid = $this->randomName();
$ds = $object->constructDatastream($this->dsid);
$ds->label = 'Test';
$ds->content = 'test';
$object->ingestDatastream($ds);
// Create three versions.
$ds->mimetype = 'application/pdf';
$ds->label = 'jaaaaa maaaan';
$ds->content = 'Tests... are the bests.';
}
/**
* Free any objects/resources created for this test.
*
* @see IslandoraWebTestCase::tearDown()
*/
public function tearDown() {
$tuque = islandora_get_tuque_connection();
$tuque->repository->purgeObject($this->pid);
parent::tearDown();
}
/**
* Check if the user can see datastream versions in the datastream table.
*/
public function testSeeDatastreamVersions() {
$user = $this->drupalCreateUser(array(
'view fedora repository objects',
'ingest fedora objects',
'view old datastream versions',
'add fedora datastreams',
));
$this->drupalLogin($user);
$this->drupalGet("islandora/object/{$this->pid}/manage/datastreams");
$this->assertLink($this->dsid);
$this->assertLink("4");
$encoded_pid = urlencode($this->pid);
$this->assertLinkByHref("islandora/object/$encoded_pid/datastream/{$this->dsid}/version");
}
/**
* Check that users without permission cannot see datastream versions.
*/
public function testNotSeeDatastreamVersions() {
$user = $this->drupalCreateUser(array(
'view fedora repository objects',
'ingest fedora objects',
'add fedora datastreams',
));
$this->drupalLogin($user);
$this->drupalGet("islandora/object/{$this->pid}/manage/datastreams");
$this->assertLink($this->dsid);
$this->assertNoLink("4");
$encoded_pid = urlencode($this->pid);
$this->assertNoLinkByHref("islandora/object/$encoded_pid/datastream/{$this->dsid}/version");
}
/**
* Check that users without permission cannot see datastream version pages.
*/
public function testDatastreamVersionPermissions() {
$this->drupalGet("islandora/object/{$this->pid}/datastream/{$this->dsid}/version");
$this->assertResponse(403);
$this->drupalGet("islandora/object/{$this->pid}/datastream/{$this->dsid}/version/0/view");
$this->assertResponse(403);
}
/**
* Check that the proper infomration is displayed on the ds version page.
*/
public function testDatastreamVersionPage() {
$user = $this->drupalCreateUser(array(
'view old datastream versions',
));
$this->drupalLogin($user);
$this->drupalGet("islandora/object/{$this->pid}/datastream/{$this->dsid}/version");
$this->assertNoLink("Delete");
$this->assertText("text/xml");
$this->assertText("application/pdf");
$this->assertText("jaaaaa maaaan");
$this->assertText("Test");
$encoded_pid = urlencode($this->pid);
$this->assertLinkByHref("islandora/object/$encoded_pid/datastream/{$this->dsid}/version/0/view");
$this->assertLinkByHref("islandora/object/$encoded_pid/datastream/{$this->dsid}/version/1/view");
$this->assertLinkByHref("islandora/object/$encoded_pid/datastream/{$this->dsid}/version/2/view");
$this->assertLinkByHref("islandora/object/$encoded_pid/datastream/{$this->dsid}/version/3/view");
}
/**
* Make sure the correct content is displayed for each datastream version.
*/
public function testDatastreamVersionContent() {
$user = $this->drupalCreateUser(array(
'view old datastream versions',
));
$this->drupalLogin($user);
$this->drupalGet("islandora/object/{$this->pid}/datastream/{$this->dsid}/version/3/view");
$content = $this->drupalGetContent();
if ($content != 'test') {
$this->fail("Incorrect datastream content");
}
$this->drupalGet("islandora/object/{$this->pid}/datastream/{$this->dsid}/version/2/view");
$content = $this->drupalGetContent();
if ($content != 'test') {
$this->fail("Incorrect datastream content");
}
$this->drupalGet("islandora/object/{$this->pid}/datastream/{$this->dsid}/version/1/view");
$content = $this->drupalGetContent();
if ($content != 'test') {
$this->fail("Incorrect datastream content");
}
$this->drupalGet("islandora/object/{$this->pid}/datastream/{$this->dsid}/version/0/view");
$content = $this->drupalGetContent();
if ($content != 'Tests... are the bests.') {
$this->fail("Incorrect datastream content");
}
$this->drupalGet("islandora/object/{$this->pid}/datastream/{$this->dsid}/version/5/view");
$this->assertResponse(404);
}
/**
* Make sure you can delete datastream versions.
*/
public function testDatastreamVersionDelete() {
$user = $this->drupalCreateUser(array(
'view old datastream versions',
'delete fedora objects and datastreams',
));
$this->drupalLogin($user);
$this->drupalGet("islandora/object/{$this->pid}/datastream/{$this->dsid}/version");
$this->assertLink("delete");
$this->assertText('text/xml');
$encoded_pid = urlencode($this->pid);
$this->assertLinkByHref("islandora/object/$encoded_pid/datastream/{$this->dsid}/version/0/delete");
$this->assertLinkByHref("islandora/object/$encoded_pid/datastream/{$this->dsid}/version/1/delete");
$this->assertLinkByHref("islandora/object/$encoded_pid/datastream/{$this->dsid}/version/2/delete");
$this->assertLinkByHref("islandora/object/$encoded_pid/datastream/{$this->dsid}/version/3/delete");
$this->drupalGet("islandora/object/{$this->pid}/datastream/{$this->dsid}/version/3/delete");
$this->drupalPost(NULL, array(), t('Delete'));
$this->assertNoText('text/xml');
}
/**
* Make sure you can't delete versions that don't exist/have only 1 version.
*/
public function testDatastreamVersionDeleteEdgeCase() {
$user = $this->drupalCreateUser(array(
'view old datastream versions',
'delete fedora objects and datastreams',
));
$this->drupalLogin($user);
$this->drupalGet("islandora/object/{$this->pid}/datastream/{$this->dsid}/version/6/delete");
$this->assertResponse(404);
$this->drupalGet("islandora/object/{$this->pid}/datastream/DC/version/0/delete");
$this->assertResponse(404);
}
}

12
tests/islandora_ingest_test.module

@ -87,7 +87,11 @@ function islandora_ingest_test_test_testcmodel2_islandora_ingest_steps(array &$f
* The Drupal form definition. * The Drupal form definition.
*/ */
function islandora_ingest_test_set_label_form(array $form, array &$form_state) { function islandora_ingest_test_set_label_form(array $form, array &$form_state) {
$models = array('test:nomorestepscmodel', 'test:testcmodel', 'test:testcmodel2'); $models = array(
'test:nomorestepscmodel',
'test:testcmodel',
'test:testcmodel2',
);
$model = isset($form_state['values']['model']) ? $form_state['values']['model'] : reset($models); $model = isset($form_state['values']['model']) ? $form_state['values']['model'] : reset($models);
$shared_storage = &islandora_ingest_form_get_shared_storage($form_state); $shared_storage = &islandora_ingest_form_get_shared_storage($form_state);
$shared_storage['models'] = array($model); $shared_storage['models'] = array($model);
@ -139,8 +143,7 @@ function islandora_ingest_test_set_label_form_submit(array $form, array &$form_s
* Test the First content model. * Test the First content model.
*/ */
function islandora_ingest_test_testcmodel_form(array $form, array &$form_state) { function islandora_ingest_test_testcmodel_form(array $form, array &$form_state) {
return array( return array();
);
} }
/** /**
@ -154,8 +157,7 @@ function islandora_ingest_test_testcmodel_form_submit(array $form, array &$form_
* Test the second content model. * Test the second content model.
*/ */
function islandora_ingest_test_testcmodel2_form(array $form, array &$form_state) { function islandora_ingest_test_testcmodel2_form(array $form, array &$form_state) {
return array( return array();
);
} }
/** /**

62
tests/islandora_web_test_case.inc

@ -157,27 +157,27 @@ class IslandoraWebTestCase extends DrupalWebTestCase {
} }
/** /**
* Asserts that the given datastreams exist on the object. * Asserts that the given datastreams exist correctly on the object.
* *
* @param AbstractObject $object * @param AbstractObject $object
* The PID of the object * The PID of the object
* @param array $datastreams * @param array $datastreams
* An array of strings containing datastream names * An array of strings containing datastream names
*/ */
public function assertDatastreams($object, array $datastreams) { public function assertDatastreams($object, array $datastreams) {
if (!is_object($object)) { if (!is_object($object)) {
$this->fail("Failed. Object passed in is invalid."); $this->fail("Failed. Object passed in is invalid.", 'Islandora');
return;
} }
foreach ($datastreams as $datastream) { foreach ($datastreams as $datastream) {
if (isset($object[$datastream])) { if (isset($object[$datastream])) {
$this->pass("Loaded datastream {$datastream} from PID {$object->id}"); $this->pass("Loaded datastream {$datastream} from PID {$object->id}.", 'Islandora');
} }
else { else {
$this->fail("Failed to load datastream {$datastream} from PID {$object->id}"); $this->fail("Failed to load datastream {$datastream} from PID {$object->id}.", 'Islandora');
} }
} }
} }
/** /**
@ -199,7 +199,7 @@ class IslandoraWebTestCase extends DrupalWebTestCase {
} }
} }
} }
$this->fail("Failed to parse path : $path."); $this->fail("Failed to parse path: $path.");
return FALSE; return FALSE;
} }
@ -208,31 +208,49 @@ class IslandoraWebTestCase extends DrupalWebTestCase {
* *
* @param string $pid * @param string $pid
* The PID of the collection to be deleted * The PID of the collection to be deleted
* @param string $button
* The label of the first 'Delete' button
*/ */
public function deleteObject($pid) { public function deleteObject($pid, $button = 'Delete') {
$current_user = $this->loggedInUser;
$user = $this->drupalCreateUser(array(
'manage object properties',
'delete fedora objects and datastreams',
'view fedora repository objects',
));
$this->drupalLogin($user);
$path = 'islandora/object/' . $pid . '/manage/properties'; $path = 'islandora/object/' . $pid . '/manage/properties';
$edit = array(); $edit = array();
$this->drupalPost($path, $edit, t('Delete')); $this->drupalPost($path, $edit, $button);
$this->drupalPost($this->url, $edit, t('Delete')); $this->drupalPost($this->url, $edit, t('Delete'));
$object = islandora_object_load($pid); $object = islandora_object_load($pid);
$this->drupalGet("islandora/object/$pid"); $this->drupalGet("islandora/object/$pid");
$this->assertResponse(404, "Object $pid successfully deleted."); $this->assertResponse(404, "Object $pid successfully deleted.");
}
/**
* Reverses a hex string and converts it to a little-endian-formatted integer.
*
* This is useful for running checks on values that appear in the binary
* of a datastream. Returns FALSE if the hex value contains non-hex characters
* or if the string would not return a 16- or 32-bit formatted big-endian
* signed integer.
*
* @param string $hex
* The hex value being converted.
*
* @return bool|int
* FALSE or the integer value that is converted.
*/
public function convertHexToInt($hex) {
if ($current_user) { // A couple of quick string checks.
$this->drupalLogin($current_user); if (!ctype_xdigit($hex)) {
$this->fail('String passed to convertHexToInt() contains non-hexidecimal characters.', 'PHP');
return FALSE;
} }
else { if (!strlen($hex) === 4 || !strlen($hex) === 8) {
$this->drupalLogout(); $this->fail('String passed to convertHexToInt() cannot create a 16- or 32-bit little-endian signed integer', 'PHP');
return FALSE;
} }
// The actual conversion.
$reverse_hex = implode('', array_reverse(str_split($hex, 2)));
$int = hexdec($reverse_hex);
return $int;
} }
} }

191
theme/theme.inc

@ -15,59 +15,71 @@ function islandora_preprocess_islandora_default_edit(array &$variables) {
$variables['islandora_editmetadata_url'] = $base_url . '/islandora/edit_form/' . $islandora_object->id; $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/datastream');
module_load_include('inc', 'islandora', 'includes/utilities'); module_load_include('inc', 'islandora', 'includes/utilities');
$header = array( $header = array();
array('data' => t('ID')), $header[] = array('data' => t('ID'));
array('data' => t('Label')), $header[] = array('data' => t('Label'));
array('data' => t('Type')), $header[] = array('data' => t('Type'));
array('data' => t('Mime type')), $header[] = array('data' => t('Mime type'));
array('data' => t('Size')), $header[] = array('data' => t('Size'));
array('data' => t('Operations'), 'colspan' => '3'), if (user_access(ISLANDORA_VIEW_DATASTREAM_HISTORY)) {
); $header[] = array('data' => t('Versions'));
}
$header[] = array('data' => t('Operations'), 'colspan' => '3');
$table_attributes = array('class' => array('manage-datastreams')); $table_attributes = array('class' => array('manage-datastreams'));
$rows = array(); $rows = array();
foreach ($islandora_object as $ds) { foreach ($islandora_object as $ds) {
$rows[] = array( $row = array();
array( $row[] = array(
'class' => 'datastream-id', 'class' => 'datastream-id',
'data' => theme('islandora_datastream_view_link', array( 'data' => theme('islandora_datastream_view_link', array(
'datastream' => $ds, 'datastream' => $ds,
)), )),
), );
array( $row[] = array(
'class' => 'datastream-label', 'class' => 'datastream-label',
'data' => $ds->label, 'data' => $ds->label,
), );
array( $row[] = array(
'class' => 'datastream-control', 'class' => 'datastream-control',
'data' => islandora_control_group_to_human_readable($ds->controlGroup), 'data' => islandora_control_group_to_human_readable($ds->controlGroup),
), );
array( $row[] = array(
'class' => 'datastream-mime', 'class' => 'datastream-mime',
'data' => $ds->mimeType, 'data' => $ds->mimeType,
), );
array( $row[] = array(
'class' => 'datastream-size', 'class' => 'datastream-size',
'data' => islandora_datastream_get_human_readable_size($ds), 'data' => islandora_datastream_get_human_readable_size($ds),
), );
array( if (user_access(ISLANDORA_VIEW_DATASTREAM_HISTORY)) {
'class' => 'datastream-download', $row[] = array(
'data' => theme('islandora_datastream_download_link', array( 'class' => 'datastream-versions',
'datastream' => $ds, 'data' => theme('islandora_datastream_version_link', array(
)),
),
array(
'class' => 'datstream-edit',
'data' => theme('islandora_datastream_edit_link', array(
'datastream' => $ds,
)),
),
array(
'class' => 'datastream-delete',
'data' => theme('islandora_datastream_delete_link', array(
'datastream' => $ds, 'datastream' => $ds,
)), )),
), );
}
$row[] = array(
'class' => 'datastream-download',
'data' => theme('islandora_datastream_download_link', array(
'datastream' => $ds,
)),
); );
$row[] = array(
'class' => 'datstream-edit',
'data' => theme('islandora_datastream_edit_link', array(
'datastream' => $ds,
)),
);
$row[] = array(
'class' => 'datastream-delete',
'data' => theme('islandora_datastream_delete_link', array(
'datastream' => $ds,
)),
);
$rows[] = $row;
} }
$caption = $islandora_object->label . ' - ' . $islandora_object->id; $caption = $islandora_object->label . ' - ' . $islandora_object->id;
$table = array( $table = array(
@ -239,6 +251,9 @@ function islandora_preprocess_islandora_objects(array &$variables) {
* @param array $vars * @param array $vars
* An array containing: * An array containing:
* - datastream: An AbstractDatastream for which to generate a download link. * - datastream: An AbstractDatastream for which to generate a download link.
*
* @return string
* Markup containing the download url if the user has access, empty otherwise.
*/ */
function theme_islandora_datastream_download_link(array $vars) { function theme_islandora_datastream_download_link(array $vars) {
$datastream = $vars['datastream']; $datastream = $vars['datastream'];
@ -256,15 +271,36 @@ function theme_islandora_datastream_download_link(array $vars) {
* @param array $vars * @param array $vars
* An array containing: * An array containing:
* - datastream: An AbstractDatastream for which to generate a view link. * - datastream: An AbstractDatastream for which to generate a view link.
* - label: (Optional) The label for the link.
* - version: (Optional) The version of the datstream to link to.
*
* @return string
* Markup containing the link to the datastream or the label if inaccessible.
*/ */
function theme_islandora_datastream_view_link(array $vars) { function theme_islandora_datastream_view_link(array $vars) {
$datastream = $vars['datastream']; $datastream = $vars['datastream'];
module_load_include('inc', 'islandora', 'includes/utilities'); module_load_include('inc', 'islandora', 'includes/utilities');
$label = check_plain($datastream->id); if ($vars['label'] === NULL) {
return islandora_datastream_access(FEDORA_VIEW_OBJECTS, $datastream) ? $label = check_plain($datastream->id);
l($label, islandora_datastream_get_url($datastream, 'view')) : }
$label; else {
$label = check_plain($vars['label']);
}
if ($vars['version'] === NULL) {
$perm = FEDORA_VIEW_OBJECTS;
}
else {
$perm = ISLANDORA_VIEW_DATASTREAM_HISTORY;
}
if (islandora_datastream_access($perm, $datastream)) {
return l($label, islandora_datastream_get_url($datastream, 'view', $vars['version']));
}
else {
return $label;
}
} }
/** /**
@ -273,6 +309,10 @@ function theme_islandora_datastream_view_link(array $vars) {
* @param array $vars * @param array $vars
* An array containing: * An array containing:
* - datastream: An AbstractDatastream for which to generate a delete link. * - datastream: An AbstractDatastream for which to generate a delete link.
* - version: (optional) the version of the datastream to delete.
*
* @return string
* Markup containing the url to delete a datastream, or empty if inaccessible.
*/ */
function theme_islandora_datastream_delete_link(array $vars) { function theme_islandora_datastream_delete_link(array $vars) {
$datastream = $vars['datastream']; $datastream = $vars['datastream'];
@ -281,9 +321,22 @@ function theme_islandora_datastream_delete_link(array $vars) {
$can_delete = !in_array($datastream->id, $datastreams) && islandora_datastream_access(FEDORA_PURGE, $datastream); $can_delete = !in_array($datastream->id, $datastreams) && islandora_datastream_access(FEDORA_PURGE, $datastream);
return $can_delete ? if ($vars['version'] !== NULL) {
l(t('delete'), "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/delete") : if (count($datastream) == 1) {
$can_delete = FALSE;
}
$link = "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/version/{$vars['version']}/delete";
}
else {
$link = "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/delete";
}
if ($can_delete) {
return l(t('delete'), $link);
}
else {
''; '';
}
} }
/** /**
@ -292,6 +345,9 @@ function theme_islandora_datastream_delete_link(array $vars) {
* @param array $vars * @param array $vars
* An array containing: * An array containing:
* - datastream: An AbstractDatastream for which to generate a edit link. * - datastream: An AbstractDatastream for which to generate a edit link.
*
* @return string
* Markup containing the url to edit a datastream, or empty if inaccessible.
*/ */
function theme_islandora_datastream_edit_link(array $vars) { function theme_islandora_datastream_edit_link(array $vars) {
$datastream = $vars['datastream']; $datastream = $vars['datastream'];
@ -304,3 +360,32 @@ function theme_islandora_datastream_edit_link(array $vars) {
l(t('edit'), "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/edit") : l(t('edit'), "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/edit") :
''; '';
} }
/**
* Renders a link to take you to the datastream versions page.
*
* @param array $vars
* An array containing:
* - datastream: An AbstractDatastream to generate the version link from.
*
* @return string
* Markup.
*/
function theme_islandora_datastream_version_link(array $vars) {
$datastream = $vars['datastream'];
module_load_include('inc', 'islandora', 'includes/utilities');
$see_history = islandora_datastream_access(ISLANDORA_VIEW_DATASTREAM_HISTORY, $datastream);
if ($see_history) {
if ($datastream->versionable) {
return l(count($datastream), "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/version");
}
else {
return t('Not Versioned');
}
}
else {
return '';
}
}

Loading…
Cancel
Save