diff --git a/css/islandora.admin.css b/css/islandora.admin.css
index 1cd1976d..c7e51b28 100644
--- a/css/islandora.admin.css
+++ b/css/islandora.admin.css
@@ -13,5 +13,11 @@
.islandora-solution-pack-fieldset table th,
.islandora-solution-pack-fieldset table td
{
- width: 33%;
+ width: 30%;
+}
+
+.islandora-solution-pack-fieldset table th:first-child,
+.islandora-solution-pack-fieldset table td:first-child
+{
+ width: 10%;
}
\ No newline at end of file
diff --git a/includes/add_datastream.form.inc b/includes/add_datastream.form.inc
index 3a1d964d..33decefc 100644
--- a/includes/add_datastream.form.inc
+++ b/includes/add_datastream.form.inc
@@ -161,7 +161,10 @@ function islandora_add_datastream_form_validate(array $form, array &$form_state)
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);
+ $allowed_extensions = array();
+ foreach ($allowed_types as $mime) {
+ $allowed_extensions = array_merge($allowed_extensions, $mime_detect->getValidExtensions($mime));
+ }
$errors = file_validate_extensions($file, implode(' ', $allowed_extensions));
if (count($errors) > 0) {
form_set_error('file', $errors[0]);
diff --git a/includes/breadcrumb.inc b/includes/breadcrumb.inc
index 05ab1bac..6f975ae3 100644
--- a/includes/breadcrumb.inc
+++ b/includes/breadcrumb.inc
@@ -28,7 +28,7 @@ function islandora_get_breadcrumbs($object) {
$breadcrumbs = islandora_get_breadcrumbs_recursive($object->id, $object->repository);
array_pop($breadcrumbs);
$context = 'islandora';
- drupal_alter('islandora_breadcrumbs', $breadcrumbs, $context);
+ drupal_alter('islandora_breadcrumbs', $breadcrumbs, $context, $object);
return $breadcrumbs;
}
@@ -114,9 +114,7 @@ function islandora_get_breadcrumbs_recursive($pid, FedoraRepository $repository,
// render the last two links and break (on the next pass).
return array_merge(
islandora_get_breadcrumbs_recursive($root, $repository, $context),
- array(
- '...',
- )
+ array('...')
);
}
}
diff --git a/includes/datastream.inc b/includes/datastream.inc
index 1d506e3d..ba2872c2 100644
--- a/includes/datastream.inc
+++ b/includes/datastream.inc
@@ -53,8 +53,19 @@ function islandora_view_datastream(AbstractDatastream $datastream, $download = F
if ($download) {
// Browsers will not append all extensions.
$mime_detect = new MimeDetect();
- $extension = $mime_detect->getExtension($datastream->mimetype);
- $filename = $datastream->label . '.' . $extension;
+ $extension = '.' . $mime_detect->getExtension($datastream->mimetype);
+
+ // Prevent adding on a duplicate extension.
+ $label = $datastream->label;
+ $extension_length = strlen($extension);
+ $duplicate_extension_position = strlen($label) > $extension_length ?
+ strripos($label, $extension, -$extension_length) :
+ FALSE;
+ $filename = $label;
+ if ($duplicate_extension_position === FALSE) {
+ $filename .= $extension;
+ }
+
header("Content-Disposition: attachment; filename=\"$filename\"");
}
@@ -70,14 +81,30 @@ function islandora_view_datastream(AbstractDatastream $datastream, $download = F
islandora_view_datastream_set_cache_headers($datastream);
drupal_page_is_cacheable(FALSE);
- // Try not to load the file into PHP memory!
- // Close and flush ALL the output buffers!
- while (@ob_end_flush()) {
- };
// New content needed.
if ($cache_check === 200) {
- $datastream->getContent('php://output');
+ // We need to see if the chunking is being requested. This will mainly
+ // happen with iOS video requests as they do not support any other way
+ // to receive content for playback.
+ $chunk_headers = FALSE;
+ if (isset($_SERVER['HTTP_RANGE'])) {
+ // Set headers specific to chunking.
+ $chunk_headers = islandora_view_datastream_set_chunk_headers($datastream);
+ }
+ // Try not to load the file into PHP memory!
+ // Close and flush ALL the output buffers!
+ while (@ob_end_flush()) {
+ };
+
+ if (isset($_SERVER['HTTP_RANGE'])) {
+ if ($chunk_headers) {
+ islandora_view_datastream_deliver_chunks($datastream, $chunk_headers);
+ }
+ }
+ else {
+ $datastream->getContent('php://output');
+ }
}
exit();
}
@@ -312,7 +339,7 @@ function islandora_edit_datastream(AbstractDatastream $datastream) {
case 0:
// No edit implementations.
drupal_set_message(t('There are no edit methods specified for this datastream.'));
- drupal_goto("islandora/object/{$object->id}/manage/datastreams");
+ drupal_goto("islandora/object/{$datastream->parent->id}/manage/datastreams");
break;
case 1:
@@ -383,3 +410,125 @@ function islandora_datastream_get_view_link(AbstractDatastream $datastream) {
'datastream' => $datastream,
));
}
+
+/**
+ * Set the headers for the chunking of our content.
+ *
+ * @param AbstractDatastream $datastream
+ * An AbstractDatastream representing a datastream on a Fedora object.
+ *
+ * @return bool
+ * TRUE if there are chunks to be returned, FALSE otherwise.
+ */
+function islandora_view_datastream_set_chunk_headers(AbstractDatastream $datastream) {
+ $file_uri = islandora_view_datastream_retrieve_file_uri($datastream);
+ // The meat of this has been taken from:
+ // http://mobiforge.com/design-development/content-delivery-mobile-devices.
+ $size = filesize($file_uri);
+ $length = $size;
+ $start = 0;
+ $end = $size - 1;
+
+ header("Accept-Ranges: 0-$length");
+ if (isset($_SERVER['HTTP_RANGE'])) {
+ $c_start = $start;
+ $c_end = $end;
+ // Extract the range string.
+ list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
+ // Make sure the client hasn't sent us a multibyte range.
+ if (strpos($range, ',') !== FALSE) {
+ // Not a valid range, notify the client.
+ header('HTTP/1.1 416 Requested Range Not Satisfiable');
+ header("Content-Range: bytes $start-$end/$size");
+ exit;
+ }
+ // If the range starts with an '-' we start from the beginning. If not, we
+ // forward the file pointer and make sure to get the end byte if specified.
+ if (strpos($range, '-') === 0) {
+ // The n-number of the last bytes is requested.
+ $c_start = $size - substr($range, 1);
+ }
+ else {
+ $range = explode('-', $range);
+ $c_start = $range[0];
+ $c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
+ }
+ /* Check the range and make sure it's treated according to the specs.
+ * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
+ */
+ // End bytes can not be larger than $end.
+ $c_end = ($c_end > $end) ? $end : $c_end;
+ // Validate the requested range and return an error if it's not correct.
+ if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size) {
+ header('HTTP/1.1 416 Requested Range Not Satisfiable');
+ header("Content-Range: bytes $start-$end/$size");
+ exit;
+ }
+ $start = $c_start;
+ $end = $c_end;
+ // Calculate new content length.
+ $length = $end - $start + 1;
+ header('HTTP/1.1 206 Partial Content');
+ }
+ // Notify the client the byte range we'll be outputting.
+ header("Content-Range: bytes $start-$end/$size");
+ header("Content-Length: $length");
+ return array(
+ 'start' => $start,
+ 'end' => $end,
+ );
+}
+
+/**
+ * Deliver back the specified chunks of a file.
+ *
+ * @param AbstractDatastream $datastream
+ * An AbstractDatastream representing a datastream on a Fedora object.
+ * @param array $params
+ * An associate array containing the start and ending chunk bytes.
+ */
+function islandora_view_datastream_deliver_chunks(AbstractDatastream $datastream, $params) {
+ $file_uri = islandora_view_datastream_retrieve_file_uri($datastream);
+ // The meat of this has been taken from:
+ // http://mobiforge.com/design-development/content-delivery-mobile-devices.
+ $fp = @fopen($file_uri, 'rb');
+ fseek($fp, $params['start']);
+ // Start buffered download.
+ $buffer = 1024 * 8;
+ while (!feof($fp) && ($p = ftell($fp)) <= $params['end']) {
+ if ($p + $buffer > $params['end']) {
+ // In case we're only outputting a chunk, make sure we don't read past the
+ // length.
+ $buffer = $params['end'] - $p + 1;
+ }
+ // Reset time limit for big files.
+ set_time_limit(0);
+ echo fread($fp, $buffer);
+ }
+ fclose($fp);
+}
+
+/**
+ * Creates/returns the file URI for the content of a datastream for chunking.
+ *
+ * @param AbstractDatastream $datastream
+ * An AbstractDatastream representing a datastream on a Fedora object.
+ *
+ * @return string
+ * The URI of the file.
+ */
+function islandora_view_datastream_retrieve_file_uri(AbstractDatastream $datastream) {
+ $mime_detect = new MimeDetect();
+ $extension = $mime_detect->getExtension($datastream->mimetype);
+ $file_uri = 'temporary://chunk_' . $datastream->parent->id . '_' . $datastream->id . '_' . $datastream->createdDate->getTimestamp() . '.' . $extension;
+ if (!file_exists($file_uri)) {
+ $file = new stdClass();
+ $file->uri = $file_uri;
+ $file->filename = drupal_basename($file_uri);
+ $file->filemime = $datastream->mimeType;
+ $file->status = 0;
+ $datastream->getContent($file_uri);
+ file_save($file);
+ }
+ return $file_uri;
+}
diff --git a/includes/datastream.version.inc b/includes/datastream.version.inc
index 507a182f..8c02aaad 100644
--- a/includes/datastream.version.inc
+++ b/includes/datastream.version.inc
@@ -1,4 +1,5 @@
parent;
drupal_set_title(t("@dsid Previous Versions", array('@dsid' => $datastream->id)));
+ $audit_values = islandora_get_audit_trail($parent->id, $datastream->id);
$header = array();
$header[] = array('data' => t('Created Date'));
$header[] = array('data' => t('Size'));
$header[] = array('data' => t('Label'));
+ $header[] = array('data' => t('Responsibility'));
$header[] = array('data' => t('Mime type'));
$header[] = array('data' => t('Operations'), 'colspan' => '2');
$rows = array();
foreach ($datastream as $version => $datastream_version) {
$row = array();
+ $reponsibility = $parent->owner;
+ foreach ($audit_values as $audit_value) {
+ $internal = $datastream_version->createdDate;
+ if ($audit_value['date'] == $datastream_version->createdDate) {
+ $reponsibility = $audit_value['responsibility'];
+ }
+ }
+ $user = user_load_by_name($reponsibility);
+ if ($user) {
+ $user_id = $user->uid;
+ $user_val = l($reponsibility, "user/$user_id");
+ }
+ else {
+ $user_val = $reponsibility;
+ }
$row[] = array(
'class' => 'datastream-date',
'data' => theme('islandora_datastream_view_link', array(
@@ -39,6 +57,10 @@ function islandora_datastream_version_table($datastream) {
'class' => 'datastream-label',
'data' => $datastream_version->label,
);
+ $row[] = array(
+ 'class' => 'datastream-responsibility',
+ 'data' => $user_val,
+ );
$row[] = array(
'class' => 'datastream-mime',
'data' => $datastream_version->mimeType,
@@ -208,3 +230,39 @@ 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";
}
+
+/**
+ * Gets Audit datastream values from foxml.
+ *
+ * @param String $pid
+ * PID of parent object
+ *
+ * @return array
+ * Array of audit values
+ */
+function islandora_get_audit_trail($pid, $dsid) {
+ $url = variable_get('islandora_base_url', 'http://localhost:8080/fedora');
+ $connection = islandora_get_tuque_connection(NULL, $url);
+ $xml = $connection->api->m->getObjectXml($pid);
+ $simple_xml = simplexml_load_string($xml);
+ $fox_ns = "info:fedora/fedora-system:def/foxml#";
+ $audit_ns = 'info:fedora/fedora-system:def/audit#';
+ $foxml_nodes = $simple_xml->children($fox_ns);
+ foreach ($foxml_nodes as $node) {
+ if ($node->attributes()->ID == "AUDIT") {
+ $content = $node->datastreamVersion->xmlContent;
+ $audit_nodes = $content->children($audit_ns);
+ }
+ }
+ $audit_values = array();
+ if (isset($audit_nodes)) {
+ foreach ($audit_nodes->auditTrail->record as $record) {
+ if ($dsid == $record->componentID) {
+ $values['responsibility'] = $record->responsibility;
+ $values['date'] = $record->date;
+ $audit_values[] = $values;
+ }
+ }
+ }
+ return $audit_values;
+}
diff --git a/includes/derivatives.inc b/includes/derivatives.inc
index 5ba4bb56..d25789cc 100644
--- a/includes/derivatives.inc
+++ b/includes/derivatives.inc
@@ -41,20 +41,7 @@ function islandora_do_derivatives(AbstractObject $object, array $options) {
$hooks = islandora_invoke_hook_list(ISLANDORA_DERVIATIVE_CREATION_HOOK, $object->models, array($object));
uasort($hooks, 'drupal_sort_weight');
$results = 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'];
- });
- }
+ $hooks = islandora_filter_derivatives($hooks, $options, $object);
foreach ($hooks as $hook) {
if (isset($hook['file'])) {
@@ -121,3 +108,94 @@ 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();
+
+ $hooks = islandora_filter_derivatives($hooks, $options, $object);
+ 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;
+}
+
+/**
+ * Filter the derivative functions to only call those which are valid.
+ *
+ * @param array $hooks
+ * An array of hooks to be filtered depending on options.
+ * @param array $options
+ * An array of options for the derivative generation.
+ * @param AbstractObject $object
+ * An AbstractObject representing an object within Fedora.
+ *
+ * @return array
+ * Returns the filtered array of hooks to be ran.
+ */
+function islandora_filter_derivatives($hooks, $options, AbstractObject $object) {
+ 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'];
+ });
+ }
+ // Do a final filtering to make sure that the source DSID exists on the object
+ // where needed. Using a defined function as opposed to the way above as
+ // it seems to break PHPCS as of 1.4.8.
+ $filter_function = function ($filter_hook) use ($object) {
+ $to_return = FALSE;
+ if (array_key_exists('source_dsid', $filter_hook)) {
+ if ($filter_hook['source_dsid'] != NULL) {
+ if (isset($object[$filter_hook['source_dsid']])) {
+ $to_return = TRUE;
+ }
+ }
+ else {
+ $to_return = TRUE;
+ }
+ }
+ return $to_return;
+ };
+ $hooks = array_filter($hooks, $filter_function);
+ return $hooks;
+}
diff --git a/includes/ingest.form.inc b/includes/ingest.form.inc
index b49556d7..89376f7d 100644
--- a/includes/ingest.form.inc
+++ b/includes/ingest.form.inc
@@ -769,10 +769,16 @@ function islandora_ingest_form_submit(array $form, array &$form_state) {
islandora_ingest_form_execute_consecutive_callback_steps($form, $form_state, $step);
}
// Ingest the objects.
+ $set_redirect = TRUE;
foreach ($form_state['islandora']['objects'] as &$object) {
try {
islandora_add_object($object);
- $form_state['redirect'] = "islandora/object/{$object->id}";
+ // We want to redirect to the first object as it's considered to be the
+ // primary object.
+ if ($set_redirect) {
+ $form_state['redirect'] = "islandora/object/{$object->id}";
+ $set_redirect = FALSE;
+ }
drupal_set_message(
t('"@label" (ID: @pid) has been ingested.', array('@label' => $object->label, '@pid' => $object->id)),
'status');
diff --git a/includes/mime_detect.inc b/includes/mime_detect.inc
index 4035afe5..e76975d6 100644
--- a/includes/mime_detect.inc
+++ b/includes/mime_detect.inc
@@ -383,4 +383,19 @@ class MimeDetect {
return $this->protectedMimeTypes;
}
+ /**
+ * Get all valid extensions for this MIME type.
+ *
+ * @param string $mimetype
+ * The MIME type we are searching for.
+ *
+ * @return array
+ * An array of valid extensions for this MIME type.
+ */
+ public function getValidExtensions($mimetype) {
+ $filter = function ($mime) use ($mimetype) {
+ return $mime == $mimetype;
+ };
+ return array_keys(array_filter($this->protectedMimeTypes, $filter));
+ }
}
diff --git a/includes/mime_type.autocomplete.inc b/includes/mime_type.autocomplete.inc
new file mode 100644
index 00000000..3ac31079
--- /dev/null
+++ b/includes/mime_type.autocomplete.inc
@@ -0,0 +1,27 @@
+getMimeTypes();
+ $output = array();
+ foreach ($mime_types as $mime_type) {
+ if (preg_match("/{$string}/i", $mime_type) !== 0) {
+ $output[$mime_type] = $mime_type;
+ }
+ }
+ return drupal_json_output($output);
+}
diff --git a/includes/object_properties.form.inc b/includes/object_properties.form.inc
index 5295f067..f9c8e23b 100644
--- a/includes/object_properties.form.inc
+++ b/includes/object_properties.form.inc
@@ -26,6 +26,15 @@ 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)) {
+ module_load_include('inc', 'islandora', 'includes/derivatives');
+ $hooks = islandora_invoke_hook_list(ISLANDORA_DERVIATIVE_CREATION_HOOK, $object->models, array($object));
+ $hooks = islandora_filter_derivatives($hooks, array('force' => TRUE), $object);
+ if (count($hooks) > 1) {
+ $regenerate_derivatives_access = TRUE;
+ }
+ }
return array(
'pid' => array(
'#type' => 'hidden',
@@ -84,6 +93,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'),
+ ),
);
}
@@ -166,15 +181,15 @@ function islandora_object_properties_form_delete(array $form, array &$form_state
/**
* Updates object state.
*
- * @param String $pid
+ * @param string $pid
* PID of object to be updated
- * @param Boolean $update_states
+ * @param bool $update_states
* If TRUE, update object state
- * @param String $state
+ * @param string $state
* Desired object state
- * @param Boolean $update_owners
+ * @param bool $update_owners
* If TRUE, update Owner
- * @param String $owner
+ * @param string $owner
* New Owner
*/
function islandora_update_object_properties($pid, $update_states, $state, $update_owners, $owner) {
@@ -188,3 +203,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/includes/solution_packs.inc b/includes/solution_packs.inc
index 65f62851..30cc8576 100644
--- a/includes/solution_packs.inc
+++ b/includes/solution_packs.inc
@@ -140,7 +140,14 @@ function islandora_solution_pack_form(array $form, array &$form_state, $solution
);
$status_severities = array_keys($status_info);
$solution_pack_status_severity = array_search('up_to_date', $status_severities);
- $table_rows = array();
+
+ // Prepair for tableselect.
+ $header = array(
+ 'label' => t('Label'),
+ 'pid' => t('PID'),
+ 'status' => t('Status'));
+
+ $object_info = array();
foreach ($objects as $object) {
$object_status = islandora_check_object_status($object);
$object_status_info = $status_info[$object_status['status']];
@@ -151,11 +158,15 @@ function islandora_solution_pack_form(array $form, array &$form_state, $solution
$exists = $object_status['status'] != 'missing';
$label = $exists ? l($object->label, "islandora/object/{$object->id}") : $object->label;
$status_msg = "{$object_status_info['image']} {$object_status['status_friendly']}";
- $table_rows[] = array($label, $object->id, $status_msg);
+ $object_info[] = array(
+ 'label' => $label,
+ 'pid' => $object->id,
+ 'status' => $status_msg);
}
$solution_pack_status = $status_severities[$solution_pack_status_severity];
$solution_pack_status_info = $status_info[$solution_pack_status];
- return array(
+
+ $form = array(
'solution_pack' => array(
'#type' => 'fieldset',
'#collapsible' => FALSE,
@@ -180,17 +191,20 @@ function islandora_solution_pack_form(array $form, array &$form_state, $solution
),
'install_status' => array(
'#markup' => t('Object status: !image !status', array(
- '!image' => $solution_pack_status_info['image'],
- '!status' => $solution_pack_status_info['solution_pack'],
- )),
+ '!image' => $solution_pack_status_info['image'],
+ '!status' => $solution_pack_status_info['solution_pack'],
+ )),
'#prefix' => '