From e498db7988ccbe8430bc8436b4b8f80b9fbfe309 Mon Sep 17 00:00:00 2001 From: Daniel Aitken Date: Wed, 29 May 2013 10:25:51 -0300 Subject: [PATCH 01/44] additional functions for binary tests --- tests/islandora_web_test_case.inc | 53 +++++++++++++++++++------------ 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/tests/islandora_web_test_case.inc b/tests/islandora_web_test_case.inc index a5117695..51ffc7a3 100644 --- a/tests/islandora_web_test_case.inc +++ b/tests/islandora_web_test_case.inc @@ -128,27 +128,27 @@ class IslandoraWebTestCase extends DrupalWebTestCase { } /** - * Asserts that the given datastreams exist on the object. + * Asserts that the given datastreams exist correctly on the object. * * @param AbstractObject $object * The PID of the object * @param array $datastreams - * An array of strings containing datastream names + * An array of strings containing datastream names */ public function assertDatastreams($object, array $datastreams) { if (!is_object($object)) { - $this->fail("Failed. Object passed in is invalid."); - return; + $this->fail("Failed. Object passed in is invalid.", 'Islandora'); } foreach ($datastreams as $datastream) { if (isset($object[$datastream])) { - $this->pass("Loaded datastream {$datastream} from PID {$object->id}"); + $this->pass("Loaded datastream {$datastream} from PID {$object->id}.", 'Islandora'); } else { - $this->fail("Failed to load datastream {$datastream} from PID {$object->id}"); + $this->fail("Failed to load datastream {$datastream} from PID {$object->id}.", 'Islandora'); } } + } /** @@ -170,7 +170,7 @@ class IslandoraWebTestCase extends DrupalWebTestCase { } } } - $this->fail("Failed to parse path : $path."); + $this->fail("Failed to parse path: $path."); return FALSE; } @@ -181,15 +181,6 @@ class IslandoraWebTestCase extends DrupalWebTestCase { * The PID of the collection to be deleted */ public function deleteObject($pid) { - $current_user = $this->loggedInUser; - $user = $this->drupalCreateUser(array( - 'manage object properties', - 'delete fedora objects and datastreams', - 'view fedora repository objects', - )); - - $this->drupalLogin($user); - $path = 'islandora/object/' . $pid . '/manage/properties'; $edit = array(); $this->drupalPost($path, $edit, t('Delete')); @@ -198,12 +189,34 @@ class IslandoraWebTestCase extends DrupalWebTestCase { $this->drupalGet("islandora/object/$pid"); $this->assertResponse(404, "Object $pid successfully deleted."); + } - if ($current_user) { - $this->drupalLogin($current_user); + /** + * Reverses a hex string and converts it to a little-endian-formatted integer. + * + * This is useful for running checks on values that appear in the binary + * of a datastream. Returns FALSE if the hex value contains non-hex characters + * or if the string would not return a 16- or 32-bit formatted big-endian + * signed integer. + * + * @param string $hex + * The hex value being converted. + */ + public function convertHexToInt($hex) { + + // A couple of quick string checks. + if (!ctype_xdigit($hex)) { + $this->fail('String passed to convertHexToInt() contains non-hexidecimal characters.', 'PHP'); + return FALSE; } - else { - $this->drupalLogout(); + if (!strlen($hex) === 4 || !strlen($hex) === 8) { + $this->fail('String passed to convertHexToInt() cannot create a 16- or 32-bit little-endian signed integer', 'PHP'); + return FALSE; } + + // The actual conversion. + $reverse_hex = implode('', array_reverse(str_split($hex, 2))); + $int = hexdec($reverse_hex); + return $int; } } From fca27751947b087853293fdd1cde78c02122be84 Mon Sep 17 00:00:00 2001 From: daitken Date: Thu, 30 May 2013 11:33:01 -0300 Subject: [PATCH 02/44] fix for deleting objects with different button labels The Book Solution Pack's 'delete' button says 'Delete Book' rather than just 'Delete'; this allows the Book Solution Pack to use its own special label, as well as any other solution packs that might use different labels in the future. --- tests/islandora_web_test_case.inc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/islandora_web_test_case.inc b/tests/islandora_web_test_case.inc index 51ffc7a3..3ed18ab8 100644 --- a/tests/islandora_web_test_case.inc +++ b/tests/islandora_web_test_case.inc @@ -179,11 +179,13 @@ class IslandoraWebTestCase extends DrupalWebTestCase { * * @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) { + public function deleteObject($pid, $button='Delete') { $path = 'islandora/object/' . $pid . '/manage/properties'; $edit = array(); - $this->drupalPost($path, $edit, t('Delete')); + $this->drupalPost($path, $edit, $button); $this->drupalPost($this->url, $edit, t('Delete')); $object = islandora_object_load($pid); From 9af857bd542d5d8e3f31a7aa297c7423fd83c5d9 Mon Sep 17 00:00:00 2001 From: daitken Date: Thu, 6 Jun 2013 16:28:48 -0300 Subject: [PATCH 03/44] code cleanup --- 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 3ed18ab8..ef900ab9 100644 --- a/tests/islandora_web_test_case.inc +++ b/tests/islandora_web_test_case.inc @@ -182,7 +182,7 @@ class IslandoraWebTestCase extends DrupalWebTestCase { * @param string $button * The label of the first 'Delete' button */ - public function deleteObject($pid, $button='Delete') { + public function deleteObject($pid, $button = 'Delete') { $path = 'islandora/object/' . $pid . '/manage/properties'; $edit = array(); $this->drupalPost($path, $edit, $button); From 3a05e8a7183f47ae6c561288593e1fdd5d23d1df Mon Sep 17 00:00:00 2001 From: nruest Date: Fri, 28 Jun 2013 14:57:13 -0400 Subject: [PATCH 04/44] add dcterms --- includes/dublin_core.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/includes/dublin_core.inc b/includes/dublin_core.inc index 14d25392..ec058181 100644 --- a/includes/dublin_core.inc +++ b/includes/dublin_core.inc @@ -133,6 +133,7 @@ class DublinCore { $dc_array[$field]['label'] = $element_label; $dc_array[$field]['value'] = $value; $dc_array[$field]['class'] = drupal_strtolower(preg_replace('/[^A-Za-z0-9]/', '-', $field)); + $dc_array[$field]['dcterms'] = preg_replace('/^dc/', 'dcterms', $field); } } } From 7bdb11e355feee7aff0626f5f7ac404347ff7005 Mon Sep 17 00:00:00 2001 From: jonathangreen Date: Thu, 4 Jul 2013 10:48:40 -0300 Subject: [PATCH 05/44] Make travis test against 3.6.2 --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index adedf7b1..4498a8fa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ branches: - 7.x env: - FEDORA_VERSION="3.5" + - FEDORA_VERSION="3.6.2" before_install: - export ISLANDORA_DIR=$TRAVIS_BUILD_DIR - $TRAVIS_BUILD_DIR/tests/scripts/travis_setup.sh From 13967dd4a5439d2b4f567835bffee7615802a9d3 Mon Sep 17 00:00:00 2001 From: jonathangreen Date: Fri, 5 Jul 2013 16:28:19 -0300 Subject: [PATCH 06/44] Updated islandora to include datastream history page --- includes/add_datastream.form.inc | 2 +- includes/datastream.versions.inc | 42 +++++++++ islandora.module | 22 ++++- theme/theme.inc | 146 ++++++++++++++++++++----------- 4 files changed, 159 insertions(+), 53 deletions(-) create mode 100644 includes/datastream.versions.inc diff --git a/includes/add_datastream.form.inc b/includes/add_datastream.form.inc index 62490c9a..1ef1bb33 100644 --- a/includes/add_datastream.form.inc +++ b/includes/add_datastream.form.inc @@ -62,7 +62,7 @@ function islandora_add_datastream_form(array $form, array &$form_state, Abstract '#element_validate' => array('islandora_add_datastream_form_field_does_not_contain_a_forward_slash'), ), 'file' => array( - '#type' => 'managed_file', + '#type' => 'file', '#required' => TRUE, '#title' => t('Upload Document'), '#size' => 48, diff --git a/includes/datastream.versions.inc b/includes/datastream.versions.inc new file mode 100644 index 00000000..5c946aba --- /dev/null +++ b/includes/datastream.versions.inc @@ -0,0 +1,42 @@ +id Previous Versions"); + + $header = array(); + $header[] = array ('data' => 'Created Date'); + $header[] = array('data' => t('Size')); + $header[] = array('data' => t('Label')); + $header[] = array('data' => t('Mime type')); + $rows = array(); + + foreach ($datastream as $version => $datastream_version) { + $row = array(); + $row[] = array( + 'class' => 'datastream-date', + 'data' => theme('islandora_datastream_view_link', array( + 'datastream' => $datastream, + 'label' => $datastream_version->createdDate->format(DATE_RFC850), + 'version' => $version, + )), + ); + $row[] = array( + 'class' => 'datastream-size', + 'data' => islandora_datastream_get_human_readable_size($datastream_version), + ); + $row[] = array( + 'class' => 'datastream-label', + 'data' => $datastream_version->label, + ); + $row[] = array( + 'class' => 'datastream-mime', + 'data' => $datastream_version->mimeType, + ); + $rows[] = $row; + } + + return theme('table', array('header' => $header, 'rows' => $rows)); +} \ No newline at end of file diff --git a/islandora.module b/islandora.module index c579580c..ab79ca9e 100644 --- a/islandora.module +++ b/islandora.module @@ -33,6 +33,7 @@ define('FEDORA_ADD_DS', 'add fedora datastreams'); define('FEDORA_INGEST', 'ingest fedora objects'); define('FEDORA_PURGE', 'delete fedora objects and datastreams'); define('FEDORA_MANAGE_PROPERTIES', 'manage object properties'); +define('ISLANDORA_VIEW_DATASTREAM_HISTORY', 'view old datastream versions'); // Hooks. define('ISLANDORA_VIEW_HOOK', 'islandora_view_object'); @@ -233,6 +234,16 @@ function islandora_menu() { 'access arguments' => array(FEDORA_PURGE, 4), 'load arguments' => array(2), ); + $items['islandora/object/%islandora_object/datastream/%islandora_datastream/versions'] = array( + 'title' => 'Datastream Versions', + 'page arguments' => array(4), + 'page callback' => 'islandora_datastream_versions_table', + 'file' => 'includes/datastream.versions.inc', + 'type' => MENU_CALLBACK, + 'access callback' => 'islandora_datastream_access', + 'access arguments' => array(ISLANDORA_VIEW_DATASTREAM_HISTORY, 4), + 'load arguments' => array(2), + ); $items['islandora/object/%islandora_object/print'] = array( 'title' => 'Print Object', 'page callback' => 'islandora_print_object', @@ -270,6 +281,7 @@ function islandora_admin_paths() { $paths['islandora/object/*/manage*'] = TRUE; $paths['islandora/object/*/delete'] = TRUE; $paths['islandora/object/*/datastream/*/edit'] = TRUE; + $paths['islandora/object/*/datastream/*/versions'] = TRUE; return $paths; } @@ -333,12 +345,16 @@ function islandora_theme() { ), 'islandora_datastream_view_link' => array( 'file' => 'theme/theme.inc', - 'variables' => array('datastream' => NULL), + 'variables' => array('datastream' => NULL, 'version' => NULL, 'label' => NULL), ), 'islandora_datastream_download_link' => array( 'file' => 'theme/theme.inc', 'variables' => array('datastream' => NULL), ), + 'islandora_datastream_version_link' => array( + 'file' => 'theme/theme.inc', + 'variables' => array('datastream' => NULL), + ), ); } @@ -371,6 +387,10 @@ function islandora_permission() { 'title' => t('Manage object properties'), 'description' => t('Modify object labels, owner IDs, and states.'), ), + ISLANDORA_VIEW_DATASTREAM_HISTORY => array( + 'title' => t('View datastream history'), + 'description' => t('View all previous versions of a datastream.'), + ), ); } diff --git a/theme/theme.inc b/theme/theme.inc index f07f95d4..8964960c 100644 --- a/theme/theme.inc +++ b/theme/theme.inc @@ -15,59 +15,71 @@ function islandora_preprocess_islandora_default_edit(array &$variables) { $variables['islandora_editmetadata_url'] = $base_url . '/islandora/edit_form/' . $islandora_object->id; module_load_include('inc', 'islandora', 'includes/datastream'); module_load_include('inc', 'islandora', 'includes/utilities'); - $header = array( - array('data' => t('ID')), - array('data' => t('Label')), - array('data' => t('Type')), - array('data' => t('Mime type')), - array('data' => t('Size')), - array('data' => t('Operations'), 'colspan' => '3'), - ); + $header = array(); + $header[] = array('data' => t('ID')); + $header[] = array('data' => t('Label')); + $header[] = array('data' => t('Type')); + $header[] = array('data' => t('Mime type')); + $header[] = array('data' => t('Size')); + if (user_access(ISLANDORA_VIEW_DATASTREAM_HISTORY)) { + $header[] = array('data' => t('Versions')); + } + + $header[] = array('data' => t('Operations'), 'colspan' => '3'); + $table_attributes = array('class' => array('manage-datastreams')); $rows = array(); foreach ($islandora_object as $ds) { - $rows[] = array( - array( - 'class' => 'datastream-id', - 'data' => theme('islandora_datastream_view_link', array( - 'datastream' => $ds, - )), - ), - array( - 'class' => 'datastream-label', - 'data' => $ds->label, - ), - array( - 'class' => 'datastream-control', - 'data' => islandora_control_group_to_human_readable($ds->controlGroup), - ), - array( - 'class' => 'datastream-mime', - 'data' => $ds->mimeType, - ), - array( - 'class' => 'datastream-size', - 'data' => islandora_datastream_get_human_readable_size($ds), - ), - array( - 'class' => 'datastream-download', - 'data' => theme('islandora_datastream_download_link', array( - 'datastream' => $ds, - )), - ), - array( - 'class' => 'datstream-edit', - 'data' => theme('islandora_datastream_edit_link', array( - 'datastream' => $ds, - )), - ), - array( - 'class' => 'datastream-delete', - 'data' => theme('islandora_datastream_delete_link', array( + $row = array(); + $row[] = array( + 'class' => 'datastream-id', + 'data' => theme('islandora_datastream_view_link', array( + 'datastream' => $ds, + )), + ); + $row[] = array( + 'class' => 'datastream-label', + 'data' => $ds->label, + ); + $row[] = array( + 'class' => 'datastream-control', + 'data' => islandora_control_group_to_human_readable($ds->controlGroup), + ); + $row[] = array( + 'class' => 'datastream-mime', + 'data' => $ds->mimeType, + ); + $row[] = array( + 'class' => 'datastream-size', + 'data' => islandora_datastream_get_human_readable_size($ds), + ); + if (user_access(ISLANDORA_VIEW_DATASTREAM_HISTORY)) { + $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( + 'datastream' => $ds, + )), ); + $row[] = array( + 'class' => 'datstream-edit', + 'data' => theme('islandora_datastream_edit_link', array( + 'datastream' => $ds, + )), + ); + $row[] = array( + 'class' => 'datastream-delete', + 'data' => theme('islandora_datastream_delete_link', array( + 'datastream' => $ds, + )), + ); + $rows[] = $row; } $caption = $islandora_object->label . ' - ' . $islandora_object->id; $table = array( @@ -261,10 +273,28 @@ function theme_islandora_datastream_view_link(array $vars) { $datastream = $vars['datastream']; module_load_include('inc', 'islandora', 'includes/utilities'); - $label = check_plain($datastream->id); - return islandora_datastream_access(FEDORA_VIEW_OBJECTS, $datastream) ? - l($label, islandora_datastream_get_url($datastream, 'view')) : - $label; + if($vars['label'] === NULL) { + $label = check_plain($datastream->id); + } + else { + $label = check_plain($vars['label']); + } + + if($vars['version'] === NULL) { + $perm = FEDORA_VIEW_OBJECTS; + $query = array(); + } + else { + $perm = ISLANDORA_VIEW_DATASTREAM_HISTORY; + $query = array('version' => $vars['version']); + } + + if (islandora_datastream_access($perm, $datastream)) { + return l($label, islandora_datastream_get_url($datastream, 'view'), array('query' => $query)); + } + else { + return $label; + } } /** @@ -304,3 +334,17 @@ function theme_islandora_datastream_edit_link(array $vars) { l(t('edit'), "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/edit") : ''; } + +function theme_islandora_datastream_version_link(array $vars) { + $datastream = $vars['datastream']; + module_load_include('inc', 'islandora', 'includes/utilities'); + + $see_history = islandora_datastream_access(ISLANDORA_VIEW_DATASTREAM_HISTORY, $datastream); + + if($see_history) { + return l(count($datastream), "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/versions"); + } + else { + return ''; + } +} \ No newline at end of file From 69216abc810ad0eaf6f8f7f4797ebe07b56ad567 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Tue, 9 Jul 2013 16:21:21 +0000 Subject: [PATCH 07/44] Use renderable arrays instead of the array of strings we used to. ... Arrays of strings are still supported... Just not encouraged. --- includes/utilities.inc | 35 +++++++++++++++++++++++++++++++++++ islandora.module | 21 +++++++++++++++------ 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/includes/utilities.inc b/includes/utilities.inc index 66c03d26..29f450b1 100644 --- a/includes/utilities.inc +++ b/includes/utilities.inc @@ -865,3 +865,38 @@ function islandora_deprecated($release, $solution = NULL) { } return $message; } + +/** + * Transform recursively-merged array of strings to renderable arrays. + * + * Previously, functions/hooks like islandora_view_object would return an + * associative array with string values containing markup. These values were + * then imploded into one large piece of markup. Here, we transform this older + * structure which was generated into a renderable array, because renderable + * arrays are awesome! + * + * @param array $markup_array + * An associative array of which the values are either a string or an array + * of strings, which we transform to renderable markup elements (by + * reference). + */ +function islandora_array_of_markup_to_renderable_array(&$markup_array) { + foreach ($markup_array as &$value) { + if (!is_array($value)) { + $value = array( + '#markup' => $value, + ); + } + else { + foreach ($value as &$inner) { + if (!is_array($inner)) { + $inner = array( + '#markup' => $inner, + ); + } + } + unset($inner); + } + } + unset($value); +} diff --git a/islandora.module b/islandora.module index c579580c..8f552f37 100644 --- a/islandora.module +++ b/islandora.module @@ -624,6 +624,7 @@ function islandora_manage_overview_object(AbstractObject $object) { $output = array(); foreach (islandora_build_hook_list(ISLANDORA_OVERVIEW_HOOK, $object->models) as $hook) { $temp = module_invoke_all($hook, $object); + islandora_array_of_markup_to_renderable_array($temp); if (!empty($temp)) { $output = array_merge_recursive($output, $temp); } @@ -634,7 +635,7 @@ function islandora_manage_overview_object(AbstractObject $object) { } arsort($output); drupal_alter(ISLANDORA_OVERVIEW_HOOK, $object, $output); - return implode('', $output); + return $output; } /** @@ -649,7 +650,9 @@ function islandora_manage_overview_object(AbstractObject $object) { */ function islandora_default_islandora_manage_overview_object(AbstractObject $object) { $output = theme('islandora_default_overview', array('islandora_object' => $object)); - return array('Default overview output' => $output); + return array('Default overview output' => array( + '#markup' => $output, + )); } /** @@ -675,6 +678,7 @@ function islandora_edit_object(AbstractObject $object) { $output = array(); foreach (islandora_build_hook_list(ISLANDORA_EDIT_HOOK, $object->models) as $hook) { $temp = module_invoke_all($hook, $object); + islandora_array_of_markup_to_renderable_array($temp); if (!empty($temp)) { $output = array_merge_recursive($output, $temp); } @@ -685,7 +689,7 @@ function islandora_edit_object(AbstractObject $object) { } arsort($output); drupal_alter(ISLANDORA_EDIT_HOOK, $object, $output); - return implode('', $output); + return $output; } /** @@ -700,7 +704,9 @@ function islandora_edit_object(AbstractObject $object) { */ function islandora_default_islandora_edit_object(AbstractObject $object) { $output = theme('islandora_default_edit', array('islandora_object' => $object)); - return array('Default Edit output' => $output); + return array('Default Edit output' => array( + '#markup' => $output, + )); } /** @@ -743,6 +749,7 @@ function islandora_view_object(AbstractObject $object) { // @todo Remove page number and size from this hook, implementers of the // hook should use drupal page handling directly. $temp = module_invoke_all($hook, $object, $page_number, $page_size); + islandora_array_of_markup_to_renderable_array($temp); if (!empty($temp)) { $output = array_merge_recursive($output, $temp); } @@ -753,7 +760,7 @@ function islandora_view_object(AbstractObject $object) { } arsort($output); drupal_alter($hooks, $object, $output); - return implode('', $output); + return $output; } @@ -786,7 +793,9 @@ function islandora_drupal_title(AbstractObject $object) { */ function islandora_default_islandora_view_object($object) { $output = theme('islandora_default', array('islandora_object' => $object)); - return array('Default output' => $output); + return array('Default output' => array( + '#markup' => $output, + )); } /** From c5680fd1e062510a1619ed6d408113ba89351251 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Tue, 9 Jul 2013 17:43:45 +0000 Subject: [PATCH 08/44] Change function name and slightly safer logic. --- includes/utilities.inc | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/includes/utilities.inc b/includes/utilities.inc index 29f450b1..5ce2ca14 100644 --- a/includes/utilities.inc +++ b/includes/utilities.inc @@ -869,6 +869,8 @@ function islandora_deprecated($release, $solution = NULL) { /** * Transform recursively-merged array of strings to renderable arrays. * + * Renderable arrays are passed-through as-is. + * * Previously, functions/hooks like islandora_view_object would return an * associative array with string values containing markup. These values were * then imploded into one large piece of markup. Here, we transform this older @@ -880,16 +882,24 @@ function islandora_deprecated($release, $solution = NULL) { * of strings, which we transform to renderable markup elements (by * reference). */ -function islandora_array_of_markup_to_renderable_array(&$markup_array) { +function islandora_as_renderable_array(&$markup_array) { foreach ($markup_array as &$value) { if (!is_array($value)) { + // Not a renderable array, just a string. Let's convert it to a + // renderable '#markup' element. $value = array( '#markup' => $value, ); } - else { + elseif (!isset($value['#type']) && !isset($value['#markup'])) { + // A simple array--possibly the result of a recursive merge? Let's + // look at each, to possibly convert them to a renderable '#markup' + // elements. foreach ($value as &$inner) { if (!is_array($inner)) { + // If it is an array at this level, we can assume that it is a + // renderable array. If it is not an array, convert to a renderable + // '#markup' element. $inner = array( '#markup' => $inner, ); From e6fe09947806fb8c095b857dd747669bee73a628 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Tue, 9 Jul 2013 17:46:36 +0000 Subject: [PATCH 09/44] Carry through through the function rename. Also, be sure to call the transformer function after the alter, just in case a modules adds in another value in the manner it used to use 'em. --- islandora.module | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/islandora.module b/islandora.module index 8f552f37..574aef51 100644 --- a/islandora.module +++ b/islandora.module @@ -624,7 +624,7 @@ function islandora_manage_overview_object(AbstractObject $object) { $output = array(); foreach (islandora_build_hook_list(ISLANDORA_OVERVIEW_HOOK, $object->models) as $hook) { $temp = module_invoke_all($hook, $object); - islandora_array_of_markup_to_renderable_array($temp); + islandora_as_renderable_array($temp); if (!empty($temp)) { $output = array_merge_recursive($output, $temp); } @@ -635,6 +635,7 @@ function islandora_manage_overview_object(AbstractObject $object) { } arsort($output); drupal_alter(ISLANDORA_OVERVIEW_HOOK, $object, $output); + islandora_as_renderable_array($output); return $output; } @@ -678,7 +679,7 @@ function islandora_edit_object(AbstractObject $object) { $output = array(); foreach (islandora_build_hook_list(ISLANDORA_EDIT_HOOK, $object->models) as $hook) { $temp = module_invoke_all($hook, $object); - islandora_array_of_markup_to_renderable_array($temp); + islandora_as_renderable_array($temp); if (!empty($temp)) { $output = array_merge_recursive($output, $temp); } @@ -689,6 +690,7 @@ function islandora_edit_object(AbstractObject $object) { } arsort($output); drupal_alter(ISLANDORA_EDIT_HOOK, $object, $output); + islandora_as_renderable_array($output); return $output; } @@ -749,7 +751,7 @@ function islandora_view_object(AbstractObject $object) { // @todo Remove page number and size from this hook, implementers of the // hook should use drupal page handling directly. $temp = module_invoke_all($hook, $object, $page_number, $page_size); - islandora_array_of_markup_to_renderable_array($temp); + islandora_as_renderable_array($temp); if (!empty($temp)) { $output = array_merge_recursive($output, $temp); } @@ -760,6 +762,7 @@ function islandora_view_object(AbstractObject $object) { } arsort($output); drupal_alter($hooks, $object, $output); + islandora_as_renderable_array($output); return $output; } From cde90385b23c175a6c2fd6ba5b296971542b04be Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Tue, 9 Jul 2013 18:49:48 +0000 Subject: [PATCH 10/44] Fix code standard issues. --- islandora.module | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/islandora.module b/islandora.module index 574aef51..5b45fb1a 100644 --- a/islandora.module +++ b/islandora.module @@ -651,9 +651,11 @@ function islandora_manage_overview_object(AbstractObject $object) { */ function islandora_default_islandora_manage_overview_object(AbstractObject $object) { $output = theme('islandora_default_overview', array('islandora_object' => $object)); - return array('Default overview output' => array( - '#markup' => $output, - )); + return array( + 'Default overview output' => array( + '#markup' => $output, + ), + ); } /** @@ -706,9 +708,11 @@ function islandora_edit_object(AbstractObject $object) { */ function islandora_default_islandora_edit_object(AbstractObject $object) { $output = theme('islandora_default_edit', array('islandora_object' => $object)); - return array('Default Edit output' => array( - '#markup' => $output, - )); + return array( + 'Default Edit output' => array( + '#markup' => $output, + ), + ); } /** @@ -796,9 +800,11 @@ function islandora_drupal_title(AbstractObject $object) { */ function islandora_default_islandora_view_object($object) { $output = theme('islandora_default', array('islandora_object' => $object)); - return array('Default output' => array( - '#markup' => $output, - )); + return array( + 'Default output' => array( + '#markup' => $output, + ), + ); } /** From 2cdc264bdf081af0f2f1805123965d81447fa04e Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Wed, 17 Jul 2013 13:45:52 -0300 Subject: [PATCH 11/44] Run all 7.x branches through Travis. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4498a8fa..17a22707 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ php: - 5.4 branches: only: - - 7.x + - /^7.x/ env: - FEDORA_VERSION="3.5" - FEDORA_VERSION="3.6.2" From 4bcb99ddcbcc2e8a01db43bcf190142a1ba06953 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Wed, 17 Jul 2013 13:46:58 -0300 Subject: [PATCH 12/44] Use references when ingesting during steps. Makes the objects available to later submission handlers... Handling a weird case, yes... Need to trigger something only after ingest, but only when ingesting through the form. --- includes/ingest.form.inc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/includes/ingest.form.inc b/includes/ingest.form.inc index 00783934..6faa642c 100644 --- a/includes/ingest.form.inc +++ b/includes/ingest.form.inc @@ -703,7 +703,7 @@ function islandora_ingest_form_submit(array $form, array &$form_state) { islandora_ingest_form_execute_consecutive_callback_steps($form, $form_state, $step); } // Ingest the objects. - foreach ($form_state['islandora']['objects'] as $object) { + foreach ($form_state['islandora']['objects'] as &$object) { try { islandora_add_object($object); $form_state['redirect'] = "islandora/object/{$object->id}"; @@ -715,6 +715,9 @@ function islandora_ingest_form_submit(array $form, array &$form_state) { drupal_set_message(t('A problem occured while ingesting "@label" (ID: @pid), please notifiy the administrator.', array('@label' => $object->label, '@pid' => $object->id)), 'error'); } } + // XXX: Foreaching with references can be weird... The reference exists in + // the scope outside. + unset($object); } /** From 6cc205ec1a390b7eca63a6983778e2c8a9c21caa Mon Sep 17 00:00:00 2001 From: Nigel Banks Date: Mon, 22 Jul 2013 12:54:55 +0200 Subject: [PATCH 13/44] Attempt to normalize XML data-streams when comparing for equality. Used during solution install/reinstall to determine if changes have been made. Fedora selectively strips newline characters within actual content. Now we normalize the two data-streams such that all newlines are made spaces and any preceding/trailing white-space within the document is removed. For Issue: https://dgi.ontimenow.com/viewitem.aspx?id=1989&type=features&force_use_number=false --- includes/solution_packs.inc | 6 ++++++ xml/strip_newlines_and_whitespace.xsl | 13 +++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 xml/strip_newlines_and_whitespace.xsl diff --git a/includes/solution_packs.inc b/includes/solution_packs.inc index 26bd77b5..18169562 100644 --- a/includes/solution_packs.inc +++ b/includes/solution_packs.inc @@ -431,12 +431,18 @@ function islandora_check_object_status(AbstractObject $object_definition) { // we need to replace the info:fedora namespace, as C14N hates it. // C14N also doesn't normalize whitespace at the end of lines and Fedora // may add some whitespace on some lines. + $xsl = new DOMDocument(); + $xsl->load(drupal_get_path('module', 'islandora') . '/xml/strip_newlines_and_whitespace.xsl'); + $xslt = new XSLTProcessor(); + $xslt->importStyleSheet($xsl); $object_definition_dom = new DOMDocument(); $object_definition_dom->preserveWhiteSpace = FALSE; $object_definition_dom->loadXML(str_replace('info:', 'http://', $ds->content)); + $object_definition_dom = $xslt->transformToDoc($object_definition_dom); $object_actual_dom = new DOMDocument(); $object_actual_dom->preserveWhiteSpace = FALSE; $object_actual_dom->loadXML(str_replace('info:', 'http://', $existing_object[$ds->id]->content)); + $object_actual_dom = $xslt->transformToDoc($object_actual_dom); // Fedora changes the xml structure so we need to cannonize it. if ($object_actual_dom->C14N() != $object_definition_dom->C14N()) { diff --git a/xml/strip_newlines_and_whitespace.xsl b/xml/strip_newlines_and_whitespace.xsl new file mode 100644 index 00000000..4d4e1057 --- /dev/null +++ b/xml/strip_newlines_and_whitespace.xsl @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file From c21ec669f66ffe57dbfa7f0b45bb9780f3cd22f1 Mon Sep 17 00:00:00 2001 From: Nigel Banks Date: Tue, 23 Jul 2013 00:59:32 +0200 Subject: [PATCH 14/44] Updated comment --- includes/solution_packs.inc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/includes/solution_packs.inc b/includes/solution_packs.inc index 18169562..72749d0d 100644 --- a/includes/solution_packs.inc +++ b/includes/solution_packs.inc @@ -430,7 +430,9 @@ function islandora_check_object_status(AbstractObject $object_definition) { // be equal as Fedora does some XML mangling. In order for C14N to work // we need to replace the info:fedora namespace, as C14N hates it. // C14N also doesn't normalize whitespace at the end of lines and Fedora - // may add some whitespace on some lines. + // will sometimes replace new-lines with white-space. So first we strip + // leading/tailing white-space and replace all new-lines within the xml + // document to account for Fedora's weird formatting. $xsl = new DOMDocument(); $xsl->load(drupal_get_path('module', 'islandora') . '/xml/strip_newlines_and_whitespace.xsl'); $xslt = new XSLTProcessor(); From eeeb78f343c7e912c9769e419ec798afed22fa6d Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Thu, 25 Jul 2013 12:01:19 -0300 Subject: [PATCH 15/44] Codesniffer upgrade breaks on these two lines. --- includes/tuque_wrapper.inc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/includes/tuque_wrapper.inc b/includes/tuque_wrapper.inc index 8563070f..780622ee 100644 --- a/includes/tuque_wrapper.inc +++ b/includes/tuque_wrapper.inc @@ -269,6 +269,7 @@ class IslandoraFedoraApiM extends FedoraApiM { switch ($action) { case 'block': throw new Exception('Purge Datastream was blocked.'); + break; case 'delete': @@ -313,6 +314,7 @@ class IslandoraFedoraApiM extends FedoraApiM { switch ($action) { case 'block': throw new Exception('Purge object was blocked.'); + break; case 'delete': From 801573614909b7dc537853646fc165bd43848c20 Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Thu, 25 Jul 2013 12:06:27 -0300 Subject: [PATCH 16/44] Unneeded breaks around throws. --- includes/tuque_wrapper.inc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/includes/tuque_wrapper.inc b/includes/tuque_wrapper.inc index 780622ee..3c14b303 100644 --- a/includes/tuque_wrapper.inc +++ b/includes/tuque_wrapper.inc @@ -270,8 +270,6 @@ class IslandoraFedoraApiM extends FedoraApiM { case 'block': throw new Exception('Purge Datastream was blocked.'); - break; - case 'delete': $object[$dsid]->state = 'D'; return array(); @@ -315,8 +313,6 @@ class IslandoraFedoraApiM extends FedoraApiM { case 'block': throw new Exception('Purge object was blocked.'); - break; - case 'delete': $object->state = 'D'; return ''; From 21b38377e1b0e45b59b244f58d68ae37fb4bad9c Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Thu, 25 Jul 2013 14:18:43 -0300 Subject: [PATCH 17/44] Force update fix. --- tests/scripts/travis_setup.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/scripts/travis_setup.sh b/tests/scripts/travis_setup.sh index 45dc3ab9..2a3694e5 100755 --- a/tests/scripts/travis_setup.sh +++ b/tests/scripts/travis_setup.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash mysql -u root -e 'create database drupal;' mysql -u root -e "create database fedora;" @@ -11,8 +11,8 @@ cd islandora_tomcat export CATALINA_HOME='.' ./bin/startup.sh cd $HOME -pear upgrade –force Console_Getopt -pear upgrade –force pear +pear upgrade –-force Console_Getopt +pear upgrade –-force pear pear upgrade-all pear channel-discover pear.drush.org pear channel-discover pear.drush.org From 8c6f39bc0422313d612128d6e7c9658ba3108229 Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Thu, 25 Jul 2013 14:23:12 -0300 Subject: [PATCH 18/44] Dashes. --- tests/scripts/travis_setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/scripts/travis_setup.sh b/tests/scripts/travis_setup.sh index 2a3694e5..19c7db78 100755 --- a/tests/scripts/travis_setup.sh +++ b/tests/scripts/travis_setup.sh @@ -11,8 +11,8 @@ cd islandora_tomcat export CATALINA_HOME='.' ./bin/startup.sh cd $HOME -pear upgrade –-force Console_Getopt -pear upgrade –-force pear +pear upgrade --force Console_Getopt +pear upgrade --force pear pear upgrade-all pear channel-discover pear.drush.org pear channel-discover pear.drush.org From 01b282aaf9481cd1a2a0724cf460f4149852b08f Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Thu, 25 Jul 2013 17:43:26 +0000 Subject: [PATCH 19/44] Add test for altering new datastreams in new objects... ... Bit of additional whitespace for readability. --- tests/hooks.test | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/hooks.test b/tests/hooks.test index 3133d656..d08c537b 100644 --- a/tests/hooks.test +++ b/tests/hooks.test @@ -75,6 +75,8 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase { /** * Test ALL THE HOOKS!. + * + * Covers the majority of cases... */ public function testHooks() { // Test ingesting with FedoraRepository::ingestObject(). @@ -85,6 +87,7 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase { $this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_INGESTED_HOOK], 'Called "hook_islandora_object_alter" when ingesting via FedoraRepository::ingestObject.'); $this->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_INGESTED_HOOK], 'Called ISLANDORA_OBJECT_INGESTED_HOOK when ingesting via FedoraRepository::ingestObject.'); $this->repository->purgeObject($object->id); + // Test blocking the ingest. $object = $this->repository->constructObject('test:testIngestedObjectHook'); $object->label = 'block'; @@ -100,6 +103,7 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase { $this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_INGESTED_HOOK], 'Called "hook_islandora_object_alter" when blocking ingesting via FedoraRepository::ingestObject.'); $this->assertFalse($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_INGESTED_HOOK], 'Did not called ISLANDORA_OBJECT_INGESTED_HOOK when blocking ingesting via FedoraRepository::ingestObject.'); } + // Test modifying via set magic functions. $object = $this->repository->constructObject('test:testModifiedObjectHook'); $this->repository->ingestObject($object); @@ -108,6 +112,7 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase { $object->label = "New Label!"; $this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_MODIFIED_HOOK], 'Called "hook_islandora_object_alter" when modifying via set magic functions.'); $this->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_MODIFIED_HOOK], 'Called ISLANDORA_OBJECT_MODIFIED_HOOK when modifying via set magic functions.'); + // Test blocking the modification. try { $_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_MODIFIED_HOOK] = FALSE; @@ -122,6 +127,7 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase { $this->assertFALSE($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_MODIFIED_HOOK], 'Called ISLANDORA_OBJECT_MODIFIED_HOOK when blocking modifying via set magic functions.'); } $this->repository->purgeObject($object->id); + // Test purging with FedoraRepository::purgeObject(). $object = $this->repository->constructObject('test:testPurgedObjectHook'); $this->repository->ingestObject($object); @@ -130,6 +136,7 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase { $this->repository->purgeObject($object->id); $this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_PURGED_HOOK], 'Called "hook_islandora_object_alter" when purging via FedoraRepository::purgeObject.'); $this->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_PURGED_HOOK], 'Called ISLANDORA_OBJECT_PURGED_HOOK when purging via FedoraRepository::purgeObject.'); + // Test deleting. $object = $this->repository->constructObject('test:testPurgedObjectHook'); $this->repository->ingestObject($object); @@ -139,6 +146,7 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase { $this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_PURGED_HOOK], 'Called "hook_islandora_object_alter" when deleting via FedoraObject::delete.'); $this->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_PURGED_HOOK], 'Called ISLANDORA_OBJECT_PURGED_HOOK when purging via FedoraObject::delete.'); $this->repository->purgeObject($object->id); + // Test alter blocking. $object = $this->repository->constructObject('test:testPurgedObjectHook'); $this->repository->ingestObject($object); @@ -154,6 +162,7 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase { $this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_PURGED_HOOK], 'Called "hook_islandora_object_alter" when blocking purge via FedoraRepository::purgeObject.'); $this->assertFalse($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_PURGED_HOOK], 'Called ISLANDORA_OBJECT_PURGED_HOOK when blocking purge via FedoraRepository::purgeObject.'); } + // Test alter delete. $_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_PURGED_HOOK] = FALSE; $_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_PURGED_HOOK] = FALSE; @@ -164,6 +173,7 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase { $this->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_PURGED_HOOK], 'Called ISLANDORA_OBJECT_PURGED_HOOK when preventing purge and deleting.'); $object->label = 'Something other than delete'; $this->repository->purgeObject($object->id); + // Test ingesting with FedoraRepository::ingestObject(). $object = $this->repository->constructObject('test:testIngestedDatastreamHook'); $this->repository->ingestObject($object); @@ -174,6 +184,7 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase { $this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_DATASTREAM_INGESTED_HOOK], 'Called "hook_islandora_datastream_alter" when ingesting via FedoraObject::ingestDatastream.'); $this->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_INGESTED_HOOK], 'Called ISLANDORA_DATASTREAM_INGESTED_HOOK when ingesting via FedoraObject::ingestDatastream.'); $this->repository->purgeObject($object->id); + // Test modifying a datastream. $object = $this->repository->constructObject('test:testModifiedDatastreamHook'); $this->repository->ingestObject($object); @@ -184,6 +195,7 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase { $ds->label = "New Label!"; $this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_DATASTREAM_MODIFIED_HOOK], 'Called "hook_islandora_datastream_alter" when modifying via set magic functions.'); $this->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_MODIFIED_HOOK], 'Called ISLANDORA_DATASTREAM_MODIFIED_HOOK when modifying via set magic functions.'); + // Test blocking modifying. try { $_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_MODIFIED_HOOK] = FALSE; @@ -197,6 +209,7 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase { $this->assertFALSE($_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_MODIFIED_HOOK], 'Called ISLANDORA_DATASTREAM_MODIFIED_HOOK when blocking modifying via set magic functions.'); } $this->repository->purgeObject($object->id); + // Test purging with FedoraRepository::purgeObject(). $object = $this->repository->constructObject('test:testPurgedDatastreamHook'); $this->repository->ingestObject($object); @@ -210,4 +223,21 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase { $this->repository->purgeObject($object->id); } + /** + * Test ALL THE HOOKS!. + * + * Ensure hooks are triggered properly in "New" objects. + */ + public function testNewIngestHooks() { + // Test ingesting with FedoraRepository::ingestObject(). + $object = $this->repository->constructObject('test:testIngestedDatastreamHook'); + $ds = $object->constructDatastream('TEST'); + $_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_INGESTED_HOOK] = FALSE; + $_SESSION['islandora_hooks']['alter'][ISLANDORA_DATASTREAM_INGESTED_HOOK] = FALSE; + $object->ingestDatastream($ds); + $this->repository->ingestObject($object); + $this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_DATASTREAM_INGESTED_HOOK], 'Called "hook_islandora_datastream_alter" when ingesting via FedoraObject::ingestDatastream.'); + $this->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_INGESTED_HOOK], 'Called ISLANDORA_DATASTREAM_INGESTED_HOOK when ingesting via FedoraObject::ingestDatastream.'); + $this->repository->purgeObject($object->id); + } } From 7ad6efc7a096c34bdcac4a62dbc4f4f532825284 Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Thu, 25 Jul 2013 17:46:43 +0000 Subject: [PATCH 20/44] Trigger datastream alter on object ingest. --- includes/tuque_wrapper.inc | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/includes/tuque_wrapper.inc b/includes/tuque_wrapper.inc index 8563070f..9f1f8067 100644 --- a/includes/tuque_wrapper.inc +++ b/includes/tuque_wrapper.inc @@ -82,13 +82,26 @@ class IslandoraFedoraRepository extends FedoraRepository { * @see FedoraRepository::ingestObject() */ public function ingestObject(NewFedoraObject &$object) { - $context = array( - 'action' => 'ingest', - 'block' => FALSE, - ); - islandora_alter_object($object, $context); try { - if ($context['block']) { + foreach ($object as $dsid => $datastream) { + $datastream_context = array( + 'action' => 'ingest', + 'block' => FALSE, + ); + islandora_alter_datastream($object, $datastream, $datastream_context); + if ($datastream_context['block']) { + throw new Exception(t('Object ingest blocked due to ingest of @dsid being blocked.', array( + '@dsid' => $dsid, + ))); + } + } + + $object_context = array( + 'action' => 'ingest', + 'block' => FALSE, + ); + islandora_alter_object($object, $object_context); + if ($object_context['block']) { throw new Exception('Ingest Object was blocked.'); } $ret = parent::ingestObject($object); From cdacfc966da905de974d2304597ee501bd1bed3e Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Mon, 29 Jul 2013 11:53:02 +0000 Subject: [PATCH 21/44] Pull out acquisition of required objects, other generalization... ... introduction of "force" parameter, so reinstallation of objects can be forced to occur. --- includes/solution_packs.inc | 189 +++++++++++++++++++++++++++--------- 1 file changed, 143 insertions(+), 46 deletions(-) diff --git a/includes/solution_packs.inc b/includes/solution_packs.inc index 72749d0d..e1cf9493 100644 --- a/includes/solution_packs.inc +++ b/includes/solution_packs.inc @@ -5,11 +5,55 @@ * Admin and callback functions for solution pack management. */ +/** + * Get the information about required object. + * + * @param string $module + * An optional string, identifying a module for which to get the required + * object information. + * + * @return array + * An associative array of info describing the required objects. If $module + * is not provided (or is NULL), then we provide the info for all modules. If + * $module is provided and we have info for the given module, only the info + * for that module is provided. If $module is provided and we have no info + * for the given module, we throw an exception. + */ +function islandora_solution_packs_get_required_objects($module = NULL) { + // Should make this statically cache, after figuring out how exactly it + // should be called... We occasionally load a module and attempt to install + // it's object right away (in the same request)... This would require + // resetting of the cache. Let's just not cache for now... + $required_objects = array(); + + if (!$required_objects) { + $connection = islandora_get_tuque_connection(); + $required_objects = module_invoke_all('islandora_required_objects', $connection); + } + + if ($module !== NULL) { + if (isset($required_objects[$module])) { + return $required_objects[$module]; + } + else { + watchdog('islandora', 'Attempted to get required objects for %module... %module does not appear to have any required objects. Clear caches?', array( + '%module' => $module, + )); + throw new Exception(t('Module "@module" has no required objects!', array( + '@module' => $module, + ))); + } + } + else { + return $required_objects; + } +} + /** * Solution pack admin page callback. * - * @return string - * The html repersentation of all solution pack forms for required objects. + * @return array + * Renderable array of all solution pack forms for required objects. */ function islandora_solution_packs_admin() { module_load_include('inc', 'islandora', 'includes/utilities'); @@ -18,17 +62,15 @@ function islandora_solution_packs_admin() { return ''; } - $connection = islandora_get_tuque_connection(); drupal_add_css(drupal_get_path('module', 'islandora') . '/css/islandora.admin.css'); - $output = ''; - $enabled_solution_packs = module_invoke_all('islandora_required_objects', $connection); + $output = array(); + $enabled_solution_packs = islandora_solution_packs_get_required_objects(); foreach ($enabled_solution_packs as $solution_pack_module => $solution_pack_info) { // @todo We should probably get the title of the solution pack from the // systems table for consistency in the interface. $solution_pack_name = $solution_pack_info['title']; $objects = array_filter($solution_pack_info['objects']); - $form = drupal_get_form('islandora_solution_pack_form_' . $solution_pack_module, $solution_pack_module, $solution_pack_name, $objects); - $output .= drupal_render($form); + $output[$solution_pack_module] = drupal_get_form('islandora_solution_pack_form_' . $solution_pack_module, $solution_pack_module, $solution_pack_name, $objects); } return $output; } @@ -161,20 +203,38 @@ function islandora_solution_pack_form(array $form, array &$form_state, $solution */ function islandora_solution_pack_form_submit(array $form, array &$form_state) { $solution_pack_module = $form_state['values']['solution_pack_module']; - $objects = $form_state['values']['objects']; + + $batch = islandora_solution_pack_get_batch($solution_pack_module); + batch_set($batch); + // Hook to let solution pack objects be modified. + // Not using module_invoke so solution packs can be expanded by other modules. + // @todo shouldn't we send the object list along as well? + module_invoke_all('islandora_postprocess_solution_pack', $solution_pack_module); +} + +/** + * Get the batch definition to reinstall all the objects for a given module. + * + * @param string $module + * The name of the modules of which to grab the required objects for to setup + * the batch. + * + * @return array + * An array defining a batch which can be passed on to batch_set(). + */ +function islandora_solution_pack_get_batch($module) { $batch = array( 'title' => t('Installing / Updating solution pack objects'), 'file' => drupal_get_path('module', 'islandora') . '/includes/solution_packs.inc', 'operations' => array(), ); - foreach ($objects as $object) { + + $info = islandora_solution_packs_get_required_objects($module); + foreach ($info['objects'] as $object) { $batch['operations'][] = array('islandora_solution_pack_batch_operation_reingest_object', array($object)); } - batch_set($batch); - // Hook to let solution pack objects be modified. - // Not using module_invoke so solution packs can be expanded by other modules. - // @todo shouldn't we send the object list along as well? - module_invoke_all('islandora_postprocess_solution_pack', $solution_pack_module); + + return $batch; } /** @@ -245,14 +305,16 @@ function islandora_solution_pack_batch_operation_reingest_object(AbstractObject * install/unistall hooks. * @param string $op * The operation to perform, either install or uninstall. + * @param bool $force + * Force the (un)installation of object. * * @todo Implement hook_modules_installed/hook_modules_uninstalled instead of * calling this function directly. * @todo Remove the second parameter and have two seperate functions. */ -function islandora_install_solution_pack($module, $op = 'install') { +function islandora_install_solution_pack($module, $op = 'install', $force = FALSE) { if ($op == 'uninstall') { - islandora_uninstall_solution_pack($module); + islandora_uninstall_solution_pack($module, $force); return; } @@ -267,9 +329,9 @@ function islandora_install_solution_pack($module, $op = 'install') { '!admin_link' => $admin_link, ); - module_load_include('module', 'islandora', 'islandora'); + drupal_load('module', 'islandora'); module_load_include('inc', 'islandora', 'includes/utilities'); - module_load_include('module', $module, $module); + drupal_load('module', $module); $info_file = drupal_get_path('module', $module) . "/{$module}.info"; $info_array = drupal_parse_info_file($info_file); $module_name = $info_array['name']; @@ -279,8 +341,8 @@ function islandora_install_solution_pack($module, $op = 'install') { return; } $connection = islandora_get_tuque_connection(); - $required_objects = module_invoke($module, 'islandora_required_objects', $connection); - $objects = $required_objects[$module]['objects']; + $required_objects = islandora_solution_packs_get_required_objects($module); + $objects = $required_objects['objects']; $status_messages = array( 'up_to_date' => $t('The object already exists and is up-to-date.', $t_params), 'missing_datastream' => $t('The object already exists but is missing a datastream. Please reinstall the object on the !admin_link page.', $t_params), @@ -288,26 +350,41 @@ function islandora_install_solution_pack($module, $op = 'install') { 'modified_datastream' => $t('The object already exists but datastreams are modified. Please reinstall the object on the !admin_link page.', $t_params), ); foreach ($objects as $object) { - $query = $connection->api->a->findObjects('query', 'pid=' . $object->id); - $already_exists = !empty($query['results']); + $already_exists = islandora_object_load($object->id); + $label = $object->label; $object_link = l($label, "islandora/object/{$object->id}"); + $deleted = FALSE; if ($already_exists) { - $object_status = islandora_check_object_status($object); - $here_params = array( - '!summary' => $t("@module: Did not install !object_link.", array( - '!object_link' => $object_link, - ) + $t_params), - '!description' => $status_messages[$object_status['status']], - ); - drupal_set_message(filter_xss(format_string('!summary !description', $here_params)), 'warning'); + if (!$force) { + $object_status = islandora_check_object_status($object); + $here_params = array( + '!summary' => $t("@module: Did not install !object_link.", array( + '!object_link' => $object_link, + ) + $t_params), + '!description' => $status_messages[$object_status['status']], + ); + drupal_set_message(filter_xss(format_string('!summary !description', $here_params)), 'warning'); + continue; + } + else { + $deleted = islandora_delete_object($already_exists); + } } - else { + + if ($already_exists && $deleted || !$already_exists) { $object = islandora_add_object($object); if ($object) { - drupal_set_message(filter_xss($t('@module: Successfully installed. !object_link.', array( - '!object_link' => $object_link, - ) + $t_params)), 'status'); + if ($deleted) { + drupal_set_message(filter_xss($t('@module: Successfully reinstalled. !object_link.', array( + '!object_link' => $object_link, + ) + $t_params)), 'status'); + } + else { + drupal_set_message(filter_xss($t('@module: Successfully installed. !object_link.', array( + '!object_link' => $object_link, + ) + $t_params)), 'status'); + } } else { drupal_set_message($t('@module: Failed to install. @label.', array( @@ -315,6 +392,11 @@ function islandora_install_solution_pack($module, $op = 'install') { ) + $t_params), 'warning'); } } + else { + drupal_set_message($t('@module: "@label" already exists and failed to be deleted.', array( + '@label' => $label, + ) + $t_params), 'warning'); + } } } @@ -323,15 +405,17 @@ function islandora_install_solution_pack($module, $op = 'install') { * * @param string $module * The solution pack to uninstall. + * @param bool $force + * Force the objects to be removed. * * @todo Implement hook_modules_uninstalled instead of calling this function * directly for each solution pack. */ -function islandora_uninstall_solution_pack($module) { +function islandora_uninstall_solution_pack($module, $force = FALSE) { $t = get_t(); - module_load_include('module', 'islandora', 'islandora'); + drupal_load('module', 'islandora'); module_load_include('inc', 'islandora', 'includes/utilities'); - module_load_include('module', $module, $module); + drupal_load('module', $module); $config_link = l($t('Islandora configuration'), 'admin/islandora/configure'); $info_file = drupal_get_path('module', $module) . "/{$module}.info"; $info_array = drupal_parse_info_file($info_file); @@ -345,22 +429,35 @@ function islandora_uninstall_solution_pack($module) { return; } $connection = islandora_get_tuque_connection(); - $required_objects = module_invoke($module, 'islandora_required_objects', $connection); - $objects = $required_objects[$module]['objects']; + $required_objects = islandora_solution_packs_get_required_objects($module); + $objects = $required_objects['objects']; $filter = function($o) use($connection) { $param = "pid={$o->id}"; $query = $connection->api->a->findObjects('query', $param); return !empty($query['results']); }; $existing_objects = array_filter($objects, $filter); - foreach ($existing_objects as $object) { - $object_link = l($object->label, "islandora/object/{$object->id}"); - $msg = $t('@module: Did not remove !object_link. It may be used by other sites.', array( - '!object_link' => $object_link, - '@module' => $module_name, - )); - drupal_set_message(filter_xss($msg), 'warning'); + if (!$force) { + foreach ($existing_objects as $object) { + $object_link = l($object->label, "islandora/object/{$object->id}"); + $msg = $t('@module: Did not remove !object_link. It may be used by other sites.', array( + '!object_link' => $object_link, + '@module' => $module_name, + )); + + drupal_set_message(filter_xss($msg), 'warning'); + } + } + else { + foreach ($existing_objects as $object) { + $params = array( + '@id' => $object->id, + '@module' => $module_name, + ); + islandora_delete_object($object); + drupal_set_message($t('@module: Deleted @id.', $params)); + } } } From 60682ad96bdd93e33a2e80b0e2afd63c38e0d52c Mon Sep 17 00:00:00 2001 From: Adam Vessey Date: Mon, 29 Jul 2013 11:54:04 +0000 Subject: [PATCH 22/44] Add Drush commands. --- islandora.drush.inc | 142 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 islandora.drush.inc diff --git a/islandora.drush.inc b/islandora.drush.inc new file mode 100644 index 00000000..b2e75c47 --- /dev/null +++ b/islandora.drush.inc @@ -0,0 +1,142 @@ + dt('Install Solution Pack objects.'), + 'options' => array( + 'module' => array( + 'description' => dt('The module for which to install the required objects.'), + 'required' => TRUE, + ), + 'force' => array( + 'description' => dt('Force reinstallation of the objects.'), + ), + ), + 'aliases' => array('ispiro'), + 'drupal dependencies' => array( + 'islandora', + ), + 'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_LOGIN, + ); + $commands['islandora-solution-pack-uninstall-required-objects'] = array( + 'description' => dt('Uninstall Solution Pack objects.'), + 'options' => array( + 'module' => array( + 'description' => dt('The module for which to uninstall the required objects.'), + 'required' => TRUE, + ), + 'force' => array( + 'description' => dt('Force reinstallation of the objects.'), + ), + ), + 'aliases' => array('ispuro'), + 'drupal dependencies' => array( + 'islandora', + ), + 'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_LOGIN, + ); + $commands['islandora-solution-pack-required-objects-status'] = array( + 'description' => dt('Get Solution Pack object status.'), + 'options' => array( + 'module' => array( + 'description' => dt('The module for which to get the status of the required objects.'), + ), + ), + 'aliases' => array('ispros'), + 'drupal dependencies' => array( + 'islandora', + ), + 'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_LOGIN, + ); + + return $commands; +} + +/** + * Command callback to install required objects. + */ +function drush_islandora_solution_pack_install_required_objects() { + module_load_include('inc', 'islandora', 'includes/solution_packs'); + + $module = drush_get_option('module'); + if (module_exists($module)) { + islandora_install_solution_pack( + $module, + 'install', + drush_get_option('force', FALSE) + ); + } + else { + drush_log(dt('"@module" is not installed/enabled?...', array( + '@module' => $module, + ))); + } +} + +/** + * Command callback to uninstall required objects. + */ +function drush_islandora_solution_pack_uninstall_required_objects() { + module_load_include('inc', 'islandora', 'includes/solution_packs'); + + $module = drush_get_option('module'); + if (module_exists($module)) { + islandora_uninstall_solution_pack( + $module, + drush_get_option('force', FALSE) + ); + } + else { + drush_log(dt('"@module" is not installed/enabled?...', array( + '@module' => $module, + ))); + } +} + +/** + * Command callback for object status. + */ +function drush_islandora_solution_pack_required_objects_status() { + module_load_include('inc', 'islandora', 'includes/solution_packs'); + + $module = drush_get_option('module', FALSE); + $required_objects = array(); + if ($module && module_exists($module)) { + $required_objects[$module] = islandora_solution_packs_get_required_objects($module); + } + elseif ($module === FALSE) { + $required_objects = islandora_solution_packs_get_required_objects(); + } + else { + drush_log(dt('"@module" is not installed/enabled?...', array( + '@module' => $module, + ))); + return; + } + + $header = array('PID', 'Machine Status', 'Readable Status'); + $widths = array(30, 20, 20); + foreach ($required_objects as $module => $info) { + $rows = array(); + drush_print($info['title']); + foreach ($info['objects'] as $object) { + $status = islandora_check_object_status($object); + $rows[] = array( + $object->id, + $status['status'], + $status['status_friendly'], + ); + } + drush_print_table($rows, $header, $widths); + } +} From 4c16e6af1dcba68d8edd2f56cbb5f9a808934f57 Mon Sep 17 00:00:00 2001 From: MorganDawe Date: Tue, 30 Jul 2013 13:57:00 -0300 Subject: [PATCH 23/44] Added the ability to print dc info and images for basic image, large image and pdf solution packs. --- css/islandora.print.css | 72 ++++++++++++ images/print-icon.png | Bin 0 -> 1510 bytes includes/solution_packs.inc | 4 +- islandora.api.php | 10 ++ islandora.module | 135 ++++++++++++++++++++++- js/add_print.js | 18 +++ theme/islandora-object-img-print.tpl.php | 18 +++ theme/islandora-object-print.tpl.php | 30 +++++ theme/islandora-object.tpl.php | 1 + theme/theme.inc | 1 + 10 files changed, 286 insertions(+), 3 deletions(-) create mode 100644 css/islandora.print.css create mode 100644 images/print-icon.png create mode 100644 js/add_print.js create mode 100644 theme/islandora-object-img-print.tpl.php create mode 100644 theme/islandora-object-print.tpl.php diff --git a/css/islandora.print.css b/css/islandora.print.css new file mode 100644 index 00000000..d54bb366 --- /dev/null +++ b/css/islandora.print.css @@ -0,0 +1,72 @@ +/** + * @file + * Print styling + * + * We provide some sane print styling for Drupal using Zen's layout method. + */ +a:link, +a:visited { /* underline all links */ + text-decoration: underline !important; +} + +#site-name a:link, +#site-name a:visited { /* Don't underline header */ + text-decoration: none !important; +} + +#content a[href^="javascript:"]:after, +#content a[href^="#"]:after { /* Only display useful links. */ +/* content: ""; */ +} + +#content abbr[title]:after { /* Add visible title after abbreviations. */ +/* content: " (" attr(title) ")"; */ +} + +#content { + left: 0 !important; + width: 100% !important; +} +uncomment when ready to test printing +#header { + display: none !important; +} + +#content { /* Un-float the content */ + float: none !important; + width: 100% !important; + margin: 0 !important; + padding: 0 !important; +} + +body, +#page, +#main, +#content { /* Turn off any background colors or images */ + color: #000; + background-color: transparent !important; + background-image: none !important; +} + +body.sidebar-first { + left: 0 !important; + width: 100% !important; +} +#skip-link, +#toolbar, +#navigation, +/* .region-sidebar-first, */ +/* .region-sidebar-second, */ +#header, +#footer, +.breadcrumb, +.tabs, +.action-links, +.links, +.book-navigation, +.forum-topic-navigation, +.pager, +.feed-icons { /* Hide sidebars and nav elements */ + visibility: hidden !important; + display: none !important; +} \ No newline at end of file diff --git a/images/print-icon.png b/images/print-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5f5a3b3c95faa1333c9f77f467e136093213cbbd GIT binary patch literal 1510 zcmV5dF;5HnHP8~zkFoB^6K1!iTL0%H)G`Pk`j8ivIL3tFJ zh&Tlq3?C#Kl+J8QMW73ji3`(g4iXduQA*$4y|=ScmqEXFCu!2O_n!Ov&iS8n?nl8S zR$YBA?%~5fa!n?aezLW;MzLqj@;<(P{rd6=S54+dE@0}LU6 zsZIk(r5M0qcLcDp+3f!lV3V(2PY;00<-+mf#Y0(HP6Ei~Wjzu}lCQx)4}j0-BY+YF zknSA7sWSO}afXeM8toL|OJg%w(Es?caR6MDn}a>sLY4^(CbOBx<8?3?j4u-s5{9e*wY9bWeSLlR zA|oTg$H#{_xb*WcAUoF#esku4R-0w9q{ z6pI!ug0ZnNvVhO$LS0iURCb~WeC8ZLON$EpOd8lBj+3B5=%ZM$V1adk z8=nWYNCV}{9tdBt7*&DRK@G5>y`u}>mM z@KS679tXZxv_YYw3xYxdL9cVP3Ruv6?{`@2!Gqj{2pAb1v!0!oN8GI7H(qg@$uK^&YeplfDdFgOC;-Q95Y>eV$=T3VXl%9Sg-u?W#5B!A)($21z6)&I zww25SIuJO5Umwat5Ah6@-wTkYq`;EUP}Eb#NEu=cw6wH@kmQz@mTJPo!?`%*_@h)R zp}edN1g-)Q2!v31x`MP(IsiD#5=ja?8y+P6C4SvHcsXy-IEKrYFGG5IxF@6+ zJ;2M$>(w~MmY<(5m^pLiesUo}Hf`E8LvwTU+r5AFd7Z01OY}kaN+uE|f(xHBxGE~@ zx8b27Cc4&<3klMcEHyRtDS@5HN$l#?+qpc!Ashjnj-CdvmJ$<_k?>wrRM(uB{AaW# zaTA*%XaQLvj4!|trJFTGDkAm-i`bA?W(f- z t('Object status: !image !status', array( '!image' => $solution_pack_status_info['image'], '!status' => $solution_pack_status_info['solution_pack'], - )), + )), '#prefix' => '
', '#suffix' => '
', ), @@ -623,7 +623,7 @@ function theme_islandora_viewers_table($variables) { 'header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'islandora-viewers-table'), - )); + )); $output .= drupal_render_children($form); return $output; } diff --git a/islandora.api.php b/islandora.api.php index 129787f4..80accfde 100644 --- a/islandora.api.php +++ b/islandora.api.php @@ -23,6 +23,16 @@ function hook_islandora_view_object($object, $user, $page_number, $page_size) { } +/** + * An alter hook to print friendly page for the given object. + * + * @param object $object + * The object form to print. + * @param string $output + * The object form to print + */ +function hook_islandora_view_print_object_alter($object, &$output) { +} /** * Generate an object's display for the given content model. * diff --git a/islandora.module b/islandora.module index 5b45fb1a..b295b7ea 100644 --- a/islandora.module +++ b/islandora.module @@ -36,6 +36,7 @@ define('FEDORA_MANAGE_PROPERTIES', 'manage object properties'); // Hooks. define('ISLANDORA_VIEW_HOOK', 'islandora_view_object'); +define('ISLANDORA_PRINT_HOOK', 'islandora_view_print_object'); define('ISLANDORA_EDIT_HOOK', 'islandora_edit_object'); define('ISLANDORA_OVERVIEW_HOOK', 'islandora_overview_object'); define('ISLANDORA_PRE_INGEST_HOOK', 'islandora_ingest_pre_ingest'); @@ -102,6 +103,13 @@ function islandora_menu() { 'access callback' => 'islandora_object_access_callback', 'access arguments' => array(FEDORA_VIEW_OBJECTS, 2), ); + $items['islandora/print/%islandora_object'] = array( + 'page callback' => 'islandora_printer_object', + 'page arguments' => array(2), + 'type' => MENU_NORMAL_ITEM, + 'access callback' => 'islandora_object_access_callback', + 'access arguments' => array(FEDORA_VIEW_OBJECTS, 2), + ); $items['islandora/object/%islandora_object/view'] = array( 'title' => 'View', 'type' => MENU_DEFAULT_LOCAL_TASK, @@ -289,6 +297,12 @@ function islandora_theme() { 'file' => 'theme/theme.inc', 'template' => 'theme/islandora-object-edit', 'variables' => array('islandora_object' => NULL), + ), + // Default edit page. + 'islandora_default_print' => array( + 'file' => 'theme/theme.inc', + 'template' => 'theme/islandora-object-print', + 'variables' => array('islandora_object' => NULL), ), // Admin table for solution pack viewer selection. 'islandora_viewers_table' => array( @@ -298,7 +312,11 @@ function islandora_theme() { // Print object view. 'islandora_object_print' => array( 'file' => 'theme/theme.inc', - 'variables' => array('object' => NULL, 'content' => array()), + 'template' => 'theme/islandora-object-print', + 'variables' => array( + 'object' => NULL, + 'content' => NULL, + 'islandora_content' => NULL), ), // Render a bunch of objects as either a grid or a list. 'islandora_objects' => array( @@ -744,8 +762,20 @@ function islandora_view_default_object() { function islandora_view_object(AbstractObject $object) { module_load_include('inc', 'islandora', 'includes/breadcrumb'); module_load_include('inc', 'islandora', 'includes/utilities'); + + // Add the print button via JavaScript. + $path = drupal_get_path('module', 'islandora'); + drupal_add_js(array( + 'islandora' => array( + 'print_img' => $path . '/images/print-icon.png'), + ), array('type' => 'setting')); + + drupal_add_js(array('islandora' => array('print_link' => '/islandora/print/' . $object->id)), array('type' => 'setting')); + drupal_add_js($path . '/js/add_print.js'); + drupal_set_title($object->label); drupal_set_breadcrumb(islandora_get_breadcrumbs($object)); + // Optional pager parameters. $page_number = (empty($_GET['page'])) ? '1' : $_GET['page']; $page_size = (empty($_GET['pagesize'])) ? '10' : $_GET['pagesize']; @@ -764,12 +794,73 @@ function islandora_view_object(AbstractObject $object) { // No results, use the default view. $output = islandora_default_islandora_view_object($object); } + arsort($output); drupal_alter($hooks, $object, $output); islandora_as_renderable_array($output); return $output; } +/** + * 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). + * + * @param AbstractObject $object + * The object to print. + * + * @return string + * An HTML representation of this object. + */ +function islandora_printer_object(AbstractObject $object) { + + $output = array(); + $output = NULL; + $islandora_object = islandora_object_load($object->id); + $obj_pid = urldecode($object->id); + $resource_url = ''; + + // Check for a valid image/pdf/large image cmodel + // TODO: More preprocessing on large image and pdf to optimize view. + if (in_array('islandora:sp_basic_image', $islandora_object->models)) { + $resource_url = url("islandora/object/{$obj_pid}/datastream/OBJ/view"); + } + elseif (in_array('islandora:sp_large_image_cmodel', $islandora_object->models)) { + $resource_url = url("islandora/object/{$obj_pid}/datastream/JPG/view"); + } + elseif (in_array('islandora:sp_pdf', $islandora_object->models)) { + // Check for higher quality data stream if available. + $dsid = isset($obj['HQ_JPG']) ? 'HQ_JPG' : 'PREVIEW'; + $resource_url = url("islandora/object/{$obj_pid}/datastream/{$dsid}/view"); + } + + $params = array( + 'title' => $islandora_object->label, + 'path' => $resource_url, + ); + // Theme the image seperatly. + $variables['islandora_img'] = theme('image', $params); + $output = islandora_default_islandora_printer_object($object, $variables['islandora_img']); + + // Dispatch print hook. + foreach (islandora_build_hook_list(ISLANDORA_PRINT_HOOK, $object->models) as $hook) { + $temp = module_invoke_all($hook, $output); + islandora_as_renderable_array($temp); + if (!empty($temp)) { + $output = array_merge_recursive($output, $temp); + } + } + + arsort($output); + drupal_alter(ISLANDORA_PRINT_HOOK, $object, $output); + islandora_as_renderable_array($output); + + return $output; +} /** * Title callback for drupal title. @@ -807,6 +898,48 @@ function islandora_default_islandora_view_object($object) { ); } +/** + * Append the image alter to the printable form. + * + * @param AbstractObject $object + * The fedora object to print. + * @param unknown $alter + * The string representation of the themed viewable object. + * + * @return array + * A renderable array + */ +function islandora_default_islandora_printer_object($object, $alter) { + module_load_include('inc', 'islandora', 'includes/utilities'); + module_load_include('inc', 'islandora', 'includes/datastream'); + + $path = drupal_get_path('module', 'islandora'); + drupal_add_css($path . '/css/islandora.print.css'); + + $islandora_object = islandora_object_load($object->id); + $repository = $islandora_object->repository; + + try { + $dc = $islandora_object['DC']->content; + $dc_object = DublinCore::importFromXMLString($dc); + } + catch (Exception $e) { + drupal_set_message(t('Error retrieving object %s %t', array('%s' => $islandora_object->id, '%t' => $e->getMessage())), 'error', FALSE); + } + + $variables = isset($dc_object) ? $dc_object->asArray() : array(); + $output = theme('islandora_object_print', array( + 'object' => $object, + 'dc_array' => $variables, + 'islandora_content' => $alter)); + + return array( + 'Default output' => array( + '#markup' => $output, + ), + ); +} + /** * Just a wrapper around fetchings the IslandoraTuque object. * diff --git a/js/add_print.js b/js/add_print.js new file mode 100644 index 00000000..7af5c3ca --- /dev/null +++ b/js/add_print.js @@ -0,0 +1,18 @@ +/** + * @file +* JavaScript file responsable for the print button behaviour. +* +* The print button is added automatically to every view, as metadata +* can be printed from every object. +* +*/ +(function ($) { + $(document).ready(function() { + $('.tabs .primary').append(''); + $('#print_btn').css("cursor","pointer"); + $('#print_btn').click(function() { + window.location=Drupal.settings.islandora.print_link; + }); + }); +})(jQuery); + diff --git a/theme/islandora-object-img-print.tpl.php b/theme/islandora-object-img-print.tpl.php new file mode 100644 index 00000000..2c79a88e --- /dev/null +++ b/theme/islandora-object-img-print.tpl.php @@ -0,0 +1,18 @@ + + +
+ +
+ \ No newline at end of file diff --git a/theme/islandora-object-print.tpl.php b/theme/islandora-object-print.tpl.php new file mode 100644 index 00000000..3e6243bc --- /dev/null +++ b/theme/islandora-object-print.tpl.php @@ -0,0 +1,30 @@ + +
+
+ +
+ +
\ No newline at end of file diff --git a/theme/islandora-object.tpl.php b/theme/islandora-object.tpl.php index 13b40ba0..6fa306c3 100644 --- a/theme/islandora-object.tpl.php +++ b/theme/islandora-object.tpl.php @@ -60,6 +60,7 @@ ?>

+
diff --git a/theme/theme.inc b/theme/theme.inc index f07f95d4..51cc3bee 100644 --- a/theme/theme.inc +++ b/theme/theme.inc @@ -165,6 +165,7 @@ function islandora_preprocess_islandora_object_print(array &$variables) { * Implements theme_hook(). */ function theme_islandora_object_print(array &$variables) { + dsm(array('obj_print' => 'obj_in_print')); return drupal_render($variables['content']); } From 735bc3bce9b611fdbc81569c7d58567742f39809 Mon Sep 17 00:00:00 2001 From: MorganDawe Date: Tue, 30 Jul 2013 14:04:47 -0300 Subject: [PATCH 24/44] Removed leftover dsm call. --- theme/theme.inc | 1 - 1 file changed, 1 deletion(-) diff --git a/theme/theme.inc b/theme/theme.inc index 51cc3bee..f07f95d4 100644 --- a/theme/theme.inc +++ b/theme/theme.inc @@ -165,7 +165,6 @@ function islandora_preprocess_islandora_object_print(array &$variables) { * Implements theme_hook(). */ function theme_islandora_object_print(array &$variables) { - dsm(array('obj_print' => 'obj_in_print')); return drupal_render($variables['content']); } From 7a2984bb77bb5dc48c17cd82886c1174b1c09f27 Mon Sep 17 00:00:00 2001 From: MorganDawe Date: Tue, 30 Jul 2013 16:05:10 -0300 Subject: [PATCH 25/44] Removed the alter hook, and implemented a generic printer hook to move more printer functionality to the solution packs. --- islandora.api.php | 5 +---- islandora.module | 54 ++++++++++------------------------------------- 2 files changed, 12 insertions(+), 47 deletions(-) diff --git a/islandora.api.php b/islandora.api.php index 80accfde..d026dd11 100644 --- a/islandora.api.php +++ b/islandora.api.php @@ -22,16 +22,13 @@ */ function hook_islandora_view_object($object, $user, $page_number, $page_size) { } - /** * An alter hook to print friendly page for the given object. * * @param object $object * The object form to print. - * @param string $output - * The object form to print */ -function hook_islandora_view_print_object_alter($object, &$output) { +function hook_islandora_view_print_object($object) { } /** * Generate an object's display for the given content model. diff --git a/islandora.module b/islandora.module index b295b7ea..69064725 100644 --- a/islandora.module +++ b/islandora.module @@ -103,7 +103,7 @@ function islandora_menu() { 'access callback' => 'islandora_object_access_callback', 'access arguments' => array(FEDORA_VIEW_OBJECTS, 2), ); - $items['islandora/print/%islandora_object'] = array( + $items['islandora/object/%islandora_object/print'] = array( 'page callback' => 'islandora_printer_object', 'page arguments' => array(2), 'type' => MENU_NORMAL_ITEM, @@ -241,15 +241,6 @@ function islandora_menu() { 'access arguments' => array(FEDORA_PURGE, 4), 'load arguments' => array(2), ); - $items['islandora/object/%islandora_object/print'] = array( - 'title' => 'Print Object', - 'page callback' => 'islandora_print_object', - 'page arguments' => array(2), - 'type' => MENU_CALLBACK, - 'access callback' => 'islandora_object_access', - 'access arguments' => array(FEDORA_VIEW_OBJECTS, 2), - 'load arguments' => array(2), - ); $items['islandora/object/%islandora_object/download_clip'] = array( 'page callback' => 'islandora_download_clip', 'page arguments' => array(2), @@ -770,7 +761,10 @@ function islandora_view_object(AbstractObject $object) { 'print_img' => $path . '/images/print-icon.png'), ), array('type' => 'setting')); - drupal_add_js(array('islandora' => array('print_link' => '/islandora/print/' . $object->id)), array('type' => 'setting')); + drupal_add_js(array( + 'islandora' => array( + 'print_link' => '/islandora/object/' . $object->id . '/print')), + array('type' => 'setting')); drupal_add_js($path . '/js/add_print.js'); drupal_set_title($object->label); @@ -817,48 +811,22 @@ function islandora_view_object(AbstractObject $object) { * An HTML representation of this object. */ function islandora_printer_object(AbstractObject $object) { - $output = array(); - $output = NULL; - $islandora_object = islandora_object_load($object->id); - $obj_pid = urldecode($object->id); - $resource_url = ''; - - // Check for a valid image/pdf/large image cmodel - // TODO: More preprocessing on large image and pdf to optimize view. - if (in_array('islandora:sp_basic_image', $islandora_object->models)) { - $resource_url = url("islandora/object/{$obj_pid}/datastream/OBJ/view"); - } - elseif (in_array('islandora:sp_large_image_cmodel', $islandora_object->models)) { - $resource_url = url("islandora/object/{$obj_pid}/datastream/JPG/view"); - } - elseif (in_array('islandora:sp_pdf', $islandora_object->models)) { - // Check for higher quality data stream if available. - $dsid = isset($obj['HQ_JPG']) ? 'HQ_JPG' : 'PREVIEW'; - $resource_url = url("islandora/object/{$obj_pid}/datastream/{$dsid}/view"); - } - - $params = array( - 'title' => $islandora_object->label, - 'path' => $resource_url, - ); - // Theme the image seperatly. - $variables['islandora_img'] = theme('image', $params); - $output = islandora_default_islandora_printer_object($object, $variables['islandora_img']); - + $temp_arr = array(); // Dispatch print hook. foreach (islandora_build_hook_list(ISLANDORA_PRINT_HOOK, $object->models) as $hook) { - $temp = module_invoke_all($hook, $output); + $temp = module_invoke_all($hook, $object); islandora_as_renderable_array($temp); if (!empty($temp)) { - $output = array_merge_recursive($output, $temp); + $temp_arr = array_merge_recursive($temp_arr, $temp); } } - + $output = islandora_default_islandora_printer_object($object, drupal_render($temp_arr)); arsort($output); - drupal_alter(ISLANDORA_PRINT_HOOK, $object, $output); islandora_as_renderable_array($output); + // Prompt to print. + drupal_add_js('jQuery(document).ready(function () { window.print(); });', 'inline'); return $output; } From 68d52ea32910bb3d37dc969f72f88c3750f4d8fc Mon Sep 17 00:00:00 2001 From: jonathangreen Date: Wed, 31 Jul 2013 22:04:40 -0300 Subject: [PATCH 26/44] Fixed bug with datastream alter. --- includes/tuque_wrapper.inc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/includes/tuque_wrapper.inc b/includes/tuque_wrapper.inc index baaf10b0..96f9919c 100644 --- a/includes/tuque_wrapper.inc +++ b/includes/tuque_wrapper.inc @@ -207,6 +207,9 @@ class IslandoraFedoraApiM extends FedoraApiM { 'params' => $params, ); islandora_alter_datastream($object, $datastream, $context); + if (isset($params['lastModifiedDate'])) { + $params['lastModifiedDate'] = (string) $object[$dsid]->createdDate; + } try { if ($context['block']) { throw new Exception('Modify Datastream was blocked.'); From 7afc0093e75165f6fab8b9e7c018829ade889245 Mon Sep 17 00:00:00 2001 From: jonathangreen Date: Thu, 25 Jul 2013 11:15:19 -0300 Subject: [PATCH 27/44] Added datastream versions forms. This commit allows users with the correct permissions to see all the previous versions of a datastream. It also allows the user to see the contents of old datastreams and delete versions of the previous datastreams. --- includes/add_datastream.form.inc | 2 +- includes/datastream.inc | 36 +++++- includes/datastream.version.inc | 125 +++++++++++++++++++ includes/datastream.versions.inc | 42 ------- islandora.info | 1 + islandora.module | 36 +++++- tests/datastream_versions.test | 198 +++++++++++++++++++++++++++++++ theme/theme.inc | 51 ++++++-- 8 files changed, 428 insertions(+), 63 deletions(-) create mode 100644 includes/datastream.version.inc delete mode 100644 includes/datastream.versions.inc create mode 100644 tests/datastream_versions.test diff --git a/includes/add_datastream.form.inc b/includes/add_datastream.form.inc index 1ef1bb33..62490c9a 100644 --- a/includes/add_datastream.form.inc +++ b/includes/add_datastream.form.inc @@ -62,7 +62,7 @@ function islandora_add_datastream_form(array $form, array &$form_state, Abstract '#element_validate' => array('islandora_add_datastream_form_field_does_not_contain_a_forward_slash'), ), 'file' => array( - '#type' => 'file', + '#type' => 'managed_file', '#required' => TRUE, '#title' => t('Upload Document'), '#size' => 48, diff --git a/includes/datastream.inc b/includes/datastream.inc index dc01bdfe..8a02439a 100644 --- a/includes/datastream.inc +++ b/includes/datastream.inc @@ -26,8 +26,19 @@ function islandora_download_datastream(AbstractDatastream $datastream) { * @param bool $download * If TRUE the file is download to the user computer for viewing otherwise it * will attempt to display in the browser natively. + * @param int $version + * The version of the datastream to display */ -function islandora_view_datastream(AbstractDatastream $datastream, $download = FALSE) { +function islandora_view_datastream(AbstractDatastream $datastream, $download = FALSE, $version = NULL) { + if ($version !== NULL) { + if (isset($datastream[$version])) { + $datastream = $datastream[$version]; + } + else { + return drupal_not_found(); + } + } + header_remove('Cache-Control'); header_remove('Expires'); header('Content-type: ' . $datastream->mimetype); @@ -69,12 +80,31 @@ function islandora_datastream_get_human_readable_size(AbstractDatastream $datast * * @param AbstractDatastream $datastream * The datastream to generated the url to. + * @param string $type + * One of: + * - download + * - view + * @param int $version + * (Optional) The version of the datastream to get a URL for. * * @return string * either the 'view' or 'download' url for the given datastream. */ -function islandora_datastream_get_url(AbstractDatastream $datastream, $type = 'download') { - return $datastream->controlGroup == 'R' ? $datastream->url : "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/$type"; +function islandora_datastream_get_url(AbstractDatastream $datastream, $type = 'download', $version = NULL) { + if ($version === NULL) { + $link = "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/$type"; + } + else { + $link = "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/version/$version/$type"; + $datastream = $datastream[$version]; + } + + if ($datastream->controlGroup == 'R') { + return $datastream->url; + } + else { + return $link; + } } /** diff --git a/includes/datastream.version.inc b/includes/datastream.version.inc new file mode 100644 index 00000000..c58b2a8c --- /dev/null +++ b/includes/datastream.version.inc @@ -0,0 +1,125 @@ + $datastream->id))); + + $header = array(); + $header[] = array('data' => 'Created Date'); + $header[] = array('data' => t('Size')); + $header[] = array('data' => t('Label')); + $header[] = array('data' => t('Mime type')); + $header[] = array('data' => t('Operations')); + $rows = array(); + + foreach ($datastream as $version => $datastream_version) { + $row = array(); + $row[] = array( + 'class' => 'datastream-date', + 'data' => theme('islandora_datastream_view_link', array( + 'datastream' => $datastream, + 'label' => $datastream_version->createdDate->format(DATE_RFC850), + 'version' => $version, + )), + ); + $row[] = array( + 'class' => 'datastream-size', + 'data' => islandora_datastream_get_human_readable_size($datastream_version), + ); + $row[] = array( + 'class' => 'datastream-label', + 'data' => $datastream_version->label, + ); + $row[] = array( + 'class' => 'datastream-mime', + 'data' => $datastream_version->mimeType, + ); + $row[] = array( + 'class' => 'datastream-delete', + 'data' => theme('islandora_datastream_delete_link', array( + 'datastream' => $datastream, + 'version' => $version, + )), + ); + $rows[] = $row; + } + + return theme('table', array('header' => $header, 'rows' => $rows)); +} + +/** + * The admin delete datastream form. + * + * @param array $form + * The Drupal form. + * @param array $form_state + * The Drupal form state. + * @param AbstractDatastream $datastream + * The datastream to be deleted. + * + * @return array + * The drupal form definition. + */ +function islandora_delete_datastream_version_form(array $form, array &$form_state, AbstractDatastream $datastream, $version) { + if (!isset($datastream[$version]) || count($datastream) < 2) { + return drupal_not_found(); + } + + $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') + ); +} + +/** + * Submit handler for the delete datastream form. + * + * Purges/Delete's the given AbstractDatastream if possible. + * + * The ISLANDORA_PRE_PURGE_DATASTREAM_HOOK will query other modules as to + * whether the given FedoraDatastream + * should be: blocked from purging; state set to 'Deleted'; or purged. + * + * @param array $form + * The Drupal form. + * @param array $form_state + * The Drupal form state. + */ +function islandora_delete_datastream_version_form_submit(array $form, array &$form_state) { + $datastream = $form_state['datastream']; + $version = $form_state['version']; + + $datastream_id = $datastream->id; + $object = $datastream->parent; + + try { + unset($datastream[$version]); + } + 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'); + } + + drupal_set_message(t('%d datastream version sucessfully deleted from Islandora object %o', array( + '%d' => $datastream_id, + '%o' => $object->label))); + + $form_state['redirect'] = "islandora/object/{$object->id}/datastream/{$datastream->id}/version"; +} diff --git a/includes/datastream.versions.inc b/includes/datastream.versions.inc deleted file mode 100644 index 5c946aba..00000000 --- a/includes/datastream.versions.inc +++ /dev/null @@ -1,42 +0,0 @@ -id Previous Versions"); - - $header = array(); - $header[] = array ('data' => 'Created Date'); - $header[] = array('data' => t('Size')); - $header[] = array('data' => t('Label')); - $header[] = array('data' => t('Mime type')); - $rows = array(); - - foreach ($datastream as $version => $datastream_version) { - $row = array(); - $row[] = array( - 'class' => 'datastream-date', - 'data' => theme('islandora_datastream_view_link', array( - 'datastream' => $datastream, - 'label' => $datastream_version->createdDate->format(DATE_RFC850), - 'version' => $version, - )), - ); - $row[] = array( - 'class' => 'datastream-size', - 'data' => islandora_datastream_get_human_readable_size($datastream_version), - ); - $row[] = array( - 'class' => 'datastream-label', - 'data' => $datastream_version->label, - ); - $row[] = array( - 'class' => 'datastream-mime', - 'data' => $datastream_version->mimeType, - ); - $rows[] = $row; - } - - return theme('table', array('header' => $header, 'rows' => $rows)); -} \ No newline at end of file diff --git a/islandora.info b/islandora.info index ce6ba947..fea3ead2 100644 --- a/islandora.info +++ b/islandora.info @@ -17,4 +17,5 @@ files[] = tests/hooks.test files[] = tests/ingest.test files[] = tests/hooked_access.test files[] = tests/islandora_manage_permissions.test +files[] = tests/datastream_versions.test php = 5.3 diff --git a/islandora.module b/islandora.module index ab79ca9e..d1f15542 100644 --- a/islandora.module +++ b/islandora.module @@ -234,16 +234,36 @@ function islandora_menu() { 'access arguments' => array(FEDORA_PURGE, 4), 'load arguments' => array(2), ); - $items['islandora/object/%islandora_object/datastream/%islandora_datastream/versions'] = array( + $items['islandora/object/%islandora_object/datastream/%islandora_datastream/version'] = array( 'title' => 'Datastream Versions', 'page arguments' => array(4), - 'page callback' => 'islandora_datastream_versions_table', - 'file' => 'includes/datastream.versions.inc', + 'page callback' => 'islandora_datastream_version_table', + 'file' => 'includes/datastream.version.inc', 'type' => MENU_CALLBACK, 'access callback' => 'islandora_datastream_access', 'access arguments' => array(ISLANDORA_VIEW_DATASTREAM_HISTORY, 4), 'load arguments' => array(2), ); + $items['islandora/object/%islandora_object/datastream/%islandora_datastream/version/%/delete'] = array( + 'title' => 'Delete datastream version', + 'page arguments' => array('islandora_delete_datastream_version_form', 4, 6), + 'page callback' => 'drupal_get_form', + 'file' => 'includes/datastream.version.inc', + 'type' => MENU_CALLBACK, + 'access callback' => 'islandora_datastream_access', + 'access arguments' => array(FEDORA_PURGE, 4), + 'load arguments' => array(2), + ); + $items['islandora/object/%islandora_object/datastream/%islandora_datastream/version/%/view'] = array( + 'title' => 'View datastream version', + 'page callback' => 'islandora_view_datastream', + 'page arguments' => array(4, FALSE, 6), + 'type' => MENU_CALLBACK, + 'file' => 'includes/datastream.inc', + 'access callback' => 'islandora_datastream_access', + 'access arguments' => array(ISLANDORA_VIEW_DATASTREAM_HISTORY, 4), + 'load arguments' => array(2), + ); $items['islandora/object/%islandora_object/print'] = array( 'title' => 'Print Object', 'page callback' => 'islandora_print_object', @@ -279,7 +299,7 @@ function islandora_menu() { function islandora_admin_paths() { $paths = array(); $paths['islandora/object/*/manage*'] = TRUE; - $paths['islandora/object/*/delete'] = TRUE; + $paths['islandora/object/*/delete*'] = TRUE; $paths['islandora/object/*/datastream/*/edit'] = TRUE; $paths['islandora/object/*/datastream/*/versions'] = TRUE; return $paths; @@ -341,11 +361,15 @@ function islandora_theme() { ), 'islandora_datastream_delete_link' => array( 'file' => 'theme/theme.inc', - 'variables' => array('datastream' => NULL), + 'variables' => array('datastream' => NULL, 'version' => NULL), ), 'islandora_datastream_view_link' => array( 'file' => 'theme/theme.inc', - 'variables' => array('datastream' => NULL, 'version' => NULL, 'label' => NULL), + 'variables' => array( + 'datastream' => NULL, + 'version' => NULL, + 'label' => NULL, + ), ), 'islandora_datastream_download_link' => array( 'file' => 'theme/theme.inc', diff --git a/tests/datastream_versions.test b/tests/datastream_versions.test new file mode 100644 index 00000000..6b22bd95 --- /dev/null +++ b/tests/datastream_versions.test @@ -0,0 +1,198 @@ + 'Islandora Datastream Versions', + 'description' => 'Tests the functionality related to datastream versions in Islandora.', + 'group' => 'Islandora', + ); + } + + /** + * Create an object with many datastram versions. + * + * @see IslandoraWebTestCase::setUp() + */ + public function setUp() { + parent::setUp(); + + $this->pid = $this->randomName() . ":" . $this->randomName(); + $tuque = islandora_get_tuque_connection(); + $object = $tuque->repository->constructObject($this->pid); + $object = $tuque->repository->ingestObject($object); + $this->dsid = $this->randomName(); + $ds = $object->constructDatastream($this->dsid); + $ds->label = 'Test'; + $ds->content = 'test'; + $object->ingestDatastream($ds); + + // Create three versions. + $ds->mimetype = 'application/pdf'; + $ds->label = 'jaaaaa maaaan'; + $ds->content = 'Tests... are the bests.'; + } + + /** + * Free any objects/resources created for this test. + * + * @see IslandoraWebTestCase::tearDown() + */ + public function tearDown() { + $tuque = islandora_get_tuque_connection(); + $tuque->repository->purgeObject($this->pid); + + parent::tearDown(); + } + + /** + * Check if the user can see datastream versions in the datastream table. + */ + public function testSeeDatastreamVersions() { + $user = $this->drupalCreateUser(array( + 'view fedora repository objects', + 'ingest fedora objects', + 'view old datastream versions', + 'add fedora datastreams', + )); + $this->drupalLogin($user); + $this->drupalGet("islandora/object/{$this->pid}/manage/datastreams"); + $this->assertLink($this->dsid); + $this->assertLink("4"); + $encoded_pid = urlencode($this->pid); + $this->assertLinkByHref("islandora/object/$encoded_pid/datastream/{$this->dsid}/version"); + } + + /** + * Check that users without permission cannot see datastream versions. + */ + public function testNotSeeDatastreamVersions() { + $user = $this->drupalCreateUser(array( + 'view fedora repository objects', + 'ingest fedora objects', + 'add fedora datastreams', + )); + $this->drupalLogin($user); + $this->drupalGet("islandora/object/{$this->pid}/manage/datastreams"); + $this->assertLink($this->dsid); + $this->assertNoLink("4"); + $encoded_pid = urlencode($this->pid); + $this->assertNoLinkByHref("islandora/object/$encoded_pid/datastream/{$this->dsid}/version"); + } + + /** + * Check that users without permission cannot see datastream version pages. + */ + public function testDatastreamVersionPermissions() { + $this->drupalGet("islandora/object/{$this->pid}/datastream/{$this->dsid}/version"); + $this->assertResponse(403); + $this->drupalGet("islandora/object/{$this->pid}/datastream/{$this->dsid}/version/0/view"); + $this->assertResponse(403); + } + + /** + * Check that the proper infomration is displayed on the ds version page. + */ + public function testDatastreamVersionPage() { + $user = $this->drupalCreateUser(array( + 'view old datastream versions', + )); + $this->drupalLogin($user); + $this->drupalGet("islandora/object/{$this->pid}/datastream/{$this->dsid}/version"); + $this->assertNoLink("Delete"); + $this->assertText("text/xml"); + $this->assertText("application/pdf"); + $this->assertText("jaaaaa maaaan"); + $this->assertText("Test"); + + $encoded_pid = urlencode($this->pid); + $this->assertLinkByHref("islandora/object/$encoded_pid/datastream/{$this->dsid}/version/0/view"); + $this->assertLinkByHref("islandora/object/$encoded_pid/datastream/{$this->dsid}/version/1/view"); + $this->assertLinkByHref("islandora/object/$encoded_pid/datastream/{$this->dsid}/version/2/view"); + $this->assertLinkByHref("islandora/object/$encoded_pid/datastream/{$this->dsid}/version/3/view"); + } + + /** + * Make sure the correct content is displayed for each datastream version. + */ + public function testDatastreamVersionContent() { + $user = $this->drupalCreateUser(array( + 'view old datastream versions', + )); + $this->drupalLogin($user); + $this->drupalGet("islandora/object/{$this->pid}/datastream/{$this->dsid}/version/3/view"); + $content = $this->drupalGetContent(); + if ($content != 'test') { + $this->fail("Incorrect datastream content"); + } + $this->drupalGet("islandora/object/{$this->pid}/datastream/{$this->dsid}/version/2/view"); + $content = $this->drupalGetContent(); + if ($content != 'test') { + $this->fail("Incorrect datastream content"); + } + $this->drupalGet("islandora/object/{$this->pid}/datastream/{$this->dsid}/version/1/view"); + $content = $this->drupalGetContent(); + if ($content != 'test') { + $this->fail("Incorrect datastream content"); + } + $this->drupalGet("islandora/object/{$this->pid}/datastream/{$this->dsid}/version/0/view"); + $content = $this->drupalGetContent(); + if ($content != 'Tests... are the bests.') { + $this->fail("Incorrect datastream content"); + } + $this->drupalGet("islandora/object/{$this->pid}/datastream/{$this->dsid}/version/5/view"); + $this->assertResponse(404); + } + + /** + * Make sure you can delete datastream versions. + */ + public function testDatastreamVersionDelete() { + $user = $this->drupalCreateUser(array( + 'view old datastream versions', + 'delete fedora objects and datastreams', + )); + $this->drupalLogin($user); + $this->drupalGet("islandora/object/{$this->pid}/datastream/{$this->dsid}/version"); + $this->assertLink("delete"); + $this->assertText('text/xml'); + + $encoded_pid = urlencode($this->pid); + $this->assertLinkByHref("islandora/object/$encoded_pid/datastream/{$this->dsid}/version/0/delete"); + $this->assertLinkByHref("islandora/object/$encoded_pid/datastream/{$this->dsid}/version/1/delete"); + $this->assertLinkByHref("islandora/object/$encoded_pid/datastream/{$this->dsid}/version/2/delete"); + $this->assertLinkByHref("islandora/object/$encoded_pid/datastream/{$this->dsid}/version/3/delete"); + + $this->drupalGet("islandora/object/{$this->pid}/datastream/{$this->dsid}/version/3/delete"); + $this->drupalPost(NULL, array(), t('Delete')); + $this->assertNoText('text/xml'); + } + + /** + * Make sure you can't delete versions that don't exist/have only 1 version. + */ + public function testDatastreamVersionDeleteEdgeCase() { + $user = $this->drupalCreateUser(array( + 'view old datastream versions', + 'delete fedora objects and datastreams', + )); + $this->drupalLogin($user); + + $this->drupalGet("islandora/object/{$this->pid}/datastream/{$this->dsid}/version/6/delete"); + $this->assertResponse(404); + + $this->drupalGet("islandora/object/{$this->pid}/datastream/DC/version/0/delete"); + $this->assertResponse(404); + } +} diff --git a/theme/theme.inc b/theme/theme.inc index 8964960c..85341838 100644 --- a/theme/theme.inc +++ b/theme/theme.inc @@ -54,7 +54,7 @@ function islandora_preprocess_islandora_default_edit(array &$variables) { 'data' => islandora_datastream_get_human_readable_size($ds), ); if (user_access(ISLANDORA_VIEW_DATASTREAM_HISTORY)) { - $row[] = array( + $row[] = array( 'class' => 'datastream-versions', 'data' => theme('islandora_datastream_version_link', array( 'datastream' => $ds, @@ -268,29 +268,29 @@ function theme_islandora_datastream_download_link(array $vars) { * @param array $vars * An array containing: * - datastream: An AbstractDatastream for which to generate a view link. + * - label: (Optional) The label for the link. + * - version: (Optional) The version of the datstream to link to. */ function theme_islandora_datastream_view_link(array $vars) { $datastream = $vars['datastream']; module_load_include('inc', 'islandora', 'includes/utilities'); - if($vars['label'] === NULL) { + if ($vars['label'] === NULL) { $label = check_plain($datastream->id); } else { $label = check_plain($vars['label']); } - if($vars['version'] === NULL) { + if ($vars['version'] === NULL) { $perm = FEDORA_VIEW_OBJECTS; - $query = array(); } else { $perm = ISLANDORA_VIEW_DATASTREAM_HISTORY; - $query = array('version' => $vars['version']); } if (islandora_datastream_access($perm, $datastream)) { - return l($label, islandora_datastream_get_url($datastream, 'view'), array('query' => $query)); + return l($label, islandora_datastream_get_url($datastream, 'view', $vars['version'])); } else { return $label; @@ -303,6 +303,7 @@ function theme_islandora_datastream_view_link(array $vars) { * @param array $vars * An array containing: * - datastream: An AbstractDatastream for which to generate a delete link. + * - version: (optional) the version of the datastream to delete. */ function theme_islandora_datastream_delete_link(array $vars) { $datastream = $vars['datastream']; @@ -311,9 +312,22 @@ function theme_islandora_datastream_delete_link(array $vars) { $can_delete = !in_array($datastream->id, $datastreams) && islandora_datastream_access(FEDORA_PURGE, $datastream); - return $can_delete ? - l(t('delete'), "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/delete") : + if ($vars['version'] !== NULL) { + if (count($datastream) == 1) { + $can_delete = FALSE; + } + $link = "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/version/{$vars['version']}/delete"; + } + else { + $link = "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/delete"; + } + + if ($can_delete) { + return l(t('delete'), $link); + } + else { ''; + } } /** @@ -335,16 +349,31 @@ function theme_islandora_datastream_edit_link(array $vars) { ''; } +/** + * Renders a link to take you to the datastream versions page. + * + * @param array $vars + * An array containing: + * - datastream: An AbstractDatastream to generate the version link from. + * + * @return string + * Markup. + */ function theme_islandora_datastream_version_link(array $vars) { $datastream = $vars['datastream']; module_load_include('inc', 'islandora', 'includes/utilities'); $see_history = islandora_datastream_access(ISLANDORA_VIEW_DATASTREAM_HISTORY, $datastream); - if($see_history) { - return l(count($datastream), "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/versions"); + if ($see_history) { + if ($datastream->versionable) { + return l(count($datastream), "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/version"); + } + else { + return t('Not Versioned'); + } } else { return ''; } -} \ No newline at end of file +} From f856e41ee91a95615523136f585d69ca1962b96d Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Thu, 1 Aug 2013 16:06:55 +0000 Subject: [PATCH 28/44] Fix doxygen comment. --- tests/islandora_web_test_case.inc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/islandora_web_test_case.inc b/tests/islandora_web_test_case.inc index f1f20eaf..baf7a8ee 100644 --- a/tests/islandora_web_test_case.inc +++ b/tests/islandora_web_test_case.inc @@ -232,6 +232,9 @@ class IslandoraWebTestCase extends DrupalWebTestCase { * * @param string $hex * The hex value being converted. + * + * @return bool|int + * FALSE or the integer value that is converted. */ public function convertHexToInt($hex) { From d7645ce1e7c562a3b246bb9ed82678a08eeb84de Mon Sep 17 00:00:00 2001 From: William Panting Date: Thu, 1 Aug 2013 16:41:18 -0300 Subject: [PATCH 29/44] not bubling permissions --- islandora.module | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/islandora.module b/islandora.module index 5b45fb1a..e618c021 100644 --- a/islandora.module +++ b/islandora.module @@ -1317,7 +1317,7 @@ function islandora_islandora_object_access($op, $object, $user) { /** * Hookable access callback for datastreams. * - * Requires the equivalent permissions on the object. + * Positive permissions on object access suggests on the datastream. */ function islandora_datastream_access($op, $datastream, $user = NULL) { $cache = &drupal_static(__FUNCTION__); @@ -1346,10 +1346,9 @@ function islandora_datastream_access($op, $datastream, $user = NULL) { $user, )); - // Neither the object nor the datastream check returned FALSE, and one in - // the object or datastream checks returned TRUE. + // The datastream check returned FALSE, and one in the object or datastream + // checks returned TRUE. $cache[$op][$datastream->parent->id][$datastream->id][$user->uid] = ( - !in_array(FALSE, $object_results, TRUE) && !in_array(FALSE, $datastream_results, TRUE) && (in_array(TRUE, $object_results, TRUE) || in_array(TRUE, $datastream_results, TRUE)) ); From e1c58125510e8c6b10d32662d5d42b820b19bf3e Mon Sep 17 00:00:00 2001 From: jonathangreen Date: Fri, 2 Aug 2013 13:18:07 -0300 Subject: [PATCH 30/44] Spellin' --- includes/datastream.version.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/datastream.version.inc b/includes/datastream.version.inc index c58b2a8c..828b6ea1 100644 --- a/includes/datastream.version.inc +++ b/includes/datastream.version.inc @@ -117,7 +117,7 @@ function islandora_delete_datastream_version_form_submit(array $form, array &$fo '%e' => $e->getMessage())), 'error'); } - drupal_set_message(t('%d datastream version sucessfully deleted from Islandora object %o', array( + drupal_set_message(t('%d datastream version successfully deleted from Islandora object %o', array( '%d' => $datastream_id, '%o' => $object->label))); From c1c7c0afae913f5e130dea292f79d1c5d3c65da4 Mon Sep 17 00:00:00 2001 From: jonathangreen Date: Fri, 2 Aug 2013 13:35:21 -0300 Subject: [PATCH 31/44] Missin t() --- includes/datastream.version.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/datastream.version.inc b/includes/datastream.version.inc index 828b6ea1..2631790f 100644 --- a/includes/datastream.version.inc +++ b/includes/datastream.version.inc @@ -14,7 +14,7 @@ function islandora_datastream_version_table($datastream) { drupal_set_title(t("@dsid Previous Versions", array('@dsid' => $datastream->id))); $header = array(); - $header[] = array('data' => 'Created Date'); + $header[] = array('data' => t('Created Date')); $header[] = array('data' => t('Size')); $header[] = array('data' => t('Label')); $header[] = array('data' => t('Mime type')); From dd9896d18787af2ea00ad0078265f41d317b164b Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Fri, 2 Aug 2013 17:19:55 +0000 Subject: [PATCH 32/44] Code style cleanup. --- includes/datastream.inc | 9 +++++++++ includes/datastream.version.inc | 2 ++ includes/ingest.form.inc | 27 ++++++++++++++++++++++----- includes/object.entity_controller.inc | 3 +++ includes/utilities.inc | 2 ++ tests/islandora_ingest_test.module | 12 +++++++----- theme/theme.inc | 12 ++++++++++++ 7 files changed, 57 insertions(+), 10 deletions(-) diff --git a/includes/datastream.inc b/includes/datastream.inc index 8a02439a..4b138bdf 100644 --- a/includes/datastream.inc +++ b/includes/datastream.inc @@ -112,6 +112,9 @@ function islandora_datastream_get_url(AbstractDatastream $datastream, $type = 'd * * @param AbstractDatastream $datastream * The datastream to generated the url to. + * + * @return string + * Markup containing the link to the confirm form to delete the datastream. */ function islandora_datastream_get_delete_link(AbstractDatastream $datastream) { $message = islandora_deprecated('7.x-1.2', 'Use the "islandora_datastream_delete_link" theme implementation.'); @@ -127,6 +130,9 @@ function islandora_datastream_get_delete_link(AbstractDatastream $datastream) { * * @param AbstractDatastream $datastream * The datastream to generated the url to. + * + * @return string + * Markup containing the link to edit the datastream. */ function islandora_datastream_edit_get_link(AbstractDatastream $datastream) { $message = islandora_deprecated('7.x-1.2', 'Use the "islandora_datastream_edit_link" theme implementation.'); @@ -169,6 +175,9 @@ function islandora_edit_datastream(AbstractDatastream $datastream) { * * @param array $edit_registry * A list of 'islandora_edit_datastream_registry' values. + * + * @return array + * A Drupal renderable array containing the "edit" markup. */ function islandora_edit_datastream_registry_render(array $edit_registry) { $markup = ''; diff --git a/includes/datastream.version.inc b/includes/datastream.version.inc index 2631790f..1e7c0830 100644 --- a/includes/datastream.version.inc +++ b/includes/datastream.version.inc @@ -65,6 +65,8 @@ function islandora_datastream_version_table($datastream) { * The Drupal form state. * @param AbstractDatastream $datastream * The datastream to be deleted. + * @param string $version + * The version number of the datastream we are trying to delete. * * @return array * The drupal form definition. diff --git a/includes/ingest.form.inc b/includes/ingest.form.inc index 6faa642c..7edd0f60 100644 --- a/includes/ingest.form.inc +++ b/includes/ingest.form.inc @@ -186,10 +186,10 @@ function islandora_ingest_form_get_step(array &$form_state, $step_id = NULL) { * * @param array $form_state * The Drupal form state. - * @param string $step + * @param array $step * The step relative to the result, if not provided the current step is used. * - * @return string + * @return array|null * The next step if found, NULL otherwise. */ function islandora_ingest_form_get_next_step(array &$form_state, array $step = NULL) { @@ -205,10 +205,10 @@ function islandora_ingest_form_get_next_step(array &$form_state, array $step = N * * @param array $form_state * The Drupal form state. - * @param string $step + * @param array $step * The step relative to the result, if not provided the current step is used. * - * @return string + * @return array|null * The next step if found, NULL otherwise. */ function islandora_ingest_form_get_previous_step(array &$form_state, array $step = NULL) { @@ -329,6 +329,9 @@ function islandora_ingest_form_decrement_step(array &$form_state) { * The Drupal form. * @param array $form_state * The Drupal form state. + * @param string $step_id + * The ID of the step relative to the result, if not provided the current + * step_id is used. * * @return array * The form definition of the current step. @@ -363,6 +366,8 @@ function islandora_ingest_form_execute_step(array $form, array &$form_state, $st * The Drupal form. * @param array $form_state * The Drupal form state. + * @param array $step + * The step we are executing. * * @return array * The form definition of the given step. @@ -391,6 +396,8 @@ function islandora_ingest_form_execute_form_step(array $form, array &$form_state * The Drupal form. * @param array $form_state * The Drupal form state. + * @param array $step + * The step that execution begins from. */ function islandora_ingest_form_execute_consecutive_callback_steps(array $form, array &$form_state, array $step) { do { @@ -409,6 +416,8 @@ function islandora_ingest_form_execute_consecutive_callback_steps(array $form, a * The Drupal form. * @param array $form_state * The Drupal form state. + * @param array $step + * The step currently being executed. */ function islandora_ingest_form_execute_callback_step(array $form, array &$form_state, array $step) { $args = array(&$form_state); @@ -425,6 +434,8 @@ function islandora_ingest_form_execute_callback_step(array $form, array &$form_s * The Drupal form. * @param array $form_state * The Drupal form state. + * @param array $step + * The step that execution begins from. */ function islandora_ingest_form_undo_consecutive_callback_steps(array $form, array &$form_state, array $step) { do { @@ -443,6 +454,8 @@ function islandora_ingest_form_undo_consecutive_callback_steps(array $form, arra * The Drupal form. * @param array $form_state * The Drupal form state. + * @param array $step + * The step which the undo callback is being called on. */ function islandora_ingest_form_undo_callback_step(array $form, array &$form_state, array $step) { $args = array(&$form_state); @@ -457,11 +470,13 @@ function islandora_ingest_form_undo_callback_step(array $form, array &$form_stat * The Drupal form. * @param array $form_state * The Drupal form state. + * @param array $step + * An array defining a ingest step. * * @return array * The stepified Drupal form definition for the given step. */ -function islandora_ingest_form_stepify(array $form, array &$form_state, $step) { +function islandora_ingest_form_stepify(array $form, array &$form_state, array $step) { $first_form_step = islandora_ingest_form_on_first_form_step($form_state); $last_form_step = islandora_ingest_form_on_last_form_step($form_state); $form['form_step_id'] = array( @@ -692,6 +707,8 @@ function islandora_ingest_form_ingest_button(array &$form_state) { * * Attempts to ingest every object built by the previous steps. * + * @param array $form + * The Drupal form. * @param array $form_state * The Drupal form state. */ diff --git a/includes/object.entity_controller.inc b/includes/object.entity_controller.inc index d3fd6986..9464d7b5 100644 --- a/includes/object.entity_controller.inc +++ b/includes/object.entity_controller.inc @@ -24,6 +24,9 @@ class IslandoraObjectEntityController implements DrupalEntityControllerInterface * The ID's of the entities. * @param array $conditions * The conditions to apply. + * + * @return array + * An array of loaded objects. */ public function load($ids = array(), $conditions = array()) { if (!empty($conditions)) { diff --git a/includes/utilities.inc b/includes/utilities.inc index 5ce2ca14..c8d1ae5e 100644 --- a/includes/utilities.inc +++ b/includes/utilities.inc @@ -14,6 +14,8 @@ * * @param int $bytes * Size in bytes to convert + * @param int $precision + * The amount of decimal precision to show. * * @return string * Human readable size. diff --git a/tests/islandora_ingest_test.module b/tests/islandora_ingest_test.module index d414c717..8a6771d9 100644 --- a/tests/islandora_ingest_test.module +++ b/tests/islandora_ingest_test.module @@ -87,7 +87,11 @@ function islandora_ingest_test_test_testcmodel2_islandora_ingest_steps(array &$f * The Drupal form definition. */ function islandora_ingest_test_set_label_form(array $form, array &$form_state) { - $models = array('test:nomorestepscmodel', 'test:testcmodel', 'test:testcmodel2'); + $models = array( + 'test:nomorestepscmodel', + 'test:testcmodel', + 'test:testcmodel2', + ); $model = isset($form_state['values']['model']) ? $form_state['values']['model'] : reset($models); $shared_storage = &islandora_ingest_form_get_shared_storage($form_state); $shared_storage['models'] = array($model); @@ -139,8 +143,7 @@ function islandora_ingest_test_set_label_form_submit(array $form, array &$form_s * Test the First content model. */ function islandora_ingest_test_testcmodel_form(array $form, array &$form_state) { - return array( - ); + return array(); } /** @@ -154,8 +157,7 @@ function islandora_ingest_test_testcmodel_form_submit(array $form, array &$form_ * Test the second content model. */ function islandora_ingest_test_testcmodel2_form(array $form, array &$form_state) { - return array( - ); + return array(); } /** diff --git a/theme/theme.inc b/theme/theme.inc index 85341838..d988ee77 100644 --- a/theme/theme.inc +++ b/theme/theme.inc @@ -251,6 +251,9 @@ function islandora_preprocess_islandora_objects(array &$variables) { * @param array $vars * An array containing: * - datastream: An AbstractDatastream for which to generate a download link. + * + * @return string + * Markup containing the download url if the user has access, empty otherwise. */ function theme_islandora_datastream_download_link(array $vars) { $datastream = $vars['datastream']; @@ -270,6 +273,9 @@ function theme_islandora_datastream_download_link(array $vars) { * - datastream: An AbstractDatastream for which to generate a view link. * - label: (Optional) The label for the link. * - version: (Optional) The version of the datstream to link to. + * + * @return string + * Markup containing the link to the datastream or the label if inaccessible. */ function theme_islandora_datastream_view_link(array $vars) { $datastream = $vars['datastream']; @@ -304,6 +310,9 @@ function theme_islandora_datastream_view_link(array $vars) { * An array containing: * - datastream: An AbstractDatastream for which to generate a delete link. * - version: (optional) the version of the datastream to delete. + * + * @return string + * Markup containing the url to delete a datastream, or empty if inaccessible. */ function theme_islandora_datastream_delete_link(array $vars) { $datastream = $vars['datastream']; @@ -336,6 +345,9 @@ function theme_islandora_datastream_delete_link(array $vars) { * @param array $vars * An array containing: * - datastream: An AbstractDatastream for which to generate a edit link. + * + * @return string + * Markup containing the url to edit a datastream, or empty if inaccessible. */ function theme_islandora_datastream_edit_link(array $vars) { $datastream = $vars['datastream']; From 1fa7d0790fa9eeb12385309c156666f38189d4a7 Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Fri, 2 Aug 2013 17:59:32 +0000 Subject: [PATCH 33/44] Actually use the fieldset that's defined. --- includes/add_datastream.form.inc | 72 ++++++++++++++++---------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/includes/add_datastream.form.inc b/includes/add_datastream.form.inc index 62490c9a..2a215478 100644 --- a/includes/add_datastream.form.inc +++ b/includes/add_datastream.form.inc @@ -40,44 +40,44 @@ function islandora_add_datastream_form(array $form, array &$form_state, Abstract 'dsid' => array( '#title' => 'Datastream ID', '#description' => t("An ID for this stream that is unique to this object. Must start with a letter and contain only alphanumeric characters, dashes and underscores. The following datastreams are defined by this content model but don't currently exist: @unused_dsids.", array('@unused_dsids' => $unused_datastreams)), + '#type' => 'textfield', + '#size' => 64, + '#maxlength' => 64, + '#required' => TRUE, + '#element_validate' => array( + 'islandora_add_datastream_form_field_is_not_an_existing_datastream_id', + 'islandora_add_datastream_form_field_starts_with_a_letter', + 'islandora_add_datastream_form_field_is_valid_dsid', + ), + '#autocomplete_path' => "islandora/object/{$object->id}/manage/datastreams/add/autocomplete", ), - '#type' => 'textfield', - '#size' => 64, - '#maxlength' => 64, - '#required' => TRUE, - '#element_validate' => array( - 'islandora_add_datastream_form_field_is_not_an_existing_datastream_id', - 'islandora_add_datastream_form_field_starts_with_a_letter', - 'islandora_add_datastream_form_field_is_valid_dsid', + 'label' => array( + '#title' => 'Datastream Label', + '#required' => TRUE, + '#size' => 64, + '#maxlength' => 64, + '#description' => t('A human-readable label'), + '#type' => 'textfield', + '#element_validate' => array('islandora_add_datastream_form_field_does_not_contain_a_forward_slash'), ), - '#autocomplete_path' => "islandora/object/{$object->id}/manage/datastreams/add/autocomplete", - ), - 'label' => array( - '#title' => 'Datastream Label', - '#required' => TRUE, - '#size' => 64, - '#maxlength' => 64, - '#description' => t('A human-readable label'), - '#type' => 'textfield', - '#element_validate' => array('islandora_add_datastream_form_field_does_not_contain_a_forward_slash'), - ), - 'file' => array( - '#type' => 'managed_file', - '#required' => TRUE, - '#title' => t('Upload Document'), - '#size' => 48, - '#description' => t('Select a file to upload.
Files must be less than @size MB.', array('@size' => $upload_size)), - '#default_value' => isset($form_state['values']['files']) ? $form_state['values']['files'] : NULL, - '#upload_location' => 'temporary://', - '#upload_validators' => array( - 'file_validate_extensions' => array(NULL), - // Assume its specified in MB. - 'file_validate_size' => array($upload_size * 1024 * 1024), + 'file' => array( + '#type' => 'managed_file', + '#required' => TRUE, + '#title' => t('Upload Document'), + '#size' => 48, + '#description' => t('Select a file to upload.
Files must be less than @size MB.', array('@size' => $upload_size)), + '#default_value' => isset($form_state['values']['files']) ? $form_state['values']['files'] : NULL, + '#upload_location' => 'temporary://', + '#upload_validators' => array( + 'file_validate_extensions' => array(NULL), + // Assume its specified in MB. + 'file_validate_size' => array($upload_size * 1024 * 1024), + ), + ), + 'submit' => array( + '#type' => 'submit', + '#value' => t('Add Datastream'), ), - ), - 'submit' => array( - '#type' => 'submit', - '#value' => t('Add Datastream'), ), ); } @@ -148,7 +148,7 @@ function islandora_add_datastream_form_field_does_not_contain_a_forward_slash(ar } /** - * Checks if the given datastream requires the upload to be a certian MIME type. + * Checks if the given datastream requires the upload to be a certain MIME type. * * @param array $form * The Drupal form. From 88448d329f41e4afd1cebbe14d29ceb9ef09a8e1 Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Fri, 2 Aug 2013 18:01:24 +0000 Subject: [PATCH 34/44] Unique array key. --- includes/add_datastream.form.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/add_datastream.form.inc b/includes/add_datastream.form.inc index 2a215478..3a1d964d 100644 --- a/includes/add_datastream.form.inc +++ b/includes/add_datastream.form.inc @@ -32,7 +32,7 @@ function islandora_add_datastream_form(array $form, array &$form_state, Abstract '#attributes' => array( 'enctype' => 'multipart/form-data', ), - 'dsid' => array( + 'dsid_fieldset' => array( '#type' => 'fieldset', '#title' => 'Add a datastream', '#collapsible' => FALSE, From 7af39f17fcf9e0ca3cccbb3ef03253764f3ae0d8 Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Fri, 2 Aug 2013 18:11:29 +0000 Subject: [PATCH 35/44] Spacing. --- includes/datastream.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/datastream.inc b/includes/datastream.inc index 4b138bdf..da55dcd5 100644 --- a/includes/datastream.inc +++ b/includes/datastream.inc @@ -131,7 +131,7 @@ function islandora_datastream_get_delete_link(AbstractDatastream $datastream) { * @param AbstractDatastream $datastream * The datastream to generated the url to. * - * @return string + * @return string * Markup containing the link to edit the datastream. */ function islandora_datastream_edit_get_link(AbstractDatastream $datastream) { From 5ec2045e15080fc0ed8a4a2c914ae04199f18cdd Mon Sep 17 00:00:00 2001 From: MorganDawe Date: Mon, 5 Aug 2013 09:11:21 -0300 Subject: [PATCH 36/44] Implemented changes requested via code review. --- css/islandora.print.css | 2 +- islandora.api.php | 23 ++++++++++++++++++++--- theme/islandora-object-img-print.tpl.php | 2 +- theme/islandora-object-print.tpl.php | 2 +- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/css/islandora.print.css b/css/islandora.print.css index d54bb366..364e75e0 100644 --- a/css/islandora.print.css +++ b/css/islandora.print.css @@ -2,7 +2,7 @@ * @file * Print styling * - * We provide some sane print styling for Drupal using Zen's layout method. + * We provide some sane print styling for Drupal, hiding most visuals. */ a:link, a:visited { /* underline all links */ diff --git a/islandora.api.php b/islandora.api.php index d026dd11..984ad6c3 100644 --- a/islandora.api.php +++ b/islandora.api.php @@ -21,9 +21,26 @@ * An array whose values are markup. */ function hook_islandora_view_object($object, $user, $page_number, $page_size) { -} -/** - * An alter hook to print friendly page for the given object. +// Example Implementation +// $islandora_object = islandora_object_load($object->id); +// $output = array(); +// if (in_array('islandora:sp_basic_image', $islandora_object->models)) { +// $resource_url = url("islandora/object/{$object->id}/datastream/OBJ/view"); +// $params = array( +// 'title' => $islandora_object->label, +// 'path' => $resource_url, +// ); + +// // Theme the image seperatly. +// $variables['islandora_img'] = theme('image', $params); +// $output = theme('islandora_default_print', array( +// 'islandora_content' => $variables['islandora_img'])); +// } + +// return $output; +} +/** + * Generate a print friendly page for the given object. * * @param object $object * The object form to print. diff --git a/theme/islandora-object-img-print.tpl.php b/theme/islandora-object-img-print.tpl.php index 2c79a88e..3ff21455 100644 --- a/theme/islandora-object-img-print.tpl.php +++ b/theme/islandora-object-img-print.tpl.php @@ -15,4 +15,4 @@
- \ No newline at end of file + diff --git a/theme/islandora-object-print.tpl.php b/theme/islandora-object-print.tpl.php index 3e6243bc..b9569061 100644 --- a/theme/islandora-object-print.tpl.php +++ b/theme/islandora-object-print.tpl.php @@ -27,4 +27,4 @@
- \ No newline at end of file + From dffb15526d6c724c3889aaec14424179807c5d8c Mon Sep 17 00:00:00 2001 From: MorganDawe Date: Mon, 5 Aug 2013 09:58:18 -0300 Subject: [PATCH 37/44] Updated via code review feedback. --- islandora.module | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/islandora.module b/islandora.module index 69064725..8495129e 100644 --- a/islandora.module +++ b/islandora.module @@ -759,7 +759,8 @@ function islandora_view_object(AbstractObject $object) { drupal_add_js(array( 'islandora' => array( 'print_img' => $path . '/images/print-icon.png'), - ), array('type' => 'setting')); + ), array( + 'type' => 'setting')); drupal_add_js(array( 'islandora' => array( From 1314c7dc06a7467ae7c9ee523df52da1a6ec6876 Mon Sep 17 00:00:00 2001 From: MorganDawe Date: Mon, 5 Aug 2013 10:29:14 -0300 Subject: [PATCH 38/44] Removed old hook. --- css/islandora.print.css | 2 +- islandora.api.php | 32 +++++++++++++++----------------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/css/islandora.print.css b/css/islandora.print.css index 364e75e0..45fca341 100644 --- a/css/islandora.print.css +++ b/css/islandora.print.css @@ -69,4 +69,4 @@ body.sidebar-first { .feed-icons { /* Hide sidebars and nav elements */ visibility: hidden !important; display: none !important; -} \ No newline at end of file +} diff --git a/islandora.api.php b/islandora.api.php index 984ad6c3..4d54a00f 100644 --- a/islandora.api.php +++ b/islandora.api.php @@ -21,23 +21,21 @@ * An array whose values are markup. */ function hook_islandora_view_object($object, $user, $page_number, $page_size) { -// Example Implementation -// $islandora_object = islandora_object_load($object->id); -// $output = array(); -// if (in_array('islandora:sp_basic_image', $islandora_object->models)) { -// $resource_url = url("islandora/object/{$object->id}/datastream/OBJ/view"); -// $params = array( -// 'title' => $islandora_object->label, -// 'path' => $resource_url, -// ); - -// // Theme the image seperatly. -// $variables['islandora_img'] = theme('image', $params); -// $output = theme('islandora_default_print', array( -// 'islandora_content' => $variables['islandora_img'])); -// } - -// return $output; + $output = array(); + if (in_array('islandora:sp_basic_image', $object->models)) { + $resource_url = url("islandora/object/{$object->id}/datastream/OBJ/view"); + $params = array( + 'title' => $object->label, + 'path' => $resource_url, + ); + + // Theme the image seperatly. + $variables['islandora_img'] = theme('image', $params); + $output = theme('islandora_default_print', array( + 'islandora_content' => $variables['islandora_img'])); + } + + return $output; } /** * Generate a print friendly page for the given object. From 1bf6024431672b1fad589ed1e4ffa3c05431d50d Mon Sep 17 00:00:00 2001 From: MorganDawe Date: Mon, 5 Aug 2013 10:34:53 -0300 Subject: [PATCH 39/44] Updated via code review feedback. --- islandora.module | 42 ------------------------------------------ 1 file changed, 42 deletions(-) diff --git a/islandora.module b/islandora.module index 97081e32..625bb4e6 100644 --- a/islandora.module +++ b/islandora.module @@ -242,48 +242,6 @@ function islandora_menu() { 'access arguments' => array(FEDORA_PURGE, 4), 'load arguments' => array(2), ); -<<<<<<< HEAD -======= - $items['islandora/object/%islandora_object/datastream/%islandora_datastream/version'] = array( - 'title' => 'Datastream Versions', - 'page arguments' => array(4), - 'page callback' => 'islandora_datastream_version_table', - 'file' => 'includes/datastream.version.inc', - 'type' => MENU_CALLBACK, - 'access callback' => 'islandora_datastream_access', - 'access arguments' => array(ISLANDORA_VIEW_DATASTREAM_HISTORY, 4), - 'load arguments' => array(2), - ); - $items['islandora/object/%islandora_object/datastream/%islandora_datastream/version/%/delete'] = array( - 'title' => 'Delete datastream version', - 'page arguments' => array('islandora_delete_datastream_version_form', 4, 6), - 'page callback' => 'drupal_get_form', - 'file' => 'includes/datastream.version.inc', - 'type' => MENU_CALLBACK, - 'access callback' => 'islandora_datastream_access', - 'access arguments' => array(FEDORA_PURGE, 4), - 'load arguments' => array(2), - ); - $items['islandora/object/%islandora_object/datastream/%islandora_datastream/version/%/view'] = array( - 'title' => 'View datastream version', - 'page callback' => 'islandora_view_datastream', - 'page arguments' => array(4, FALSE, 6), - 'type' => MENU_CALLBACK, - 'file' => 'includes/datastream.inc', - 'access callback' => 'islandora_datastream_access', - 'access arguments' => array(ISLANDORA_VIEW_DATASTREAM_HISTORY, 4), - 'load arguments' => array(2), - ); - $items['islandora/object/%islandora_object/print'] = array( - 'title' => 'Print Object', - 'page callback' => 'islandora_print_object', - 'page arguments' => array(2), - 'type' => MENU_CALLBACK, - 'access callback' => 'islandora_object_access', - 'access arguments' => array(FEDORA_VIEW_OBJECTS, 2), - 'load arguments' => array(2), - ); ->>>>>>> 73e09a9d0d9f0f91f2cbca4d6a204a96c9695fa1 $items['islandora/object/%islandora_object/download_clip'] = array( 'page callback' => 'islandora_download_clip', 'page arguments' => array(2), From 735cdca6dac996dc79c79aac27cfac2f7eabe089 Mon Sep 17 00:00:00 2001 From: MorganDawe Date: Mon, 5 Aug 2013 11:37:36 -0300 Subject: [PATCH 40/44] Travis build was failing, added menu callbacks back into core. --- islandora.module | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/islandora.module b/islandora.module index 625bb4e6..4b0a5411 100644 --- a/islandora.module +++ b/islandora.module @@ -242,6 +242,45 @@ function islandora_menu() { 'access arguments' => array(FEDORA_PURGE, 4), 'load arguments' => array(2), ); + $items['islandora/object/%islandora_object/datastream/%islandora_datastream/version'] = array( + 'title' => 'Datastream Versions', + 'page arguments' => array(4), + 'page callback' => 'islandora_datastream_version_table', + 'file' => 'includes/datastream.version.inc', + 'type' => MENU_CALLBACK, + 'access callback' => 'islandora_datastream_access', + 'access arguments' => array(ISLANDORA_VIEW_DATASTREAM_HISTORY, 4), + 'load arguments' => array(2), + ); + $items['islandora/object/%islandora_object/datastream/%islandora_datastream/version/%/delete'] = array( + 'title' => 'Delete datastream version', + 'page arguments' => array('islandora_delete_datastream_version_form', 4, 6), + 'page callback' => 'drupal_get_form', + 'file' => 'includes/datastream.version.inc', + 'type' => MENU_CALLBACK, + 'access callback' => 'islandora_datastream_access', + 'access arguments' => array(FEDORA_PURGE, 4), + 'load arguments' => array(2), + ); + $items['islandora/object/%islandora_object/datastream/%islandora_datastream/version/%/view'] = array( + 'title' => 'View datastream version', + 'page callback' => 'islandora_view_datastream', + 'page arguments' => array(4, FALSE, 6), + 'type' => MENU_CALLBACK, + 'file' => 'includes/datastream.inc', + 'access callback' => 'islandora_datastream_access', + 'access arguments' => array(ISLANDORA_VIEW_DATASTREAM_HISTORY, 4), + 'load arguments' => array(2), + ); + $items['islandora/object/%islandora_object/print'] = array( + 'title' => 'Print Object', + 'page callback' => 'islandora_print_object', + 'page arguments' => array(2), + 'type' => MENU_CALLBACK, + 'access callback' => 'islandora_object_access', + 'access arguments' => array(FEDORA_VIEW_OBJECTS, 2), + 'load arguments' => array(2), + ); $items['islandora/object/%islandora_object/download_clip'] = array( 'page callback' => 'islandora_download_clip', 'page arguments' => array(2), From 86431678d0f0a6e32cba37aea162a64fbc48e1a0 Mon Sep 17 00:00:00 2001 From: MorganDawe Date: Tue, 6 Aug 2013 09:07:07 -0300 Subject: [PATCH 41/44] Corrected duplicate menu access path in core. --- islandora.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/islandora.module b/islandora.module index 4b0a5411..0704bfc2 100644 --- a/islandora.module +++ b/islandora.module @@ -272,7 +272,7 @@ function islandora_menu() { 'access arguments' => array(ISLANDORA_VIEW_DATASTREAM_HISTORY, 4), 'load arguments' => array(2), ); - $items['islandora/object/%islandora_object/print'] = array( + $items['islandora/object/%islandora_object/printer'] = array( 'title' => 'Print Object', 'page callback' => 'islandora_print_object', 'page arguments' => array(2), From 0f4a02b7f024e255de11cd5d1952eb568fbf86e4 Mon Sep 17 00:00:00 2001 From: MorganDawe Date: Tue, 6 Aug 2013 11:23:14 -0300 Subject: [PATCH 42/44] After consulting my coworkers, i have remoted the previous print preview menu callback in favor of the new print callback i have implemented. --- islandora.module | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/islandora.module b/islandora.module index 0704bfc2..8a136988 100644 --- a/islandora.module +++ b/islandora.module @@ -272,15 +272,6 @@ function islandora_menu() { 'access arguments' => array(ISLANDORA_VIEW_DATASTREAM_HISTORY, 4), 'load arguments' => array(2), ); - $items['islandora/object/%islandora_object/printer'] = array( - 'title' => 'Print Object', - 'page callback' => 'islandora_print_object', - 'page arguments' => array(2), - 'type' => MENU_CALLBACK, - 'access callback' => 'islandora_object_access', - 'access arguments' => array(FEDORA_VIEW_OBJECTS, 2), - 'load arguments' => array(2), - ); $items['islandora/object/%islandora_object/download_clip'] = array( 'page callback' => 'islandora_download_clip', 'page arguments' => array(2), @@ -329,12 +320,6 @@ function islandora_theme() { 'file' => 'theme/theme.inc', 'template' => 'theme/islandora-object-edit', 'variables' => array('islandora_object' => NULL), - ), - // Default edit page. - 'islandora_default_print' => array( - 'file' => 'theme/theme.inc', - 'template' => 'theme/islandora-object-print', - 'variables' => array('islandora_object' => NULL), ), // Admin table for solution pack viewer selection. 'islandora_viewers_table' => array( @@ -1356,24 +1341,6 @@ function islandora_entity_property_info() { return $info; } - -/** - * Renders the print page for the given object. - * - * Modules can either implement preprocess functions to append content onto the - * 'content' variable, or override the display by providing a theme suggestion. - * - * @param AbstractObject $object - * The object. - * - * @return array - * A renderable array. - */ -function islandora_print_object(AbstractObject $object) { - drupal_set_title($object->label); - return theme('islandora_object_print', array('object' => $object)); -} - /** * Menu callback downloads the given clip. */ From cc1e4138fd5fc8297ae051fe8fdcc40a04a893a6 Mon Sep 17 00:00:00 2001 From: jonathangreen Date: Tue, 6 Aug 2013 12:05:13 -0300 Subject: [PATCH 43/44] Fixed bug in audio/video solution pack We were implicitly passing the extra datastream version paramerter in the islandora video solution pack because we were going to the url: islandora/object/pid/datastream/MP3/view/name.mp3 and because the datastream view fucntion now took an extra parameter this was getting implicitly passed on. So we would try to download version name.mp3. This makes sure that it won't happen. --- islandora.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/islandora.module b/islandora.module index 8a8ee6be..9f1532c1 100644 --- a/islandora.module +++ b/islandora.module @@ -189,7 +189,7 @@ function islandora_menu() { $items['islandora/object/%islandora_object/datastream/%islandora_datastream'] = array( 'title' => 'View datastream', 'page callback' => 'islandora_view_datastream', - 'page arguments' => array(4, FALSE), + 'page arguments' => array(4, FALSE, NULL), 'type' => MENU_CALLBACK, 'file' => 'includes/datastream.inc', 'access callback' => 'islandora_datastream_access', From aba19555cae618000fdc5eb87033a2160baacbec Mon Sep 17 00:00:00 2001 From: William Panting Date: Tue, 13 Aug 2013 12:05:27 -0300 Subject: [PATCH 44/44] test working again --- tests/islandora_hooked_access_test.module | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/islandora_hooked_access_test.module b/tests/islandora_hooked_access_test.module index de417738..e69fc1cc 100644 --- a/tests/islandora_hooked_access_test.module +++ b/tests/islandora_hooked_access_test.module @@ -23,6 +23,9 @@ function islandora_hooked_access_test_islandora_object_access($op, $object, $use * Implements hook_islandora_datastream_access(). */ function islandora_hooked_access_test_islandora_datastream_access($op, $datastream, $user) { + if ($op == FEDORA_PURGE) { + return FALSE; + } if (isset($_SESSION['islandora_hooked_access_test']) && $_SESSION['islandora_hooked_access_test'] === func_get_args()) { return TRUE; }