diff --git a/includes/datastream.version.inc b/includes/datastream.version.inc
index ecef019d..91e8d295 100644
--- a/includes/datastream.version.inc
+++ b/includes/datastream.version.inc
@@ -231,6 +231,112 @@ function islandora_revert_datastream_version_form_submit(array $form, array &$fo
$form_state['redirect'] = "islandora/object/{$islandora_object->id}/datastream/{$datastream_to_revert->id}/version";
}
+/**
+ * The admin replace datastream form.
+ *
+ * @param array $form
+ * The Drupal form.
+ * @param array $form_state
+ * The Drupal form state.
+ * @param AbstractDatastream $datastream
+ * The datastream to be updated.
+ *
+ * @return array
+ * The drupal form definition.
+ */
+function islandora_datastream_version_replace_form($form, &$form_state, AbstractDatastream $datastream) {
+ module_load_include('inc', 'islandora', 'includes/content_model');
+ module_load_include('inc', 'islandora', 'includes/utilities');
+
+ $object = islandora_object_load($datastream->parent->id);
+ $form_state['object_id'] = $object->id;
+ $form_state['dsid'] = $datastream->id;
+ $form_state['object'] = $object;
+
+ $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',
+ ),
+ 'dsid_fieldset' => array(
+ '#type' => 'fieldset',
+ '#title' => 'Update datastream with latest version',
+ '#collapsible' => FALSE,
+ '#collapsed' => FALSE,
+ 'dsid' => array(
+ '#disabled' => TRUE,
+ '#default_value' => $datastream->id,
+ '#title' => 'Datastream ID',
+ '#description' => t("The current ID for this stream that is unique to this object."),
+ '#type' => 'textfield',
+ '#size' => 64,
+ '#maxlength' => 64,
+ '#required' => TRUE,
+ ),
+ 'label' => array(
+ '#disabled' => TRUE,
+ '#default_value' => $datastream->label,
+ '#title' => 'Datastream Label',
+ '#required' => TRUE,
+ '#size' => 64,
+ '#maxlength' => 64,
+ '#description' => t('The DSID human-readable label'),
+ '#type' => 'textfield',
+ ),
+ 'file' => array(
+ '#type' => 'managed_file',
+ '#required' => TRUE,
+ '#title' => t('Upload Document'),
+ '#size' => 48,
+ '#description' => t('Select a file to upload.
Files must be less than @size MB.', array('@size' => $upload_size)),
+ '#default_value' => isset($form_state['values']['files']) ? $form_state['values']['files'] : NULL,
+ '#upload_location' => 'temporary://',
+ '#upload_validators' => array(
+ 'file_validate_extensions' => array(NULL),
+ // Assume its specified in MB.
+ 'file_validate_size' => array($upload_size * 1024 * 1024),
+ ),
+ ),
+ 'submit' => array(
+ '#type' => 'submit',
+ '#value' => t('Add Contents'),
+ ),
+ ),
+ );
+}
+
+/**
+ * Submit handler for the replace datastream form.
+ *
+ * Adds a new datastream version as latest.
+ *
+ * @param array $form
+ * The Drupal form.
+ * @param array $form_state
+ * The Drupal form state.
+ */
+function islandora_datastream_version_replace_form_submit($form, &$form_state) {
+ $object = islandora_object_load($form_state['object_id']);
+ $form_state['redirect'] = "islandora/object/{$object->id}";
+ $file = file_load($form_state['values']['file']);
+ try {
+ $ds = $object[$form_state['dsid']];
+ $ds->label = $form_state['values']['label'];
+ $ds->mimetype = $file->filemime;
+ $path = drupal_realpath($file->uri);
+ $ds->setContentFromFile($path);
+ file_delete($file);
+ }
+ catch (exception $e) {
+ drupal_set_message(t('@message', array('@message' => check_plain($e->getMessage()))), 'error');
+ file_delete($file);
+ return;
+ }
+ drupal_set_message(t("Successfully Updated Datastream"));
+ $form_state['redirect'] = "islandora/object/{$object->id}";
+}
+
/**
* Gets Audit datastream values from foxml.
*
diff --git a/islandora.module b/islandora.module
index 21c902c2..fafb7f8e 100644
--- a/islandora.module
+++ b/islandora.module
@@ -34,10 +34,11 @@ 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_ADD_NEW_DATASTREAM_VERSION', 'add a new datastream version as latest');
define('ISLANDORA_MANAGE_DELETED_OBJECTS', 'manage deleted objects');
define('ISLANDORA_REVERT_DATASTREAM', 'revert to old datastream');
define('ISLANDORA_REGENERATE_DERIVATIVES', 'regenerate derivatives for an object');
-
+define('ISLANDORA_REPLACE_DATASTREAM', 'replace a datastream with new content, preserving version history');
// Hooks.
define('ISLANDORA_VIEW_HOOK', 'islandora_view_object');
@@ -317,6 +318,16 @@ function islandora_menu() {
'access arguments' => array(ISLANDORA_VIEW_DATASTREAM_HISTORY, 4),
'load arguments' => array(2),
);
+ $items['islandora/object/%islandora_object/datastream/%islandora_datastream/replace'] = array(
+ 'title' => 'Replace Datastream',
+ 'page arguments' => array('islandora_datastream_version_replace_form', 4),
+ 'page callback' => 'drupal_get_form',
+ 'file' => 'includes/datastream.version.inc',
+ 'type' => MENU_CALLBACK,
+ 'access callback' => 'islandora_datastream_access',
+ 'access arguments' => array(ISLANDORA_ADD_NEW_DATASTREAM_VERSION, 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),
@@ -516,6 +527,10 @@ function islandora_theme() {
'file' => 'theme/theme.inc',
'variables' => array('datastream' => NULL),
),
+ 'islandora_datastream_replace_link' => array(
+ 'file' => 'theme/theme.inc',
+ 'variables' => array('datastream' => NULL),
+ ),
'islandora_dublin_core_display' => array(
'file' => 'theme/theme.inc',
'template' => 'theme/islandora-dublin-core-display',
@@ -582,6 +597,10 @@ function islandora_permission() {
'title' => t('View datastream history'),
'description' => t('View all previous versions of a datastream.'),
),
+ ISLANDORA_ADD_NEW_DATASTREAM_VERSION => array(
+ 'title' => t('Add datastream version'),
+ 'description' => t('Add to a datastreams version history as latest.'),
+ ),
ISLANDORA_REVERT_DATASTREAM => array(
'title' => t('Revert datastream history'),
'description' => t('Revert to a previous version of a datastream.'),
@@ -594,6 +613,10 @@ function islandora_permission() {
'title' => t('Regenerate derivatives'),
'description' => t('Regenerate derivatives for an object or per datastream.'),
),
+ ISLANDORA_REPLACE_DERIVATIVES => array(
+ 'title' => t('Replace derivatives'),
+ 'description' => t('Replace derivatives for an object or per datastream.'),
+ ),
);
}
@@ -1874,8 +1897,7 @@ function islandora_islandora_datastream_access($op, AbstractDatastream $datastre
$hooks = islandora_invoke_hook_list(ISLANDORA_DERVIATIVE_CREATION_HOOK, $object->models, array($object));
$hooks = islandora_filter_derivatives($hooks, array('force' => TRUE), $object);
foreach ($hooks as $hook) {
- if ($hook['destination_dsid'] == $datastream->id &&
- (is_null($hook['source_dsid']) || islandora_datastream_access(ISLANDORA_VIEW_OBJECTS, $object[$hook['source_dsid']], $user))) {
+ if ($hook['destination_dsid'] == $datastream->id && islandora_datastream_access(ISLANDORA_VIEW_OBJECTS, $object[$hook['source_dsid']], $user)) {
$applicable_hook = TRUE;
break;
}
diff --git a/theme/theme.inc b/theme/theme.inc
index feac06b2..a47c2062 100644
--- a/theme/theme.inc
+++ b/theme/theme.inc
@@ -23,6 +23,7 @@ function islandora_preprocess_islandora_default_edit(array &$variables) {
$header[] = array('data' => t('Size'));
if (user_access(ISLANDORA_VIEW_DATASTREAM_HISTORY)) {
$header[] = array('data' => t('Versions'));
+ $header[] = array('data' => t('Replace'));
}
$header[] = array('data' => t('Operations'), 'colspan' => '4');
@@ -60,6 +61,13 @@ function islandora_preprocess_islandora_default_edit(array &$variables) {
'datastream' => $ds,
)),
);
+ // Add new datastream content as the lastest version.
+ $row[] = array(
+ 'class' => 'datastream-replace',
+ 'data' => theme('islandora_datastream_replace_link', array(
+ 'datastream' => $ds,
+ )),
+ );
}
$row[] = array(
'class' => 'datastream-download',
@@ -436,6 +444,28 @@ function theme_islandora_datastream_version_link(array $vars) {
}
}
+/**
+ * Renders a link to take you to the datastream add latest version page.
+ *
+ * @param array $vars
+ * An array containing:
+ * - datastream: An AbstractDatastream to generate a new version.
+ *
+ * @return string
+ * Markup.
+ */
+function theme_islandora_datastream_replace_link(array $vars) {
+ $datastream = $vars['datastream'];
+ //TODO: RELS-EXT and RELS-INT should never be replaced, but should
+ // be moved out into configuration somewhere. Hard coded === bad time.
+ if (islandora_datastream_access(ISLANDORA_REPLACE_DATASTREAM, $datastream) &&
+ islandora_datastream_access(ISLANDORA_ADD_NEW_DATASTREAM_VERSION, $datastream)) {
+ if (strcmp('RELS-EXT', $datastream->id) != 0 && strcmp('RELS-INT', $datastream->id) != 0) {
+ return l(t('replace'), "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/replace");
+ }
+ }
+}
+
/**
* Renders a link that will re-create derivatives for a datastream.
*