diff --git a/includes/derivatives.inc b/includes/derivatives.inc
index 5ba4bb56..78f00aab 100644
--- a/includes/derivatives.inc
+++ b/includes/derivatives.inc
@@ -121,3 +121,60 @@ function islandora_derivative_logging(array $logging_results) {
}
}
}
+
+/**
+ * Kicks off derivative functions based upon hooks and conditions.
+ *
+ * @param AbstractObject $object
+ * An AbstractObject representing a FedoraObject.
+ * @param array $options
+ * An array of parameters containing:
+ * - force: Bool denoting whether we are forcing the generation of
+ * derivatives.
+ * - source_dsid: (Optional) String of the datastream id we are generating
+ * from or NULL if it's the object itself.
+ * - destination_dsid: (Optional) String of the datastream id that is being
+ * created. To be used in the UI.
+ *
+ * @return array
+ * An array of operations to be called from within a batch.
+ */
+function islandora_do_batch_derivatives(AbstractObject $object, array $options) {
+ module_load_include('inc', 'islandora', 'includes/utilities');
+ $options += array(
+ 'force' => FALSE,
+ );
+ $hooks = islandora_invoke_hook_list(ISLANDORA_DERVIATIVE_CREATION_HOOK, $object->models, array($object));
+ uasort($hooks, 'drupal_sort_weight');
+ $operations = array();
+
+ if (array_key_exists('source_dsid', $options)) {
+ $hooks = array_filter($hooks, function($filter_hook) use($options) {
+ return array_key_exists('source_dsid', $filter_hook) &&
+ $filter_hook['source_dsid'] == $options['source_dsid'];
+ });
+ }
+
+ if (array_key_exists('destination_dsid', $options)) {
+ $hooks = array_filter($hooks, function($filter_hook) use($options) {
+ return array_key_exists('destination_dsid', $filter_hook) &&
+ $filter_hook['destination_dsid'] == $options['destination_dsid'];
+ });
+ }
+
+ foreach ($hooks as $hook) {
+ $file = FALSE;
+ if (isset($hook['file'])) {
+ $file = $hook['file'];
+ }
+ foreach ($hook['function'] as $function) {
+ $operations[] = array('islandora_derivative_perform_batch_operation', array(
+ $function,
+ $file,
+ $object->id,
+ $options['force']),
+ );
+ }
+ }
+ return $operations;
+}
diff --git a/includes/object_properties.form.inc b/includes/object_properties.form.inc
index 676f0d0c..be31719c 100644
--- a/includes/object_properties.form.inc
+++ b/includes/object_properties.form.inc
@@ -26,6 +26,12 @@ function islandora_object_properties_form(array $form, array &$form_state, Abstr
if (!empty($temp)) {
$related_objects_pids = array_merge_recursive($related_objects_pids, $temp);
}
+ $regenerate_derivatives_access = FALSE;
+ if (islandora_object_access(ISLANDORA_REGENERATE_DERIVATIVES, $object)) {
+ if (count(islandora_invoke_hook_list(ISLANDORA_DERVIATIVE_CREATION_HOOK, $object->models, array($object))) > 0) {
+ $regenerate_derivatives_access = TRUE;
+ }
+ }
return array(
'pid' => array(
'#type' => 'hidden',
@@ -84,6 +90,12 @@ function islandora_object_properties_form(array $form, array &$form_state, Abstr
'#submit' => array('islandora_object_properties_form_delete'),
'#limit_validation_errors' => array(array('pid')),
),
+ 'regenerate' => array(
+ '#type' => 'submit',
+ '#access' => $regenerate_derivatives_access,
+ '#value' => t("Regenerate all derivatives"),
+ '#submit' => array('islandora_object_properties_regenerate_derivatives'),
+ ),
);
}
@@ -188,3 +200,15 @@ function islandora_update_object_properties($pid, $update_states, $state, $updat
}
}
}
+
+/**
+ * Callback function for object properties regenerate all derivatives.
+ *
+ * @param array $form
+ * The Drupal form.
+ * @param array $form_state
+ * The Drupal form state.
+ */
+function islandora_object_properties_regenerate_derivatives(array $form, array &$form_state) {
+ drupal_goto("islandora/object/{$form_state['object']}/regenerate");
+}
diff --git a/includes/regenerate_derivatives.form.inc b/includes/regenerate_derivatives.form.inc
new file mode 100644
index 00000000..a7ef147c
--- /dev/null
+++ b/includes/regenerate_derivatives.form.inc
@@ -0,0 +1,178 @@
+ $datastream->id)),
+ "islandora/object/{$datastream->parent->id}/manage/datastreams",
+ t('This will create a new version of the datastream. Please wait while this happens.'),
+ t('Regenerate'),
+ t('Cancel')
+ );
+}
+
+/**
+ * Submit handler for the regenerate datastream derivative form.
+ *
+ * @param array $form
+ * The Drupal form.
+ * @param array $form_state
+ * The Drupal form state.
+ */
+function islandora_regenerate_datastream_derivative_form_submit(array $form, array &$form_state) {
+ module_load_include('inc', 'islandora', 'includes/derivatives');
+ $datastream = $form_state['datastream'];
+ $batch = islandora_regenerate_datastream_derivative_batch($datastream);
+ batch_set($batch);
+ $form_state['redirect'] = "islandora/object/{$datastream->parent->id}/manage/datastreams";
+}
+
+/**
+ * Regenerate all derivatives on an object.
+ *
+ * @param array $form
+ * The Drupal form.
+ * @param array $form_state
+ * The Drupal form state.
+ * @param AbstractObject $object
+ * The object that is having its derivatives regenerated.
+ *
+ * @return array
+ * The Drupal form definition.
+ */
+function islandora_regenerate_object_derivatives_form(array $form, array &$form_state, AbstractObject $object) {
+ $form_state['object'] = $object;
+ return confirm_form($form,
+ t('Are you sure you want to regenerate all the derivatives for %title?', array('%title' => $object->label)),
+ "islandora/object/{$object->id}/manage/properties",
+ t('This will create a new version for every datastream on the object. Please wait while this happens.'),
+ t('Regenerate'),
+ t('Cancel')
+ );
+}
+
+/**
+ * Submit handler for the regenerate object derivativse form.
+ *
+ * @param array $form
+ * The Drupal form.
+ * @param array $form_state
+ * The Drupal form state.
+ */
+function islandora_regenerate_object_derivatives_form_submit(array $form, array &$form_state) {
+ $object = $form_state['object'];
+ $batch = islandora_regenerate_object_derivatives_batch($object);
+ batch_set($batch);
+ $form_state['redirect'] = "islandora/object/{$object->id}/manage/properties";
+}
+
+/**
+ * Creates a batch to go out and re-create all of the derivatives for an object.
+ *
+ * @param AbstractObject $object
+ * A AbstractObject representing an object within Fedora.
+ *
+ * @return array
+ * An array specifying the Drupal batch.
+ */
+function islandora_regenerate_object_derivatives_batch(AbstractObject $object) {
+ module_load_include('inc', 'islandora', 'includes/derivatives');
+ return array(
+ 'title' => t('Regenerating all derivatives for @label', array('@label' => $object->label)),
+ 'operations' => islandora_do_batch_derivatives($object, array('force' => TRUE)),
+ 'init_message' => t('Preparing to regenerate derivatives...'),
+ 'progress_message' => t('Time elapsed: @elapsed
Estimated time remaning @estimate.'),
+ 'error_message' => t('An error has occurred.'),
+ 'file' => drupal_get_path('module', 'islandora') . '/includes/regenerate_derivatives.form.inc',
+ 'finished' => 'islandora_regenerate_derivative_batch_finished',
+ );
+}
+
+/**
+ * Creates a batch to go out and re-create the derivative for a datastream.
+ *
+ * @param AbstractDatastream $datastream
+ * A AbstractDatastream representing a datastream on an object within Fedora.
+ *
+ * @return array
+ * An array specifying the Drupal batch.
+ */
+function islandora_regenerate_datastream_derivative_batch(AbstractDatastream $datastream) {
+ module_load_include('inc', 'islandora', 'includes/derivatives');
+ return array(
+ 'title' => t('Regenerating derivatives for the @dsid datastream', array('@dsid' => $datastream->id)),
+ 'operations' => islandora_do_batch_derivatives($datastream->parent, array(
+ 'force' => TRUE,
+ 'destination_dsid' => $datastream->id,
+ )),
+ 'init_message' => t('Preparing to regenerate derivatives...'),
+ 'progress_message' => t('Time elapsed: @elapsed
Estimated time remaning @estimate.'),
+ 'error_message' => t('An error has occurred.'),
+ 'file' => drupal_get_path('module', 'islandora') . '/includes/regenerate_derivatives.form.inc',
+ 'finished' => 'islandora_regenerate_derivative_batch_finished',
+ );
+}
+
+/**
+ * Wrapper to call out to batch operations.
+ *
+ * @param string $function
+ * The name of the function we are calling for derivatives.
+ * @param bool|string $file
+ * FALSE if there is no file to load, the path to require otherwise
+ * @param string $pid
+ * The pid of the object we are performing.
+ * @param bool $force
+ * Whether we are forcing derivative regeneration or not.
+ * @param array $context
+ * The context of the current batch operation.
+ */
+function islandora_derivative_perform_batch_operation($function, $file, $pid, $force, &$context) {
+ if ($file) {
+ require_once $file;
+ }
+ if (function_exists($function)) {
+ $logging = call_user_func($function, islandora_object_load($pid), $force);
+ if (!empty($logging)) {
+ $context['results']['logging'][] = $logging;
+ }
+ }
+ else {
+ watchdog('islandora', 'Unable to call derivative function @function as it was not found!', array('@function' => $function), WATCHDOG_ERROR);
+ }
+}
+
+/**
+ * Finished function for derivative batch regeneration.
+ *
+ * @param array $success
+ * An array of success passed from the batch.
+ * @param array $results
+ * An array of results passed from the batch.
+ * @param array $operations
+ * An array of operations passed from the batch.
+ */
+function islandora_regenerate_derivative_batch_finished($success, $results, $operations) {
+ module_load_include('inc', 'islandora', 'includes/derivatives');
+ if (!empty($results['logging'])) {
+ islandora_derivative_logging($results['logging']);
+ }
+}
diff --git a/islandora.module b/islandora.module
index 17f13724..fb165f1e 100644
--- a/islandora.module
+++ b/islandora.module
@@ -36,6 +36,7 @@ define('ISLANDORA_MANAGE_PROPERTIES', 'manage object properties');
define('ISLANDORA_VIEW_DATASTREAM_HISTORY', 'view old datastream versions');
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');
// Hooks.
@@ -209,6 +210,15 @@ function islandora_menu() {
'access callback' => 'islandora_object_access_callback',
'access arguments' => array(ISLANDORA_PURGE, 2),
);
+ $items['islandora/object/%islandora_object/regenerate'] = array(
+ 'title' => 'Regenerate all derivatives on an object',
+ 'file' => 'includes/regenerate_derivatives.form.inc',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('islandora_regenerate_object_derivatives_form', 2),
+ 'type' => MENU_CALLBACK,
+ 'access callback' => 'islandora_object_access_callback',
+ 'access arguments' => array(ISLANDORA_REGENERATE_DERIVATIVES, 2),
+ );
$items['islandora/object/%islandora_object/manage/datastreams/add'] = array(
'title' => 'Add a datastream',
'file' => 'includes/add_datastream.form.inc',
@@ -314,6 +324,16 @@ function islandora_menu() {
'access arguments' => array(ISLANDORA_VIEW_DATASTREAM_HISTORY, 4),
'load arguments' => array(2),
);
+ $items['islandora/object/%islandora_object/datastream/%islandora_datastream/regenerate'] = array(
+ 'title' => 'Regenrate datastream derivative',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('islandora_regenerate_datastream_derivative_form', 4),
+ 'file' => 'includes/regenerate_derivatives.form.inc',
+ 'type' => MENU_CALLBACK,
+ 'access callback' => 'islandora_datastream_access',
+ 'access arguments' => array(ISLANDORA_REGENERATE_DERIVATIVES, 4),
+ 'load arguments' => array(2),
+ );
$items['islandora/object/%islandora_object/download_clip'] = array(
'page callback' => 'islandora_download_clip',
'page arguments' => array(2),
@@ -460,6 +480,10 @@ function islandora_theme() {
'file' => 'theme/theme.inc',
'variables' => array('datastream' => NULL),
),
+ 'islandora_datastream_regenerate_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',
@@ -534,6 +558,10 @@ function islandora_permission() {
'title' => t('Manage deleted objects'),
'description' => t('Purge or revert deleted objects.'),
),
+ ISLANDORA_REGENERATE_DERIVATIVES => array(
+ 'title' => t('Regenerate derivatives'),
+ 'description' => t('Regenerate derivatives for an object or per datastream.'),
+ ),
);
}
@@ -1069,7 +1097,7 @@ function islandora_default_islandora_view_object($object) {
*
* @param AbstractObject $object
* The fedora object to print.
- * @param unknown $alter
+ * @param string $alter
* The string representation of the themed viewable object.
*
* @return array
diff --git a/theme/theme.inc b/theme/theme.inc
index 6a80fbb6..0e62f0d7 100644
--- a/theme/theme.inc
+++ b/theme/theme.inc
@@ -25,7 +25,7 @@ function islandora_preprocess_islandora_default_edit(array &$variables) {
$header[] = array('data' => t('Versions'));
}
- $header[] = array('data' => t('Operations'), 'colspan' => '3');
+ $header[] = array('data' => t('Operations'), 'colspan' => '4');
$table_attributes = array('class' => array('manage-datastreams'));
$rows = array();
@@ -53,7 +53,7 @@ function islandora_preprocess_islandora_default_edit(array &$variables) {
'class' => 'datastream-size',
'data' => islandora_datastream_get_human_readable_size($ds),
);
- if (user_access(ISLANDORA_VIEW_DATASTREAM_HISTORY)) {
+ if (islandora_datastream_access(ISLANDORA_VIEW_DATASTREAM_HISTORY, $ds)) {
$row[] = array(
'class' => 'datastream-versions',
'data' => theme('islandora_datastream_version_link', array(
@@ -79,6 +79,14 @@ function islandora_preprocess_islandora_default_edit(array &$variables) {
'datastream' => $ds,
)),
);
+ if (islandora_datastream_access(ISLANDORA_REGENERATE_DERIVATIVES, $ds)) {
+ $row[] = array(
+ 'class' => 'datastream-regenerate',
+ 'data' => theme('islandora_datastream_regenerate_link', array(
+ 'datastream' => $ds,
+ )),
+ );
+ }
$rows[] = $row;
}
$caption = filter_xss($islandora_object->label) . ' - ' . $islandora_object->id;
@@ -424,6 +432,27 @@ function theme_islandora_datastream_version_link(array $vars) {
}
}
+/**
+ * Renders a link that will re-create derivatives for a datastream.
+ *
+ * @param array $vars
+ * An array containing:
+ * - datastream: An AbstractDatastream to generate the version link from.
+ *
+ * @return string
+ * Markup.
+ */
+function theme_islandora_datastream_regenerate_link(array $vars) {
+ $datastream = $vars['datastream'];
+ $object = $datastream->parent;
+ $hooks = islandora_invoke_hook_list(ISLANDORA_DERVIATIVE_CREATION_HOOK, $object->models, array($object));
+ foreach ($hooks as $hook) {
+ if ($hook['destination_dsid'] == $datastream->id) {
+ return l(t('regenerate'), "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/regenerate");
+ }
+ }
+}
+
/**
* Implements hook_preprocess().
*/