From 798312bedb9a2990fd862fc58f033814ad0c5307 Mon Sep 17 00:00:00 2001 From: Christian Selig Date: Wed, 21 Aug 2013 19:46:02 +0000 Subject: [PATCH] Added ability to revert to previous versions of datastreams. --- includes/datastream.version.inc | 90 ++++++++++++++++++++++++++++++++- islandora.module | 20 ++++++++ theme/theme.inc | 35 +++++++++++++ 3 files changed, 144 insertions(+), 1 deletion(-) diff --git a/includes/datastream.version.inc b/includes/datastream.version.inc index 1e7c0830..23ac870b 100644 --- a/includes/datastream.version.inc +++ b/includes/datastream.version.inc @@ -18,7 +18,7 @@ function islandora_datastream_version_table($datastream) { $header[] = array('data' => t('Size')); $header[] = array('data' => t('Label')); $header[] = array('data' => t('Mime type')); - $header[] = array('data' => t('Operations')); + $header[] = array('data' => t('Operations'), 'colspan' => '2'); $rows = array(); foreach ($datastream as $version => $datastream_version) { @@ -50,6 +50,13 @@ function islandora_datastream_version_table($datastream) { 'version' => $version, )), ); + $row[] = array( + 'class' => 'datastream-revert', + 'data' => theme('islandora_datastream_revert_link', array( + 'datastream' => $datastream, + 'version' => $version, + )), + ); $rows[] = $row; } @@ -125,3 +132,84 @@ function islandora_delete_datastream_version_form_submit(array $form, array &$fo $form_state['redirect'] = "islandora/object/{$object->id}/datastream/{$datastream->id}/version"; } + +/** + * The admin revert 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_revert_datastream_version_form(array $form, array &$form_state, AbstractDatastream $datastream, $version) { + if (!isset($datastream[$version]) || count($datastream) < 2) { + return drupal_not_found(); + } + + $form_state['dsid'] = $datastream->id; + $form_state['object_id'] = $datastream->parent->id; + $form_state['version'] = $version; + + return confirm_form($form, + t('Are you sure you want to revert to version @version of the @dsid datastream?', array('@dsid' => $datastream->id, '@version' => $version)), + "islandora/object/{$datastream->parent->id}", + "", + t('Revert'), + t('Cancel') + ); +} + +/** + * Submit handler for the revert 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_revert_datastream_version_form_submit(array $form, array &$form_state) { + $islandora_object = islandora_object_load($form_state['object_id']); + + $datastream_to_revert = $islandora_object[$form_state['dsid']]; + $version = $form_state['version']; + + // Create file holding specified datastream version, and set datastream to it. + $datastream_to_revert_to = $datastream_to_revert[$version]; + if (in_array($datastream_to_revert->controlGroup, array('R', 'E'))) { + $datastream_to_revert->url = $datastream_to_revert_to->url; + } + else { + $filename = file_create_filename('datastream_temp_file', '.'); + $datastream_to_revert_to->getContent($filename); + $datastream_to_revert->setContentFromFile($filename); + file_unmanaged_delete($filename); + } + + if ($datastream_to_revert->mimeType != $datastream_to_revert_to->mimeType) { + $datastream_to_revert->mimeType = $datastream_to_revert_to->mimeType; + } + if ($datastream_to_revert->label != $datastream_to_revert_to->label) { + $datastream_to_revert->label = $datastream_to_revert_to->label; + } + + drupal_set_message(t('%d datastream successfully reverted to version %v for Islandora object %o', array( + '%d' => $datastream_to_revert->id, + '%v' => $version, + '%o' => $islandora_object->label))); + + $form_state['redirect'] = "islandora/object/{$islandora_object->id}/datastream/{$datastream_to_revert->id}/version"; +} + diff --git a/islandora.module b/islandora.module index 96fd5f0d..465719d9 100644 --- a/islandora.module +++ b/islandora.module @@ -34,6 +34,7 @@ define('ISLANDORA_INGEST', 'ingest fedora objects'); define('ISLANDORA_PURGE', 'delete fedora objects and datastreams'); define('ISLANDORA_MANAGE_PROPERTIES', 'manage object properties'); define('ISLANDORA_VIEW_DATASTREAM_HISTORY', 'view old datastream versions'); +define('ISLANDORA_REVERT_DATASTREAM', 'revert to old datastream'); // Hooks. define('ISLANDORA_VIEW_HOOK', 'islandora_view_object'); @@ -276,6 +277,16 @@ function islandora_menu() { 'access arguments' => array(ISLANDORA_PURGE, 4), 'load arguments' => array(2), ); + $items['islandora/object/%islandora_object/datastream/%islandora_datastream/version/%/revert'] = array( + 'title' => 'Revert to datastream version', + 'page arguments' => array('islandora_revert_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(ISLANDORA_REVERT_DATASTREAM, 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', @@ -380,6 +391,10 @@ function islandora_theme() { 'file' => 'theme/theme.inc', 'variables' => array('datastream' => NULL, 'version' => NULL), ), + 'islandora_datastream_revert_link' => array( + 'file' => 'theme/theme.inc', + 'variables' => array('datastream' => NULL, 'version' => NULL), + ), 'islandora_datastream_view_link' => array( 'file' => 'theme/theme.inc', 'variables' => array( @@ -432,6 +447,10 @@ function islandora_permission() { 'title' => t('View datastream history'), 'description' => t('View all previous versions of a datastream.'), ), + ISLANDORA_REVERT_DATASTREAM => array( + 'title' => t('Revert datastream history'), + 'description' => t('Revert to a previous version of a datastream.'), + ), ); } @@ -1552,3 +1571,4 @@ function islandora_islandora_datastream_modified(AbstractObject $object, Abstrac )); islandora_derivative_logging($logging_results); } + diff --git a/theme/theme.inc b/theme/theme.inc index 10e1cd29..863ef901 100644 --- a/theme/theme.inc +++ b/theme/theme.inc @@ -339,6 +339,40 @@ function theme_islandora_datastream_delete_link(array $vars) { } } +/** + * Renders a link to allow replacing of a datatream. + * + * @param array $vars + * An array containing: + * - datastream: An AbstractDatastream for which to generate a revert link. + * - version: (optional) the version of the datastream to revert. + * + * @return string + * Markup containing the url to delete a datastream, or empty if inaccessible. + */ +function theme_islandora_datastream_revert_link(array $vars) { + $datastream = $vars['datastream']; + + $can_revert = islandora_datastream_access(ISLANDORA_REVERT_DATASTREAM, $datastream); + + if ($vars['version'] !== NULL) { + if (count($datastream) == 1) { + $can_revert = FALSE; + } + $link = "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/version/{$vars['version']}/revert"; + } + else { + $link = "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/revert"; + } + + if ($can_revert) { + return l(t('revert'), $link); + } + else { + ''; + } +} + /** * Renders a link to allow editing of a datatream. * @@ -389,3 +423,4 @@ function theme_islandora_datastream_version_link(array $vars) { return ''; } } +