From b42d3d339d34818398061b0d4935d08a0cf63614 Mon Sep 17 00:00:00 2001 From: qadan Date: Thu, 28 Nov 2013 13:08:41 -0400 Subject: [PATCH 01/50] PHP Codesniffer got broke ... ... so we're installing an older version for now --- tests/scripts/travis_setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/scripts/travis_setup.sh b/tests/scripts/travis_setup.sh index 2fa3fd0e..3a52bb75 100755 --- a/tests/scripts/travis_setup.sh +++ b/tests/scripts/travis_setup.sh @@ -19,7 +19,7 @@ pear channel-discover pear.drush.org pear channel-discover pear.drush.org pear channel-discover pear.phpqatools.org pear channel-discover pear.netpirates.net -pear install pear/PHP_CodeSniffer +pear install pear/PHP_CodeSniffer-1.4.8 pear install pear.phpunit.de/phpcpd pear install drush/drush-5.9.0 phpenv rehash From 1be38b1aee57d277af50666e7312a9c7cceaf39a Mon Sep 17 00:00:00 2001 From: Alan Stanley Date: Thu, 28 Nov 2013 15:58:22 -0400 Subject: [PATCH 02/50] added responsibility filed to versions --- includes/datastream.version.inc | 92 +++++++++++++++++++++++++-------- 1 file changed, 70 insertions(+), 22 deletions(-) diff --git a/includes/datastream.version.inc b/includes/datastream.version.inc index 507a182f..15720bdf 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, @@ -85,12 +107,7 @@ function islandora_delete_datastream_version_form(array $form, array &$form_stat $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') + 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') ); } @@ -120,15 +137,15 @@ function islandora_delete_datastream_version_form_submit(array $form, array &$fo } 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'); + '%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))); + '%d' => $datastream_id, + '%o' => $object->label))); $form_state['redirect'] = "islandora/object/{$object->id}/datastream/{$datastream->id}/version"; } @@ -157,12 +174,7 @@ function islandora_revert_datastream_version_form(array $form, array &$form_stat $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') + 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') ); } @@ -202,9 +214,45 @@ function islandora_revert_datastream_version_form_submit(array $form, array &$fo } 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))); + '%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"; } + +/** + * 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; +} From 28dda16086105d962e6361e4f1f13a9a81c56ea1 Mon Sep 17 00:00:00 2001 From: Alan Stanley Date: Thu, 28 Nov 2013 16:02:10 -0400 Subject: [PATCH 03/50] added responsibility filed to versions --- includes/datastream.version.inc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/includes/datastream.version.inc b/includes/datastream.version.inc index 15720bdf..6f501cc6 100644 --- a/includes/datastream.version.inc +++ b/includes/datastream.version.inc @@ -107,7 +107,12 @@ function islandora_delete_datastream_version_form(array $form, array &$form_stat $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') + 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') ); } From 82ffcea0c2a847eae2b83420d902cf4210ff06f3 Mon Sep 17 00:00:00 2001 From: Alan Stanley Date: Thu, 28 Nov 2013 16:08:41 -0400 Subject: [PATCH 04/50] reverted formatting --- includes/datastream.version.inc | 35 +++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/includes/datastream.version.inc b/includes/datastream.version.inc index 6f501cc6..3e926f37 100644 --- a/includes/datastream.version.inc +++ b/includes/datastream.version.inc @@ -108,11 +108,11 @@ function islandora_delete_datastream_version_form(array $form, array &$form_stat $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') + 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') ); } @@ -142,15 +142,15 @@ function islandora_delete_datastream_version_form_submit(array $form, array &$fo } 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'); + '%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))); + '%d' => $datastream_id, + '%o' => $object->label))); $form_state['redirect'] = "islandora/object/{$object->id}/datastream/{$datastream->id}/version"; } @@ -179,7 +179,12 @@ function islandora_revert_datastream_version_form(array $form, array &$form_stat $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') + 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') ); } @@ -219,9 +224,9 @@ function islandora_revert_datastream_version_form_submit(array $form, array &$fo } 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))); + '%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"; } From 8242bd272a31145954f26f86a296d91642a7e033 Mon Sep 17 00:00:00 2001 From: Alan Stanley Date: Thu, 28 Nov 2013 16:10:42 -0400 Subject: [PATCH 05/50] reverted formatting --- includes/datastream.version.inc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/includes/datastream.version.inc b/includes/datastream.version.inc index 3e926f37..8c02aaad 100644 --- a/includes/datastream.version.inc +++ b/includes/datastream.version.inc @@ -110,9 +110,9 @@ function islandora_delete_datastream_version_form(array $form, array &$form_stat 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') + t('This action cannot be undone.'), + t('Delete'), + t('Cancel') ); } @@ -182,9 +182,9 @@ function islandora_revert_datastream_version_form(array $form, array &$form_stat 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') + "", + t('Revert'), + t('Cancel') ); } From d4783db6a314894b86d4ca9f3585e1a44d994ecb Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Thu, 28 Nov 2013 20:41:45 +0000 Subject: [PATCH 06/50] Fix MimeDetect to allow checking MIMEs for multiple mapped values. --- includes/add_datastream.form.inc | 5 ++++- includes/mime_detect.inc | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) 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/mime_detect.inc b/includes/mime_detect.inc index 4035afe5..c275f150 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)); + } } From 25c6c4fe2a459ec7b358c553f3ca51b82d7a991e Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Fri, 29 Nov 2013 13:36:22 +0000 Subject: [PATCH 07/50] Coding standards. --- includes/mime_detect.inc | 2 +- includes/object_properties.form.inc | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/includes/mime_detect.inc b/includes/mime_detect.inc index c275f150..e76975d6 100644 --- a/includes/mime_detect.inc +++ b/includes/mime_detect.inc @@ -393,7 +393,7 @@ class MimeDetect { * An array of valid extensions for this MIME type. */ public function getValidExtensions($mimetype) { - $filter = function($mime) use ($mimetype) { + $filter = function ($mime) use ($mimetype) { return $mime == $mimetype; }; return array_keys(array_filter($this->protectedMimeTypes, $filter)); diff --git a/includes/object_properties.form.inc b/includes/object_properties.form.inc index 5295f067..676f0d0c 100644 --- a/includes/object_properties.form.inc +++ b/includes/object_properties.form.inc @@ -166,15 +166,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) { From 0fa2d5d4543376065fb24a563438ec843cb80d00 Mon Sep 17 00:00:00 2001 From: Nigel Banks Date: Mon, 9 Dec 2013 02:35:09 +0100 Subject: [PATCH 08/50] Prevent fatal error when using a batch within a multistep form. --- includes/tuque_wrapper.inc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/includes/tuque_wrapper.inc b/includes/tuque_wrapper.inc index 2aa85a8b..98e9c62c 100644 --- a/includes/tuque_wrapper.inc +++ b/includes/tuque_wrapper.inc @@ -8,7 +8,11 @@ * @todo Overload functions and apply pre/post hooks. */ -$islandora_module_path = drupal_get_path('module', 'islandora'); +// This function may not exist when a batch operation is running from a +// multistep form. +if (function_exists('drupal_get_path')) { + $islandora_module_path = drupal_get_path('module', 'islandora'); +} // @todo this until we expost these in a module or library @include_once 'sites/all/libraries/tuque/Datastream.php'; From b42aeaffdcc6bed2c7a56a8aff44adca48473c5a Mon Sep 17 00:00:00 2001 From: Nigel Banks Date: Tue, 10 Dec 2013 05:46:23 +0100 Subject: [PATCH 09/50] Redirect the user to the primary object when the ingest form submits, rather than the last object created. --- includes/ingest.form.inc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) 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'); From b66f15393b7c782558db65c49c04c6c0557819a6 Mon Sep 17 00:00:00 2001 From: Yuqing Jiang Date: Fri, 13 Dec 2013 15:12:21 +0000 Subject: [PATCH 10/50] Add checkbox in every object. install by object. --- includes/solution_packs.inc | 93 ++++++++++++++++++++++++++++++++----- islandora.module | 5 ++ 2 files changed, 86 insertions(+), 12 deletions(-) diff --git a/includes/solution_packs.inc b/includes/solution_packs.inc index 6a005a18..1646f0da 100644 --- a/includes/solution_packs.inc +++ b/includes/solution_packs.inc @@ -140,7 +140,7 @@ 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(); + $object_info = array(); foreach ($objects as $object) { $object_status = islandora_check_object_status($object); $object_status_info = $status_info[$object_status['status']]; @@ -151,11 +151,14 @@ 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 +183,16 @@ 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' => '
', '#suffix' => '
', ), 'table' => array( '#type' => 'item', - '#markup' => theme('table', array( - 'header' => array(t('Label'), t('PID'), t('Status')), - 'rows' => $table_rows)), + '#tree' => TRUE, + '#theme' => 'islandora_solution_pack_table', ), 'submit' => array( '#type' => 'submit', @@ -200,6 +202,25 @@ function islandora_solution_pack_form(array $form, array &$form_state, $solution ), ), ); + foreach ($object_info as $object) { + $pid = $object['pid']; + $form['solution_pack']['table']['label'][$pid] = array( + '#type' => 'item', + '#markup' => $object['label'], + ); + $form['solution_pack']['table']['pid'][$pid] = array( + '#type' => 'item', + '#markup' => $pid, + ); + $form['solution_pack']['table']['status'][$pid] = array( + '#type' => 'item', + '#markup' => $object['status'], + ); + $form['solution_pack']['table']['check'][$pid] = array( + '#type' => 'checkbox', + ); + } + return $form; } /** @@ -211,9 +232,20 @@ function islandora_solution_pack_form(array $form, array &$form_state, $solution * The state of the form submited. */ function islandora_solution_pack_form_submit(array $form, array &$form_state) { + $not_checked = array(); + if (isset($form_state['values']['table']['check'])) { + foreach ($form_state['values']['table']['check'] as $key => $value) { + if ($value === 0) { + $not_checked[] = $key; + } + } + } $solution_pack_module = $form_state['values']['solution_pack_module']; - $batch = islandora_solution_pack_get_batch($solution_pack_module); + // Use not_checked instead of checked. Remove not checked item from betch. so + // that get batch function can get all object ingest batch if not checked list + // is empty. + $batch = islandora_solution_pack_get_batch($solution_pack_module, $not_checked); batch_set($batch); // Hook to let solution pack objects be modified. // Not using module_invoke so solution packs can be expanded by other modules. @@ -227,11 +259,13 @@ function islandora_solution_pack_form_submit(array $form, array &$form_state) { * @param string $module * The name of the modules of which to grab the required objects for to setup * the batch. - * + * @param array $not_checked + * The object that will bot be install. + * * @return array * An array defining a batch which can be passed on to batch_set(). */ -function islandora_solution_pack_get_batch($module) { +function islandora_solution_pack_get_batch($module, $not_checked = array()) { $batch = array( 'title' => t('Installing / Updating solution pack objects'), 'file' => drupal_get_path('module', 'islandora') . '/includes/solution_packs.inc', @@ -239,6 +273,14 @@ function islandora_solution_pack_get_batch($module) { ); $info = islandora_solution_packs_get_required_objects($module); + foreach ($info['objects'] as $key => $object) { + foreach ($not_checked as $not) { + if ($object->id == $not) { + unset($info['objects'][$key]); + } + } + } + foreach ($info['objects'] as $object) { $batch['operations'][] = array('islandora_solution_pack_batch_operation_reingest_object', array($object)); } @@ -638,6 +680,7 @@ function islandora_viewers_form($variable_id = NULL, $mimetype = NULL, $model = '#value' => $name, ); $form['viewers'][$variable_id]['label'][$name] = array( + '#type' => 'item', '#type' => 'item', '#markup' => $profile['label'], ); @@ -798,6 +841,32 @@ function islandora_get_viewer_callback($viewer_id = NULL) { return FALSE; } +/** + * Implements theme_hook(). + */ +function theme_islandora_solution_pack_table($variables) { + $form = $variables['form']; + $rows = array(); + foreach ($form['label'] as $key => $element) { + if (is_array($element) && element_child($key)) { + $row = array(); + $row[] = array('data' => drupal_render($form['label'][$key])); + $row[] = array('data' => drupal_render($form['pid'][$key])); + $row[] = array('data' => drupal_render($form['status'][$key])); + $row[] = array('data' => drupal_render($form['check'][$key])); + $rows[] = array('data' => $row); + } + } + $header = array(t('Label'), t('PID'), t('Status'), ''); + + $output = ''; + $output .= theme('table', array( + 'header' => $header, + 'rows' => $rows, + 'attributes' => array('id' => 'islandora-viewers-table'), + )); + return $output; +} /** * @} End of "defgroup viewer-functions". */ diff --git a/islandora.module b/islandora.module index 25244bbc..17f13724 100644 --- a/islandora.module +++ b/islandora.module @@ -485,6 +485,11 @@ function islandora_theme() { 'pattern' => 'islandora_dublin_core_description__', 'variables' => array('islandora_object' => NULL), ), + // Table for install/reinstall content model and collections. + 'islandora_solution_pack_table' => array( + 'file' => 'includes/solution_packs.inc', + 'render element' => 'form', + ), ); } From e816ffc1ba87990c45724d0e79981df929114a25 Mon Sep 17 00:00:00 2001 From: Yuqing Jiang Date: Fri, 13 Dec 2013 15:15:41 +0000 Subject: [PATCH 11/50] Fix a issue --- includes/solution_packs.inc | 1 - 1 file changed, 1 deletion(-) diff --git a/includes/solution_packs.inc b/includes/solution_packs.inc index 1646f0da..c0305f88 100644 --- a/includes/solution_packs.inc +++ b/includes/solution_packs.inc @@ -680,7 +680,6 @@ function islandora_viewers_form($variable_id = NULL, $mimetype = NULL, $model = '#value' => $name, ); $form['viewers'][$variable_id]['label'][$name] = array( - '#type' => 'item', '#type' => 'item', '#markup' => $profile['label'], ); From d85de15813a270ffa9901afc02ccb070b7bf186a Mon Sep 17 00:00:00 2001 From: Yuqing Jiang Date: Wed, 18 Dec 2013 13:28:45 +0000 Subject: [PATCH 12/50] move the check box to left. --- css/islandora.admin.css | 2 +- includes/solution_packs.inc | 26 ++++++++++++++------------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/css/islandora.admin.css b/css/islandora.admin.css index 1cd1976d..3b62e099 100644 --- a/css/islandora.admin.css +++ b/css/islandora.admin.css @@ -13,5 +13,5 @@ .islandora-solution-pack-fieldset table th, .islandora-solution-pack-fieldset table td { - width: 33%; + width: 25%; } \ No newline at end of file diff --git a/includes/solution_packs.inc b/includes/solution_packs.inc index c0305f88..d68c3e27 100644 --- a/includes/solution_packs.inc +++ b/includes/solution_packs.inc @@ -204,6 +204,9 @@ function islandora_solution_pack_form(array $form, array &$form_state, $solution ); foreach ($object_info as $object) { $pid = $object['pid']; + $form['solution_pack']['table']['check'][$pid] = array( + '#type' => 'checkbox', + ); $form['solution_pack']['table']['label'][$pid] = array( '#type' => 'item', '#markup' => $object['label'], @@ -216,9 +219,6 @@ function islandora_solution_pack_form(array $form, array &$form_state, $solution '#type' => 'item', '#markup' => $object['status'], ); - $form['solution_pack']['table']['check'][$pid] = array( - '#type' => 'checkbox', - ); } return $form; } @@ -846,17 +846,19 @@ function islandora_get_viewer_callback($viewer_id = NULL) { function theme_islandora_solution_pack_table($variables) { $form = $variables['form']; $rows = array(); - foreach ($form['label'] as $key => $element) { - if (is_array($element) && element_child($key)) { - $row = array(); - $row[] = array('data' => drupal_render($form['label'][$key])); - $row[] = array('data' => drupal_render($form['pid'][$key])); - $row[] = array('data' => drupal_render($form['status'][$key])); - $row[] = array('data' => drupal_render($form['check'][$key])); - $rows[] = array('data' => $row); + if (isset($form['label'])) { + foreach ($form['label'] as $key => $element) { + if (is_array($element) && element_child($key)) { + $row = array(); + $row[] = array('data' => drupal_render($form['check'][$key])); + $row[] = array('data' => drupal_render($form['label'][$key])); + $row[] = array('data' => drupal_render($form['pid'][$key])); + $row[] = array('data' => drupal_render($form['status'][$key])); + $rows[] = array('data' => $row); + } } } - $header = array(t('Label'), t('PID'), t('Status'), ''); + $header = array('', t('Label'), t('PID'), t('Status')); $output = ''; $output .= theme('table', array( From bc99dc2d88fbb0e655fa5dade4c6a884c1a3f76a Mon Sep 17 00:00:00 2001 From: Yuqing Jiang Date: Thu, 19 Dec 2013 15:09:33 +0000 Subject: [PATCH 13/50] Change to tableselect --- includes/solution_packs.inc | 43 ++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/includes/solution_packs.inc b/includes/solution_packs.inc index d68c3e27..ce850081 100644 --- a/includes/solution_packs.inc +++ b/includes/solution_packs.inc @@ -140,6 +140,13 @@ 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); + + // 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); @@ -158,6 +165,7 @@ function islandora_solution_pack_form(array $form, array &$form_state, $solution } $solution_pack_status = $status_severities[$solution_pack_status_severity]; $solution_pack_status_info = $status_info[$solution_pack_status]; + $form = array( 'solution_pack' => array( '#type' => 'fieldset', @@ -190,9 +198,13 @@ function islandora_solution_pack_form(array $form, array &$form_state, $solution '#suffix' => '', ), 'table' => array( - '#type' => 'item', - '#tree' => TRUE, - '#theme' => 'islandora_solution_pack_table', + '#type' => 'tableselect', + '#header' => $header, + '#options' => $object_info, + ), + 'tablevalue' => array( + '#type' => 'hidden', + '#value' => json_encode($object_info), ), 'submit' => array( '#type' => 'submit', @@ -202,24 +214,6 @@ function islandora_solution_pack_form(array $form, array &$form_state, $solution ), ), ); - foreach ($object_info as $object) { - $pid = $object['pid']; - $form['solution_pack']['table']['check'][$pid] = array( - '#type' => 'checkbox', - ); - $form['solution_pack']['table']['label'][$pid] = array( - '#type' => 'item', - '#markup' => $object['label'], - ); - $form['solution_pack']['table']['pid'][$pid] = array( - '#type' => 'item', - '#markup' => $pid, - ); - $form['solution_pack']['table']['status'][$pid] = array( - '#type' => 'item', - '#markup' => $object['status'], - ); - } return $form; } @@ -233,10 +227,11 @@ function islandora_solution_pack_form(array $form, array &$form_state, $solution */ function islandora_solution_pack_form_submit(array $form, array &$form_state) { $not_checked = array(); - if (isset($form_state['values']['table']['check'])) { - foreach ($form_state['values']['table']['check'] as $key => $value) { + $object_info = json_decode($form_state['values']['tablevalue']); + if (isset($form_state['values']['table'])) { + foreach ($form_state['values']['table'] as $key => $value) { if ($value === 0) { - $not_checked[] = $key; + $not_checked[] = $object_info[$key]->pid; } } } From 26ceda4b1073286dd6324e7b58fdfbfe15b4245a Mon Sep 17 00:00:00 2001 From: Yuqing Jiang Date: Thu, 19 Dec 2013 15:13:39 +0000 Subject: [PATCH 14/50] remove table theme. --- includes/solution_packs.inc | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/includes/solution_packs.inc b/includes/solution_packs.inc index ce850081..e07e76e7 100644 --- a/includes/solution_packs.inc +++ b/includes/solution_packs.inc @@ -834,35 +834,6 @@ function islandora_get_viewer_callback($viewer_id = NULL) { } return FALSE; } - -/** - * Implements theme_hook(). - */ -function theme_islandora_solution_pack_table($variables) { - $form = $variables['form']; - $rows = array(); - if (isset($form['label'])) { - foreach ($form['label'] as $key => $element) { - if (is_array($element) && element_child($key)) { - $row = array(); - $row[] = array('data' => drupal_render($form['check'][$key])); - $row[] = array('data' => drupal_render($form['label'][$key])); - $row[] = array('data' => drupal_render($form['pid'][$key])); - $row[] = array('data' => drupal_render($form['status'][$key])); - $rows[] = array('data' => $row); - } - } - } - $header = array('', t('Label'), t('PID'), t('Status')); - - $output = ''; - $output .= theme('table', array( - 'header' => $header, - 'rows' => $rows, - 'attributes' => array('id' => 'islandora-viewers-table'), - )); - return $output; -} /** * @} End of "defgroup viewer-functions". */ From 302acf4eacfb432c6c0368251b4ee99dcd6801f0 Mon Sep 17 00:00:00 2001 From: Yuqing Jiang Date: Thu, 19 Dec 2013 15:24:09 +0000 Subject: [PATCH 15/50] edit css. --- css/islandora.admin.css | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/css/islandora.admin.css b/css/islandora.admin.css index 3b62e099..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: 25%; + 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 From 28b3deedccf63a3b66de38699d4ce807122a95ad Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Fri, 20 Dec 2013 22:24:50 +0000 Subject: [PATCH 16/50] Add derivative regeneration to the UI. --- includes/datastream.inc | 2 +- includes/object_properties.form.inc | 24 ++++ includes/regenerate_derivatives.form.inc | 163 +++++++++++++++++++++++ islandora.module | 30 ++++- theme/theme.inc | 31 ++++- 5 files changed, 247 insertions(+), 3 deletions(-) create mode 100644 includes/regenerate_derivatives.form.inc diff --git a/includes/datastream.inc b/includes/datastream.inc index 1d506e3d..c9976cad 100644 --- a/includes/datastream.inc +++ b/includes/datastream.inc @@ -312,7 +312,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: 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..917154ea --- /dev/null +++ b/includes/regenerate_derivatives.form.inc @@ -0,0 +1,163 @@ + $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}/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) { + module_load_include('inc', 'islandora', 'includes/derivatives'); + $object = $form_state['object']; + $batch = islandora_regenerate_object_derivatives_batch($object); + batch_set($batch); + $form_state['redirect'] = "islandora/object/{$object}/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) { + return array( + 'title' => t('Regenerating all derivatives for @label', array('@label' => $object->label)), + 'operations' => array( + array('islandora_regenerate_object_derivatives_batch_operation', array($object)), + ), + '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', + ); +} + +/** + * Defines the regenerate object derivatives batch operation. + * + * @param AbstractObject $object + * A AbstractObject representing an object within Fedora. + * @param array $context + * An array containing the context of the current batch. + */ +function islandora_regenerate_object_derivatives_batch_operation(AbstractObject $object, &$context) { + module_load_include('inc', 'islandora', 'includes/derivatives'); + $logging_results = islandora_do_derivatives($object, array( + 'force' => TRUE, + )); + islandora_derivative_logging($logging_results); +} + +/** + * 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) { + return array( + 'title' => t('Regenerating derivatives for the @dsid datastream', array('@dsid' => $datastream->id)), + 'operations' => array( + array('islandora_regenerate_datastream_derivative_batch_operation', array($datastream)), + ), + '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', + ); +} + +/** + * Defines the regenerate datastream derivative batch operation. + * + * @param AbstractDatastream $datastream + * A AbstractDatastream representing a datastream on an object within Fedora. + * @param array $context + * An array containing the context of the current batch. + */ +function islandora_regenerate_datastream_derivative_batch_operation(AbstractDatastream $datastream, &$context) { + module_load_include('inc', 'islandora', 'includes/derivatives'); + $logging_results = islandora_do_derivatives($datastream->parent, array( + 'force' => TRUE, + 'destination_dsid' => $datastream->id, + )); + islandora_derivative_logging($logging_results); +} 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..e057771c 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(); @@ -79,6 +79,14 @@ function islandora_preprocess_islandora_default_edit(array &$variables) { 'datastream' => $ds, )), ); + if (user_access(ISLANDORA_REGENERATE_DERIVATIVES)) { + $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(). */ From 19bb4b34685fcff71842f27357e3fa9c69bf61d9 Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Tue, 7 Jan 2014 19:31:38 +0000 Subject: [PATCH 17/50] Add byte range chunking support to Islandora. --- includes/datastream.inc | 150 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 144 insertions(+), 6 deletions(-) diff --git a/includes/datastream.inc b/includes/datastream.inc index 1d506e3d..72a86c5f 100644 --- a/includes/datastream.inc +++ b/includes/datastream.inc @@ -70,14 +70,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 +328,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 +399,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; +} From 545cc9d70898fb47254765ab8e4dbc6afa1c84fc Mon Sep 17 00:00:00 2001 From: Alan Stanley Date: Fri, 10 Jan 2014 14:15:41 -0400 Subject: [PATCH 18/50] added object for context in hook --- includes/breadcrumb.inc | 6 ++---- islandora.api.php | 4 +++- 2 files changed, 5 insertions(+), 5 deletions(-) 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/islandora.api.php b/islandora.api.php index 04d8bd49..1aec1198 100644 --- a/islandora.api.php +++ b/islandora.api.php @@ -691,8 +691,10 @@ function hook_islandora_update_related_objects_properties(AbstractObject $object * Breadcrumbs array to be altered by reference. Each element is markup. * @param string $context * Where the alter is originating from for distinguishing. + * @param AbstractObject $object + * AbstractObject representing object providing breadcrumb path */ -function hook_islandora_breadcrumbs_alter(&$breadcrumbs, $context) { +function hook_islandora_breadcrumbs_alter(&$breadcrumbs, $context, $object) { } From 035ee14fdadf053d4cbffef62c654ac2081322a1 Mon Sep 17 00:00:00 2001 From: Alan Stanley Date: Fri, 10 Jan 2014 14:18:21 -0400 Subject: [PATCH 19/50] added object for context in hook --- islandora.api.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/islandora.api.php b/islandora.api.php index 1aec1198..fb27a543 100644 --- a/islandora.api.php +++ b/islandora.api.php @@ -692,7 +692,7 @@ function hook_islandora_update_related_objects_properties(AbstractObject $object * @param string $context * Where the alter is originating from for distinguishing. * @param AbstractObject $object - * AbstractObject representing object providing breadcrumb path + * (Optional) AbstractObject representing object providing breadcrumb path */ function hook_islandora_breadcrumbs_alter(&$breadcrumbs, $context, $object) { From 9d4aa56e75a15e246bf5f5dfcda03c89eff4fa3d Mon Sep 17 00:00:00 2001 From: Alan Stanley Date: Fri, 10 Jan 2014 14:20:24 -0400 Subject: [PATCH 20/50] added object for context in hook --- islandora.api.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/islandora.api.php b/islandora.api.php index fb27a543..51aeb343 100644 --- a/islandora.api.php +++ b/islandora.api.php @@ -694,7 +694,7 @@ function hook_islandora_update_related_objects_properties(AbstractObject $object * @param AbstractObject $object * (Optional) AbstractObject representing object providing breadcrumb path */ -function hook_islandora_breadcrumbs_alter(&$breadcrumbs, $context, $object) { +function hook_islandora_breadcrumbs_alter(&$breadcrumbs, $context, $object = NULL) { } From 6405a453ce2306ec1744f68e51c03fc575ba8e37 Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Fri, 10 Jan 2014 20:24:20 +0000 Subject: [PATCH 21/50] Batch each derivative operation individually. --- includes/derivatives.inc | 57 +++++++++++++++++++++++ includes/regenerate_derivatives.form.inc | 59 +++++++++++++++++++++--- 2 files changed, 110 insertions(+), 6 deletions(-) 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/regenerate_derivatives.form.inc b/includes/regenerate_derivatives.form.inc index 917154ea..e9c1b986 100644 --- a/includes/regenerate_derivatives.form.inc +++ b/includes/regenerate_derivatives.form.inc @@ -97,13 +97,12 @@ function islandora_regenerate_object_derivatives_form_submit(array $form, array function islandora_regenerate_object_derivatives_batch(AbstractObject $object) { return array( 'title' => t('Regenerating all derivatives for @label', array('@label' => $object->label)), - 'operations' => array( - array('islandora_regenerate_object_derivatives_batch_operation', array($object)), - ), + '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', ); } @@ -135,13 +134,15 @@ function islandora_regenerate_object_derivatives_batch_operation(AbstractObject function islandora_regenerate_datastream_derivative_batch(AbstractDatastream $datastream) { return array( 'title' => t('Regenerating derivatives for the @dsid datastream', array('@dsid' => $datastream->id)), - 'operations' => array( - array('islandora_regenerate_datastream_derivative_batch_operation', array($datastream)), - ), + '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', ); } @@ -161,3 +162,49 @@ function islandora_regenerate_datastream_derivative_batch_operation(AbstractData )); islandora_derivative_logging($logging_results); } + +/** + * 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']); + } +} From 6c340bfbecf1467ba95b33625342e1e1366e4baf Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Mon, 13 Jan 2014 12:50:44 +0000 Subject: [PATCH 22/50] Remove superfluous functions. --- includes/regenerate_derivatives.form.inc | 33 ------------------------ 1 file changed, 33 deletions(-) diff --git a/includes/regenerate_derivatives.form.inc b/includes/regenerate_derivatives.form.inc index e9c1b986..5c0dcef7 100644 --- a/includes/regenerate_derivatives.form.inc +++ b/includes/regenerate_derivatives.form.inc @@ -106,22 +106,6 @@ function islandora_regenerate_object_derivatives_batch(AbstractObject $object) { ); } -/** - * Defines the regenerate object derivatives batch operation. - * - * @param AbstractObject $object - * A AbstractObject representing an object within Fedora. - * @param array $context - * An array containing the context of the current batch. - */ -function islandora_regenerate_object_derivatives_batch_operation(AbstractObject $object, &$context) { - module_load_include('inc', 'islandora', 'includes/derivatives'); - $logging_results = islandora_do_derivatives($object, array( - 'force' => TRUE, - )); - islandora_derivative_logging($logging_results); -} - /** * Creates a batch to go out and re-create the derivative for a datastream. * @@ -146,23 +130,6 @@ function islandora_regenerate_datastream_derivative_batch(AbstractDatastream $da ); } -/** - * Defines the regenerate datastream derivative batch operation. - * - * @param AbstractDatastream $datastream - * A AbstractDatastream representing a datastream on an object within Fedora. - * @param array $context - * An array containing the context of the current batch. - */ -function islandora_regenerate_datastream_derivative_batch_operation(AbstractDatastream $datastream, &$context) { - module_load_include('inc', 'islandora', 'includes/derivatives'); - $logging_results = islandora_do_derivatives($datastream->parent, array( - 'force' => TRUE, - 'destination_dsid' => $datastream->id, - )); - islandora_derivative_logging($logging_results); -} - /** * Wrapper to call out to batch operations. * From 63ce9e2b633f02086311e94c33b355bee13e1811 Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Mon, 13 Jan 2014 19:03:36 +0000 Subject: [PATCH 23/50] Changes based on code review. --- includes/regenerate_derivatives.form.inc | 7 ++++--- theme/theme.inc | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/includes/regenerate_derivatives.form.inc b/includes/regenerate_derivatives.form.inc index 5c0dcef7..a7ef147c 100644 --- a/includes/regenerate_derivatives.form.inc +++ b/includes/regenerate_derivatives.form.inc @@ -62,7 +62,7 @@ function islandora_regenerate_object_derivatives_form(array $form, array &$form_ $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}/manage/properties", + "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') @@ -78,11 +78,10 @@ function islandora_regenerate_object_derivatives_form(array $form, array &$form_ * The Drupal form state. */ function islandora_regenerate_object_derivatives_form_submit(array $form, array &$form_state) { - module_load_include('inc', 'islandora', 'includes/derivatives'); $object = $form_state['object']; $batch = islandora_regenerate_object_derivatives_batch($object); batch_set($batch); - $form_state['redirect'] = "islandora/object/{$object}/manage/properties"; + $form_state['redirect'] = "islandora/object/{$object->id}/manage/properties"; } /** @@ -95,6 +94,7 @@ function islandora_regenerate_object_derivatives_form_submit(array $form, 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)), @@ -116,6 +116,7 @@ function islandora_regenerate_object_derivatives_batch(AbstractObject $object) { * 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( diff --git a/theme/theme.inc b/theme/theme.inc index e057771c..0e62f0d7 100644 --- a/theme/theme.inc +++ b/theme/theme.inc @@ -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,7 +79,7 @@ function islandora_preprocess_islandora_default_edit(array &$variables) { 'datastream' => $ds, )), ); - if (user_access(ISLANDORA_REGENERATE_DERIVATIVES)) { + if (islandora_datastream_access(ISLANDORA_REGENERATE_DERIVATIVES, $ds)) { $row[] = array( 'class' => 'datastream-regenerate', 'data' => theme('islandora_datastream_regenerate_link', array( From 91a379067af751e495411dac900e9731dd94704e Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Tue, 14 Jan 2014 17:40:17 +0000 Subject: [PATCH 24/50] Only render the regenerate under certain conditions. --- theme/theme.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/theme/theme.inc b/theme/theme.inc index 0e62f0d7..2675ab7a 100644 --- a/theme/theme.inc +++ b/theme/theme.inc @@ -447,7 +447,7 @@ function theme_islandora_datastream_regenerate_link(array $vars) { $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) { + if (isset($hook['source_dsid']) && isset($object[$hook['source_dsid']]) && $hook['destination_dsid'] == $datastream->id) { return l(t('regenerate'), "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/regenerate"); } } From 9a76642364e4977664f05cc4b0948c9b31ebb5bf Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Tue, 14 Jan 2014 19:00:06 +0000 Subject: [PATCH 25/50] Make the rendering of the regenerate link respect things. --- islandora.module | 17 +++++++++++++++++ theme/theme.inc | 36 ++++++++++++++---------------------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/islandora.module b/islandora.module index fb165f1e..6537ef21 100644 --- a/islandora.module +++ b/islandora.module @@ -1829,3 +1829,20 @@ function islandora_islandora_metadata_display_info() { ), ); } + +/** + * Implements hook_islandora_datastream_access(). + */ +function islandora_islandora_datastream_access($op, AbstractDatastream $datastream, $user) { + if ($op == ISLANDORA_REGENERATE_DERIVATIVES) { + $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 && ((isset($hook['source_dsid']) && isset($object[$hook['source_dsid']]) && islandora_datastream_access(ISLANDORA_VIEW_OBJECTS, $object[$hook['source_dsid']], $user)) || (array_key_exists('source_dsid', $hook) && $hook['source_dsid'] == NULL))) { + return TRUE; + } + } + return FALSE; + } + return NULL; +} diff --git a/theme/theme.inc b/theme/theme.inc index 2675ab7a..2d3fe898 100644 --- a/theme/theme.inc +++ b/theme/theme.inc @@ -53,14 +53,12 @@ function islandora_preprocess_islandora_default_edit(array &$variables) { 'class' => 'datastream-size', 'data' => islandora_datastream_get_human_readable_size($ds), ); - if (islandora_datastream_access(ISLANDORA_VIEW_DATASTREAM_HISTORY, $ds)) { - $row[] = array( - 'class' => 'datastream-versions', - 'data' => theme('islandora_datastream_version_link', array( - 'datastream' => $ds, - )), - ); - } + $row[] = array( + 'class' => 'datastream-versions', + 'data' => theme('islandora_datastream_version_link', array( + 'datastream' => $ds, + )), + ); $row[] = array( 'class' => 'datastream-download', 'data' => theme('islandora_datastream_download_link', array( @@ -79,14 +77,12 @@ 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, - )), - ); - } + $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; @@ -444,12 +440,8 @@ function theme_islandora_datastream_version_link(array $vars) { */ 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 (isset($hook['source_dsid']) && isset($object[$hook['source_dsid']]) && $hook['destination_dsid'] == $datastream->id) { - return l(t('regenerate'), "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/regenerate"); - } + if (islandora_datastream_access(ISLANDORA_REGENERATE_DERIVATIVES, $datastream)) { + return l(t('regenerate'), "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/regenerate"); } } From 12620a4bf6bdc98b17532418adf9158225a58c57 Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Tue, 14 Jan 2014 19:14:24 +0000 Subject: [PATCH 26/50] Make our datastream_access call work and revert change to themeing of version links. --- islandora.module | 2 +- theme/theme.inc | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/islandora.module b/islandora.module index 6537ef21..9c1ae7d9 100644 --- a/islandora.module +++ b/islandora.module @@ -1839,7 +1839,7 @@ function islandora_islandora_datastream_access($op, AbstractDatastream $datastre $hooks = islandora_invoke_hook_list(ISLANDORA_DERVIATIVE_CREATION_HOOK, $object->models, array($object)); foreach ($hooks as $hook) { if ($hook['destination_dsid'] == $datastream->id && ((isset($hook['source_dsid']) && isset($object[$hook['source_dsid']]) && islandora_datastream_access(ISLANDORA_VIEW_OBJECTS, $object[$hook['source_dsid']], $user)) || (array_key_exists('source_dsid', $hook) && $hook['source_dsid'] == NULL))) { - return TRUE; + return user_access(ISLANDORA_REGENERATE_DERIVATIVES); } } return FALSE; diff --git a/theme/theme.inc b/theme/theme.inc index 2d3fe898..b783cfa8 100644 --- a/theme/theme.inc +++ b/theme/theme.inc @@ -53,12 +53,14 @@ function islandora_preprocess_islandora_default_edit(array &$variables) { 'class' => 'datastream-size', 'data' => islandora_datastream_get_human_readable_size($ds), ); - $row[] = array( - 'class' => 'datastream-versions', - 'data' => theme('islandora_datastream_version_link', array( - 'datastream' => $ds, - )), - ); + if (islandora_datastream_access(ISLANDORA_VIEW_DATASTREAM_HISTORY, $ds)) { + $row[] = array( + 'class' => 'datastream-versions', + 'data' => theme('islandora_datastream_version_link', array( + 'datastream' => $ds, + )), + ); + } $row[] = array( 'class' => 'datastream-download', 'data' => theme('islandora_datastream_download_link', array( From 587c4e22aee5ac40c496ba159ede812201bf9d33 Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Tue, 14 Jan 2014 19:24:17 +0000 Subject: [PATCH 27/50] Fix a bug where user_access/namespaces were not getting checked for datastreams. --- islandora.module | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/islandora.module b/islandora.module index 9c1ae7d9..8173df52 100644 --- a/islandora.module +++ b/islandora.module @@ -1834,15 +1834,22 @@ function islandora_islandora_metadata_display_info() { * Implements hook_islandora_datastream_access(). */ function islandora_islandora_datastream_access($op, AbstractDatastream $datastream, $user) { - if ($op == ISLANDORA_REGENERATE_DERIVATIVES) { + module_load_include('inc', 'islandora', 'includes/utilities'); + $result = islandora_namespace_accessible($datastream->parent->id) && user_access($op, $user); + + if ($result && $op == ISLANDORA_REGENERATE_DERIVATIVES) { + $applicable_hook = FALSE; $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 && ((isset($hook['source_dsid']) && isset($object[$hook['source_dsid']]) && islandora_datastream_access(ISLANDORA_VIEW_OBJECTS, $object[$hook['source_dsid']], $user)) || (array_key_exists('source_dsid', $hook) && $hook['source_dsid'] == NULL))) { - return user_access(ISLANDORA_REGENERATE_DERIVATIVES); + $applicable_hook = TRUE; + break; } } - return FALSE; + if (!$applicable_hook) { + $result = FALSE; + } } - return NULL; + return $result; } From 6e7a659f51af66830226a14437515ebb51a7c37e Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Wed, 15 Jan 2014 19:18:27 +0000 Subject: [PATCH 28/50] Update some derivative tests and add a filter function to smarterly filter. --- includes/derivatives.inc | 77 ++++++++++++++++--------- includes/object_properties.form.inc | 5 +- islandora.module | 4 +- tests/derivatives.test | 31 +++++++++- tests/islandora_derivatives_test.module | 9 ++- 5 files changed, 90 insertions(+), 36 deletions(-) diff --git a/includes/derivatives.inc b/includes/derivatives.inc index 78f00aab..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'])) { @@ -148,20 +135,7 @@ function islandora_do_batch_derivatives(AbstractObject $object, array $options) 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']; - }); - } - + $hooks = islandora_filter_derivatives($hooks, $options, $object); foreach ($hooks as $hook) { $file = FALSE; if (isset($hook['file'])) { @@ -178,3 +152,50 @@ function islandora_do_batch_derivatives(AbstractObject $object, array $options) } 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/object_properties.form.inc b/includes/object_properties.form.inc index be31719c..f9c8e23b 100644 --- a/includes/object_properties.form.inc +++ b/includes/object_properties.form.inc @@ -28,7 +28,10 @@ function islandora_object_properties_form(array $form, array &$form_state, Abstr } $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) { + 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; } } diff --git a/islandora.module b/islandora.module index 8173df52..8e480baa 100644 --- a/islandora.module +++ b/islandora.module @@ -1838,11 +1838,13 @@ function islandora_islandora_datastream_access($op, AbstractDatastream $datastre $result = islandora_namespace_accessible($datastream->parent->id) && user_access($op, $user); if ($result && $op == ISLANDORA_REGENERATE_DERIVATIVES) { + module_load_include('inc', 'islandora', 'includes/derivatives'); $applicable_hook = FALSE; $object = $datastream->parent; $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 && ((isset($hook['source_dsid']) && isset($object[$hook['source_dsid']]) && islandora_datastream_access(ISLANDORA_VIEW_OBJECTS, $object[$hook['source_dsid']], $user)) || (array_key_exists('source_dsid', $hook) && $hook['source_dsid'] == NULL))) { + if ($hook['destination_dsid'] == $datastream->id && islandora_datastream_access(ISLANDORA_VIEW_OBJECTS, $object[$hook['source_dsid']], $user)) { $applicable_hook = TRUE; break; } diff --git a/tests/derivatives.test b/tests/derivatives.test index 13014880..b7eeae9b 100644 --- a/tests/derivatives.test +++ b/tests/derivatives.test @@ -159,7 +159,8 @@ class IslandoraDerivativesTestCase extends IslandoraWebTestCase { public function testDerivativeFilteringOnSourceDSID() { global $_islandora_derivative_test_derivative_functions; $_islandora_derivative_test_derivative_functions = array(); - $this->constructBaseObject(); + $object = $this->constructBaseObject(); + $this->constructSOMEWEIRDDATASTREAMDatastream($object); $object = islandora_object_load($this->pid); islandora_do_derivatives($object, array( 'source_dsid' => 'OBJ', @@ -207,7 +208,8 @@ class IslandoraDerivativesTestCase extends IslandoraWebTestCase { public function testNoSourceDSIDNoForce() { global $_islandora_derivative_test_derivative_functions; $_islandora_derivative_test_derivative_functions = array(); - $this->constructBaseObject(); + $object = $this->constructBaseObject(); + $object = $this->constructSOMEWEIRDDATASTREAMDatastream($object); $object = islandora_object_load($this->pid); islandora_do_derivatives($object, array()); $this->assertDatastreams($object, array( @@ -216,6 +218,8 @@ class IslandoraDerivativesTestCase extends IslandoraWebTestCase { 'OBJ', 'DERIV', 'NOSOURCE', + 'SOMEWEIRDDATASTREAM', + 'STANLEY', )); $this->assertEqual(3, count($_islandora_derivative_test_derivative_functions), 'Expected 3 derivative functions when there is no source_dsid, got ' . count($_islandora_derivative_test_derivative_functions) . '.'); } @@ -226,7 +230,8 @@ class IslandoraDerivativesTestCase extends IslandoraWebTestCase { public function testNoSourceDSIDForce() { global $_islandora_derivative_test_derivative_functions; $_islandora_derivative_test_derivative_functions = array(); - $this->constructBaseObject(); + $object = $this->constructBaseObject(); + $this->constructSOMEWEIRDDATASTREAMDatastream($object); $object = islandora_object_load($this->pid); islandora_do_derivatives($object, array( 'force' => TRUE, @@ -236,6 +241,8 @@ class IslandoraDerivativesTestCase extends IslandoraWebTestCase { 'RELS-EXT', 'OBJ', 'DERIV', + 'SOMEWEIRDDATASTREAM', + 'STANLEY', 'NOSOURCE', )); $this->assertEqual(3, count($_islandora_derivative_test_derivative_functions), 'Expected 3 derivative functions when there is no source_dsid, got ' . count($_islandora_derivative_test_derivative_functions) . '.'); @@ -293,4 +300,22 @@ class IslandoraDerivativesTestCase extends IslandoraWebTestCase { $object->ingestDatastream($ds); return $object; } + + /** + * Helper function to construct the SWD datastream without firing hooks. + * + * @param AbstractObject $object + * An AbstractObject representing a FedoraObject. + * + * @return AbstractObject + * The modified AbstractObject. + */ + public function constructSOMEWEIRDDATASTREAMDatastream(AbstractObject $object) { + $dsid = 'SOMEWEIRDDATASTREAM'; + $ds = $object->constructDatastream($dsid); + $ds->label = 'Test'; + $ds->content = 'Omnomnom'; + $object->ingestDatastream($ds); + return $object; + } } diff --git a/tests/islandora_derivatives_test.module b/tests/islandora_derivatives_test.module index 80530296..dd5dd206 100644 --- a/tests/islandora_derivatives_test.module +++ b/tests/islandora_derivatives_test.module @@ -23,7 +23,7 @@ function islandora_derivatives_test_some_cmodel_islandora_derivative() { 'destination_dsid' => 'STANLEY', 'weight' => '-1', 'function' => array( - 'islandora_derivatives_test_create_some_weird_datastream', + 'islandora_derivatives_test_create_some_stanley_datastream', ), ), array( @@ -81,17 +81,20 @@ function islandora_derivatives_test_create_deriv_datastream(AbstractObject $obje } /** - * Stub function that used only for datastream filtering counts. + * Creates the STANLEY datastream for use in testing. * * @param AbstractObject $object * An AbstractObject representing a Fedora object. * @param bool $force * Whether the derivatives are being forcefully generated or not. */ -function islandora_derivatives_test_create_some_weird_datastream(AbstractObject $object, $force = FALSE) { +function islandora_derivatives_test_create_some_stanley_datastream(AbstractObject $object, $force = FALSE) { global $_islandora_derivative_test_derivative_functions; // Add to the global that we got to this function. $_islandora_derivative_test_derivative_functions[] = 'islandora_derivatives_test_create_some_weird_datastream'; + if (!isset($object['STANLEY']) || (isset($object['STANLEY']) && $force === TRUE)) { + islandora_derivatives_test_add_datastream($object, 'STANLEY', 'yum'); + } } /** From c75bc9a0292de051fa8a49acfc8367486d790acd Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Wed, 15 Jan 2014 19:20:08 +0000 Subject: [PATCH 29/50] Change the testing function name. --- tests/islandora_derivatives_test.module | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/islandora_derivatives_test.module b/tests/islandora_derivatives_test.module index dd5dd206..2e27c5c7 100644 --- a/tests/islandora_derivatives_test.module +++ b/tests/islandora_derivatives_test.module @@ -23,7 +23,7 @@ function islandora_derivatives_test_some_cmodel_islandora_derivative() { 'destination_dsid' => 'STANLEY', 'weight' => '-1', 'function' => array( - 'islandora_derivatives_test_create_some_stanley_datastream', + 'islandora_derivatives_test_create_stanley_datastream', ), ), array( @@ -88,7 +88,7 @@ function islandora_derivatives_test_create_deriv_datastream(AbstractObject $obje * @param bool $force * Whether the derivatives are being forcefully generated or not. */ -function islandora_derivatives_test_create_some_stanley_datastream(AbstractObject $object, $force = FALSE) { +function islandora_derivatives_test_create_stanley_datastream(AbstractObject $object, $force = FALSE) { global $_islandora_derivative_test_derivative_functions; // Add to the global that we got to this function. $_islandora_derivative_test_derivative_functions[] = 'islandora_derivatives_test_create_some_weird_datastream'; From d35c4826120752709b33f492f2e451bac0972c8b Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Thu, 16 Jan 2014 20:12:00 +0000 Subject: [PATCH 30/50] Avoid adding on duplicate extensions. As we often use filenames for datastream labels, and then use the labels to generate file names for download, we were ending up with file extensions being doubled up. --- includes/datastream.inc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/includes/datastream.inc b/includes/datastream.inc index 72a86c5f..26a7a8d5 100644 --- a/includes/datastream.inc +++ b/includes/datastream.inc @@ -53,8 +53,16 @@ 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. + $extension_length = strlen($extension); + $duplicate_extension_position = strripos($datastream->label, $extension, -$extension_length); + $filename = $datastream->label; + if ($duplicate_extension_position === FALSE) { + $filename .= $extension; + } + header("Content-Disposition: attachment; filename=\"$filename\""); } From 7b7a74170d8b3b457f57806c6781c527cfea50bd Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Fri, 17 Jan 2014 19:05:44 +0000 Subject: [PATCH 31/50] Add MIME type autocompletion to core. --- includes/mime_type.autocomplete.inc | 27 +++++++++++++++++++++++++++ islandora.module | 10 ++++++++++ 2 files changed, 37 insertions(+) create mode 100644 includes/mime_type.autocomplete.inc 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/islandora.module b/islandora.module index 8e480baa..99a5740b 100644 --- a/islandora.module +++ b/islandora.module @@ -62,6 +62,7 @@ define('ISLANDORA_DERVIATIVE_CREATION_HOOK', 'islandora_derivative'); // Autocomplete paths. define('ISLANDORA_CONTENT_MODELS_AUTOCOMPLETE', 'islandora/autocomplete/content-models'); +define('ISLANDORA_MIME_TYPES_AUTOCOMPLETE', 'islandora/autocomplete/mime-types'); /** * @deprecated Constants. @@ -358,6 +359,15 @@ function islandora_menu() { 'access arguments' => array('administer site configuration'), 'type' => MENU_CALLBACK, ); + $items[ISLANDORA_MIME_TYPES_AUTOCOMPLETE] = array( + 'title' => 'Autocomplete callback', + 'description' => 'Autocomplete MIME Types.', + 'file' => 'includes/mime_type.autocomplete.inc', + 'page callback' => 'islandora_mime_type_autocomplete', + 'page arguments' => array(3), + 'access arguments' => array('administer site configuration'), + 'type' => MENU_CALLBACK, + ); $items['admin/islandora/restore/prep'] = array( 'description' => 'Restore or permanantly remove objects with Deleted status', 'title' => 'Manage Deleted Objects', From 50e16d2822fc8045d4c3e39b9ab3f80659f5f97f Mon Sep 17 00:00:00 2001 From: qadan Date: Fri, 17 Jan 2014 20:42:36 +0000 Subject: [PATCH 32/50] better handling of objects --- tests/islandora_web_test_case.inc | 55 ++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/tests/islandora_web_test_case.inc b/tests/islandora_web_test_case.inc index 0ea96e8e..df48125b 100644 --- a/tests/islandora_web_test_case.inc +++ b/tests/islandora_web_test_case.inc @@ -7,6 +7,13 @@ class IslandoraWebTestCase extends DrupalWebTestCase { + /** + * An array of users that may be created over the course of a test. + * + * @var array + */ + protected $users = array(); + /** * Sets up the Drupal filter to access this test Drupal instances database. * @@ -131,6 +138,7 @@ class IslandoraWebTestCase extends DrupalWebTestCase { } else { parent::drupalLogin($account); + $this->users[] = $account; } } @@ -155,6 +163,9 @@ class IslandoraWebTestCase extends DrupalWebTestCase { * @see DrupalWebTestCase::tearDown() */ public function tearDown() { + foreach ($this->users as $user) { + $this->deleteUserCreatedObjects($user); + } if ($this->configuration['use_drupal_filter']) { $this->restoreDrupalFilter(); } @@ -170,20 +181,31 @@ class IslandoraWebTestCase extends DrupalWebTestCase { * The PID of the object * @param array $datastreams * An array of strings containing datastream names + * + * @return bool + * TRUE on success, FALSE on fail. */ public function assertDatastreams($object, array $datastreams) { if (!is_object($object)) { $this->fail("Failed. Object passed in is invalid.", 'Islandora'); } else { + $fails = 0; foreach ($datastreams as $datastream) { if (isset($object[$datastream])) { $this->pass("Loaded datastream {$datastream} from PID {$object->id}.", 'Islandora'); } else { $this->fail("Failed to load datastream {$datastream} from PID {$object->id}.", 'Islandora'); + $fails++; } } + if ($fails) { + return FALSE; + } + else { + return TRUE; + } } } @@ -266,7 +288,6 @@ class IslandoraWebTestCase extends DrupalWebTestCase { $this->drupalPost($path, $edit, "Permanently remove '{$object->label}' from repository"); } $this->drupalPost($this->url, $edit, t('Delete')); - $object = islandora_object_load($pid); $this->drupalGet("islandora/object/$pid"); $this->assertResponse(404, "Object $pid successfully deleted."); @@ -367,4 +388,36 @@ class IslandoraWebTestCase extends DrupalWebTestCase { return $object; } + /** + * Deletes all objects created by the given user. + * + * @param object $user + * The user whose objects we'd like to remove. + * + * @return bool + * TRUE on success, FALSE on failure. + */ + public function deleteUserCreatedObjects($user) { + if (is_object($user) && isset($user->name)) { + $query = << WHERE +{ + ?object "$user->name" +} +QUERY; + + $objects = $this->admin->repository->ri->sparqlQuery($query); + foreach ($objects as $object) { + $loaded_object = islandora_object_load($object['object']['value']); + islandora_delete_object($loaded_object); + $this->assertFalse(islandora_object_load($object['object']['value']), "Object {$object['object']['value']} successfully removed from repository.", 'Islandora'); + } + return TRUE; + } + else { + $this->fail("Invalid user passed in for object deletion.", "Islandora"); + return FAIL; + } + } + } From cb41135270f1b4b0204add200880b87eaef678f8 Mon Sep 17 00:00:00 2001 From: qadan Date: Fri, 17 Jan 2014 20:59:37 +0000 Subject: [PATCH 33/50] a tiny bit of cleanup --- tests/islandora_web_test_case.inc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/islandora_web_test_case.inc b/tests/islandora_web_test_case.inc index df48125b..245e8844 100644 --- a/tests/islandora_web_test_case.inc +++ b/tests/islandora_web_test_case.inc @@ -203,9 +203,7 @@ class IslandoraWebTestCase extends DrupalWebTestCase { if ($fails) { return FALSE; } - else { - return TRUE; - } + return TRUE; } } From 4df5398b711a49e77c1868e5c47ddb9876cf449c Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Mon, 20 Jan 2014 14:01:05 +0000 Subject: [PATCH 34/50] Fix warning when the datastream label was shorter than the extension. --- includes/datastream.inc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/includes/datastream.inc b/includes/datastream.inc index 26a7a8d5..ba2872c2 100644 --- a/includes/datastream.inc +++ b/includes/datastream.inc @@ -56,9 +56,12 @@ function islandora_view_datastream(AbstractDatastream $datastream, $download = F $extension = '.' . $mime_detect->getExtension($datastream->mimetype); // Prevent adding on a duplicate extension. + $label = $datastream->label; $extension_length = strlen($extension); - $duplicate_extension_position = strripos($datastream->label, $extension, -$extension_length); - $filename = $datastream->label; + $duplicate_extension_position = strlen($label) > $extension_length ? + strripos($label, $extension, -$extension_length) : + FALSE; + $filename = $label; if ($duplicate_extension_position === FALSE) { $filename .= $extension; } From e4b054d2363fadb84a1d45560af91dd2bfbbb612 Mon Sep 17 00:00:00 2001 From: qadan Date: Tue, 21 Jan 2014 15:22:04 +0000 Subject: [PATCH 35/50] fixes, better deletion function, better handling of deletion --- tests/islandora_web_test_case.inc | 81 ++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 23 deletions(-) diff --git a/tests/islandora_web_test_case.inc b/tests/islandora_web_test_case.inc index 245e8844..46a032be 100644 --- a/tests/islandora_web_test_case.inc +++ b/tests/islandora_web_test_case.inc @@ -138,7 +138,7 @@ class IslandoraWebTestCase extends DrupalWebTestCase { } else { parent::drupalLogin($account); - $this->users[] = $account; + $this->users[] = $account->name; } } @@ -190,20 +190,17 @@ class IslandoraWebTestCase extends DrupalWebTestCase { $this->fail("Failed. Object passed in is invalid.", 'Islandora'); } else { - $fails = 0; + $fails = FALSE; foreach ($datastreams as $datastream) { if (isset($object[$datastream])) { $this->pass("Loaded datastream {$datastream} from PID {$object->id}.", 'Islandora'); } else { $this->fail("Failed to load datastream {$datastream} from PID {$object->id}.", 'Islandora'); - $fails++; + $fails = TRUE; } } - if ($fails) { - return FALSE; - } - return TRUE; + return $fails; } } @@ -270,12 +267,23 @@ class IslandoraWebTestCase extends DrupalWebTestCase { /** * Deletes an object using the PID. This does the deletion using the UI. * + * Deprecated: please use IslandoraWebTestCase::deleteTestObject() instead, as + * it doesn't require a label, is safer, and is also not generally ridiculous. + * * @param string $pid * The PID of the collection to be deleted * @param string $button * The label of the first 'Delete' button */ public function deleteObject($pid, $button = NULL) { + // Hey, good for you coming down to check this out. + $message = islandora_deprecated('7.x-1.3', 'Use the "IslandoraWebTestCase::deleteTestObject()" function.'); + $this->assert('debug', $message, "Debug", array( + 'file' => "islandora_web_test_case.inc", + 'function' => "IslandoraWebTestCase->deleteObject()", + 'line' => '278', + )); + $path = 'islandora/object/' . $pid . '/manage/properties'; $edit = array(); if (isset($button)) { @@ -291,6 +299,31 @@ class IslandoraWebTestCase extends DrupalWebTestCase { $this->assertResponse(404, "Object $pid successfully deleted."); } + /** + * Deletes an object using the PID. This does the deletion using the UI. + * + * @param string $pid + * The PID of the object. + * @param bool $safety + * If TRUE, this will only delete objects owned by users in $this->users. + * + * @return bool + * TRUE on success, FALSE on failure. + */ + public function deleteTestObject($pid, $safety = TRUE) { + $object = islandora_object_load($pid); + if (!$safety || in_array($object->owner, $this->users)) { + $this->drupalPost('islandora/object/' . $pid . '/delete', array(), 'Delete'); + $this->drupalGet('islandora/object/' . $pid); + $this->assertResponse(404, "Successfully deleted object $pid", 'Islandora'); + return TRUE; + } + else { + $this->fail("Cannot delete object {$pid}; it is owned by non-test user {$object->owner}, and this function was called with the safety on."); + + } + } + /** * Constructs and ingests a Fedora object and datastream(s) via tuque. * @@ -302,7 +335,9 @@ class IslandoraWebTestCase extends DrupalWebTestCase { * 'label' - The object label; randomized if not set. * 'pid' - 'namespace:pid', or just 'namespace' to generate the suffix. * 'models' - An array that can contain multiple content model PIDs. - * 'owner' - The object's owner. + * 'owner' - The object's owner. Defaults to the currently logged-in user, + * if available. It is recommended to set this to a value that can be found + * in $this->users; otherwise, this object will have to be manually deleted. * 'parent' - The PID of the parent collection. * @param array $datastreams * An array containing zero or more datastream arrays that use the keys: @@ -335,6 +370,9 @@ class IslandoraWebTestCase extends DrupalWebTestCase { if (isset($properties['owner'])) { $object->owner = $properties['owner']; } + elseif (is_object($this->loggedInUser)) { + $object->owner = $this->loggedInUser->name; + } if (isset($properties['models']) && is_array($properties['models'])) { foreach ($properties['models'] as $model) { @@ -389,33 +427,30 @@ class IslandoraWebTestCase extends DrupalWebTestCase { /** * Deletes all objects created by the given user. * - * @param object $user + * @param object $username * The user whose objects we'd like to remove. * * @return bool * TRUE on success, FALSE on failure. */ - public function deleteUserCreatedObjects($user) { - if (is_object($user) && isset($user->name)) { - $query = << WHERE { - ?object "$user->name" + ?object "$username" } QUERY; - $objects = $this->admin->repository->ri->sparqlQuery($query); - foreach ($objects as $object) { - $loaded_object = islandora_object_load($object['object']['value']); - islandora_delete_object($loaded_object); - $this->assertFalse(islandora_object_load($object['object']['value']), "Object {$object['object']['value']} successfully removed from repository.", 'Islandora'); + $objects = $this->admin->repository->ri->sparqlQuery($query); + $fail = FALSE; + foreach ($objects as $object) { + $loaded_object = islandora_object_load($object['object']['value']); + islandora_delete_object($loaded_object); + if ($this->assertFalse(islandora_object_load($object['object']['value']), "Object {$object['object']['value']} successfully removed from repository.", 'Islandora')) { + $fail = TRUE; } - return TRUE; - } - else { - $this->fail("Invalid user passed in for object deletion.", "Islandora"); - return FAIL; } + return $fail; } } From 127b53c111754560787f37d3e29aeef5e6a257d9 Mon Sep 17 00:00:00 2001 From: qadan Date: Tue, 21 Jan 2014 15:25:38 +0000 Subject: [PATCH 36/50] missed a line --- tests/islandora_web_test_case.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/islandora_web_test_case.inc b/tests/islandora_web_test_case.inc index 46a032be..5c198e16 100644 --- a/tests/islandora_web_test_case.inc +++ b/tests/islandora_web_test_case.inc @@ -320,7 +320,7 @@ class IslandoraWebTestCase extends DrupalWebTestCase { } else { $this->fail("Cannot delete object {$pid}; it is owned by non-test user {$object->owner}, and this function was called with the safety on."); - + return FALSE; } } From 4ec2185d2d7a41d553b8b3e13742e95cba81e8c4 Mon Sep 17 00:00:00 2001 From: qadan Date: Tue, 21 Jan 2014 15:33:45 +0000 Subject: [PATCH 37/50] let's add in one last failsafe --- tests/islandora_web_test_case.inc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/islandora_web_test_case.inc b/tests/islandora_web_test_case.inc index 5c198e16..45d887ee 100644 --- a/tests/islandora_web_test_case.inc +++ b/tests/islandora_web_test_case.inc @@ -434,6 +434,11 @@ class IslandoraWebTestCase extends DrupalWebTestCase { * TRUE on success, FALSE on failure. */ public function deleteUserCreatedObjects($username) { + if ($username === $this->configuration['admin_user']) { + $this->fail("This function will under no circumstance attempt deletion of all objects owned by the configured Fedora admin user ({$this->configuration['admin_user']}), as this would irreparably damage the repository.", 'Islandora'); + return FALSE; + } + $query = << WHERE { From 9e523d5881b6b8486f8f774f1c39b0d0f094a199 Mon Sep 17 00:00:00 2001 From: qadan Date: Tue, 21 Jan 2014 15:36:02 +0000 Subject: [PATCH 38/50] i mixed up some of the return values --- tests/islandora_web_test_case.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/islandora_web_test_case.inc b/tests/islandora_web_test_case.inc index 45d887ee..35a04a90 100644 --- a/tests/islandora_web_test_case.inc +++ b/tests/islandora_web_test_case.inc @@ -447,12 +447,12 @@ SELECT ?object FROM <#ri> WHERE QUERY; $objects = $this->admin->repository->ri->sparqlQuery($query); - $fail = FALSE; + $fail = TRUE; foreach ($objects as $object) { $loaded_object = islandora_object_load($object['object']['value']); islandora_delete_object($loaded_object); if ($this->assertFalse(islandora_object_load($object['object']['value']), "Object {$object['object']['value']} successfully removed from repository.", 'Islandora')) { - $fail = TRUE; + $fail = FALSE; } } return $fail; From a67ab871e35c552612df22414a023530de8937df Mon Sep 17 00:00:00 2001 From: qadan Date: Tue, 21 Jan 2014 17:59:31 +0000 Subject: [PATCH 39/50] flip-flopping --- tests/islandora_web_test_case.inc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/islandora_web_test_case.inc b/tests/islandora_web_test_case.inc index 35a04a90..d355ef7a 100644 --- a/tests/islandora_web_test_case.inc +++ b/tests/islandora_web_test_case.inc @@ -190,17 +190,17 @@ class IslandoraWebTestCase extends DrupalWebTestCase { $this->fail("Failed. Object passed in is invalid.", 'Islandora'); } else { - $fails = FALSE; + $result = TRUE; foreach ($datastreams as $datastream) { if (isset($object[$datastream])) { $this->pass("Loaded datastream {$datastream} from PID {$object->id}.", 'Islandora'); } else { $this->fail("Failed to load datastream {$datastream} from PID {$object->id}.", 'Islandora'); - $fails = TRUE; + $result = FALSE; } } - return $fails; + return $result; } } From 5c70875f8be13ba830857164603ba3e79f407a92 Mon Sep 17 00:00:00 2001 From: Stefan Langer Date: Tue, 21 Jan 2014 13:53:59 -0500 Subject: [PATCH 40/50] Added 'islandora_os_check' function, primarily for Windows detection. --- islandora.module | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/islandora.module b/islandora.module index 99a5740b..ef1bf8cc 100644 --- a/islandora.module +++ b/islandora.module @@ -1865,3 +1865,19 @@ function islandora_islandora_datastream_access($op, AbstractDatastream $datastre } return $result; } + +/** + * Determines the server's operating system. + * + * @return string + * The name of the operating system being used. + */ +function islandora_os_check() { + // Determine if PHP is currently running on Windows. (The constant + // "PHP_OS" may return "Windows," "WIN32," "WINNT," "CYGWIN_NT-5.1," etc.) + if ((strtolower(substr(PHP_OS, 0, 3)) == 'win') || + (strtolower(substr(PHP_OS, 0, 6)) == 'cygwin')) { + return 'Windows'; + } + return 'Unix'; +} From d9392e5fd36c50be2955e87b38ffefbca35d0f04 Mon Sep 17 00:00:00 2001 From: qadan Date: Wed, 22 Jan 2014 15:42:34 +0000 Subject: [PATCH 41/50] fixes from code review --- tests/islandora_web_test_case.inc | 85 +++++++++++-------------------- 1 file changed, 30 insertions(+), 55 deletions(-) diff --git a/tests/islandora_web_test_case.inc b/tests/islandora_web_test_case.inc index d355ef7a..78b54926 100644 --- a/tests/islandora_web_test_case.inc +++ b/tests/islandora_web_test_case.inc @@ -190,17 +190,20 @@ class IslandoraWebTestCase extends DrupalWebTestCase { $this->fail("Failed. Object passed in is invalid.", 'Islandora'); } else { - $result = TRUE; - foreach ($datastreams as $datastream) { - if (isset($object[$datastream])) { - $this->pass("Loaded datastream {$datastream} from PID {$object->id}.", 'Islandora'); - } - else { - $this->fail("Failed to load datastream {$datastream} from PID {$object->id}.", 'Islandora'); - $result = FALSE; + $object_datastreams = array_keys($this->admin->repository->api->a->listDatastreams($object->id)); + $missing_datastreams = implode(', ', array_diff_key($datastreams, $object_datastreams)); + $present_datastreams = implode(', ', array_intersect_key($datastreams, $object_datastreams)); + + if ($missing_datastreams !== '') { + $this->fail("Failed to load datastreams {$missing_datastreams} from object {$object->id}."); + if ($present_datastreams !== '') { + $this->pass("Loaded datastreams {$present_datastreams} from object {$object->id}"); } + return FALSE; } - return $result; + + $this->pass("Loaded datastreams {$present_datastreams} from object {$object->id}"); + return TRUE; } } @@ -267,56 +270,29 @@ class IslandoraWebTestCase extends DrupalWebTestCase { /** * Deletes an object using the PID. This does the deletion using the UI. * - * Deprecated: please use IslandoraWebTestCase::deleteTestObject() instead, as - * it doesn't require a label, is safer, and is also not generally ridiculous. - * * @param string $pid * The PID of the collection to be deleted * @param string $button * The label of the first 'Delete' button - */ - public function deleteObject($pid, $button = NULL) { - // Hey, good for you coming down to check this out. - $message = islandora_deprecated('7.x-1.3', 'Use the "IslandoraWebTestCase::deleteTestObject()" function.'); - $this->assert('debug', $message, "Debug", array( - 'file' => "islandora_web_test_case.inc", - 'function' => "IslandoraWebTestCase->deleteObject()", - 'line' => '278', - )); - - $path = 'islandora/object/' . $pid . '/manage/properties'; - $edit = array(); - if (isset($button)) { - $this->drupalPost($path, $edit, $button); - } - else { - $object = islandora_object_load($pid); - $this->drupalPost($path, $edit, "Permanently remove '{$object->label}' from repository"); - } - $this->drupalPost($this->url, $edit, t('Delete')); - - $this->drupalGet("islandora/object/$pid"); - $this->assertResponse(404, "Object $pid successfully deleted."); - } - - /** - * Deletes an object using the PID. This does the deletion using the UI. - * - * @param string $pid - * The PID of the object. * @param bool $safety * If TRUE, this will only delete objects owned by users in $this->users. - * - * @return bool - * TRUE on success, FALSE on failure. */ - public function deleteTestObject($pid, $safety = TRUE) { + public function deleteObject($pid, $button = NULL, $safety = TRUE) { $object = islandora_object_load($pid); if (!$safety || in_array($object->owner, $this->users)) { - $this->drupalPost('islandora/object/' . $pid . '/delete', array(), 'Delete'); - $this->drupalGet('islandora/object/' . $pid); - $this->assertResponse(404, "Successfully deleted object $pid", 'Islandora'); - return TRUE; + $path = 'islandora/object/' . $pid . '/manage/properties'; + $edit = array(); + if (isset($button)) { + $this->drupalPost($path, $edit, $button); + } + else { + $object = islandora_object_load($pid); + $this->drupalPost($path, $edit, "Permanently remove '{$object->label}' from repository"); + } + $this->drupalPost($this->url, $edit, t('Delete')); + + $this->drupalGet("islandora/object/$pid"); + $this->assertResponse(404, "Object $pid successfully deleted."); } else { $this->fail("Cannot delete object {$pid}; it is owned by non-test user {$object->owner}, and this function was called with the safety on."); @@ -370,7 +346,7 @@ class IslandoraWebTestCase extends DrupalWebTestCase { if (isset($properties['owner'])) { $object->owner = $properties['owner']; } - elseif (is_object($this->loggedInUser)) { + elseif ($this->loggedInUser !== FALSE) { $object->owner = $this->loggedInUser->name; } @@ -435,7 +411,7 @@ class IslandoraWebTestCase extends DrupalWebTestCase { */ public function deleteUserCreatedObjects($username) { if ($username === $this->configuration['admin_user']) { - $this->fail("This function will under no circumstance attempt deletion of all objects owned by the configured Fedora admin user ({$this->configuration['admin_user']}), as this would irreparably damage the repository.", 'Islandora'); + $this->fail("This function will under no circumstance attempt deletion of all objects owned by the configured Fedora admin user ({$this->configuration['admin_user']}), as this could irreparably damage the repository.", 'Islandora'); return FALSE; } @@ -447,15 +423,14 @@ SELECT ?object FROM <#ri> WHERE QUERY; $objects = $this->admin->repository->ri->sparqlQuery($query); - $fail = TRUE; foreach ($objects as $object) { $loaded_object = islandora_object_load($object['object']['value']); islandora_delete_object($loaded_object); if ($this->assertFalse(islandora_object_load($object['object']['value']), "Object {$object['object']['value']} successfully removed from repository.", 'Islandora')) { - $fail = FALSE; + return FALSE; } + return TRUE; } - return $fail; } } From 2bf3bf71d6267318babf129be58e593f3c4ecd0d Mon Sep 17 00:00:00 2001 From: qadan Date: Wed, 22 Jan 2014 16:07:47 +0000 Subject: [PATCH 42/50] a bit of cleanup --- tests/islandora_web_test_case.inc | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/tests/islandora_web_test_case.inc b/tests/islandora_web_test_case.inc index 78b54926..4f7b302a 100644 --- a/tests/islandora_web_test_case.inc +++ b/tests/islandora_web_test_case.inc @@ -190,19 +190,14 @@ class IslandoraWebTestCase extends DrupalWebTestCase { $this->fail("Failed. Object passed in is invalid.", 'Islandora'); } else { - $object_datastreams = array_keys($this->admin->repository->api->a->listDatastreams($object->id)); - $missing_datastreams = implode(', ', array_diff_key($datastreams, $object_datastreams)); - $present_datastreams = implode(', ', array_intersect_key($datastreams, $object_datastreams)); + $missing_datastreams = implode(', ', array_diff_key($datastreams, array_keys($this->admin->repository->api->a->listDatastreams($object->id)))); if ($missing_datastreams !== '') { - $this->fail("Failed to load datastreams {$missing_datastreams} from object {$object->id}."); - if ($present_datastreams !== '') { - $this->pass("Loaded datastreams {$present_datastreams} from object {$object->id}"); - } + $this->fail("Failed to find datastreams {$missing_datastreams} in object {$object->id}."); return FALSE; } - $this->pass("Loaded datastreams {$present_datastreams} from object {$object->id}"); + $this->pass("Found all required datastreams in object {$object->id}"); return TRUE; } } From f652e75396d0f704935cf5f253bc0bba6aa11146 Mon Sep 17 00:00:00 2001 From: qadan Date: Wed, 22 Jan 2014 17:53:33 +0000 Subject: [PATCH 43/50] more code review fixes --- tests/islandora_web_test_case.inc | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/tests/islandora_web_test_case.inc b/tests/islandora_web_test_case.inc index 4f7b302a..b77e5b12 100644 --- a/tests/islandora_web_test_case.inc +++ b/tests/islandora_web_test_case.inc @@ -190,10 +190,10 @@ class IslandoraWebTestCase extends DrupalWebTestCase { $this->fail("Failed. Object passed in is invalid.", 'Islandora'); } else { - $missing_datastreams = implode(', ', array_diff_key($datastreams, array_keys($this->admin->repository->api->a->listDatastreams($object->id)))); + $missing_datastreams = array_diff($datastreams, array_keys($this->admin->repository->api->a->listDatastreams($object->id))); - if ($missing_datastreams !== '') { - $this->fail("Failed to find datastreams {$missing_datastreams} in object {$object->id}."); + if (!empty($missing_datastreams)) { + $this->fail("Failed to find datastreams " . implode(', ', $missing_datastreams) . " in object {$object->id}."); return FALSE; } @@ -275,16 +275,15 @@ class IslandoraWebTestCase extends DrupalWebTestCase { public function deleteObject($pid, $button = NULL, $safety = TRUE) { $object = islandora_object_load($pid); if (!$safety || in_array($object->owner, $this->users)) { - $path = 'islandora/object/' . $pid . '/manage/properties'; - $edit = array(); + $path = "islandora/object/$pid/manage/properties"; if (isset($button)) { - $this->drupalPost($path, $edit, $button); + $this->drupalPost($path, array(), $button); } else { $object = islandora_object_load($pid); - $this->drupalPost($path, $edit, "Permanently remove '{$object->label}' from repository"); + $this->drupalPost($path, array(), "Permanently remove '{$object->label}' from repository"); } - $this->drupalPost($this->url, $edit, t('Delete')); + $this->drupalPost($this->url, array(), t('Delete')); $this->drupalGet("islandora/object/$pid"); $this->assertResponse(404, "Object $pid successfully deleted."); From faf6e67456e6c2c4289ad4939371e51b2e58068e Mon Sep 17 00:00:00 2001 From: qadan Date: Wed, 22 Jan 2014 18:36:20 +0000 Subject: [PATCH 44/50] general array_diff_key messiness --- tests/islandora_web_test_case.inc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/islandora_web_test_case.inc b/tests/islandora_web_test_case.inc index b77e5b12..d417ff37 100644 --- a/tests/islandora_web_test_case.inc +++ b/tests/islandora_web_test_case.inc @@ -190,14 +190,14 @@ class IslandoraWebTestCase extends DrupalWebTestCase { $this->fail("Failed. Object passed in is invalid.", 'Islandora'); } else { - $missing_datastreams = array_diff($datastreams, array_keys($this->admin->repository->api->a->listDatastreams($object->id))); + $missing_datastreams = array_diff_key(array_flip($datastreams), $this->admin->repository->api->a->listDatastreams($object->id)); if (!empty($missing_datastreams)) { - $this->fail("Failed to find datastreams " . implode(', ', $missing_datastreams) . " in object {$object->id}."); + $this->fail("Failed to find datastream(s) " . implode(', ', array_flip($missing_datastreams)) . " in object {$object->id}."); return FALSE; } - $this->pass("Found all required datastreams in object {$object->id}"); + $this->pass("Found required datastream(s) in object {$object->id}"); return TRUE; } } From 31d0e6b1726428a8a9d908e0b81a88cf9cf58d5a Mon Sep 17 00:00:00 2001 From: Alan Stanley Date: Thu, 23 Jan 2014 10:35:50 -0400 Subject: [PATCH 45/50] added command to update solution pack content models --- islandora.drush.inc | 58 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 6 deletions(-) diff --git a/islandora.drush.inc b/islandora.drush.inc index 6ba73cb5..acf3994f 100644 --- a/islandora.drush.inc +++ b/islandora.drush.inc @@ -70,7 +70,23 @@ function islandora_drush_command() { ), 'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_LOGIN, ); - + $commands['islandora-solution-pack-install-content_models'] = array( + 'description' => dt('Install Solution Pack content models.'), + 'options' => array( + 'module' => array( + 'description' => dt('The module for which to install the content models.'), + 'required' => TRUE, + ), + ), + 'aliases' => array('ispicm'), + 'drupal dependencies' => array( + 'islandora', + ), + 'examples' => array( + 'drush -u 1 ispicm --module=islandora' => dt('Install missing solution pack objects for the "islandora" module.'), + ), + 'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_LOGIN, + ); return $commands; } @@ -83,9 +99,7 @@ function drush_islandora_solution_pack_install_required_objects() { $module = drush_get_option('module'); if (module_exists($module)) { islandora_install_solution_pack( - $module, - 'install', - drush_get_option('force', FALSE) + $module, 'install', drush_get_option('force', FALSE) ); } else { @@ -104,8 +118,7 @@ function drush_islandora_solution_pack_uninstall_required_objects() { $module = drush_get_option('module'); if (module_exists($module)) { islandora_uninstall_solution_pack( - $module, - drush_get_option('force', FALSE) + $module, drush_get_option('force', FALSE) ); } else { @@ -152,3 +165,36 @@ function drush_islandora_solution_pack_required_objects_status() { drush_print_table($rows, $header, $widths); } } + +/** + * Command callback to install required objects. + */ +function drush_islandora_solution_pack_install_content_models() { + module_load_include('inc', 'islandora', 'includes/solution_packs'); + $module = drush_get_option('module'); + if (module_exists($module)) { + $info = islandora_solution_packs_get_required_objects($module); + $objects_to_add = array(); + foreach ($info['objects'] as $key => $candidate) { + $object = islandora_object_load($candidate); + if (in_array('fedora-system:ContentModel-3.0', $object->models)) { + $objects_to_add[] = $candidate; + } + } + foreach ($objects_to_add as $object_to_add) { + $old_object = islandora_object_load($object_to_add->id); + if ($old_object) { + $deleted = islandora_delete_object($old_object); + if (!$deleted) { + drush_log(dt('@object did not delete.', array('@object' => $old_object->id), 'error')); + continue; + } + } + $new_object = islandora_add_object($object_to_add); + $verb = $deleted ? dt("Replaced") : dt("Added"); + if ($new_object) { + drush_log("$verb " . $object_to_add->id . " - " . $object_to_add->label); + } + } + } +} From 6a1d902de7f3b11be995c0e78531a6b209be12e8 Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Thu, 23 Jan 2014 20:17:13 +0000 Subject: [PATCH 46/50] Force re-load an object when purging so we don't try to access things that no longer exist in Fedora. --- includes/tuque_wrapper.inc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/includes/tuque_wrapper.inc b/includes/tuque_wrapper.inc index 98e9c62c..d30af147 100644 --- a/includes/tuque_wrapper.inc +++ b/includes/tuque_wrapper.inc @@ -298,7 +298,14 @@ class IslandoraFedoraApiM extends FedoraApiM { default: $ret = parent::purgeDatastream($pid, $dsid, $params); - islandora_invoke_datastream_hooks(ISLANDORA_DATASTREAM_PURGED_HOOK, $object->models, $dsid, $object, $dsid); + // We need to remove this object from the cache and reload it as + // Tuque may not have an updated copy. That is the datastream could + // still be present within the object even though it's purged out of + // Fedora. + $tuque = islandora_get_tuque_connection(); + $tuque->cache->delete($pid); + $non_cached_object = islandora_object_load($pid); + islandora_invoke_datastream_hooks(ISLANDORA_DATASTREAM_PURGED_HOOK, $non_cached_object->models, $dsid, $non_cached_object, $dsid); return $ret; } } From bc98a7e373a0ffd2c90dc11860fffafb08d18234 Mon Sep 17 00:00:00 2001 From: Stefan Langer Date: Mon, 27 Jan 2014 18:43:59 -0500 Subject: [PATCH 47/50] ISLANDORA-450 Instead of PHP_OS, now using php_uname() for OS detection. --- islandora.module | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/islandora.module b/islandora.module index ef1bf8cc..15ef0a88 100644 --- a/islandora.module +++ b/islandora.module @@ -1873,11 +1873,9 @@ function islandora_islandora_datastream_access($op, AbstractDatastream $datastre * The name of the operating system being used. */ function islandora_os_check() { - // Determine if PHP is currently running on Windows. (The constant - // "PHP_OS" may return "Windows," "WIN32," "WINNT," "CYGWIN_NT-5.1," etc.) - if ((strtolower(substr(PHP_OS, 0, 3)) == 'win') || - (strtolower(substr(PHP_OS, 0, 6)) == 'cygwin')) { + // Determine if PHP is currently running on Windows. + if (strpos(strtolower(php_uname('s')), 'windows') !== FALSE) { return 'Windows'; } - return 'Unix'; + return 'Linux'; } From ba90b6b0ea32a3723b5f5893bcb46cf7ce12006d Mon Sep 17 00:00:00 2001 From: Stefan Langer Date: Wed, 29 Jan 2014 11:11:12 -0500 Subject: [PATCH 48/50] ISLANDORA-450 Function renamed, moved to utilities.inc; now returns boolean. --- includes/utilities.inc | 14 ++++++++++++++ islandora.module | 14 -------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/includes/utilities.inc b/includes/utilities.inc index d858ff0c..0710f8f3 100644 --- a/includes/utilities.inc +++ b/includes/utilities.inc @@ -981,3 +981,17 @@ function islandora_scale_thumbnail($file, $width, $height) { } return FALSE; } + +/** + * Determines if the server operating system is Windows. + * + * @return bool + * TRUE if Windows, FALSE otherwise. + */ +function islandora_deployed_on_windows() { + // Determine if PHP is currently running on Windows. + if (strpos(strtolower(php_uname('s')), 'windows') !== FALSE) { + return TRUE; + } + return FALSE; +} diff --git a/islandora.module b/islandora.module index 15ef0a88..99a5740b 100644 --- a/islandora.module +++ b/islandora.module @@ -1865,17 +1865,3 @@ function islandora_islandora_datastream_access($op, AbstractDatastream $datastre } return $result; } - -/** - * Determines the server's operating system. - * - * @return string - * The name of the operating system being used. - */ -function islandora_os_check() { - // Determine if PHP is currently running on Windows. - if (strpos(strtolower(php_uname('s')), 'windows') !== FALSE) { - return 'Windows'; - } - return 'Linux'; -} From 32d87eeeff78db5ab21861b9c9b87dbe3362d5b4 Mon Sep 17 00:00:00 2001 From: William Panting Date: Wed, 29 Jan 2014 13:27:00 -0400 Subject: [PATCH 49/50] no longer used template removed --- theme/islandora-object-img-print.tpl.php | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 theme/islandora-object-img-print.tpl.php diff --git a/theme/islandora-object-img-print.tpl.php b/theme/islandora-object-img-print.tpl.php deleted file mode 100644 index 3ff21455..00000000 --- a/theme/islandora-object-img-print.tpl.php +++ /dev/null @@ -1,18 +0,0 @@ - - -
- -
- From 9fd2c718900496fbf7db8e41e88da7ab5d342c8f Mon Sep 17 00:00:00 2001 From: William Panting Date: Wed, 29 Jan 2014 13:50:51 -0400 Subject: [PATCH 50/50] better doc --- islandora.module | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/islandora.module b/islandora.module index 99a5740b..a2f2625e 100644 --- a/islandora.module +++ b/islandora.module @@ -1037,11 +1037,9 @@ function islandora_view_object(AbstractObject $object) { /** * This will prepare an object to be printed. * - * By default, all fedora objects can print DC record data, - * however, Solution packs that wish to modify the form - * to be printed must implement hook_islandora_view_print_object_alter, - * create a theme.tpl.php file, and return its markup by calling - * theme(themename.tpl.php). + * By default all fedora objects can print DC record data. Solution packs that + * wish to modify the data to be printed can implement + * hook_islandora_view_print_object or hook_islandora_metadata_display_info. * * @param AbstractObject $object * The object to print.