Browse Source

Merge pull request #1 from Islandora/7.x

update 7.x
pull/402/head
qadan 11 years ago
parent
commit
fa744f4a39
  1. 6
      includes/admin.form.inc
  2. 6
      includes/authtokens.inc
  3. 2
      includes/breadcrumb.inc
  4. 164
      includes/datastream.inc
  5. 85
      includes/datastream.version.inc
  6. 105
      includes/derivatives.inc
  7. 2
      includes/object_properties.form.inc
  8. 4
      includes/solution_packs.inc
  9. 4
      includes/utilities.inc
  10. 133
      islandora.api.php
  11. 14
      islandora.drush.inc
  12. 2
      islandora.info
  13. 201
      islandora.module
  14. 8
      js/add_print.js
  15. 2
      tests/authtokens.test
  16. 160
      tests/datastream_cache.test
  17. 296
      tests/derivatives.test
  18. 6
      tests/hooked_access.test
  19. 7
      tests/islandora_derivatives_test.info
  20. 202
      tests/islandora_derivatives_test.module
  21. 5
      tests/islandora_hooked_access_test.module
  22. 50
      tests/islandora_manage_permissions.test
  23. 52
      theme/theme.inc

6
includes/admin.form.inc

@ -55,6 +55,12 @@ function islandora_repository_admin(array $form, array &$form_state) {
'#description' => t('The PID of the Root Collection Object'),
'#required' => TRUE,
),
'islandora_use_datastream_cache_headers' => array(
'#type' => 'checkbox',
'#title' => t('Generate/parse datastream HTTP cache headers'),
'#description' => t('HTTP caching can reduce network traffic, by allowing clients to used cached copies.'),
'#default_value' => variable_get('islandora_use_datastream_cache_headers', TRUE),
),
),
'islandora_namespace' => array(
'#type' => 'fieldset',

6
includes/authtokens.inc

@ -10,7 +10,7 @@
// Token lifespan(seconds): after this duration the token expires.
// 5 minutes.
define('TOKEN_TIMEOUT', 300);
define('ISLANDORA_AUTHTOKEN_TOKEN_TIMEOUT', 300);
/**
* Request Islandora to construct an object/datastream authentication token.
@ -92,7 +92,7 @@ function islandora_validate_object_token($pid, $dsid, $token) {
->condition('pid', $pid, '=')
->condition('dsid', $dsid, '=')
->condition('time', $time, '<=')
->condition('time', $time - TOKEN_TIMEOUT, '>')
->condition('time', $time - ISLANDORA_AUTHTOKEN_TOKEN_TIMEOUT, '>')
->execute()
->fetchAll();
if ($result) {
@ -131,6 +131,6 @@ function islandora_validate_object_token($pid, $dsid, $token) {
function islandora_remove_expired_tokens() {
$time = time();
db_delete("islandora_authtokens")
->condition('time', $time - TOKEN_TIMEOUT, '<')
->condition('time', $time - ISLANDORA_AUTHTOKEN_TOKEN_TIMEOUT, '<')
->execute();
}

2
includes/breadcrumb.inc

@ -27,6 +27,8 @@
function islandora_get_breadcrumbs($object) {
$breadcrumbs = islandora_get_breadcrumbs_recursive($object->id, $object->repository);
array_pop($breadcrumbs);
$context = 'islandora';
drupal_alter('islandora_breadcrumbs', $breadcrumbs, $context);
return $breadcrumbs;
}

164
includes/datastream.inc

@ -30,6 +30,13 @@ function islandora_download_datastream(AbstractDatastream $datastream) {
* The version of the datastream to display
*/
function islandora_view_datastream(AbstractDatastream $datastream, $download = FALSE, $version = NULL) {
// XXX: Certain features of the Devel module rely on the use of "shutdown
// handlers", such as query logging... The problem is that they might blindly
// add additional output which will break things if what is actually being
// output is anything but a webpage... like an image or video or audio or
// whatever the datastream is here.
$GLOBALS['devel_shutdown'] = FALSE;
if ($version !== NULL) {
if (isset($datastream[$version])) {
$datastream = $datastream[$version];
@ -39,8 +46,6 @@ function islandora_view_datastream(AbstractDatastream $datastream, $download = F
}
}
header_remove('Cache-Control');
header_remove('Expires');
header('Content-type: ' . $datastream->mimetype);
if ($datastream->controlGroup == 'M' || $datastream->controlGroup == 'X') {
header('Content-length: ' . $datastream->size);
@ -52,13 +57,164 @@ function islandora_view_datastream(AbstractDatastream $datastream, $download = F
$filename = $datastream->label . '.' . $extension;
header("Content-Disposition: attachment; filename=\"$filename\"");
}
$cache_check = islandora_view_datastream_cache_check($datastream);
if ($cache_check !== 200) {
if ($cache_check === 304) {
header('HTTP/1.1 304 Not Modified');
}
elseif ($cache_check === 412) {
header('HTTP/1.0 412 Precondition Failed');
}
}
islandora_view_datastream_set_cache_headers($datastream);
drupal_page_is_cacheable(FALSE);
// Try not to load the file into PHP memory!
ob_end_flush();
$datastream->getContent('php://output');
// Close and flush ALL the output buffers!
while (@ob_end_flush()) {
};
// New content needed.
if ($cache_check === 200) {
$datastream->getContent('php://output');
}
exit();
}
/**
* Parse "etags" from HTTP If-Match or If-None-Match headers.
*
* Parses from the CSV-like struture supported by HTTP headers into an array,
* so `"asdf", "fdsa", W/"2132"` should become an array containing the strings:
* - asdf
* - fdsa
* - 2132
*
* @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.24
* @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.26
*
* @param string $header_value
* The value from the headers.
*
* @return array
* An array containing all the etags present.
*/
function islandora_parse_http_match_headers($header_value) {
$matches = array();
// Match the CSV-like structure supported by the HTTP headers.
$count = preg_match_all('/(((W\/)?("?)(\*|.+?)\4)(, +)?)/', $header_value, $matches);
// The fifth sub-expression/group is which will contain the etags.
return $matches[5];
}
/**
* Validate cache headers.
*
* @param AbstractDatastream $datastream
* The datastream for which to check the request headers against.
*
* @return int
* An integer representing the HTTP response code. One of:
* - 200: Proceed as normal. (Full download).
* - 304: Resource hasn't changed; pass cache validation.
* - 412: Resource has changed; fail cache validation.
*
* @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
*/
function islandora_view_datastream_cache_check(AbstractDatastream $datastream) {
if (!variable_get('islandora_use_datastream_cache_headers', TRUE)) {
return 200;
}
// Let's assume that if we get here, we'll be able to complete the request.
$return = 200;
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
$modified_since = DateTime::createFromFormat('D, d M Y H:i:s e', $_SERVER['HTTP_IF_MODIFIED_SINCE']);
if ($datastream->createdDate->getTimestamp() - $modified_since->getTimestamp() > 0) {
// Changed!
return $return;
}
else {
$return = 304;
}
}
if ($return === 200 && isset($_SERVER['HTTP_IF_UNMODIFIED_SINCE'])) {
$unmodified_since = DateTime::createFromFormat('D, d M Y H:i:s e', $_SERVER['HTTP_IF_UNMODIFIED_SINCE']);
if ($datastream->createdDate->getTimestamp() !== $unmodified_since->getTimestamp()) {
// Changed!
$return = 412;
}
else {
return $return;
}
}
// Only consider Etags we have provided.
if (isset($datastream->checksum)) {
$tags = array();
foreach ($datastream as $offset => $version) {
if (isset($version->checksum)) {
$tags[$offset] = $version->checksum;
}
}
if ($return === 200 && isset($_SERVER['HTTP_IF_MATCH'])) {
$request_tags = islandora_parse_http_match_headers($_SERVER['HTTP_IF_MATCH']);
if (in_array('*', $request_tags) || count(array_intersect($tags, $request_tags)) > 0) {
// There's a match... Let things go ahead.
return $return;
}
else {
$return = 412;
}
}
if (in_array($return, array(200, 304), TRUE) && isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
$request_tags = islandora_parse_http_match_headers($_SERVER['HTTP_IF_NONE_MATCH']);
if (in_array('*', $request_tags) || count(array_intersect($tags, $request_tags)) > 0) {
$return = 304;
}
else {
$return = 200;
}
}
}
return $return;
}
/**
* Set various HTTP headers for caching.
*
* @param AbstractDatastream $datastream
* The datastream being viewed/downloaded.
*/
function islandora_view_datastream_set_cache_headers(AbstractDatastream $datastream) {
if (variable_get('islandora_use_datastream_cache_headers', TRUE)) {
// Force cache revalidation.
header('Expires: Sun, 19 Nov 1978 05:00:00 GMT');
$cache_control = array();
if ($datastream->parent->repository->api->connection->username == 'anonymous') {
$cache_control[] = 'public';
}
else {
$cache_control[] = 'private';
}
$cache_control[] = 'must-revalidate';
$cache_control[] = 'max-age=0';
header('Cache-Control: ' . implode(', ', $cache_control));
header('Last-Modified: ' . $datastream->createdDate->format('D, d M Y H:i:s \G\M\T'));
if (isset($datastream->checksum)) {
header("Etag: \"{$datastream->checksum}\"");
}
}
else {
header_remove('Cache-Control');
header_remove('Expires');
}
}
/**
* Get the human readable size of the given datastream.
*

85
includes/datastream.version.inc

@ -18,7 +18,7 @@ function islandora_datastream_version_table($datastream) {
$header[] = array('data' => t('Size'));
$header[] = array('data' => t('Label'));
$header[] = array('data' => t('Mime type'));
$header[] = array('data' => t('Operations'));
$header[] = array('data' => t('Operations'), 'colspan' => '2');
$rows = array();
foreach ($datastream as $version => $datastream_version) {
@ -50,6 +50,13 @@ function islandora_datastream_version_table($datastream) {
'version' => $version,
)),
);
$row[] = array(
'class' => 'datastream-revert',
'data' => theme('islandora_datastream_revert_link', array(
'datastream' => $datastream,
'version' => $version,
)),
);
$rows[] = $row;
}
@ -125,3 +132,79 @@ function islandora_delete_datastream_version_form_submit(array $form, array &$fo
$form_state['redirect'] = "islandora/object/{$object->id}/datastream/{$datastream->id}/version";
}
/**
* The admin revert 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 revert to.
*
* @return array
* The drupal form definition.
*/
function islandora_revert_datastream_version_form(array $form, array &$form_state, AbstractDatastream $datastream, $version) {
if (!isset($datastream[$version]) || count($datastream) < 2) {
return drupal_not_found();
}
$form_state['dsid'] = $datastream->id;
$form_state['object_id'] = $datastream->parent->id;
$form_state['version'] = $version;
return confirm_form($form,
t('Are you sure you want to revert to version @version of the @dsid datastream?', array('@dsid' => $datastream->id, '@version' => $version)),
"islandora/object/{$datastream->parent->id}",
"",
t('Revert'),
t('Cancel')
);
}
/**
* Submit handler for the revert datastream form.
*
* Reverts the given AbstractDatastream if possible.
*
* @param array $form
* The Drupal form.
* @param array $form_state
* The Drupal form state.
*/
function islandora_revert_datastream_version_form_submit(array $form, array &$form_state) {
$islandora_object = islandora_object_load($form_state['object_id']);
$datastream_to_revert = $islandora_object[$form_state['dsid']];
$version = $form_state['version'];
// Create file holding specified datastream version, and set datastream to it.
$datastream_to_revert_to = $datastream_to_revert[$version];
if (in_array($datastream_to_revert->controlGroup, array('R', 'E'))) {
$datastream_to_revert->url = $datastream_to_revert_to->url;
}
else {
$filename = file_create_filename('datastream_temp_file', 'temporary://');
$datastream_to_revert_to->getContent($filename);
$datastream_to_revert->setContentFromFile($filename);
file_unmanaged_delete($filename);
}
if ($datastream_to_revert->mimeType != $datastream_to_revert_to->mimeType) {
$datastream_to_revert->mimeType = $datastream_to_revert_to->mimeType;
}
if ($datastream_to_revert->label != $datastream_to_revert_to->label) {
$datastream_to_revert->label = $datastream_to_revert_to->label;
}
drupal_set_message(t('%d datastream successfully reverted to version %v for Islandora object %o', array(
'%d' => $datastream_to_revert->id,
'%v' => $version,
'%o' => $islandora_object->label)));
$form_state['redirect'] = "islandora/object/{$islandora_object->id}/datastream/{$datastream_to_revert->id}/version";
}

105
includes/derivatives.inc

@ -0,0 +1,105 @@
<?php
/**
* @file
* Defines functions used when constructing derivatives.
*/
/**
* Kicks off derivative functions based upon hooks and conditions.
*
* @param AbstractObject $object
* An AbstractObject representing a FedoraObject.
* @param array $options
* An array of parameters containing:
* - force: Bool denoting whether we are forcing the generation of
* derivatives.
* - source_dsid: (Optional) String of the datastream id we are generating
* from or NULL if it's the object itself.
* - destination_dsid: (Optional) String of the datastream id that is being
* created. To be used in the UI.
*
* @return array
* An array of messages describing the outcome of the derivative events.
* Each individual message array has the following structure:
* - success: Bool denoting whether the operation was successful.
* - messages: An array structure containing:
* - message: A string passed through t() describing the
* outcome of the operation.
* - message_sub: (Optional) Substitutions to be passed along to t() or
* watchdog.
* - type: A string denoting whether the output is to be
* drupal_set_messaged (dsm) or watchdogged (watchdog).
* - severity: (Optional) A severity level / status to be used when
* logging messages. Uses the defaults of drupal_set_message and
* watchdog if not defined.
*/
function islandora_do_derivatives(AbstractObject $object, array $options) {
$options += array(
'force' => FALSE,
);
$hooks = islandora_invoke_hook_list(ISLANDORA_DERVIATIVE_CREATION_HOOK, $object->models, array());
uasort($hooks, 'drupal_sort_weight');
$results = array();
if (array_key_exists('source_dsid', $options)) {
$hooks = array_filter($hooks, function($filter_hook) use($options) {
return array_key_exists('source_dsid', $filter_hook) &&
$filter_hook['source_dsid'] == $options['source_dsid'];
});
}
if (array_key_exists('destination_dsid', $options)) {
$hooks = array_filter($hooks, function($filter_hook) use($options) {
return array_key_exists('destination_dsid', $filter_hook) &&
$filter_hook['destination_dsid'] == $options['destination_dsid'];
});
}
foreach ($hooks as $hook) {
if (isset($hook['file'])) {
require_once $hook['file'];
}
foreach ($hook['function'] as $function) {
$logging = call_user_func($function, $object, $options['force']);
if (!empty($logging)) {
$results[] = $logging;
}
}
}
return $results;
}
/**
* Handles the logging of derivative messages.
*
* @param array $logging_results
* An array of messages describing the outcome of the derivative events.
* Each individual message array has the following structure:
* - success: Bool denoting whether the operation was successful.
* - messages: An array structure containing:
* - message: A string passed through t() describing the
* outcome of the operation.
* - message_sub: (Optional) Substitutions to be passed along to t() or
* watchdog.
* - type: A string denoting whether the output is to be
* drupal_set_messaged (dsm) or watchdogged (watchdog).
* - severity: (Optional) A severity level / status to be used when
* logging messages. Uses the defaults of drupal_set_message and
* watchdog if not defined.
*/
function islandora_derivative_logging(array $logging_results) {
foreach ($logging_results as $result) {
foreach ($result['messages'] as $message) {
if ($message['type'] === 'dsm') {
drupal_set_message(filter_xss(format_string($message['message'], isset($message['message_sub']) ? $message['message_sub'] : array())), isset($message['severity']) ? $message['severity'] : 'status');
}
else {
// We know what we are doing here. Passing through the translated
// message and the substitutions needed. We are using
// call_user_func until such time as the @ignore changes
// are merged into the standard release for Coder.
call_user_func('watchdog', 'islandora_derivatives', $message['message'], isset($message['message_sub']) ? $message['message_sub'] : array(), isset($message['severity']) ? $message['severity'] : WATCHDOG_NOTICE);
}
}
}
}

2
includes/object_properties.form.inc

@ -60,7 +60,7 @@ function islandora_object_properties_form(array $form, array &$form_state, Abstr
),
'delete' => array(
'#type' => 'submit',
'#access' => islandora_object_access(FEDORA_PURGE, $object),
'#access' => islandora_object_access(ISLANDORA_PURGE, $object),
'#value' => t('Delete'),
'#submit' => array('islandora_object_properties_form_delete'),
'#limit_validation_errors' => array(array('pid')),

4
includes/solution_packs.inc

@ -745,7 +745,9 @@ function islandora_get_viewer($params = NULL, $variable_id = NULL, $fedora_objec
$viewer_id = islandora_get_viewer_id($variable_id);
if ($viewer_id AND $params !== NULL) {
$callback = islandora_get_viewer_callback($viewer_id);
return $callback($params, $fedora_object);
if (function_exists($callback)) {
return $callback($params, $fedora_object);
}
}
}
return FALSE;

4
includes/utilities.inc

@ -391,10 +391,10 @@ function islandora_get_datastreams_requirements_from_models(array $models) {
* - "optional": A boolean indicating if the given stream is optional.
*/
function islandora_get_datastreams_requirements_from_content_model(AbstractObject $object) {
if (empty($object[DS_COMP_STREAM]) || !islandora_datastream_access(FEDORA_VIEW_OBJECTS, $object[DS_COMP_STREAM])) {
if (empty($object[ISLANDORA_DS_COMP_STREAM]) || !islandora_datastream_access(ISLANDORA_VIEW_OBJECTS, $object[ISLANDORA_DS_COMP_STREAM])) {
return array();
}
$xml = new SimpleXMLElement($object[DS_COMP_STREAM]->content);
$xml = new SimpleXMLElement($object[ISLANDORA_DS_COMP_STREAM]->content);
foreach ($xml->dsTypeModel as $ds) {
$dsid = (string) $ds['ID'];
$optional = strtolower((string) $ds['optional']);

133
islandora.api.php

@ -86,7 +86,7 @@ function hook_CMODEL_PID_islandora_view_object_alter(&$object, &$rendered) {
}
/**
* Generate an object's management display.
* Generate an object's datastreams management display.
*
* @param AbstractObject $object
* A Tuque FedoraObject
@ -98,7 +98,7 @@ function hook_islandora_edit_object($object) {
}
/**
* Generate an object's management display for the given content model.
* Generate an object's datastreams management display based on content model.
*
* Content models PIDs have colons and hyphens changed to underscores, to
* create the hook name.
@ -113,7 +113,7 @@ function hook_CMODEL_PID_islandora_edit_object($object) {
}
/**
* Allow management display output to be altered.
* Allow datastreams management display output to be altered.
*
* @param AbstractObject $object
* A Tuque FedoraObject
@ -477,10 +477,11 @@ function hook_CMODEL_PID_islandora_ingest_steps(array $form_state) {
* @param object $user
* A loaded user object, as the global $user variable might contain.
*
* @return bool|NULL
* @return bool|NULL|array
* Either boolean TRUE or FALSE to explicitly allow or deny the operation on
* the given object, or NULL to indicate that we are making no assertion
* about the outcome.
* about the outcome. Can also be an array containing multiple
* TRUE/FALSE/NULLs, due to how hooks work.
*/
function hook_islandora_object_access($op, $object, $user) {
switch ($op) {
@ -515,10 +516,11 @@ function hook_CMODEL_PID_islandora_object_access($op, $object, $user) {
* @param object $user
* A loaded user object, as the global $user variable might contain.
*
* @return bool|NULL
* @return bool|NULL|array
* Either boolean TRUE or FALSE to explicitly allow or deny the operation on
* the given object, or NULL to indicate that we are making no assertion
* about the outcome.
* about the outcome. Can also be an array containing multiple
* TRUE/FALSE/NULLs, due to how hooks work.
*/
function hook_islandora_datastream_access($op, $object, $user) {
switch ($op) {
@ -541,3 +543,120 @@ function hook_islandora_datastream_access($op, $object, $user) {
*/
function hook_CMODEL_PID_islandora_datastream_access($op, $object, $user) {
}
/**
* Lets one add to the overview tab in object management.
*/
function hook_islandora_overview_object(AbstractObject $object) {
return drupal_render(drupal_get_form('some_form', $object));
}
/**
* Lets one add to the overview tab in object management.
*
* Content model specific.
*/
function hook_CMODEL_PID_islandora_overview_object(AbstractObject $object) {
return drupal_render(drupal_get_form('some_form', $object));
}
/**
* Lets one alter the overview tab in object management.
*/
function hook_islandora_overview_object_alter(AbstractObject &$object, &$output) {
$output = $output . drupal_render(drupal_get_form('some_form', $object));
}
/**
* Lets one alter the overview tab in object management.
*
* Content model specific.
*/
function hook_CMODEL_PID_islandora_overview_object_alter(AbstractObject &$object, &$output) {
$output = $output . drupal_render(drupal_get_form('some_form', $object));
}
/*
* Defines derivative functions to be executed based on certain conditions.
*
* This hook fires when an object/datastream is ingested or a datastream is
* modified.
*
* @return array
* An array containing an entry for each derivative to be created. Each entry
* is an array of parameters containing:
* - force: Bool denoting whether we are forcing the generation of
* derivatives.
* - source_dsid: (Optional) String of the datastream id we are generating
* from or NULL if it's the object itself.
* - destination_dsid: (Optional) String of the datastream id that is being
* created. To be used in the UI.
* - weight: A string denoting the weight of the function. This value is
* sorted upon to run functions in order.
* - function: An array of function(s) to be ran when constructing
* derivatives. Functions that are defined to be called for derivation
* creation must have the following structure:
* module_name_derivative_creation_function($object, $force = FALSE)
* These functions must return an array in the structure of:
* - success: Bool denoting whether the operation was successful.
* - messages: An array structure containing:
* - message: A string passed through t() describing the
* outcome of the operation.
* - message_sub: (Optional) Substitutions to be passed along to t() or
* watchdog.
* - type: A string denoting whether the output is to be
* drupal_set_messaged (dsm) or watchdogged (watchdog).
* - severity: (Optional) A severity level / status to be used when
* logging messages. Uses the defaults of drupal_set_message and
* watchdog if not defined.
* - file: A string denoting the path to the file where the function
* is being called from.
*/
function hook_islandora_derivative() {
return array(
array(
'source_dsid' => 'OBJ',
'destination_dsid' => 'DERIV',
'weight' => '0',
'function' => array(
'islandora_derivatives_test_create_deriv_datastream',
),
),
array(
'source_dsid' => 'SOMEWEIRDDATASTREAM',
'destination_dsid' => 'STANLEY',
'weight' => '-1',
'function' => array(
'islandora_derivatives_test_create_some_weird_datastream',
),
),
array(
'source_dsid' => NULL,
'destination_dsid' => 'NOSOURCE',
'weight' => '-3',
'function' => array(
'islandora_derivatives_test_create_nosource_datastream',
),
),
);
}
/**
* Content model specific version of hook_islandora_derivative().
*
* @see hook_islandora_derivative()
*/
function hook_CMODEL_PID_islandora_derivative() {
}
/**
* Alters breadcrumbs used on Solr search results and within Islandora views.
*
* @param array $breadcrumbs
* Breadcrumbs array to be altered by reference. Each element is markup.
* @param string $context
* Where the alter is originating from for distinguishing.
*/
function hook_islandora_breadcrumbs_alter(&$breadcrumbs, $context) {
}

14
islandora.drush.inc

@ -26,6 +26,10 @@ function islandora_drush_command() {
'drupal dependencies' => array(
'islandora',
),
'examples' => array(
'drush -u 1 ispiro --module=islandora' => dt('Install missing solution pack objects for the "islandora" module.'),
'drush -u 1 ispiro --module=islandora --force' => dt('Install all solution pack objects for the "islandora" module, purging any which currently exist.'),
),
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_LOGIN,
);
$commands['islandora-solution-pack-uninstall-required-objects'] = array(
@ -36,13 +40,17 @@ function islandora_drush_command() {
'required' => TRUE,
),
'force' => array(
'description' => dt('Force reinstallation of the objects.'),
'description' => dt('Force uninstallation of the objects.'),
),
),
'aliases' => array('ispuro'),
'drupal dependencies' => array(
'islandora',
),
'examples' => array(
'drush -u 1 ispuro --module=islandora' => dt('Uninstall solution pack objects for the "islandora" module.'),
'drush -u 1 ispuro --module=islandora --force' => dt('Force uninstallation of all solution pack objects for the "islandora" module.'),
),
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_LOGIN,
);
$commands['islandora-solution-pack-required-objects-status'] = array(
@ -56,6 +64,10 @@ function islandora_drush_command() {
'drupal dependencies' => array(
'islandora',
),
'examples' => array(
'drush -u 1 ispros' => dt('Get the status of all solution pack objects.'),
'drush -u 1 ispros --module=islandora' => dt('Get the status of solution pack objects for the "islandora" module.'),
),
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_LOGIN,
);

2
islandora.info

@ -18,4 +18,6 @@ files[] = tests/ingest.test
files[] = tests/hooked_access.test
files[] = tests/islandora_manage_permissions.test
files[] = tests/datastream_versions.test
files[] = tests/datastream_cache.test
files[] = tests/derivatives.test
php = 5.3

201
islandora.module

@ -24,16 +24,17 @@
*/
// Common datastreams.
define('DS_COMP_STREAM', 'DS-COMPOSITE-MODEL');
define('ISLANDORA_DS_COMP_STREAM', 'DS-COMPOSITE-MODEL');
// Permissions.
define('FEDORA_VIEW_OBJECTS', 'view fedora repository objects');
define('FEDORA_METADATA_EDIT', 'edit fedora metadata');
define('FEDORA_ADD_DS', 'add fedora datastreams');
define('FEDORA_INGEST', 'ingest fedora objects');
define('FEDORA_PURGE', 'delete fedora objects and datastreams');
define('FEDORA_MANAGE_PROPERTIES', 'manage object properties');
define('ISLANDORA_VIEW_OBJECTS', 'view fedora repository objects');
define('ISLANDORA_METADATA_EDIT', 'edit fedora metadata');
define('ISLANDORA_ADD_DS', 'add fedora datastreams');
define('ISLANDORA_INGEST', 'ingest fedora objects');
define('ISLANDORA_PURGE', 'delete fedora objects and datastreams');
define('ISLANDORA_MANAGE_PROPERTIES', 'manage object properties');
define('ISLANDORA_VIEW_DATASTREAM_HISTORY', 'view old datastream versions');
define('ISLANDORA_REVERT_DATASTREAM', 'revert to old datastream');
// Hooks.
define('ISLANDORA_VIEW_HOOK', 'islandora_view_object');
@ -53,10 +54,24 @@ define('ISLANDORA_DATASTREAM_INGESTED_HOOK', 'islandora_datastream_ingested');
define('ISLANDORA_DATASTREAM_MODIFIED_HOOK', 'islandora_datastream_modified');
define('ISLANDORA_DATASTREAM_PURGED_HOOK', 'islandora_datastream_purged');
define('ISLANDORA_INGEST_STEP_HOOK', 'islandora_ingest_steps');
define('ISLANDORA_DERVIATIVE_CREATION_HOOK', 'islandora_derivative');
// Autocomplete paths.
define('ISLANDORA_CONTENT_MODELS_AUTOCOMPLETE', 'islandora/autocomplete/content-models');
/**
* @deprecated Constants.
*/
// @codingStandardsIgnoreStart
define('DS_COMP_STREAM', ISLANDORA_DS_COMP_STREAM);
define('FEDORA_VIEW_OBJECTS', ISLANDORA_VIEW_OBJECTS);
define('FEDORA_METADATA_EDIT', ISLANDORA_METADATA_EDIT);
define('FEDORA_ADD_DS', ISLANDORA_ADD_DS);
define('FEDORA_INGEST', ISLANDORA_INGEST);
define('FEDORA_PURGE', ISLANDORA_PURGE);
define('FEDORA_MANAGE_PROPERTIES', ISLANDORA_MANAGE_PROPERTIES);
// @codingStandardsIgnoreEnd
/**
* Implements hook_menu().
*
@ -85,7 +100,7 @@ function islandora_menu() {
'title' => 'Solution packs',
'description' => 'Install content models and collections required by installed solution packs.',
'page callback' => 'islandora_solution_packs_admin',
'access arguments' => array(FEDORA_ADD_DS),
'access arguments' => array(ISLANDORA_ADD_DS),
'file' => 'includes/solution_packs.inc',
'type' => MENU_NORMAL_ITEM,
);
@ -93,7 +108,7 @@ function islandora_menu() {
'title' => 'Islandora Repository',
'page callback' => 'islandora_view_default_object',
'type' => MENU_NORMAL_ITEM,
'access arguments' => array(FEDORA_VIEW_OBJECTS),
'access arguments' => array(ISLANDORA_VIEW_OBJECTS),
);
$items['islandora/object/%islandora_object'] = array(
'title callback' => 'islandora_drupal_title',
@ -102,14 +117,23 @@ function islandora_menu() {
'page arguments' => array(2),
'type' => MENU_NORMAL_ITEM,
'access callback' => 'islandora_object_access_callback',
'access arguments' => array(FEDORA_VIEW_OBJECTS, 2),
'access arguments' => array(ISLANDORA_VIEW_OBJECTS, 2),
);
$items['islandora/object/%islandora_object/print'] = array(
$items['islandora/object/%islandora_object/print_object'] = array(
'page callback' => 'islandora_printer_object',
'page arguments' => array(2),
'type' => MENU_NORMAL_ITEM,
'access callback' => 'islandora_object_access_callback',
'access arguments' => array(FEDORA_VIEW_OBJECTS, 2),
'access callback' => 'islandora_object_access',
'access arguments' => array(ISLANDORA_VIEW_OBJECTS, 2),
);
$items['islandora/object/%islandora_object/print'] = array(
'title' => 'Print Object',
'page callback' => 'islandora_print_object',
'page arguments' => array(2),
'type' => MENU_CALLBACK,
'access callback' => 'islandora_object_access',
'access arguments' => array(ISLANDORA_VIEW_OBJECTS, 2),
'load arguments' => array(2),
);
$items['islandora/object/%islandora_object/view'] = array(
'title' => 'View',
@ -129,20 +153,18 @@ function islandora_menu() {
'access callback' => 'islandora_object_manage_access_callback',
'access arguments' => array(
array(
FEDORA_MANAGE_PROPERTIES,
FEDORA_METADATA_EDIT,
FEDORA_ADD_DS,
FEDORA_PURGE,
FEDORA_INGEST,
ISLANDORA_MANAGE_PROPERTIES,
ISLANDORA_METADATA_EDIT,
ISLANDORA_ADD_DS,
ISLANDORA_PURGE,
ISLANDORA_INGEST,
), 2),
);
$items['islandora/object/%islandora_object/manage/overview'] = array(
'title' => 'Overview',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -20,
);
$items['islandora/object/%islandora_object/manage/datastreams'] = array(
'title' => 'Datastreams',
'type' => MENU_LOCAL_TASK,
@ -151,13 +173,12 @@ function islandora_menu() {
'access callback' => 'islandora_object_manage_access_callback',
'access arguments' => array(
array(
FEDORA_METADATA_EDIT,
FEDORA_ADD_DS,
FEDORA_PURGE,
ISLANDORA_METADATA_EDIT,
ISLANDORA_ADD_DS,
ISLANDORA_PURGE,
), 2),
'weight' => -10,
);
$items['islandora/object/%islandora_object/manage/properties'] = array(
'title' => 'Properties',
'page callback' => 'drupal_get_form',
@ -165,7 +186,7 @@ function islandora_menu() {
'page arguments' => array('islandora_object_properties_form', 2),
'type' => MENU_LOCAL_TASK,
'access callback' => 'islandora_object_access_callback',
'access arguments' => array(FEDORA_MANAGE_PROPERTIES, 2),
'access arguments' => array(ISLANDORA_MANAGE_PROPERTIES, 2),
'weight' => -5,
);
$items['islandora/object/%islandora_object/delete'] = array(
@ -175,7 +196,7 @@ function islandora_menu() {
'page arguments' => array('islandora_delete_object_form', 2),
'type' => MENU_CALLBACK,
'access callback' => 'islandora_object_access_callback',
'access arguments' => array(FEDORA_PURGE, 2),
'access arguments' => array(ISLANDORA_PURGE, 2),
);
$items['islandora/object/%islandora_object/manage/datastreams/add'] = array(
'title' => 'Add a datastream',
@ -184,7 +205,7 @@ function islandora_menu() {
'page arguments' => array('islandora_add_datastream_form', 2),
'type' => MENU_LOCAL_ACTION,
'access callback' => 'islandora_object_access_callback',
'access arguments' => array(FEDORA_ADD_DS, 2),
'access arguments' => array(ISLANDORA_ADD_DS, 2),
);
$items['islandora/object/%islandora_object/manage/datastreams/add/autocomplete'] = array(
'file' => 'includes/add_datastream.form.inc',
@ -192,7 +213,7 @@ function islandora_menu() {
'page arguments' => array(2),
'type' => MENU_CALLBACK,
'access callback' => 'islandora_object_access_callback',
'access arguments' => array(FEDORA_ADD_DS, 2),
'access arguments' => array(ISLANDORA_ADD_DS, 2),
);
$items['islandora/object/%islandora_object/datastream/%islandora_datastream'] = array(
'title' => 'View datastream',
@ -201,7 +222,7 @@ function islandora_menu() {
'type' => MENU_CALLBACK,
'file' => 'includes/datastream.inc',
'access callback' => 'islandora_datastream_access',
'access arguments' => array(FEDORA_VIEW_OBJECTS, 4),
'access arguments' => array(ISLANDORA_VIEW_OBJECTS, 4),
'load arguments' => array(2),
);
// This menu item uses token authentication in islandora_tokened_object.
@ -209,7 +230,7 @@ function islandora_menu() {
'title' => 'View datastream',
'load arguments' => array('%map'),
'access callback' => 'islandora_object_datastream_tokened_access_callback',
'access arguments' => array(FEDORA_VIEW_OBJECTS, 2, 4),
'access arguments' => array(ISLANDORA_VIEW_OBJECTS, 2, 4),
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['islandora/object/%islandora_object/datastream/%islandora_datastream/download'] = array(
@ -219,7 +240,7 @@ function islandora_menu() {
'type' => MENU_CALLBACK,
'file' => 'includes/datastream.inc',
'access callback' => 'islandora_datastream_access',
'access arguments' => array(FEDORA_VIEW_OBJECTS, 4),
'access arguments' => array(ISLANDORA_VIEW_OBJECTS, 4),
'load arguments' => array(2),
);
$items['islandora/object/%islandora_object/datastream/%islandora_datastream/edit'] = array(
@ -229,7 +250,7 @@ function islandora_menu() {
'type' => MENU_CALLBACK,
'file' => 'includes/datastream.inc',
'access callback' => 'islandora_datastream_access',
'access arguments' => array(FEDORA_METADATA_EDIT, 4),
'access arguments' => array(ISLANDORA_METADATA_EDIT, 4),
'load arguments' => array(2),
);
$items['islandora/object/%islandora_object/datastream/%islandora_datastream/delete'] = array(
@ -239,7 +260,7 @@ function islandora_menu() {
'file' => 'includes/delete_datastream.form.inc',
'type' => MENU_CALLBACK,
'access callback' => 'islandora_datastream_access',
'access arguments' => array(FEDORA_PURGE, 4),
'access arguments' => array(ISLANDORA_PURGE, 4),
'load arguments' => array(2),
);
$items['islandora/object/%islandora_object/datastream/%islandora_datastream/version'] = array(
@ -259,7 +280,17 @@ function islandora_menu() {
'file' => 'includes/datastream.version.inc',
'type' => MENU_CALLBACK,
'access callback' => 'islandora_datastream_access',
'access arguments' => array(FEDORA_PURGE, 4),
'access arguments' => array(ISLANDORA_PURGE, 4),
'load arguments' => array(2),
);
$items['islandora/object/%islandora_object/datastream/%islandora_datastream/version/%/revert'] = array(
'title' => 'Revert to datastream version',
'page arguments' => array('islandora_revert_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(ISLANDORA_REVERT_DATASTREAM, 4),
'load arguments' => array(2),
);
$items['islandora/object/%islandora_object/datastream/%islandora_datastream/version/%/view'] = array(
@ -277,7 +308,7 @@ function islandora_menu() {
'page arguments' => array(2),
'type' => MENU_CALLBACK,
'access callback' => 'islandora_object_access',
'access arguments' => array(FEDORA_VIEW_OBJECTS, 2),
'access arguments' => array(ISLANDORA_VIEW_OBJECTS, 2),
'load arguments' => array(2),
);
$items[ISLANDORA_CONTENT_MODELS_AUTOCOMPLETE] = array(
@ -326,8 +357,13 @@ function islandora_theme() {
'file' => 'includes/solution_packs.inc',
'render element' => 'form',
),
// Print object view.
// Print used by the clipper.
'islandora_object_print' => array(
'file' => 'theme/theme.inc',
'variables' => array('object' => NULL, 'content' => array()),
),
// Print object view, prints islandora objects.
'islandora_object_print_object' => array(
'file' => 'theme/theme.inc',
'template' => 'theme/islandora-object-print',
'variables' => array(
@ -366,6 +402,10 @@ function islandora_theme() {
'file' => 'theme/theme.inc',
'variables' => array('datastream' => NULL, 'version' => NULL),
),
'islandora_datastream_revert_link' => array(
'file' => 'theme/theme.inc',
'variables' => array('datastream' => NULL, 'version' => NULL),
),
'islandora_datastream_view_link' => array(
'file' => 'theme/theme.inc',
'variables' => array(
@ -390,27 +430,27 @@ function islandora_theme() {
*/
function islandora_permission() {
return array(
FEDORA_VIEW_OBJECTS => array(
ISLANDORA_VIEW_OBJECTS => array(
'title' => t('View repository objects'),
'description' => t('View objects in the repository. Note: Fedora XACML security policies may override this permission.'),
),
FEDORA_ADD_DS => array(
ISLANDORA_ADD_DS => array(
'title' => t('Add datastreams to repository objects'),
'description' => t('Add datastreams to objects in the repository. Note: Fedora XACML security policies may override this position.'),
),
FEDORA_METADATA_EDIT => array(
ISLANDORA_METADATA_EDIT => array(
'title' => t('Edit metadata'),
'description' => t('Edit metadata for objects in the repository.'),
),
FEDORA_INGEST => array(
ISLANDORA_INGEST => array(
'title' => t('Create new repository objects'),
'description' => t('Create new objects in the repository.'),
),
FEDORA_PURGE => array(
ISLANDORA_PURGE => array(
'title' => t('Permanently remove objects from the repository'),
'description' => t('Permanently remove objects from the repository.'),
),
FEDORA_MANAGE_PROPERTIES => array(
ISLANDORA_MANAGE_PROPERTIES => array(
'title' => t('Manage object properties'),
'description' => t('Modify object labels, owner IDs, and states.'),
),
@ -418,9 +458,29 @@ function islandora_permission() {
'title' => t('View datastream history'),
'description' => t('View all previous versions of a datastream.'),
),
ISLANDORA_REVERT_DATASTREAM => array(
'title' => t('Revert datastream history'),
'description' => t('Revert to a previous version of a datastream.'),
),
);
}
/**
* 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));
}
/**
* Implements hook_forms().
*/
@ -802,7 +862,7 @@ function islandora_view_object(AbstractObject $object) {
drupal_add_js(array(
'islandora' => array(
'print_link' => '/islandora/object/' . $object->id . '/print')),
'print_link' => 'islandora/object/' . $object->id . '/print_object')),
array('type' => 'setting'));
drupal_add_js($path . '/js/add_print.js');
@ -935,7 +995,7 @@ function islandora_default_islandora_printer_object($object, $alter) {
}
$variables = isset($dc_object) ? $dc_object->asArray() : array();
$output = theme('islandora_object_print', array(
$output = theme('islandora_object_print_object', array(
'object' => $object,
'dc_array' => $variables,
'islandora_content' => $alter));
@ -1439,7 +1499,7 @@ function islandora_islandora_object_access($op, $object, $user) {
/**
* Hookable access callback for datastreams.
*
* Requires the equivalent permissions on the object.
* Positive permissions on object access suggests on the datastream.
*/
function islandora_datastream_access($op, $datastream, $user = NULL) {
$cache = &drupal_static(__FUNCTION__);
@ -1468,10 +1528,9 @@ function islandora_datastream_access($op, $datastream, $user = NULL) {
$user,
));
// Neither the object nor the datastream check returned FALSE, and one in
// the object or datastream checks returned TRUE.
// The datastream check returned FALSE, and one in the object or datastream
// checks returned TRUE.
$cache[$op][$datastream->parent->id][$datastream->id][$user->uid] = (
!in_array(FALSE, $object_results, TRUE) &&
!in_array(FALSE, $datastream_results, TRUE) &&
(in_array(TRUE, $object_results, TRUE) || in_array(TRUE, $datastream_results, TRUE))
);
@ -1493,3 +1552,49 @@ function islandora_islandora_basic_collection_get_query_filters() {
));
}
}
/**
* Implements hook_islandora_object_ingested().
*
* On object ingestion we call the case of source_dsid being NULL only as
* the islandora_islandora_datastream_ingested hook will handle the cases
* where specific values of source_dsid can occur.
*/
function islandora_islandora_object_ingested(AbstractObject $object) {
module_load_include('inc', 'islandora', 'includes/derivatives');
$logging_results = islandora_do_derivatives($object, array(
'source_dsid' => NULL,
));
islandora_derivative_logging($logging_results);
}
/**
* Implements hook_islandora_datastream_ingested().
*
* When a datastream is ingested we filter the derivatives on source_dsid being
* equal to the current ingested datastream's id.
*/
function islandora_islandora_datastream_ingested(AbstractObject $object, AbstractDatastream $datastream) {
module_load_include('inc', 'islandora', 'includes/derivatives');
$logging_results = islandora_do_derivatives($object, array(
'source_dsid' => $datastream->id,
));
islandora_derivative_logging($logging_results);
}
/**
* Implements hook_islandora_datastream_modified().
*
* When a datastream is modified we filter the derivatives on source_dsid being
* equal to the current ingested datastream's id. Force is set to TRUE such that
* existing derivatives will be updated to reflect the change in the source.
*/
function islandora_islandora_datastream_modified(AbstractObject $object, AbstractDatastream $datastream) {
module_load_include('inc', 'islandora', 'includes/derivatives');
$logging_results = islandora_do_derivatives($object, array(
'source_dsid' => $datastream->id,
'force' => TRUE,
));
islandora_derivative_logging($logging_results);
}

8
js/add_print.js

@ -8,11 +8,11 @@
*/
(function ($) {
$(document).ready(function() {
$('.tabs .primary').append('<img id="print_btn" title="Print" src="/' + Drupal.settings.islandora.print_img + '"></img>');
$('.tabs .primary').append('<img id="print_btn" title="Print" src="' + Drupal.settings.basePath + Drupal.settings.islandora.print_img + '"></img>');
$('#print_btn').css("cursor","pointer");
$('#print_btn').click(function() {
window.location=Drupal.settings.islandora.print_link;
window.location=Drupal.settings.basePath + Drupal.settings.islandora.print_link;
});
});
})(jQuery);
})(jQuery);

2
tests/authtokens.test

@ -74,7 +74,7 @@ class IslandoraAuthtokensTestCase extends IslandoraWebTestCase {
$this->drupalGet("islandora/object/{$newpid}/datastream/JP2/view");
$this->assertResponse(403, 'Page not found as anonymous');
$account = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS));
$account = $this->drupalCreateUser(array(ISLANDORA_VIEW_OBJECTS));
$this->drupalLogin($account);
$this->drupalGet("islandora/object/{$newpid}/datastream/JP2/view");

160
tests/datastream_cache.test

@ -0,0 +1,160 @@
<?php
/**
* @file
* Tests to verify the cache headers we provide.
*/
class IslandoraDatastreamCacheTestCase extends IslandoraWebTestCase {
/**
* Gets info to display to describe this test.
*
* @see IslandoraWebTestCase::getInfo()
*/
public static function getInfo() {
return array(
'name' => 'Datastream Cache Headers',
'description' => 'Check our headers work as we expect them to.',
'group' => 'Islandora',
);
}
/**
* Creates an admin user and a connection to a fedora repository.
*
* @see IslandoraWebTestCase::setUp()
*/
public function setUp() {
parent::setUp();
$this->repository = $this->admin->repository;
$this->purgeTestObjects();
}
/**
* Free any objects/resources created for this test.
*
* @see IslandoraWebTestCase::tearDown()
*/
public function tearDown() {
$this->purgeTestObjects();
parent::tearDown();
}
/**
* Purge any objects created by the test's in this class.
*/
public function purgeTestObjects() {
$objects = array(
'test:test',
);
foreach ($objects as $object) {
try {
$object = $this->repository->getObject($object);
$this->repository->purgeObject($object->id);
}
catch (Exception $e) {
// Meh... Either it didn't exist or the purge failed.
}
}
}
/**
* Create our test object.
*/
protected function createTestObject() {
$object = $this->repository->constructObject('test:test');
$object->label = 'Test object';
$object->models = 'test:model';
$datastream = $object->constructDatastream('asdf', 'M');
$datastream->label = 'datastream of doom';
$datastream->mimetype = 'text/plain';
$datastream->content = 'And then things happened.';
$datastream->checksumType = 'SHA-1';
$object->ingestDatastream($datastream);
$this->repository->ingestObject($object);
return $object;
}
/**
* Test HTTP cache headers.
*/
public function testCacheHeaders() {
$object = $this->createTestObject();
$datastream = $object['asdf'];
$user = $this->drupalCreateUser(array(ISLANDORA_VIEW_OBJECTS));
$this->drupalLogin($user);
// Test If-Modified-Since.
$result = $this->drupalGet("islandora/object/{$object->id}/datastream/{$datastream->id}/view", array(), array(
'If-Modified-Since: ' . $datastream->createdDate->format('D, d M Y H:i:s \G\M\T'),
));
$this->assertResponse(304);
$result = $this->drupalGet("islandora/object/{$object->id}/datastream/{$datastream->id}/view", array(), array(
'If-Modified-Since: ' . $datastream->createdDate->sub(new DateInterval('P1M'))->format('D, d M Y H:i:s \G\M\T'),
));
$this->assertResponse(200);
// Test If-Unmodified-Since.
$result = $this->drupalGet("islandora/object/{$object->id}/datastream/{$datastream->id}/view", array(), array(
'If-Unmodified-Since: ' . $datastream->createdDate->format('D, d M Y H:i:s \G\M\T'),
));
$this->assertResponse(200);
$result = $this->drupalGet("islandora/object/{$object->id}/datastream/{$datastream->id}/view", array(), array(
'If-Unmodified-Since: ' . $datastream->createdDate->sub(new DateInterval('P1M'))->format('D, d M Y H:i:s \G\M\T'),
));
$this->assertResponse(412);
// Test If-Match.
$result = $this->drupalGet("islandora/object/{$object->id}/datastream/{$datastream->id}/view", array(), array(
format_string('If-Match: "!checksum"', array(
'!checksum' => $datastream->checksum,
)),
));
$this->assertResponse(200);
$result = $this->drupalGet("islandora/object/{$object->id}/datastream/{$datastream->id}/view", array(), array(
format_string('If-Match: "!checksum"', array(
'!checksum' => 'dont-match' . $datastream->checksum,
)),
));
$this->assertResponse(412);
// Test If-None-Match.
$result = $this->drupalGet("islandora/object/{$object->id}/datastream/{$datastream->id}/view", array(), array(
format_string('If-None-Match: "!checksum"', array(
'!checksum' => $datastream->checksum,
)),
));
$this->assertResponse(304);
$result = $this->drupalGet("islandora/object/{$object->id}/datastream/{$datastream->id}/view", array(), array(
format_string('If-None-Match: "!checksum"', array(
'!checksum' => 'dont-match' . $datastream->checksum,
)),
));
$this->assertResponse(200);
// Test combination of If-None-Match and If-Modified-Since
$result = $this->drupalGet("islandora/object/{$object->id}/datastream/{$datastream->id}/view", array(), array(
'If-Modified-Since: ' . $datastream->createdDate->format('D, d M Y H:i:s \G\M\T'),
format_string('If-None-Match: "!checksum"', array(
'!checksum' => $datastream->checksum,
)),
));
$this->assertResponse(304);
$result = $this->drupalGet("islandora/object/{$object->id}/datastream/{$datastream->id}/view", array(), array(
'If-Modified-Since: ' . $datastream->createdDate->format('D, d M Y H:i:s \G\M\T'),
format_string('If-None-Match: "!checksum"', array(
'!checksum' => 'dont-match' . $datastream->checksum,
)),
));
$this->assertResponse(200);
$result = $this->drupalGet("islandora/object/{$object->id}/datastream/{$datastream->id}/view", array(), array(
'If-Modified-Since: ' . $datastream->createdDate->sub(new DateInterval('P1M'))->format('D, d M Y H:i:s \G\M\T'),
format_string('If-None-Match: "!checksum"', array(
'!checksum' => $datastream->checksum,
)),
));
$this->assertResponse(200);
}
}

296
tests/derivatives.test

@ -0,0 +1,296 @@
<?php
/**
* @file
* Tests to see if the hooks get called when appropriate.
*
* In the test module 'islandora_derivatives_test' there are implementations
* of hooks being tested. These implementations modifies the session, and
* that's how we test if the hook gets called.
*
* To make sense of these tests reference islandora_derivatives_test.module.
*/
class IslandoraDerivativesTestCase extends IslandoraWebTestCase {
/**
* Gets info to display to describe this test.
*
* @see IslandoraWebTestCase::getInfo()
*/
public static function getInfo() {
return array(
'name' => 'Islandora Derivative Generation',
'description' => 'Ensure that the derivative generation hooks return appropriate results.',
'group' => 'Islandora',
);
}
/**
* Creates an admin user and a connection to a fedora repository.
*
* @see IslandoraWebTestCase::setUp()
*/
public function setUp() {
parent::setUp(
array(
'islandora_derivatives_test',
)
);
$url = variable_get('islandora_base_url', 'http://localhost:8080/fedora');
$this->connection = new RepositoryConnection($url, $this->admin->name, $this->admin->pass);
$this->connection->reuseConnection = TRUE;
$this->api = new FedoraApi($this->connection);
$this->cache = new SimpleCache();
$this->repository = new FedoraRepository($this->api, $this->cache);
$this->pid = $this->randomName() . ":" . $this->randomName();
}
/**
* Free any objects/resources created for this test.
*
* @see IslandoraWebTestCase::tearDown()
*/
public function tearDown() {
$tuque = islandora_get_tuque_connection();
parent::tearDown();
}
/**
* Tests that the islandora_islandora_object_ingested hook gets fired.
*/
public function testDerivativeOnIngest() {
global $_islandora_derivative_test_ingest_method;
$_islandora_derivative_test_ingest_method = 'modifyDatastream';
$tuque = islandora_get_tuque_connection();
$object = $tuque->repository->constructObject($this->pid);
$object->models = array(
'some:cmodel',
);
$dsid = 'OBJ';
$ds = $object->constructDatastream($dsid);
$ds->label = 'Test';
$ds->content = 'test';
$object->ingestDatastream($ds);
$tuque->repository->ingestObject($object);
$this->assertDatastreams($object, array(
'RELS-EXT',
'DC',
'OBJ',
'DERIV',
'NOSOURCE',
));
$this->assertEqual('ingestDatastream', $_islandora_derivative_test_ingest_method, 'The expected ingest method is "ingestDatastream", got "' . $_islandora_derivative_test_ingest_method . '".');
$this->assertEqual('test some string', $object['DERIV']->content, 'The expected content of the DERIV datastream is "test some string", got "' . $object['DERIV']->content . '".');
$this->assertEqual('NOSOURCE', $object['NOSOURCE']->content, 'The expected content of the NOSOURCE datastream is "NOSOURCE", got "' . $object['NOSOURCE']->content . '".');
}
/**
* Tests the ingest method when when forcing on existing datastreams.
*/
public function testDerivativeOnForceExistingDatastream() {
global $_islandora_derivative_test_ingest_method;
$_islandora_derivative_test_ingest_method = 'ingestDatastream';
$object = $this->constructBaseObject();
$object = $this->constructDERIVDatastream($object);
$this->constructNOSOURCEDatastream($object);
$islandora_object = islandora_object_load($this->pid);
islandora_do_derivatives($islandora_object, array(
'force' => TRUE,
));
$this->assertEqual('modifyDatastream', $_islandora_derivative_test_ingest_method, 'The expected ingest method is "modifyDatastream", got "' . $_islandora_derivative_test_ingest_method . '".');
$this->assertEqual('FORCEFULLY APPENDING CONTENT TO test', $islandora_object['DERIV']->content, 'The expected content of the DERIV datastream is "FORCEFULLY APPENDING CONTENT TO test", got "' . $islandora_object['DERIV']->content . '".');
}
/**
* Tests the ingest method when forcing on non-existing datastreams.
*/
public function testDerivativeOnForceNonExistingDatastream() {
global $_islandora_derivative_test_ingest_method;
$_islandora_derivative_test_ingest_method = 'modifyDatastream';
$this->constructBaseObject();
$object = islandora_object_load($this->pid);
islandora_do_derivatives($object, array(
'force' => TRUE,
));
$this->assertEqual('ingestDatastream', $_islandora_derivative_test_ingest_method, 'The expected ingest method is "ingestDatastream", got "' . $_islandora_derivative_test_ingest_method . '".');
$this->assertEqual('test some string', $object['DERIV']->content, 'The expected content of the DERIV datastream is "test some string", got "' . $object['DERIV']->content . '".');
}
/**
* Tests the islandora_datastream_modified hook when there are existing DSes.
*/
public function testDerivativeOnModifyExistingDatastream() {
global $_islandora_derivative_test_ingest_method;
$_islandora_derivative_test_ingest_method = 'ingestDatastream';
$object = $this->constructBaseObject();
$this->constructDERIVDatastream($object);
// Need to do this as Tuque caches.
$connection = islandora_get_tuque_connection();
$connection->cache->resetCache();
$islandora_object = islandora_object_load($this->pid);
$changed_content = 'islandora beast';
$islandora_object['OBJ']->content = $changed_content;
$this->assertEqual('modifyDatastream', $_islandora_derivative_test_ingest_method, 'The expected ingest method is "modifyDatastream", got "' . $_islandora_derivative_test_ingest_method . '".');
$this->assertEqual('FORCEFULLY APPENDING CONTENT TO ' . $changed_content, $islandora_object['DERIV']->content, 'The expected content of the DERIV datastream is "FORCEFULLY APPENDING CONTENT TO islandora beast", got "' . $islandora_object['DERIV']->content . '".');
}
/**
* Tests islandora_datastream_modified hook when there are no existing DSes.
*/
public function testDerivativeOnModifyNonExistingDatastream() {
global $_islandora_derivative_test_ingest_method;
$_islandora_derivative_test_ingest_method = 'modifyDatastream';
$this->constructBaseObject();
// Need to do this as Tuque caches.
$connection = islandora_get_tuque_connection();
$connection->cache->resetCache();
$islandora_object = islandora_object_load($this->pid);
$changed_content = 'islandora beast';
$islandora_object['OBJ']->content = $changed_content;
$this->assertEqual('ingestDatastream', $_islandora_derivative_test_ingest_method, 'The expected ingest method is "ingestDatastream", got "' . $_islandora_derivative_test_ingest_method . '".');
$this->assertEqual($changed_content . ' some string', $islandora_object['DERIV']->content, 'The expected content of the DERIV datastream is "islandora beast string", got "' . $islandora_object['DERIV']->content . '".');
}
/**
* Tests derivative hook filtering based upon source_dsid.
*/
public function testDerivativeFilteringOnSourceDSID() {
global $_islandora_derivative_test_derivative_functions;
$_islandora_derivative_test_derivative_functions = array();
$this->constructBaseObject();
$object = islandora_object_load($this->pid);
islandora_do_derivatives($object, array(
'source_dsid' => 'OBJ',
));
$this->assertEqual(1, count($_islandora_derivative_test_derivative_functions), 'Expected 1 derivative function for the source_dsid of "OBJ", got ' . count($_islandora_derivative_test_derivative_functions) . '.');
$called_function = (string) reset($_islandora_derivative_test_derivative_functions);
$this->assertEqual('islandora_derivatives_test_create_deriv_datastream', $called_function, 'Expected derivative function is "islandora_derivatives_test_create_deriv_datastream", got "' . $called_function . '".');
// Reset the derivative functions array as we are going to use it again.
$_islandora_derivative_test_derivative_functions = array();
islandora_do_derivatives($object, array(
'source_dsid' => 'SOMEWEIRDDATASTREAM',
));
$this->assertEqual(1, count($_islandora_derivative_test_derivative_functions), 'Expected 1 derivative function for the source_dsid of "SOMEWEIRDDATASTREAM", got ' . count($_islandora_derivative_test_derivative_functions) . '.');
$called_function = (string) reset($_islandora_derivative_test_derivative_functions);
$this->assertEqual('islandora_derivatives_test_create_some_weird_datastream', $called_function, 'Expected derivative function is "islandora_derivatives_test_create_some_weird_datastream", got "' . $called_function . '".');
}
/**
* Tests that only functions were the source_dsid is NULL are fired.
*/
public function testNULLSourceDSID() {
global $_islandora_derivative_test_derivative_functions;
$_islandora_derivative_test_derivative_functions = array();
$this->constructBaseObject();
$object = islandora_object_load($this->pid);
islandora_do_derivatives($object, array(
'source_dsid' => NULL,
));
$this->assertDatastreams($object, array(
'DC',
'RELS-EXT',
'OBJ',
'NOSOURCE',
));
$this->assertEqual(1, count($_islandora_derivative_test_derivative_functions), 'Expected 1 derivative function for the source_dsid of "NULL", got ' . count($_islandora_derivative_test_derivative_functions) . '.');
$called_function = (string) reset($_islandora_derivative_test_derivative_functions);
$this->assertEqual('islandora_derivatives_test_create_nosource_datastream', $called_function, 'Expected derivative function is "islandora_derivatives_test_create_nosource_datastream", got "' . $called_function . '".');
$this->assertEqual('NOSOURCE', $object['NOSOURCE']->content, 'The expected content of the NOSOURCE datastream is "NOSOURCE", got "' . $object['NOSOURCE']->content . '".');
}
/**
* Tests that when no source_dsid all derivative functions are called.
*/
public function testNoSourceDSIDNoForce() {
global $_islandora_derivative_test_derivative_functions;
$_islandora_derivative_test_derivative_functions = array();
$this->constructBaseObject();
$object = islandora_object_load($this->pid);
islandora_do_derivatives($object, array());
$this->assertDatastreams($object, array(
'DC',
'RELS-EXT',
'OBJ',
'DERIV',
'NOSOURCE',
));
$this->assertEqual(3, count($_islandora_derivative_test_derivative_functions), 'Expected 3 derivative functions when there is no source_dsid, got ' . count($_islandora_derivative_test_derivative_functions) . '.');
}
/**
* Tests that when no source_dsid all derivative functions are called.
*/
public function testNoSourceDSIDForce() {
global $_islandora_derivative_test_derivative_functions;
$_islandora_derivative_test_derivative_functions = array();
$this->constructBaseObject();
$object = islandora_object_load($this->pid);
islandora_do_derivatives($object, array(
'force' => TRUE,
));
$this->assertDatastreams($object, array(
'DC',
'RELS-EXT',
'OBJ',
'DERIV',
'NOSOURCE',
));
$this->assertEqual(3, count($_islandora_derivative_test_derivative_functions), 'Expected 3 derivative functions when there is no source_dsid, got ' . count($_islandora_derivative_test_derivative_functions) . '.');
}
/**
* Helper function that will construct a base object.
*/
public function constructBaseObject() {
$object = $this->repository->constructObject($this->pid);
$object->models = array(
'some:cmodel',
);
$dsid = 'OBJ';
$ds = $object->constructDatastream($dsid);
$ds->label = 'Test';
$ds->content = 'test';
$object->ingestDatastream($ds);
$this->repository->ingestObject($object);
return $object;
}
/**
* Helper function to construct the DERIV datastream without firing hooks.
*
* @param AbstractObject $object
* An AbstractObject representing a FedoraObject.
*
* @return AbstractObject
* The modified AbstractObject.
*/
public function constructDERIVDatastream(AbstractObject $object) {
$dsid = 'DERIV';
$ds = $object->constructDatastream($dsid);
$ds->label = 'Test';
$ds->content = 'test some string';
$object->ingestDatastream($ds);
return $object;
}
/**
* Helper function to construct the NOSOURCE datastream without firing hooks.
*
* @param AbstractObject $object
* An AbstractObject representing a FedoraObject.
*
* @return AbstractObject
* The modified AbstractObject.
*/
public function constructNOSOURCEDatastream(AbstractObject $object) {
$dsid = 'NOSOURCE';
$ds = $object->constructDatastream($dsid);
$ds->label = 'Test';
$ds->content = 'NOSOURCE';
$object->ingestDatastream($ds);
return $object;
}
}

6
tests/hooked_access.test

@ -37,9 +37,9 @@ class IslandoraHookedAccessTestCase extends IslandoraWebTestCase {
$this->objects = array(
'test:testAccessHook',
);
$this->op = FEDORA_VIEW_OBJECTS;
$this->other_op = FEDORA_INGEST;
$this->denied_op = FEDORA_PURGE;
$this->op = ISLANDORA_VIEW_OBJECTS;
$this->other_op = ISLANDORA_INGEST;
$this->denied_op = ISLANDORA_PURGE;
$this->purgeTestObjects();
$this->dsid = 'asdf';
$this->createTestObjects();

7
tests/islandora_derivatives_test.info

@ -0,0 +1,7 @@
name = Islandora Derivatives Generation testing
description = Tests derivative generation hooks. Do not enable.
core = 7.x
package = Testing
hidden = TRUE
files[] = islandora_derivatives_test.module
dependencies[] = islandora

202
tests/islandora_derivatives_test.module

@ -0,0 +1,202 @@
<?php
/**
* @file
* Tests for derivative generation.
*/
/**
* Implements hook_islandora_CMODEL_PID_derivative().
*/
function islandora_derivatives_test_some_cmodel_islandora_derivative() {
return array(
array(
'source_dsid' => 'OBJ',
'destination_dsid' => 'DERIV',
'weight' => '0',
'function' => array(
'islandora_derivatives_test_create_deriv_datastream',
),
),
array(
'source_dsid' => 'SOMEWEIRDDATASTREAM',
'destination_dsid' => 'STANLEY',
'weight' => '-1',
'function' => array(
'islandora_derivatives_test_create_some_weird_datastream',
),
),
array(
'source_dsid' => NULL,
'destination_dsid' => 'NOSOURCE',
'weight' => '-3',
'function' => array(
'islandora_derivatives_test_create_nosource_datastream',
),
),
);
}
/**
* Creates the DERIV datastream for use in testing.
*
* @param AbstractObject $object
* An AbstractObject representing a Fedora object.
* @param bool $force
* Whether or not derivative generation is to be forced.
* @return array
* An array detailing the success of the operation.
*
* @see hook_islandora_derivative()
*/
function islandora_derivatives_test_create_deriv_datastream(AbstractObject $object, $force = FALSE) {
global $_islandora_derivative_test_derivative_functions;
$_islandora_derivative_test_derivative_functions[] = 'islandora_derivatives_test_create_deriv_datastream';
$return = '';
if (!isset($object['DERIV']) || (isset($object['DERIV']) && $force === TRUE)) {
if ($force !== TRUE || !isset($object['DERIV'])) {
$deriv_string = $object['OBJ']->content . ' some string';
}
else {
$deriv_string = "FORCEFULLY APPENDING CONTENT TO " . $object['OBJ']->content;
}
$added_successfully = islandora_derivatives_test_add_datastream($object, 'DERIV', $deriv_string);
if ($added_successfully !== TRUE) {
$return = islandora_derivatives_test_failed_adding($added_successfully);
}
else {
$return = array(
'success' => TRUE,
'messages' => array(
array(
'message' => t('The DERIV datastream was added successfully for @pid!'),
'message_sub' => array('@pid' => $object->id),
'type' => 'dsm',
),
),
);
}
return $return;
}
}
/**
* Stub function that used only for datastream filtering counts.
*
* @param AbstractObject $object
* An AbstractObject representing a Fedora object.
* @param bool $force
* Whether the derivatives are being forcefully generated or not.
*/
function islandora_derivatives_test_create_some_weird_datastream(AbstractObject $object, $force = FALSE) {
global $_islandora_derivative_test_derivative_functions;
// Add to the global that we got to this function.
$_islandora_derivative_test_derivative_functions[] = 'islandora_derivatives_test_create_some_weird_datastream';
}
/**
* Creates the NOSOURCE datastream for use in testing.
*
* @param AbstractObject $object
* An AbstractObject representing a Fedora object.
* @param bool $force
* Whether or not derivative generation is to be forced.
* @return array
* An array detailing the success of the operation.
*
* @see hook_islandora_derivative()
*/
function islandora_derivatives_test_create_nosource_datastream(AbstractObject $object, $force = FALSE) {
global $_islandora_derivative_test_derivative_functions;
$_islandora_derivative_test_derivative_functions[] = 'islandora_derivatives_test_create_nosource_datastream';
$return = '';
if (!isset($object['NOSOURCE']) || (isset($object['NOSOURCE']) && $force === TRUE)) {
if ($force !== TRUE || !isset($object['NOSOURCE'])) {
$deriv_string = 'NOSOURCE';
}
else {
$deriv_string = "FORCEFULLY APPENDING CONTENT TO " . $object['NOSOURCE']->content;
}
$added_successfully = islandora_derivatives_test_add_datastream($object, 'NOSOURCE', $deriv_string);
if ($added_successfully !== TRUE) {
$return = islandora_derivatives_test_failed_adding($added_successfully);
}
else {
$return = array(
'success' => TRUE,
'messages' => array(
array(
'message' => t('The DERIV datastream was added successfully for @pid!'),
'message_sub' => array('@pid' => $object->id),
'type' => 'dsm',
),
),
);
}
return $return;
}
}
/**
* Helper function that adds/modifies the datastream to the object in testing.
*
* @param AbstractObject $object
* An AbstractObject representing a Fedora object.
* @param string $dsid
* The datastream id for which we are adding/modifying.
* @param string $deriv_string
* The content of the datastream we are adding.
*
* @return bool|string
* A bool if the operation was successfully, the error message otherwise.
*/
function islandora_derivatives_test_add_datastream(AbstractObject $object, $dsid, $deriv_string) {
global $_islandora_derivative_test_ingest_method;
try {
$ingest = !isset($object[$dsid]);
if ($ingest) {
$ds = $object->constructDatastream($dsid, 'M');
$ds->label = $dsid;
}
else {
$ds = $object[$dsid];
}
$ds->content = $deriv_string;
if ($ingest) {
$_islandora_derivative_test_ingest_method = 'ingestDatastream';
$object->ingestDatastream($ds);
}
else {
$_islandora_derivative_test_ingest_method = 'modifyDatastream';
}
return TRUE;
}
catch (exception $e) {
$message = $e->getMessage();
return $message;
}
}
/**
* Returns a message if we failed to add a derivative.
*
* @see hook_islandora_derivative()
*
* @param string $message
* The error message to be returned back.
*
* @return array
* An array describing the outcome of our failure.
*/
function islandora_derivatives_test_failed_adding($message) {
return array(
'success' => FALSE,
'messages' => array(
array(
'message' => $message,
'type' => 'watchdog',
'severity' => WATCHDOG_ERROR,
),
),
);
}

5
tests/islandora_hooked_access_test.module

@ -9,7 +9,7 @@
* Implements hook_islandora_object_access().
*/
function islandora_hooked_access_test_islandora_object_access($op, $object, $user) {
if ($op == FEDORA_PURGE) {
if ($op == ISLANDORA_PURGE) {
return FALSE;
}
if (isset($_SESSION['islandora_hooked_access_test']) && $_SESSION['islandora_hooked_access_test'] === func_get_args()) {
@ -23,6 +23,9 @@ function islandora_hooked_access_test_islandora_object_access($op, $object, $use
* Implements hook_islandora_datastream_access().
*/
function islandora_hooked_access_test_islandora_datastream_access($op, $datastream, $user) {
if ($op == FEDORA_PURGE) {
return FALSE;
}
if (isset($_SESSION['islandora_hooked_access_test']) && $_SESSION['islandora_hooked_access_test'] === func_get_args()) {
return TRUE;
}

50
tests/islandora_manage_permissions.test

@ -33,16 +33,16 @@ class IslandoraPermissionsTestCase extends IslandoraWebTestCase {
* Test manage permissions.
*/
public function testManagePermissions() {
// Test permission FEDORA_VIEW_OBJECTS.
// Test permission ISLANDORA_VIEW_OBJECTS.
// Create a user with permission.
$user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS));
$user = $this->drupalCreateUser(array(ISLANDORA_VIEW_OBJECTS));
// Log the user in.
$this->drupalLogin($user);
$this->clickLink(t('Islandora Repository'));
$this->assertNoLink('Manage', 'Manage tab is not on current page.');
// Test permission FEDORA_VIEW_OBJECTS, FEDORA_MANAGE_PROPERTIES.
$user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS, FEDORA_MANAGE_PROPERTIES));
// Test permission ISLANDORA_VIEW_OBJECTS, ISLANDORA_MANAGE_PROPERTIES.
$user = $this->drupalCreateUser(array(ISLANDORA_VIEW_OBJECTS, ISLANDORA_MANAGE_PROPERTIES));
$this->drupalLogin($user);
$this->clickLink(t('Islandora Repository'));
$this->assertLink('Manage', 0, 'Manage tab is on current page.');
@ -51,8 +51,8 @@ class IslandoraPermissionsTestCase extends IslandoraWebTestCase {
$this->assertNoLink('Datastreams', 'Datastreams tab is not on current page.');
$this->assertNoLink('Collection', 'Collection tab is not on current page.');
// Test permission FEDORA_VIEW_OBJECTS, FEDORA_ADD_DS.
$user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS, FEDORA_ADD_DS));
// Test permission ISLANDORA_VIEW_OBJECTS, ISLANDORA_ADD_DS.
$user = $this->drupalCreateUser(array(ISLANDORA_VIEW_OBJECTS, ISLANDORA_ADD_DS));
$this->drupalLogin($user);
$this->clickLink(t('Islandora Repository'));
$this->assertLink('Manage', 0, 'Manage tab is on current page.');
@ -61,8 +61,8 @@ class IslandoraPermissionsTestCase extends IslandoraWebTestCase {
$this->assertNoLink('Properties', 'Properties tab is not on current page.');
$this->assertNoLink('Collection', 'Collection tab is not on current page.');
// Test permission FEDORA_VIEW_OBJECTS, FEDORA_METADATA_EDIT.
$user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS, FEDORA_METADATA_EDIT));
// Test permission ISLANDORA_VIEW_OBJECTS, ISLANDORA_METADATA_EDIT.
$user = $this->drupalCreateUser(array(ISLANDORA_VIEW_OBJECTS, ISLANDORA_METADATA_EDIT));
$this->drupalLogin($user);
$this->clickLink(t('Islandora Repository'));
$this->assertLink('Manage', 0, 'Manage tab is on current page.');
@ -71,8 +71,8 @@ class IslandoraPermissionsTestCase extends IslandoraWebTestCase {
$this->assertNoLink('Properties', 'Properties tab is not on current page.');
$this->assertNoLink('Collection', 'Collection tab is not on current page.');
// Test permission FEDORA_VIEW_OBJECTS, FEDORA_PURGE.
$user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS, FEDORA_PURGE));
// Test permission ISLANDORA_VIEW_OBJECTS, ISLANDORA_PURGE.
$user = $this->drupalCreateUser(array(ISLANDORA_VIEW_OBJECTS, ISLANDORA_PURGE));
$this->drupalLogin($user);
$this->clickLink(t('Islandora Repository'));
$this->assertLink('Manage', 0, 'Manage tab is on current page.');
@ -98,39 +98,39 @@ class IslandoraPermissionsTestCase extends IslandoraWebTestCase {
$ret = islandora_user_access($object, array());
$this->assertFalse($ret, 'User access denied when no permissions are provided.');
// Test access with matching permission.
$user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS));
$ret = islandora_user_access($object, array(FEDORA_VIEW_OBJECTS), array(), TRUE, $user);
$user = $this->drupalCreateUser(array(ISLANDORA_VIEW_OBJECTS));
$ret = islandora_user_access($object, array(ISLANDORA_VIEW_OBJECTS), array(), TRUE, $user);
$this->assertTrue($ret, 'User access granted when permissions match.');
// Test access with matching permission but access any is FALSE.
$user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS));
$ret = islandora_user_access($object, array(FEDORA_VIEW_OBJECTS, FEDORA_PURGE), array(), FALSE, $user);
$user = $this->drupalCreateUser(array(ISLANDORA_VIEW_OBJECTS));
$ret = islandora_user_access($object, array(ISLANDORA_VIEW_OBJECTS, ISLANDORA_PURGE), array(), FALSE, $user);
$this->assertFalse($ret, 'User access denied for matching permission but with access any set to FALSE.');
// Test access with non-matching permission.
$user = $this->drupalCreateUser(array(FEDORA_PURGE));
$ret = islandora_user_access($object, array(FEDORA_VIEW_OBJECTS), array(), TRUE, $user);
$user = $this->drupalCreateUser(array(ISLANDORA_PURGE));
$ret = islandora_user_access($object, array(ISLANDORA_VIEW_OBJECTS), array(), TRUE, $user);
$this->assertFalse($ret, 'User access denied when permissions did not match.');
// Test access with both permissions and content model.
$user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS));
$user = $this->drupalCreateUser(array(ISLANDORA_VIEW_OBJECTS));
$model = $object->models;
$model = reset($model);
$ret = islandora_user_access($object, array(FEDORA_VIEW_OBJECTS), array($model), TRUE, $user);
$ret = islandora_user_access($object, array(ISLANDORA_VIEW_OBJECTS), array($model), TRUE, $user);
$this->assertTrue($ret, 'User access granted for matching permission and model.');
// Test access with matching permissions and non-matching content model.
$user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS));
$ret = islandora_user_access($object, array(FEDORA_VIEW_OBJECTS), array('islandora:obviouslyNotACModel'), TRUE, $user);
$user = $this->drupalCreateUser(array(ISLANDORA_VIEW_OBJECTS));
$ret = islandora_user_access($object, array(ISLANDORA_VIEW_OBJECTS), array('islandora:obviouslyNotACModel'), TRUE, $user);
$this->assertFalse($ret, 'User access denied for matching permission and non-matching model.');
// Test access with all matching permissions and one matching model but
// access any is FALSE.
$user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS, FEDORA_PURGE));
$user = $this->drupalCreateUser(array(ISLANDORA_VIEW_OBJECTS, ISLANDORA_PURGE));
$model = $object->models;
$model = reset($model);
$ret = islandora_user_access($object, array(FEDORA_VIEW_OBJECTS, FEDORA_PURGE), array($model, 'islandora:obviouslyNotACModel'), FALSE, $user);
$ret = islandora_user_access($object, array(ISLANDORA_VIEW_OBJECTS, ISLANDORA_PURGE), array($model, 'islandora:obviouslyNotACModel'), FALSE, $user);
$this->assertFalse($ret, 'User access denied for all matching permissions and one matching model but with access any set to FALSE.');
$ret = islandora_user_access($object, array(FEDORA_VIEW_OBJECTS, FEDORA_PURGE), array($model), FALSE, $user);
$ret = islandora_user_access($object, array(ISLANDORA_VIEW_OBJECTS, ISLANDORA_PURGE), array($model), FALSE, $user);
$this->assertTrue($ret, 'User access granted for all matching permissions and matching models with access any set to FALSE.');
// Test passing in a Datastream.
$user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS, FEDORA_PURGE));
$ret = islandora_user_access($object['DC'], array(FEDORA_VIEW_OBJECTS), array(), TRUE, $user);
$user = $this->drupalCreateUser(array(ISLANDORA_VIEW_OBJECTS, ISLANDORA_PURGE));
$ret = islandora_user_access($object['DC'], array(ISLANDORA_VIEW_OBJECTS), array(), TRUE, $user);
$this->assertTrue($ret, 'User access granted for matching permissions, with a datastream given instead of an object.');
}
}

52
theme/theme.inc

@ -115,7 +115,7 @@ function islandora_preprocess_islandora_default(&$variables) {
$download_path = islandora_datastream_get_url($ds, 'download');
$datastreams[$id]['id'] = $id;
$datastreams[$id]['label'] = $label;
$datastreams[$id]['label_link'] = islandora_datastream_access(FEDORA_VIEW_OBJECTS, $ds) ?
$datastreams[$id]['label_link'] = islandora_datastream_access(ISLANDORA_VIEW_OBJECTS, $ds) ?
l($label, $download_path) :
$label;
$datastreams[$id]['download_url'] = $download_path;
@ -130,14 +130,14 @@ function islandora_preprocess_islandora_default(&$variables) {
}
$variables['datastreams'] = $datastreams;
// Objects in fcrepo4 don't always contain a DC datastream.
if (isset($islandora_object['DC']) && islandora_datastream_access(FEDORA_VIEW_OBJECTS, $islandora_object['DC'])) {
if (isset($islandora_object['DC']) && islandora_datastream_access(ISLANDORA_VIEW_OBJECTS, $islandora_object['DC'])) {
$dc_object = DublinCore::importFromXMLString($islandora_object['DC']->content);
$dc_array = $dc_object->asArray();
}
$variables['dc_array'] = isset($dc_array) ? $dc_array : array();
$variables['islandora_dublin_core'] = isset($dc_object) ? $dc_object : NULL;
$variables['islandora_object_label'] = $islandora_object->label;
if (isset($islandora_object['TN']) && islandora_datastream_access(FEDORA_VIEW_OBJECTS, $islandora_object['TN'])) {
if (isset($islandora_object['TN']) && islandora_datastream_access(ISLANDORA_VIEW_OBJECTS, $islandora_object['TN'])) {
$variables['islandora_thumbnail_url'] = url("islandora/object/{$islandora_object->id}/datastream/TN/view");
}
}
@ -219,11 +219,11 @@ function islandora_preprocess_islandora_objects(array &$variables) {
$o = islandora_object_load($o);
$url = "islandora/object/{$o->id}";
$link_options = array('html' => TRUE, 'attributes' => array('title' => $o->label));
$img = islandora_datastream_access(FEDORA_VIEW_OBJECTS, $o['TN']) ?
$img = islandora_datastream_access(ISLANDORA_VIEW_OBJECTS, $o['TN']) ?
theme('image', array('path' => url("$url/datastream/TN/view"), 'attributes' => array())) :
'';
$description = NULL;
if (isset($o['DC']) && islandora_datastream_access(FEDORA_VIEW_OBJECTS, $o['DC'])) {
if (isset($o['DC']) && islandora_datastream_access(ISLANDORA_VIEW_OBJECTS, $o['DC'])) {
$dc = DublinCore::importFromXMLString($o['DC']->content);
if ($dc) {
$dc = $dc->asArray();
@ -260,7 +260,7 @@ function theme_islandora_datastream_download_link(array $vars) {
module_load_include('inc', 'islandora', 'includes/utilities');
$label = t('download');
return islandora_datastream_access(FEDORA_VIEW_OBJECTS, $datastream) ?
return islandora_datastream_access(ISLANDORA_VIEW_OBJECTS, $datastream) ?
l($label, islandora_datastream_get_url($datastream, 'download')) :
'';
}
@ -289,7 +289,7 @@ function theme_islandora_datastream_view_link(array $vars) {
}
if ($vars['version'] === NULL) {
$perm = FEDORA_VIEW_OBJECTS;
$perm = ISLANDORA_VIEW_OBJECTS;
}
else {
$perm = ISLANDORA_VIEW_DATASTREAM_HISTORY;
@ -319,7 +319,7 @@ function theme_islandora_datastream_delete_link(array $vars) {
$datastreams = module_invoke_all('islandora_undeletable_datastreams', $datastream->parent->models);
$can_delete = !in_array($datastream->id, $datastreams) && islandora_datastream_access(FEDORA_PURGE, $datastream);
$can_delete = !in_array($datastream->id, $datastreams) && islandora_datastream_access(ISLANDORA_PURGE, $datastream);
if ($vars['version'] !== NULL) {
if (count($datastream) == 1) {
@ -339,6 +339,40 @@ function theme_islandora_datastream_delete_link(array $vars) {
}
}
/**
* Renders a link to allow replacing of a datatream.
*
* @param array $vars
* An array containing:
* - datastream: An AbstractDatastream for which to generate a revert link.
* - version: (optional) the version of the datastream to revert.
*
* @return string
* Markup containing the url to delete a datastream, or empty if inaccessible.
*/
function theme_islandora_datastream_revert_link(array $vars) {
$datastream = $vars['datastream'];
$can_revert = islandora_datastream_access(ISLANDORA_REVERT_DATASTREAM, $datastream);
if ($vars['version'] !== NULL) {
if (count($datastream) == 1) {
$can_revert = FALSE;
}
$link = "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/version/{$vars['version']}/revert";
}
else {
$can_revert = FALSE;
}
if ($can_revert) {
return l(t('revert'), $link);
}
else {
return '';
}
}
/**
* Renders a link to allow editing of a datatream.
*
@ -354,7 +388,7 @@ function theme_islandora_datastream_edit_link(array $vars) {
$edit_registry = module_invoke_all('islandora_edit_datastream_registry', $datastream->parent, $datastream);
$can_edit = count($edit_registry) > 0 && islandora_datastream_access(FEDORA_METADATA_EDIT, $datastream);
$can_edit = count($edit_registry) > 0 && islandora_datastream_access(ISLANDORA_METADATA_EDIT, $datastream);
return $can_edit ?
l(t('edit'), "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/edit") :

Loading…
Cancel
Save