Browse Source

Merge branch '7.x' of github.com:Islandora/islandora into HEAD

pull/384/head
root 11 years ago
parent
commit
2feda07786
  1. 3
      .travis.yml
  2. 72
      css/islandora.print.css
  3. BIN
      images/print-icon.png
  4. 6
      includes/add_datastream.form.inc
  5. 45
      includes/datastream.inc
  6. 127
      includes/datastream.version.inc
  7. 1
      includes/dublin_core.inc
  8. 32
      includes/ingest.form.inc
  9. 3
      includes/object.entity_controller.inc
  10. 161
      includes/solution_packs.inc
  11. 26
      includes/tuque_wrapper.inc
  12. 47
      includes/utilities.inc
  13. 24
      islandora.api.php
  14. 142
      islandora.drush.inc
  15. 1
      islandora.info
  16. 217
      islandora.module
  17. 18
      js/add_print.js
  18. 198
      tests/datastream_versions.test
  19. 30
      tests/hooks.test
  20. 3
      tests/islandora_hooked_access_test.module
  21. 12
      tests/islandora_ingest_test.module
  22. 60
      tests/islandora_web_test_case.inc
  23. 4
      tests/scripts/travis_setup.sh
  24. 18
      theme/islandora-object-img-print.tpl.php
  25. 30
      theme/islandora-object-print.tpl.php
  26. 1
      theme/islandora-object.tpl.php
  27. 145
      theme/theme.inc
  28. 13
      xml/strip_newlines_and_whitespace.xsl

3
.travis.yml

@ -4,9 +4,10 @@ php:
- 5.4 - 5.4
branches: branches:
only: only:
- 7.x - /^7.x/
env: env:
- FEDORA_VERSION="3.5" - FEDORA_VERSION="3.5"
- FEDORA_VERSION="3.6.2"
before_install: before_install:
- export ISLANDORA_DIR=$TRAVIS_BUILD_DIR - export ISLANDORA_DIR=$TRAVIS_BUILD_DIR
- $TRAVIS_BUILD_DIR/tests/scripts/travis_setup.sh - $TRAVIS_BUILD_DIR/tests/scripts/travis_setup.sh

72
css/islandora.print.css

@ -0,0 +1,72 @@
/**
* @file
* Print styling
*
* We provide some sane print styling for Drupal, hiding most visuals.
*/
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;
}

BIN
images/print-icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

6
includes/add_datastream.form.inc

@ -32,7 +32,7 @@ function islandora_add_datastream_form(array $form, array &$form_state, Abstract
'#attributes' => array( '#attributes' => array(
'enctype' => 'multipart/form-data', 'enctype' => 'multipart/form-data',
), ),
'dsid' => array( 'dsid_fieldset' => array(
'#type' => 'fieldset', '#type' => 'fieldset',
'#title' => 'Add a datastream', '#title' => 'Add a datastream',
'#collapsible' => FALSE, '#collapsible' => FALSE,
@ -40,7 +40,6 @@ function islandora_add_datastream_form(array $form, array &$form_state, Abstract
'dsid' => array( 'dsid' => array(
'#title' => 'Datastream ID', '#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: <b>@unused_dsids</b>.", array('@unused_dsids' => $unused_datastreams)), '#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: <b>@unused_dsids</b>.", array('@unused_dsids' => $unused_datastreams)),
),
'#type' => 'textfield', '#type' => 'textfield',
'#size' => 64, '#size' => 64,
'#maxlength' => 64, '#maxlength' => 64,
@ -79,6 +78,7 @@ function islandora_add_datastream_form(array $form, array &$form_state, Abstract
'#type' => 'submit', '#type' => 'submit',
'#value' => t('Add Datastream'), '#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 * @param array $form
* The Drupal form. * The Drupal form.

45
includes/datastream.inc

@ -26,8 +26,19 @@ function islandora_download_datastream(AbstractDatastream $datastream) {
* @param bool $download * @param bool $download
* If TRUE the file is download to the user computer for viewing otherwise it * If TRUE the file is download to the user computer for viewing otherwise it
* will attempt to display in the browser natively. * 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('Cache-Control');
header_remove('Expires'); header_remove('Expires');
header('Content-type: ' . $datastream->mimetype); header('Content-type: ' . $datastream->mimetype);
@ -69,12 +80,31 @@ function islandora_datastream_get_human_readable_size(AbstractDatastream $datast
* *
* @param AbstractDatastream $datastream * @param AbstractDatastream $datastream
* The datastream to generated the url to. * 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 * @return string
* either the 'view' or 'download' url for the given datastream. * either the 'view' or 'download' url for the given datastream.
*/ */
function islandora_datastream_get_url(AbstractDatastream $datastream, $type = 'download') { function islandora_datastream_get_url(AbstractDatastream $datastream, $type = 'download', $version = NULL) {
return $datastream->controlGroup == 'R' ? $datastream->url : "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/$type"; 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;
}
} }
/** /**
@ -82,6 +112,9 @@ function islandora_datastream_get_url(AbstractDatastream $datastream, $type = 'd
* *
* @param AbstractDatastream $datastream * @param AbstractDatastream $datastream
* The datastream to generated the url to. * 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) { function islandora_datastream_get_delete_link(AbstractDatastream $datastream) {
$message = islandora_deprecated('7.x-1.2', 'Use the "islandora_datastream_delete_link" theme implementation.'); $message = islandora_deprecated('7.x-1.2', 'Use the "islandora_datastream_delete_link" theme implementation.');
@ -97,6 +130,9 @@ function islandora_datastream_get_delete_link(AbstractDatastream $datastream) {
* *
* @param AbstractDatastream $datastream * @param AbstractDatastream $datastream
* The datastream to generated the url to. * 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) { function islandora_datastream_edit_get_link(AbstractDatastream $datastream) {
$message = islandora_deprecated('7.x-1.2', 'Use the "islandora_datastream_edit_link" theme implementation.'); $message = islandora_deprecated('7.x-1.2', 'Use the "islandora_datastream_edit_link" theme implementation.');
@ -139,6 +175,9 @@ function islandora_edit_datastream(AbstractDatastream $datastream) {
* *
* @param array $edit_registry * @param array $edit_registry
* A list of 'islandora_edit_datastream_registry' values. * 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) { function islandora_edit_datastream_registry_render(array $edit_registry) {
$markup = ''; $markup = '';

127
includes/datastream.version.inc

@ -0,0 +1,127 @@
<?php
/**
* @file
* The form displayed that shows the datastream version history.
*/
/**
* Function that returns markup for the datastream versions page.
*/
function islandora_datastream_version_table($datastream) {
module_load_include('inc', 'islandora', 'includes/datastream');
module_load_include('inc', 'islandora', 'includes/utilities');
drupal_set_title(t("@dsid Previous Versions", array('@dsid' => $datastream->id)));
$header = array();
$header[] = array('data' => t('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.
* @param string $version
* The version number of the datastream we are trying to delete.
*
* @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 successfully deleted from Islandora object %o', array(
'%d' => $datastream_id,
'%o' => $object->label)));
$form_state['redirect'] = "islandora/object/{$object->id}/datastream/{$datastream->id}/version";
}

1
includes/dublin_core.inc

@ -133,6 +133,7 @@ class DublinCore {
$dc_array[$field]['label'] = $element_label; $dc_array[$field]['label'] = $element_label;
$dc_array[$field]['value'] = $value; $dc_array[$field]['value'] = $value;
$dc_array[$field]['class'] = drupal_strtolower(preg_replace('/[^A-Za-z0-9]/', '-', $field)); $dc_array[$field]['class'] = drupal_strtolower(preg_replace('/[^A-Za-z0-9]/', '-', $field));
$dc_array[$field]['dcterms'] = preg_replace('/^dc/', 'dcterms', $field);
} }
} }
} }

32
includes/ingest.form.inc

@ -186,10 +186,10 @@ function islandora_ingest_form_get_step(array &$form_state, $step_id = NULL) {
* *
* @param array $form_state * @param array $form_state
* The Drupal 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. * 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. * The next step if found, NULL otherwise.
*/ */
function islandora_ingest_form_get_next_step(array &$form_state, array $step = NULL) { 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 * @param array $form_state
* The Drupal 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. * 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. * The next step if found, NULL otherwise.
*/ */
function islandora_ingest_form_get_previous_step(array &$form_state, array $step = NULL) { 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. * The Drupal form.
* @param array $form_state * @param array $form_state
* The Drupal 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 * @return array
* The form definition of the current step. * 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. * The Drupal form.
* @param array $form_state * @param array $form_state
* The Drupal form state. * The Drupal form state.
* @param array $step
* The step we are executing.
* *
* @return array * @return array
* The form definition of the given step. * 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. * The Drupal form.
* @param array $form_state * @param array $form_state
* The Drupal 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) { function islandora_ingest_form_execute_consecutive_callback_steps(array $form, array &$form_state, array $step) {
do { do {
@ -409,6 +416,8 @@ function islandora_ingest_form_execute_consecutive_callback_steps(array $form, a
* The Drupal form. * The Drupal form.
* @param array $form_state * @param array $form_state
* The Drupal 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) { function islandora_ingest_form_execute_callback_step(array $form, array &$form_state, array $step) {
$args = array(&$form_state); $args = array(&$form_state);
@ -425,6 +434,8 @@ function islandora_ingest_form_execute_callback_step(array $form, array &$form_s
* The Drupal form. * The Drupal form.
* @param array $form_state * @param array $form_state
* The Drupal 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) { function islandora_ingest_form_undo_consecutive_callback_steps(array $form, array &$form_state, array $step) {
do { do {
@ -443,6 +454,8 @@ function islandora_ingest_form_undo_consecutive_callback_steps(array $form, arra
* The Drupal form. * The Drupal form.
* @param array $form_state * @param array $form_state
* The Drupal 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) { function islandora_ingest_form_undo_callback_step(array $form, array &$form_state, array $step) {
$args = array(&$form_state); $args = array(&$form_state);
@ -457,11 +470,13 @@ function islandora_ingest_form_undo_callback_step(array $form, array &$form_stat
* The Drupal form. * The Drupal form.
* @param array $form_state * @param array $form_state
* The Drupal form state. * The Drupal form state.
* @param array $step
* An array defining a ingest step.
* *
* @return array * @return array
* The stepified Drupal form definition for the given step. * 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); $first_form_step = islandora_ingest_form_on_first_form_step($form_state);
$last_form_step = islandora_ingest_form_on_last_form_step($form_state); $last_form_step = islandora_ingest_form_on_last_form_step($form_state);
$form['form_step_id'] = array( $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. * Attempts to ingest every object built by the previous steps.
* *
* @param array $form
* The Drupal form.
* @param array $form_state * @param array $form_state
* The Drupal form state. * The Drupal form state.
*/ */
@ -703,7 +720,7 @@ function islandora_ingest_form_submit(array $form, array &$form_state) {
islandora_ingest_form_execute_consecutive_callback_steps($form, $form_state, $step); islandora_ingest_form_execute_consecutive_callback_steps($form, $form_state, $step);
} }
// Ingest the objects. // Ingest the objects.
foreach ($form_state['islandora']['objects'] as $object) { foreach ($form_state['islandora']['objects'] as &$object) {
try { try {
islandora_add_object($object); islandora_add_object($object);
$form_state['redirect'] = "islandora/object/{$object->id}"; $form_state['redirect'] = "islandora/object/{$object->id}";
@ -715,6 +732,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'); 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);
} }
/** /**

3
includes/object.entity_controller.inc

@ -24,6 +24,9 @@ class IslandoraObjectEntityController implements DrupalEntityControllerInterface
* The ID's of the entities. * The ID's of the entities.
* @param array $conditions * @param array $conditions
* The conditions to apply. * The conditions to apply.
*
* @return array
* An array of loaded objects.
*/ */
public function load($ids = array(), $conditions = array()) { public function load($ids = array(), $conditions = array()) {
if (!empty($conditions)) { if (!empty($conditions)) {

161
includes/solution_packs.inc

@ -5,11 +5,55 @@
* Admin and callback functions for solution pack management. * 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. * Solution pack admin page callback.
* *
* @return string * @return array
* The html repersentation of all solution pack forms for required objects. * Renderable array of all solution pack forms for required objects.
*/ */
function islandora_solution_packs_admin() { function islandora_solution_packs_admin() {
module_load_include('inc', 'islandora', 'includes/utilities'); module_load_include('inc', 'islandora', 'includes/utilities');
@ -18,17 +62,15 @@ function islandora_solution_packs_admin() {
return ''; return '';
} }
$connection = islandora_get_tuque_connection();
drupal_add_css(drupal_get_path('module', 'islandora') . '/css/islandora.admin.css'); drupal_add_css(drupal_get_path('module', 'islandora') . '/css/islandora.admin.css');
$output = ''; $output = array();
$enabled_solution_packs = module_invoke_all('islandora_required_objects', $connection); $enabled_solution_packs = islandora_solution_packs_get_required_objects();
foreach ($enabled_solution_packs as $solution_pack_module => $solution_pack_info) { foreach ($enabled_solution_packs as $solution_pack_module => $solution_pack_info) {
// @todo We should probably get the title of the solution pack from the // @todo We should probably get the title of the solution pack from the
// systems table for consistency in the interface. // systems table for consistency in the interface.
$solution_pack_name = $solution_pack_info['title']; $solution_pack_name = $solution_pack_info['title'];
$objects = array_filter($solution_pack_info['objects']); $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[$solution_pack_module] = drupal_get_form('islandora_solution_pack_form_' . $solution_pack_module, $solution_pack_module, $solution_pack_name, $objects);
$output .= drupal_render($form);
} }
return $output; 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) { function islandora_solution_pack_form_submit(array $form, array &$form_state) {
$solution_pack_module = $form_state['values']['solution_pack_module']; $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( $batch = array(
'title' => t('Installing / Updating solution pack objects'), 'title' => t('Installing / Updating solution pack objects'),
'file' => drupal_get_path('module', 'islandora') . '/includes/solution_packs.inc', 'file' => drupal_get_path('module', 'islandora') . '/includes/solution_packs.inc',
'operations' => array(), '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['operations'][] = array('islandora_solution_pack_batch_operation_reingest_object', array($object));
} }
batch_set($batch);
// Hook to let solution pack objects be modified. return $batch;
// 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);
} }
/** /**
@ -245,14 +305,16 @@ function islandora_solution_pack_batch_operation_reingest_object(AbstractObject
* install/unistall hooks. * install/unistall hooks.
* @param string $op * @param string $op
* The operation to perform, either install or uninstall. * 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 * @todo Implement hook_modules_installed/hook_modules_uninstalled instead of
* calling this function directly. * calling this function directly.
* @todo Remove the second parameter and have two seperate functions. * @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') { if ($op == 'uninstall') {
islandora_uninstall_solution_pack($module); islandora_uninstall_solution_pack($module, $force);
return; return;
} }
@ -267,9 +329,9 @@ function islandora_install_solution_pack($module, $op = 'install') {
'!admin_link' => $admin_link, '!admin_link' => $admin_link,
); );
module_load_include('module', 'islandora', 'islandora'); drupal_load('module', 'islandora');
module_load_include('inc', 'islandora', 'includes/utilities'); 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_file = drupal_get_path('module', $module) . "/{$module}.info";
$info_array = drupal_parse_info_file($info_file); $info_array = drupal_parse_info_file($info_file);
$module_name = $info_array['name']; $module_name = $info_array['name'];
@ -279,8 +341,8 @@ function islandora_install_solution_pack($module, $op = 'install') {
return; return;
} }
$connection = islandora_get_tuque_connection(); $connection = islandora_get_tuque_connection();
$required_objects = module_invoke($module, 'islandora_required_objects', $connection); $required_objects = islandora_solution_packs_get_required_objects($module);
$objects = $required_objects[$module]['objects']; $objects = $required_objects['objects'];
$status_messages = array( $status_messages = array(
'up_to_date' => $t('The object already exists and is up-to-date.', $t_params), '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), 'missing_datastream' => $t('The object already exists but is missing a datastream. Please reinstall the object on the !admin_link page.', $t_params),
@ -288,11 +350,13 @@ 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), '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) { foreach ($objects as $object) {
$query = $connection->api->a->findObjects('query', 'pid=' . $object->id); $already_exists = islandora_object_load($object->id);
$already_exists = !empty($query['results']);
$label = $object->label; $label = $object->label;
$object_link = l($label, "islandora/object/{$object->id}"); $object_link = l($label, "islandora/object/{$object->id}");
$deleted = FALSE;
if ($already_exists) { if ($already_exists) {
if (!$force) {
$object_status = islandora_check_object_status($object); $object_status = islandora_check_object_status($object);
$here_params = array( $here_params = array(
'!summary' => $t("@module: Did not install !object_link.", array( '!summary' => $t("@module: Did not install !object_link.", array(
@ -301,20 +365,38 @@ function islandora_install_solution_pack($module, $op = 'install') {
'!description' => $status_messages[$object_status['status']], '!description' => $status_messages[$object_status['status']],
); );
drupal_set_message(filter_xss(format_string('!summary !description', $here_params)), 'warning'); drupal_set_message(filter_xss(format_string('!summary !description', $here_params)), 'warning');
continue;
} }
else { else {
$deleted = islandora_delete_object($already_exists);
}
}
if ($already_exists && $deleted || !$already_exists) {
$object = islandora_add_object($object); $object = islandora_add_object($object);
if ($object) { if ($object) {
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( drupal_set_message(filter_xss($t('@module: Successfully installed. !object_link.', array(
'!object_link' => $object_link, '!object_link' => $object_link,
) + $t_params)), 'status'); ) + $t_params)), 'status');
} }
}
else { else {
drupal_set_message($t('@module: Failed to install. @label.', array( drupal_set_message($t('@module: Failed to install. @label.', array(
'@label' => $label, '@label' => $label,
) + $t_params), 'warning'); ) + $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 * @param string $module
* The solution pack to uninstall. * The solution pack to uninstall.
* @param bool $force
* Force the objects to be removed.
* *
* @todo Implement hook_modules_uninstalled instead of calling this function * @todo Implement hook_modules_uninstalled instead of calling this function
* directly for each solution pack. * directly for each solution pack.
*/ */
function islandora_uninstall_solution_pack($module) { function islandora_uninstall_solution_pack($module, $force = FALSE) {
$t = get_t(); $t = get_t();
module_load_include('module', 'islandora', 'islandora'); drupal_load('module', 'islandora');
module_load_include('inc', 'islandora', 'includes/utilities'); 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'); $config_link = l($t('Islandora configuration'), 'admin/islandora/configure');
$info_file = drupal_get_path('module', $module) . "/{$module}.info"; $info_file = drupal_get_path('module', $module) . "/{$module}.info";
$info_array = drupal_parse_info_file($info_file); $info_array = drupal_parse_info_file($info_file);
@ -345,14 +429,16 @@ function islandora_uninstall_solution_pack($module) {
return; return;
} }
$connection = islandora_get_tuque_connection(); $connection = islandora_get_tuque_connection();
$required_objects = module_invoke($module, 'islandora_required_objects', $connection); $required_objects = islandora_solution_packs_get_required_objects($module);
$objects = $required_objects[$module]['objects']; $objects = $required_objects['objects'];
$filter = function($o) use($connection) { $filter = function($o) use($connection) {
$param = "pid={$o->id}"; $param = "pid={$o->id}";
$query = $connection->api->a->findObjects('query', $param); $query = $connection->api->a->findObjects('query', $param);
return !empty($query['results']); return !empty($query['results']);
}; };
$existing_objects = array_filter($objects, $filter); $existing_objects = array_filter($objects, $filter);
if (!$force) {
foreach ($existing_objects as $object) { foreach ($existing_objects as $object) {
$object_link = l($object->label, "islandora/object/{$object->id}"); $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( $msg = $t('@module: Did not remove !object_link. It may be used by other sites.', array(
@ -362,6 +448,17 @@ function islandora_uninstall_solution_pack($module) {
drupal_set_message(filter_xss($msg), 'warning'); 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));
}
}
} }
/** /**
@ -430,13 +527,21 @@ function islandora_check_object_status(AbstractObject $object_definition) {
// be equal as Fedora does some XML mangling. In order for C14N to work // 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. // 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 // 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();
$xslt->importStyleSheet($xsl);
$object_definition_dom = new DOMDocument(); $object_definition_dom = new DOMDocument();
$object_definition_dom->preserveWhiteSpace = FALSE; $object_definition_dom->preserveWhiteSpace = FALSE;
$object_definition_dom->loadXML(str_replace('info:', 'http://', $ds->content)); $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 = new DOMDocument();
$object_actual_dom->preserveWhiteSpace = FALSE; $object_actual_dom->preserveWhiteSpace = FALSE;
$object_actual_dom->loadXML(str_replace('info:', 'http://', $existing_object[$ds->id]->content)); $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. // Fedora changes the xml structure so we need to cannonize it.
if ($object_actual_dom->C14N() != $object_definition_dom->C14N()) { if ($object_actual_dom->C14N() != $object_definition_dom->C14N()) {

26
includes/tuque_wrapper.inc

@ -82,13 +82,26 @@ class IslandoraFedoraRepository extends FedoraRepository {
* @see FedoraRepository::ingestObject() * @see FedoraRepository::ingestObject()
*/ */
public function ingestObject(NewFedoraObject &$object) { public function ingestObject(NewFedoraObject &$object) {
$context = array( try {
foreach ($object as $dsid => $datastream) {
$datastream_context = array(
'action' => 'ingest', 'action' => 'ingest',
'block' => FALSE, 'block' => FALSE,
); );
islandora_alter_object($object, $context); islandora_alter_datastream($object, $datastream, $datastream_context);
try { if ($datastream_context['block']) {
if ($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.'); throw new Exception('Ingest Object was blocked.');
} }
$ret = parent::ingestObject($object); $ret = parent::ingestObject($object);
@ -194,6 +207,9 @@ class IslandoraFedoraApiM extends FedoraApiM {
'params' => $params, 'params' => $params,
); );
islandora_alter_datastream($object, $datastream, $context); islandora_alter_datastream($object, $datastream, $context);
if (isset($params['lastModifiedDate'])) {
$params['lastModifiedDate'] = (string) $object[$dsid]->createdDate;
}
try { try {
if ($context['block']) { if ($context['block']) {
throw new Exception('Modify Datastream was blocked.'); throw new Exception('Modify Datastream was blocked.');
@ -269,7 +285,6 @@ class IslandoraFedoraApiM extends FedoraApiM {
switch ($action) { switch ($action) {
case 'block': case 'block':
throw new Exception('Purge Datastream was blocked.'); throw new Exception('Purge Datastream was blocked.');
break;
case 'delete': case 'delete':
$object[$dsid]->state = 'D'; $object[$dsid]->state = 'D';
@ -313,7 +328,6 @@ class IslandoraFedoraApiM extends FedoraApiM {
switch ($action) { switch ($action) {
case 'block': case 'block':
throw new Exception('Purge object was blocked.'); throw new Exception('Purge object was blocked.');
break;
case 'delete': case 'delete':
$object->state = 'D'; $object->state = 'D';

47
includes/utilities.inc

@ -14,6 +14,8 @@
* *
* @param int $bytes * @param int $bytes
* Size in bytes to convert * Size in bytes to convert
* @param int $precision
* The amount of decimal precision to show.
* *
* @return string * @return string
* Human readable size. * Human readable size.
@ -865,3 +867,48 @@ function islandora_deprecated($release, $solution = NULL) {
} }
return $message; return $message;
} }
/**
* 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
* 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_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,
);
}
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,
);
}
}
unset($inner);
}
}
unset($value);
}

24
islandora.api.php

@ -21,8 +21,30 @@
* An array whose values are markup. * An array whose values are markup.
*/ */
function hook_islandora_view_object($object, $user, $page_number, $page_size) { function hook_islandora_view_object($object, $user, $page_number, $page_size) {
} $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.
*
* @param object $object
* The object form to print.
*/
function hook_islandora_view_print_object($object) {
}
/** /**
* Generate an object's display for the given content model. * Generate an object's display for the given content model.
* *

142
islandora.drush.inc

@ -0,0 +1,142 @@
<?php
/**
* @file
* Drush command/hook implementation.
*/
/**
* Implements hook_drush_command().
*/
function islandora_drush_command() {
$commands = array();
$commands['islandora-solution-pack-install-required-objects'] = array(
'description' => 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);
}
}

1
islandora.info

@ -17,4 +17,5 @@ files[] = tests/hooks.test
files[] = tests/ingest.test files[] = tests/ingest.test
files[] = tests/hooked_access.test files[] = tests/hooked_access.test
files[] = tests/islandora_manage_permissions.test files[] = tests/islandora_manage_permissions.test
files[] = tests/datastream_versions.test
php = 5.3 php = 5.3

217
islandora.module

@ -33,9 +33,11 @@ define('FEDORA_ADD_DS', 'add fedora datastreams');
define('FEDORA_INGEST', 'ingest fedora objects'); define('FEDORA_INGEST', 'ingest fedora objects');
define('FEDORA_PURGE', 'delete fedora objects and datastreams'); define('FEDORA_PURGE', 'delete fedora objects and datastreams');
define('FEDORA_MANAGE_PROPERTIES', 'manage object properties'); define('FEDORA_MANAGE_PROPERTIES', 'manage object properties');
define('ISLANDORA_VIEW_DATASTREAM_HISTORY', 'view old datastream versions');
// Hooks. // Hooks.
define('ISLANDORA_VIEW_HOOK', 'islandora_view_object'); define('ISLANDORA_VIEW_HOOK', 'islandora_view_object');
define('ISLANDORA_PRINT_HOOK', 'islandora_view_print_object');
define('ISLANDORA_EDIT_HOOK', 'islandora_edit_object'); define('ISLANDORA_EDIT_HOOK', 'islandora_edit_object');
define('ISLANDORA_OVERVIEW_HOOK', 'islandora_overview_object'); define('ISLANDORA_OVERVIEW_HOOK', 'islandora_overview_object');
define('ISLANDORA_PRE_INGEST_HOOK', 'islandora_ingest_pre_ingest'); define('ISLANDORA_PRE_INGEST_HOOK', 'islandora_ingest_pre_ingest');
@ -102,6 +104,13 @@ function islandora_menu() {
'access callback' => 'islandora_object_access_callback', 'access callback' => 'islandora_object_access_callback',
'access arguments' => array(FEDORA_VIEW_OBJECTS, 2), 'access arguments' => array(FEDORA_VIEW_OBJECTS, 2),
); );
$items['islandora/object/%islandora_object/print'] = 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( $items['islandora/object/%islandora_object/view'] = array(
'title' => 'View', 'title' => 'View',
'type' => MENU_DEFAULT_LOCAL_TASK, 'type' => MENU_DEFAULT_LOCAL_TASK,
@ -188,7 +197,7 @@ function islandora_menu() {
$items['islandora/object/%islandora_object/datastream/%islandora_datastream'] = array( $items['islandora/object/%islandora_object/datastream/%islandora_datastream'] = array(
'title' => 'View datastream', 'title' => 'View datastream',
'page callback' => 'islandora_view_datastream', 'page callback' => 'islandora_view_datastream',
'page arguments' => array(4, FALSE), 'page arguments' => array(4, FALSE, NULL),
'type' => MENU_CALLBACK, 'type' => MENU_CALLBACK,
'file' => 'includes/datastream.inc', 'file' => 'includes/datastream.inc',
'access callback' => 'islandora_datastream_access', 'access callback' => 'islandora_datastream_access',
@ -233,13 +242,34 @@ function islandora_menu() {
'access arguments' => array(FEDORA_PURGE, 4), 'access arguments' => array(FEDORA_PURGE, 4),
'load arguments' => array(2), 'load arguments' => array(2),
); );
$items['islandora/object/%islandora_object/print'] = array( $items['islandora/object/%islandora_object/datastream/%islandora_datastream/version'] = array(
'title' => 'Print Object', 'title' => 'Datastream Versions',
'page callback' => 'islandora_print_object', 'page arguments' => array(4),
'page arguments' => array(2), 'page callback' => 'islandora_datastream_version_table',
'file' => 'includes/datastream.version.inc',
'type' => MENU_CALLBACK, 'type' => MENU_CALLBACK,
'access callback' => 'islandora_object_access', 'access callback' => 'islandora_datastream_access',
'access arguments' => array(FEDORA_VIEW_OBJECTS, 2), '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), 'load arguments' => array(2),
); );
$items['islandora/object/%islandora_object/download_clip'] = array( $items['islandora/object/%islandora_object/download_clip'] = array(
@ -268,8 +298,9 @@ function islandora_menu() {
function islandora_admin_paths() { function islandora_admin_paths() {
$paths = array(); $paths = array();
$paths['islandora/object/*/manage*'] = TRUE; $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/*/edit'] = TRUE;
$paths['islandora/object/*/datastream/*/versions'] = TRUE;
return $paths; return $paths;
} }
@ -298,7 +329,11 @@ function islandora_theme() {
// Print object view. // Print object view.
'islandora_object_print' => array( 'islandora_object_print' => array(
'file' => 'theme/theme.inc', '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. // Render a bunch of objects as either a grid or a list.
'islandora_objects' => array( 'islandora_objects' => array(
@ -329,16 +364,24 @@ function islandora_theme() {
), ),
'islandora_datastream_delete_link' => array( 'islandora_datastream_delete_link' => array(
'file' => 'theme/theme.inc', 'file' => 'theme/theme.inc',
'variables' => array('datastream' => NULL), 'variables' => array('datastream' => NULL, 'version' => NULL),
), ),
'islandora_datastream_view_link' => array( 'islandora_datastream_view_link' => array(
'file' => 'theme/theme.inc', 'file' => 'theme/theme.inc',
'variables' => array('datastream' => NULL), 'variables' => array(
'datastream' => NULL,
'version' => NULL,
'label' => NULL,
),
), ),
'islandora_datastream_download_link' => array( 'islandora_datastream_download_link' => array(
'file' => 'theme/theme.inc', 'file' => 'theme/theme.inc',
'variables' => array('datastream' => NULL), 'variables' => array('datastream' => NULL),
), ),
'islandora_datastream_version_link' => array(
'file' => 'theme/theme.inc',
'variables' => array('datastream' => NULL),
),
); );
} }
@ -371,6 +414,10 @@ function islandora_permission() {
'title' => t('Manage object properties'), 'title' => t('Manage object properties'),
'description' => t('Modify object labels, owner IDs, and states.'), '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.'),
),
); );
} }
@ -624,6 +671,7 @@ function islandora_manage_overview_object(AbstractObject $object) {
$output = array(); $output = array();
foreach (islandora_build_hook_list(ISLANDORA_OVERVIEW_HOOK, $object->models) as $hook) { foreach (islandora_build_hook_list(ISLANDORA_OVERVIEW_HOOK, $object->models) as $hook) {
$temp = module_invoke_all($hook, $object); $temp = module_invoke_all($hook, $object);
islandora_as_renderable_array($temp);
if (!empty($temp)) { if (!empty($temp)) {
$output = array_merge_recursive($output, $temp); $output = array_merge_recursive($output, $temp);
} }
@ -634,7 +682,8 @@ function islandora_manage_overview_object(AbstractObject $object) {
} }
arsort($output); arsort($output);
drupal_alter(ISLANDORA_OVERVIEW_HOOK, $object, $output); drupal_alter(ISLANDORA_OVERVIEW_HOOK, $object, $output);
return implode('', $output); islandora_as_renderable_array($output);
return $output;
} }
/** /**
@ -649,7 +698,11 @@ function islandora_manage_overview_object(AbstractObject $object) {
*/ */
function islandora_default_islandora_manage_overview_object(AbstractObject $object) { function islandora_default_islandora_manage_overview_object(AbstractObject $object) {
$output = theme('islandora_default_overview', array('islandora_object' => $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 +728,7 @@ function islandora_edit_object(AbstractObject $object) {
$output = array(); $output = array();
foreach (islandora_build_hook_list(ISLANDORA_EDIT_HOOK, $object->models) as $hook) { foreach (islandora_build_hook_list(ISLANDORA_EDIT_HOOK, $object->models) as $hook) {
$temp = module_invoke_all($hook, $object); $temp = module_invoke_all($hook, $object);
islandora_as_renderable_array($temp);
if (!empty($temp)) { if (!empty($temp)) {
$output = array_merge_recursive($output, $temp); $output = array_merge_recursive($output, $temp);
} }
@ -685,7 +739,8 @@ function islandora_edit_object(AbstractObject $object) {
} }
arsort($output); arsort($output);
drupal_alter(ISLANDORA_EDIT_HOOK, $object, $output); drupal_alter(ISLANDORA_EDIT_HOOK, $object, $output);
return implode('', $output); islandora_as_renderable_array($output);
return $output;
} }
/** /**
@ -700,7 +755,11 @@ function islandora_edit_object(AbstractObject $object) {
*/ */
function islandora_default_islandora_edit_object(AbstractObject $object) { function islandora_default_islandora_edit_object(AbstractObject $object) {
$output = theme('islandora_default_edit', array('islandora_object' => $object)); $output = theme('islandora_default_edit', array('islandora_object' => $object));
return array('Default Edit output' => $output); return array(
'Default Edit output' => array(
'#markup' => $output,
),
);
} }
/** /**
@ -732,8 +791,24 @@ function islandora_view_default_object() {
function islandora_view_object(AbstractObject $object) { function islandora_view_object(AbstractObject $object) {
module_load_include('inc', 'islandora', 'includes/breadcrumb'); module_load_include('inc', 'islandora', 'includes/breadcrumb');
module_load_include('inc', 'islandora', 'includes/utilities'); 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/object/' . $object->id . '/print')),
array('type' => 'setting'));
drupal_add_js($path . '/js/add_print.js');
drupal_set_title($object->label); drupal_set_title($object->label);
drupal_set_breadcrumb(islandora_get_breadcrumbs($object)); drupal_set_breadcrumb(islandora_get_breadcrumbs($object));
// Optional pager parameters. // Optional pager parameters.
$page_number = (empty($_GET['page'])) ? '1' : $_GET['page']; $page_number = (empty($_GET['page'])) ? '1' : $_GET['page'];
$page_size = (empty($_GET['pagesize'])) ? '10' : $_GET['pagesize']; $page_size = (empty($_GET['pagesize'])) ? '10' : $_GET['pagesize'];
@ -743,6 +818,7 @@ function islandora_view_object(AbstractObject $object) {
// @todo Remove page number and size from this hook, implementers of the // @todo Remove page number and size from this hook, implementers of the
// hook should use drupal page handling directly. // hook should use drupal page handling directly.
$temp = module_invoke_all($hook, $object, $page_number, $page_size); $temp = module_invoke_all($hook, $object, $page_number, $page_size);
islandora_as_renderable_array($temp);
if (!empty($temp)) { if (!empty($temp)) {
$output = array_merge_recursive($output, $temp); $output = array_merge_recursive($output, $temp);
} }
@ -751,11 +827,47 @@ function islandora_view_object(AbstractObject $object) {
// No results, use the default view. // No results, use the default view.
$output = islandora_default_islandora_view_object($object); $output = islandora_default_islandora_view_object($object);
} }
arsort($output); arsort($output);
drupal_alter($hooks, $object, $output); drupal_alter($hooks, $object, $output);
return implode('', $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();
$temp_arr = array();
// Dispatch print hook.
foreach (islandora_build_hook_list(ISLANDORA_PRINT_HOOK, $object->models) as $hook) {
$temp = module_invoke_all($hook, $object);
islandora_as_renderable_array($temp);
if (!empty($temp)) {
$temp_arr = array_merge_recursive($temp_arr, $temp);
}
}
$output = islandora_default_islandora_printer_object($object, drupal_render($temp_arr));
arsort($output);
islandora_as_renderable_array($output);
// Prompt to print.
drupal_add_js('jQuery(document).ready(function () { window.print(); });', 'inline');
return $output;
}
/** /**
* Title callback for drupal title. * Title callback for drupal title.
@ -786,7 +898,53 @@ function islandora_drupal_title(AbstractObject $object) {
*/ */
function islandora_default_islandora_view_object($object) { function islandora_default_islandora_view_object($object) {
$output = theme('islandora_default', array('islandora_object' => $object)); $output = theme('islandora_default', array('islandora_object' => $object));
return array('Default output' => $output); return array(
'Default output' => array(
'#markup' => $output,
),
);
}
/**
* 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,
),
);
} }
/** /**
@ -1183,24 +1341,6 @@ function islandora_entity_property_info() {
return $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. * Menu callback downloads the given clip.
*/ */
@ -1299,7 +1439,7 @@ function islandora_islandora_object_access($op, $object, $user) {
/** /**
* Hookable access callback for datastreams. * 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) { function islandora_datastream_access($op, $datastream, $user = NULL) {
$cache = &drupal_static(__FUNCTION__); $cache = &drupal_static(__FUNCTION__);
@ -1328,10 +1468,9 @@ function islandora_datastream_access($op, $datastream, $user = NULL) {
$user, $user,
)); ));
// Neither the object nor the datastream check returned FALSE, and one in // The datastream check returned FALSE, and one in the object or datastream
// the object or datastream checks returned TRUE. // checks returned TRUE.
$cache[$op][$datastream->parent->id][$datastream->id][$user->uid] = ( $cache[$op][$datastream->parent->id][$datastream->id][$user->uid] = (
!in_array(FALSE, $object_results, TRUE) &&
!in_array(FALSE, $datastream_results, TRUE) && !in_array(FALSE, $datastream_results, TRUE) &&
(in_array(TRUE, $object_results, TRUE) || in_array(TRUE, $datastream_results, TRUE)) (in_array(TRUE, $object_results, TRUE) || in_array(TRUE, $datastream_results, TRUE))
); );

18
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('<img id="print_btn" title="Print" src="/' + Drupal.settings.islandora.print_img + '"></img>');
$('#print_btn').css("cursor","pointer");
$('#print_btn').click(function() {
window.location=Drupal.settings.islandora.print_link;
});
});
})(jQuery);

198
tests/datastream_versions.test

@ -0,0 +1,198 @@
<?php
/**
* @file
* Tests that datastream versions code works as intended
*/
class IslandoraDatastreamVersionTestCase extends IslandoraWebTestCase {
/**
* Gets info to display to describe this test.
*
* @see IslandoraWebTestCase::getInfo()
*/
public static function getInfo() {
return array(
'name' => '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);
}
}

30
tests/hooks.test

@ -75,6 +75,8 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase {
/** /**
* Test ALL THE HOOKS!. * Test ALL THE HOOKS!.
*
* Covers the majority of cases...
*/ */
public function testHooks() { public function testHooks() {
// Test ingesting with FedoraRepository::ingestObject(). // 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']['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->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_INGESTED_HOOK], 'Called ISLANDORA_OBJECT_INGESTED_HOOK when ingesting via FedoraRepository::ingestObject.');
$this->repository->purgeObject($object->id); $this->repository->purgeObject($object->id);
// Test blocking the ingest. // Test blocking the ingest.
$object = $this->repository->constructObject('test:testIngestedObjectHook'); $object = $this->repository->constructObject('test:testIngestedObjectHook');
$object->label = 'block'; $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->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.'); $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. // Test modifying via set magic functions.
$object = $this->repository->constructObject('test:testModifiedObjectHook'); $object = $this->repository->constructObject('test:testModifiedObjectHook');
$this->repository->ingestObject($object); $this->repository->ingestObject($object);
@ -108,6 +112,7 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase {
$object->label = "New Label!"; $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']['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.'); $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. // Test blocking the modification.
try { try {
$_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_MODIFIED_HOOK] = FALSE; $_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->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); $this->repository->purgeObject($object->id);
// Test purging with FedoraRepository::purgeObject(). // Test purging with FedoraRepository::purgeObject().
$object = $this->repository->constructObject('test:testPurgedObjectHook'); $object = $this->repository->constructObject('test:testPurgedObjectHook');
$this->repository->ingestObject($object); $this->repository->ingestObject($object);
@ -130,6 +136,7 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase {
$this->repository->purgeObject($object->id); $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']['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.'); $this->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_PURGED_HOOK], 'Called ISLANDORA_OBJECT_PURGED_HOOK when purging via FedoraRepository::purgeObject.');
// Test deleting. // Test deleting.
$object = $this->repository->constructObject('test:testPurgedObjectHook'); $object = $this->repository->constructObject('test:testPurgedObjectHook');
$this->repository->ingestObject($object); $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']['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->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_PURGED_HOOK], 'Called ISLANDORA_OBJECT_PURGED_HOOK when purging via FedoraObject::delete.');
$this->repository->purgeObject($object->id); $this->repository->purgeObject($object->id);
// Test alter blocking. // Test alter blocking.
$object = $this->repository->constructObject('test:testPurgedObjectHook'); $object = $this->repository->constructObject('test:testPurgedObjectHook');
$this->repository->ingestObject($object); $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->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.'); $this->assertFalse($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_PURGED_HOOK], 'Called ISLANDORA_OBJECT_PURGED_HOOK when blocking purge via FedoraRepository::purgeObject.');
} }
// Test alter delete. // Test alter delete.
$_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_PURGED_HOOK] = FALSE; $_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_PURGED_HOOK] = FALSE;
$_SESSION['islandora_hooks']['alter'][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.'); $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'; $object->label = 'Something other than delete';
$this->repository->purgeObject($object->id); $this->repository->purgeObject($object->id);
// Test ingesting with FedoraRepository::ingestObject(). // Test ingesting with FedoraRepository::ingestObject().
$object = $this->repository->constructObject('test:testIngestedDatastreamHook'); $object = $this->repository->constructObject('test:testIngestedDatastreamHook');
$this->repository->ingestObject($object); $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']['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->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_INGESTED_HOOK], 'Called ISLANDORA_DATASTREAM_INGESTED_HOOK when ingesting via FedoraObject::ingestDatastream.');
$this->repository->purgeObject($object->id); $this->repository->purgeObject($object->id);
// Test modifying a datastream. // Test modifying a datastream.
$object = $this->repository->constructObject('test:testModifiedDatastreamHook'); $object = $this->repository->constructObject('test:testModifiedDatastreamHook');
$this->repository->ingestObject($object); $this->repository->ingestObject($object);
@ -184,6 +195,7 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase {
$ds->label = "New Label!"; $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']['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.'); $this->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_MODIFIED_HOOK], 'Called ISLANDORA_DATASTREAM_MODIFIED_HOOK when modifying via set magic functions.');
// Test blocking modifying. // Test blocking modifying.
try { try {
$_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_MODIFIED_HOOK] = FALSE; $_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->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); $this->repository->purgeObject($object->id);
// Test purging with FedoraRepository::purgeObject(). // Test purging with FedoraRepository::purgeObject().
$object = $this->repository->constructObject('test:testPurgedDatastreamHook'); $object = $this->repository->constructObject('test:testPurgedDatastreamHook');
$this->repository->ingestObject($object); $this->repository->ingestObject($object);
@ -210,4 +223,21 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase {
$this->repository->purgeObject($object->id); $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);
}
} }

3
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(). * Implements hook_islandora_datastream_access().
*/ */
function islandora_hooked_access_test_islandora_datastream_access($op, $datastream, $user) { 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()) { if (isset($_SESSION['islandora_hooked_access_test']) && $_SESSION['islandora_hooked_access_test'] === func_get_args()) {
return TRUE; return TRUE;
} }

12
tests/islandora_ingest_test.module

@ -87,7 +87,11 @@ function islandora_ingest_test_test_testcmodel2_islandora_ingest_steps(array &$f
* The Drupal form definition. * The Drupal form definition.
*/ */
function islandora_ingest_test_set_label_form(array $form, array &$form_state) { 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); $model = isset($form_state['values']['model']) ? $form_state['values']['model'] : reset($models);
$shared_storage = &islandora_ingest_form_get_shared_storage($form_state); $shared_storage = &islandora_ingest_form_get_shared_storage($form_state);
$shared_storage['models'] = array($model); $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. * Test the First content model.
*/ */
function islandora_ingest_test_testcmodel_form(array $form, array &$form_state) { 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. * Test the second content model.
*/ */
function islandora_ingest_test_testcmodel2_form(array $form, array &$form_state) { function islandora_ingest_test_testcmodel2_form(array $form, array &$form_state) {
return array( return array();
);
} }
/** /**

60
tests/islandora_web_test_case.inc

@ -157,7 +157,7 @@ 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 * @param AbstractObject $object
* The PID of the object * The PID of the object
@ -166,18 +166,18 @@ class IslandoraWebTestCase extends DrupalWebTestCase {
*/ */
public function assertDatastreams($object, array $datastreams) { public function assertDatastreams($object, array $datastreams) {
if (!is_object($object)) { if (!is_object($object)) {
$this->fail("Failed. Object passed in is invalid."); $this->fail("Failed. Object passed in is invalid.", 'Islandora');
return;
} }
foreach ($datastreams as $datastream) { foreach ($datastreams as $datastream) {
if (isset($object[$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 { else {
$this->fail("Failed to load datastream {$datastream} from PID {$object->id}"); $this->fail("Failed to load datastream {$datastream} from PID {$object->id}.", 'Islandora');
} }
} }
} }
/** /**
@ -199,7 +199,7 @@ class IslandoraWebTestCase extends DrupalWebTestCase {
} }
} }
} }
$this->fail("Failed to parse path : $path."); $this->fail("Failed to parse path: $path.");
return FALSE; return FALSE;
} }
@ -208,31 +208,49 @@ class IslandoraWebTestCase extends DrupalWebTestCase {
* *
* @param string $pid * @param string $pid
* The PID of the collection to be deleted * 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') {
$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'; $path = 'islandora/object/' . $pid . '/manage/properties';
$edit = array(); $edit = array();
$this->drupalPost($path, $edit, t('Delete')); $this->drupalPost($path, $edit, $button);
$this->drupalPost($this->url, $edit, t('Delete')); $this->drupalPost($this->url, $edit, t('Delete'));
$object = islandora_object_load($pid); $object = islandora_object_load($pid);
$this->drupalGet("islandora/object/$pid"); $this->drupalGet("islandora/object/$pid");
$this->assertResponse(404, "Object $pid successfully deleted."); $this->assertResponse(404, "Object $pid successfully deleted.");
}
/**
* 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.
*
* @return bool|int
* FALSE or the integer value that is converted.
*/
public function convertHexToInt($hex) {
if ($current_user) { // A couple of quick string checks.
$this->drupalLogin($current_user); if (!ctype_xdigit($hex)) {
$this->fail('String passed to convertHexToInt() contains non-hexidecimal characters.', 'PHP');
return FALSE;
} }
else { if (!strlen($hex) === 4 || !strlen($hex) === 8) {
$this->drupalLogout(); $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;
} }
} }

4
tests/scripts/travis_setup.sh

@ -11,8 +11,8 @@ cd islandora_tomcat
export CATALINA_HOME='.' export CATALINA_HOME='.'
./bin/startup.sh ./bin/startup.sh
cd $HOME cd $HOME
pear upgrade force Console_Getopt pear upgrade --force Console_Getopt
pear upgrade force pear pear upgrade --force pear
pear upgrade-all pear upgrade-all
pear channel-discover pear.drush.org pear channel-discover pear.drush.org
pear channel-discover pear.drush.org pear channel-discover pear.drush.org

18
theme/islandora-object-img-print.tpl.php

@ -0,0 +1,18 @@
<?php
/**
* @file
* The default view to theme an image of an object.
*
* This view is passed into 'islandora-object-print' theme file
* and is rendred as an image. Allows for seperate theming of image
* and metadata.
*
*/
?>
<?php if (isset($islandora_content)): ?>
<div>
<?php print $islandora_content; ?>
</div>
<?php endif; ?>

30
theme/islandora-object-print.tpl.php

@ -0,0 +1,30 @@
<?php
/**
* @file
* The default view to print objects.
*
*/
?>
<div>
<div>
<?php print $islandora_content; ?>
</div>
<fieldset class="islandora-basic-image-metadata islandora">
<legend><span class="fieldset-legend"><?php print t('Details'); ?></span></legend>
<div class="fieldset-wrapper">
<dl class="islandora-inline-metadata islandora-basic-image-fields">
<?php $row_field = 0; ?>
<?php foreach( $dc_array as $key => $value): ?>
<dt class="<?php print $value['class']; ?><?php print $row_field == 0 ? ' first' : ''; ?>">
<?php print $value['label']; ?>
</dt>
<dd class="<?php print $value['class']; ?><?php print $row_field == 0 ? ' first' : ''; ?>">
<?php print $value['value']; ?>
</dd>
<?php $row_field++; ?>
<?php endforeach; ?>
</dl>
</div>
</fieldset>
</div>

1
theme/islandora-object.tpl.php

@ -60,6 +60,7 @@
?> ?>
<div class="islandora-object islandora"> <div class="islandora-object islandora">
<h2><?php print t('Details'); ?></h2> <h2><?php print t('Details'); ?></h2>
<dl class="islandora-object-tn"> <dl class="islandora-object-tn">
<dt> <dt>
<?php if (isset($variables['islandora_thumbnail_url'])): ?> <?php if (isset($variables['islandora_thumbnail_url'])): ?>

145
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; $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/datastream');
module_load_include('inc', 'islandora', 'includes/utilities'); module_load_include('inc', 'islandora', 'includes/utilities');
$header = array( $header = array();
array('data' => t('ID')), $header[] = array('data' => t('ID'));
array('data' => t('Label')), $header[] = array('data' => t('Label'));
array('data' => t('Type')), $header[] = array('data' => t('Type'));
array('data' => t('Mime type')), $header[] = array('data' => t('Mime type'));
array('data' => t('Size')), $header[] = array('data' => t('Size'));
array('data' => t('Operations'), 'colspan' => '3'), 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')); $table_attributes = array('class' => array('manage-datastreams'));
$rows = array(); $rows = array();
foreach ($islandora_object as $ds) { foreach ($islandora_object as $ds) {
$rows[] = array( $row = array();
array( $row[] = array(
'class' => 'datastream-id', 'class' => 'datastream-id',
'data' => theme('islandora_datastream_view_link', array( 'data' => theme('islandora_datastream_view_link', array(
'datastream' => $ds, 'datastream' => $ds,
)), )),
), );
array( $row[] = array(
'class' => 'datastream-label', 'class' => 'datastream-label',
'data' => $ds->label, 'data' => $ds->label,
), );
array( $row[] = array(
'class' => 'datastream-control', 'class' => 'datastream-control',
'data' => islandora_control_group_to_human_readable($ds->controlGroup), 'data' => islandora_control_group_to_human_readable($ds->controlGroup),
), );
array( $row[] = array(
'class' => 'datastream-mime', 'class' => 'datastream-mime',
'data' => $ds->mimeType, 'data' => $ds->mimeType,
), );
array( $row[] = array(
'class' => 'datastream-size', 'class' => 'datastream-size',
'data' => islandora_datastream_get_human_readable_size($ds), 'data' => islandora_datastream_get_human_readable_size($ds),
), );
array( 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', 'class' => 'datastream-download',
'data' => theme('islandora_datastream_download_link', array( 'data' => theme('islandora_datastream_download_link', array(
'datastream' => $ds, 'datastream' => $ds,
)), )),
), );
array( $row[] = array(
'class' => 'datstream-edit', 'class' => 'datstream-edit',
'data' => theme('islandora_datastream_edit_link', array( 'data' => theme('islandora_datastream_edit_link', array(
'datastream' => $ds, 'datastream' => $ds,
)), )),
), );
array( $row[] = array(
'class' => 'datastream-delete', 'class' => 'datastream-delete',
'data' => theme('islandora_datastream_delete_link', array( 'data' => theme('islandora_datastream_delete_link', array(
'datastream' => $ds, 'datastream' => $ds,
)), )),
),
); );
$rows[] = $row;
} }
$caption = $islandora_object->label . ' - ' . $islandora_object->id; $caption = $islandora_object->label . ' - ' . $islandora_object->id;
$table = array( $table = array(
@ -239,6 +251,9 @@ function islandora_preprocess_islandora_objects(array &$variables) {
* @param array $vars * @param array $vars
* An array containing: * An array containing:
* - datastream: An AbstractDatastream for which to generate a download link. * - 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) { function theme_islandora_datastream_download_link(array $vars) {
$datastream = $vars['datastream']; $datastream = $vars['datastream'];
@ -256,15 +271,36 @@ function theme_islandora_datastream_download_link(array $vars) {
* @param array $vars * @param array $vars
* An array containing: * An array containing:
* - datastream: An AbstractDatastream for which to generate a view link. * - 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) { function theme_islandora_datastream_view_link(array $vars) {
$datastream = $vars['datastream']; $datastream = $vars['datastream'];
module_load_include('inc', 'islandora', 'includes/utilities'); module_load_include('inc', 'islandora', 'includes/utilities');
if ($vars['label'] === NULL) {
$label = check_plain($datastream->id); $label = check_plain($datastream->id);
return islandora_datastream_access(FEDORA_VIEW_OBJECTS, $datastream) ? }
l($label, islandora_datastream_get_url($datastream, 'view')) : else {
$label; $label = check_plain($vars['label']);
}
if ($vars['version'] === NULL) {
$perm = FEDORA_VIEW_OBJECTS;
}
else {
$perm = ISLANDORA_VIEW_DATASTREAM_HISTORY;
}
if (islandora_datastream_access($perm, $datastream)) {
return l($label, islandora_datastream_get_url($datastream, 'view', $vars['version']));
}
else {
return $label;
}
} }
/** /**
@ -273,6 +309,10 @@ function theme_islandora_datastream_view_link(array $vars) {
* @param array $vars * @param array $vars
* An array containing: * An array containing:
* - datastream: An AbstractDatastream for which to generate a delete link. * - 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) { function theme_islandora_datastream_delete_link(array $vars) {
$datastream = $vars['datastream']; $datastream = $vars['datastream'];
@ -281,9 +321,22 @@ function theme_islandora_datastream_delete_link(array $vars) {
$can_delete = !in_array($datastream->id, $datastreams) && islandora_datastream_access(FEDORA_PURGE, $datastream); $can_delete = !in_array($datastream->id, $datastreams) && islandora_datastream_access(FEDORA_PURGE, $datastream);
return $can_delete ? if ($vars['version'] !== NULL) {
l(t('delete'), "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/delete") : 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 {
''; '';
}
} }
/** /**
@ -292,6 +345,9 @@ function theme_islandora_datastream_delete_link(array $vars) {
* @param array $vars * @param array $vars
* An array containing: * An array containing:
* - datastream: An AbstractDatastream for which to generate a edit link. * - 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) { function theme_islandora_datastream_edit_link(array $vars) {
$datastream = $vars['datastream']; $datastream = $vars['datastream'];
@ -304,3 +360,32 @@ function theme_islandora_datastream_edit_link(array $vars) {
l(t('edit'), "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/edit") : l(t('edit'), "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/edit") :
''; '';
} }
/**
* 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) {
if ($datastream->versionable) {
return l(count($datastream), "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/version");
}
else {
return t('Not Versioned');
}
}
else {
return '';
}
}

13
xml/strip_newlines_and_whitespace.xsl

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" media-type="text/xml"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="translate(., '&#xA;', ' ')"/>
</xsl:template>
</xsl:stylesheet>
Loading…
Cancel
Save