Browse Source

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

pull/354/head
phil 11 years ago
parent
commit
6bf864de83
  1. 6
      README.md
  2. 8
      includes/add_datastream.form.inc
  3. 17
      includes/breadcrumb.inc
  4. 57
      includes/content_model.autocomplete.inc
  5. 28
      includes/datastream.inc
  6. 6
      includes/delete_datastream.form.inc
  7. 4
      includes/delete_object.form.inc
  8. 143
      includes/ingest.form.inc
  9. 18
      includes/mime_detect.inc
  10. 4
      includes/object_properties.form.inc
  11. 10
      includes/solution_packs.inc
  12. 4
      includes/tuque_wrapper.inc
  13. 64
      includes/utilities.inc
  14. 70
      islandora.api.php
  15. 3
      islandora.info
  16. 123
      islandora.module
  17. 6
      islandora.rules.inc
  18. 4
      tests/README.md
  19. 118
      tests/ingest.test
  20. 14
      tests/islandora_hooks_test.module
  21. 7
      tests/islandora_ingest_test.info
  22. 166
      tests/islandora_ingest_test.module
  23. 125
      tests/islandora_web_test_case.inc
  24. 18
      tests/scripts/travis_setup.sh

6
README.md

@ -23,7 +23,11 @@ https://jira.duraspace.org/browse/ISLANDORA
REQUIREMENTS
------------
The Tuque library must be installed to use Islandora. It can be found here:
http://github.com/Islandora/tuque
It is expected to be in one of two paths:
- sites/all/libraries/tuque (libraries directory may need to be created)
- islandora_folder/libraries/tuque
INSTALLATION
------------

8
includes/add_datastream.form.inc

@ -12,13 +12,13 @@
* The Drupal form.
* @param array $form_state
* The Drupal form state.
* @param FedoraObject $object
* @param AbstractObject $object
* The object to be deleted.
*
* @return array
* The drupal form definition.
*/
function islandora_add_datastream_form(array $form, array &$form_state, FedoraObject $object) {
function islandora_add_datastream_form(array $form, array &$form_state, AbstractObject $object) {
module_load_include('inc', 'islandora', 'includes/content_model');
module_load_include('inc', 'islandora', 'includes/utilities');
form_load_include($form_state, 'inc', 'islandora', 'includes/add_datastream.form');
@ -206,13 +206,13 @@ function islandora_add_datastream_form_submit(array $form, array &$form_state) {
*
* It lists the missing required (may be optional) datastreams.
*
* @param FedoraObject $object
* @param AbstractObject $object
* The object used to check for missing required datastreams used to populate
* the options in this callback.
* @param string $query
* vThe user query to match against the missing required datastreams.
*/
function islandora_add_datastream_form_autocomplete_callback(FedoraObject $object, $query = '') {
function islandora_add_datastream_form_autocomplete_callback(AbstractObject $object, $query = '') {
module_load_include('inc', 'islandora', 'includes/content_model');
module_load_include('inc', 'islandora', 'includes/utilities');
$dsids = array_keys(islandora_get_missing_datastreams_requirements($object));

17
includes/breadcrumb.inc

@ -14,7 +14,7 @@
* ancestry which is identified by any of the following RELS-EXT terms
* (isMemberOf,isMemberOfCollection,isPartOf).
*
* @param FedoraObject $object
* @param AbstractObject $object
* An object whose ancestry will be mapped to bread-crumbs.
*
* @see drupal_set_breadcrumb()
@ -57,10 +57,21 @@ function islandora_get_breadcrumbs_recursive($pid, FedoraRepository $repository,
$root = variable_get('islandora_repository_pid', 'islandora:root');
if ($pid == $root) {
$item = menu_get_item('islandora');
$title = 'Islandora Repository';
$mlid = db_select('menu_links', 'ml')
->condition('ml.link_path', 'islandora')
->fields('ml', array('mlid'))
->execute()
->fetchField();
if ($mlid) {
$link = menu_link_load($mlid);
$title = (isset($link['title']) ? $link['title'] : $title);
}
return array(
l(t('Home'), '<front>'),
l($item['title'], 'islandora'),
l($title, 'islandora'),
);
}
else {

57
includes/content_model.autocomplete.inc

@ -0,0 +1,57 @@
<?php
/**
* @file
* Autocomplete functionality for content models in Islandora.
*/
/**
* Autocomplete the content model name.
*
* @param string $string
* A search string.
*
* @return string
* The rendered JSON results.
*/
function islandora_content_model_autocomplete($string) {
$content_models = islandora_get_content_model_names();
$output = array();
foreach ($content_models as $model => $label) {
if (preg_match("/{$string}/i", $label) !== 0) {
$output[$model] = $label;
}
}
return drupal_json_output($output);
}
/**
* Gets a map of form names suitable for use as select #options.
*/
function islandora_get_content_model_names() {
module_load_include('inc', 'islandora', 'includes/utilities');
$results = islandora_get_content_models();
$ret = array();
foreach ($results as $result) {
$ret[$result['pid']] = "{$result['label']} ({$result['pid']})";
}
return $ret;
}
/**
* Minor array transformation.
*
* @param array $content
* The array of results as returned from Tuque's RI query interface.
*
* @return array
* An array of results in a more usable format.
*/
function islandora_parse_query($content) {
$content_models = array();
foreach ($content as $model) {
$content_models[] = $model['object']['value'];
}
$content_models = array_unique($content_models);
$content_models = array_values($content_models);
return $content_models;
}

28
includes/datastream.inc

@ -8,10 +8,10 @@
/**
* Callback to download the given datastream to the users computer.
*
* @param FedoraDatastream $datastream
* @param AbstractDatastream $datastream
* The datastream to download.
*/
function islandora_download_datastream(FedoraDatastream $datastream) {
function islandora_download_datastream(AbstractDatastream $datastream) {
islandora_view_datastream($datastream, TRUE);
}
@ -21,13 +21,13 @@ function islandora_download_datastream(FedoraDatastream $datastream) {
* @note
* This function calls exit().
*
* @param FedoraDatastream $datastream
* @param AbstractDatastream $datastream
* The datastream to view/download.
* @param bool $download
* If TRUE the file is download to the user computer for viewing otherwise it
* will attempt to display in the browser natively.
*/
function islandora_view_datastream(FedoraDatastream $datastream, $download = FALSE) {
function islandora_view_datastream(AbstractDatastream $datastream, $download = FALSE) {
header_remove('Cache-Control');
header_remove('Expires');
header('Content-type: ' . $datastream->mimetype);
@ -51,14 +51,14 @@ function islandora_view_datastream(FedoraDatastream $datastream, $download = FAL
/**
* Get the human readable size of the given datastream.
*
* @param FedoraDatastream $datastream
* @param AbstractDatastream $datastream
* The datastream to check.
*
* @return string
* A human readable size of the given datastream, or '-' if the size could not
* be determined.
*/
function islandora_datastream_get_human_readable_size(FedoraDatastream $datastream) {
function islandora_datastream_get_human_readable_size(AbstractDatastream $datastream) {
module_load_include('inc', 'islandora', 'includes/utilities');
$size_is_calculatable = $datastream->controlGroup == 'M' || $datastream->controlGroup == 'X';
return $size_is_calculatable ? islandora_convert_bytes_to_human_readable($datastream->size) : '-';
@ -67,23 +67,23 @@ function islandora_datastream_get_human_readable_size(FedoraDatastream $datastre
/**
* Get either the 'view' or 'download' url for the given datastream if possible.
*
* @param FedoraDatastream $datastream
* @param AbstractDatastream $datastream
* The datastream to generated the url to.
*
* @return string
* either the 'view' or 'download' url for the given datastream.
*/
function islandora_datastream_get_url(FedoraDatastream $datastream, $type = 'download') {
function islandora_datastream_get_url(AbstractDatastream $datastream, $type = 'download') {
return $datastream->controlGroup == 'R' ? $datastream->url : "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/$type";
}
/**
* Gets the delete link.
*
* @param FedoraDatastream $datastream
* @param AbstractDatastream $datastream
* The datastream to generated the url to.
*/
function islandora_datastream_get_delete_link(FedoraDatastream $datastream) {
function islandora_datastream_get_delete_link(AbstractDatastream $datastream) {
$datastreams = module_invoke_all('islandora_undeletable_datastreams', $datastream->parent->models);
$can_delete = !in_array($datastream->id, $datastreams);
return $can_delete ? l(t('delete'), "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/delete") : '';
@ -92,10 +92,10 @@ function islandora_datastream_get_delete_link(FedoraDatastream $datastream) {
/**
* Gets the edit link.
*
* @param FedoraDatastream $datastream
* @param AbstractDatastream $datastream
* The datastream to generated the url to.
*/
function islandora_datastream_edit_get_link(FedoraDatastream $datastream) {
function islandora_datastream_edit_get_link(AbstractDatastream $datastream) {
$edit_registry = module_invoke_all('islandora_edit_datastream_registry', $datastream->parent, $datastream);
$can_edit = count($edit_registry) > 0 && user_access(FEDORA_METADATA_EDIT);
return $can_edit ? l(t('edit'), "islandora/object/{$datastream->parent->id}/datastream/{$datastream->id}/edit") : '';
@ -104,10 +104,10 @@ function islandora_datastream_edit_get_link(FedoraDatastream $datastream) {
/**
* Display the edit datastream page.
*
* @param FedoraDatastream $datastream
* @param AbstractDatastream $datastream
* The datastream to edit.
*/
function islandora_edit_datastream(FedoraDatastream $datastream) {
function islandora_edit_datastream(AbstractDatastream $datastream) {
$edit_registry = module_invoke_all('islandora_edit_datastream_registry', $datastream->parent, $datastream);
$edit_count = count($edit_registry);
switch ($edit_count) {

6
includes/delete_datastream.form.inc

@ -12,13 +12,13 @@
* The Drupal form.
* @param array $form_state
* The Drupal form state.
* @param FedoraDatastream $datastream
* @param AbstractDatastream $datastream
* The datastream to be deleted.
*
* @return array
* The drupal form definition.
*/
function islandora_delete_datastream_form(array $form, array &$form_state, FedoraDatastream $datastream) {
function islandora_delete_datastream_form(array $form, array &$form_state, AbstractDatastream $datastream) {
$form_state['datastream'] = $datastream;
return confirm_form($form,
t('Are you sure you want to delete the %dsid datastream?', array('%dsid' => $datastream->id)),
@ -32,7 +32,7 @@ function islandora_delete_datastream_form(array $form, array &$form_state, Fedor
/**
* Submit handler for the delete datastream form.
*
* Purges/Delete's the given FedoraDatastream if possible.
* Purges/Delete's the given AbstractDatastream if possible.
*
* The ISLANDORA_PRE_PURGE_DATASTREAM_HOOK will query other modules as to
* whether the given FedoraDatastream

4
includes/delete_object.form.inc

@ -12,13 +12,13 @@
* The Drupal form.
* @param array $form_state
* The Drupal form state.
* @param FedoraObject $object
* @param AbstractObject $object
* The object to be deleted.
*
* @return array
* The drupal form definition.
*/
function islandora_delete_object_form(array $form, array &$form_state, FedoraObject $object) {
function islandora_delete_object_form(array $form, array &$form_state, AbstractObject $object) {
$form_state['object'] = $object;
return confirm_form($form,
t('Are you sure you want to delete %title?', array('%title' => $object->label)),

143
includes/ingest.form.inc

@ -5,6 +5,25 @@
* Defines the multi-page ingest form and any relevant hooks and functions.
*/
/**
* Checks if the given configuration can be used to display the ingest form.
*
* @param array $configuration
* The list of key/value pairs of configuration.
*
* @return bool
* TRUE if the give configuration defines one or more form steps, FALSE
* otherwise.
*/
function islandora_ingest_can_display_ingest_form(array $configuration) {
$form_state = array();
islandora_ingest_form_init_form_state_storage($form_state, $configuration);
$form_steps = islandora_ingest_form_get_form_steps($form_state);
// Forget the stubbed steps for the remainder of this request.
drupal_static_reset('islandora_ingest_form_get_steps');
return count($form_steps) > 0;
}
/**
* Ingest form build function.
*
@ -44,26 +63,6 @@ function islandora_ingest_form(array $form, array &$form_state, array $configura
}
}
/**
* Validates the given ingest configuration.
*
* At the moment it only requires that models are present.
*
* @todo Add hook for manipulating/validating the configuration.
*
* @see islandora_ingest_form()
*
* @throws InvalidArgumentException
*
* @param array $configuration
* The key value pairs that are used to build the multi-paged ingest process.
*/
function islandora_ingest_form_validate_configuration(array $configuration) {
if (empty($configuration['models'])) {
throw new InvalidArgumentException('Ingest configuration not vaild, no models were given');
}
}
/**
* Initializes the form_state storage for use in the ingest multi-page forms.
*
@ -75,12 +74,23 @@ function islandora_ingest_form_validate_configuration(array $configuration) {
*/
function islandora_ingest_form_init_form_state_storage(array &$form_state, array $configuration) {
if (empty($form_state['islandora'])) {
// Validate the configuration before we use it.
islandora_ingest_form_validate_configuration($configuration);
$object = islandora_ingest_form_prepare_new_object($configuration);
$objects = isset($configuration['objects']) ? $configuration['objects'] : array();
if (empty($objects)) {
$objects[] = islandora_ingest_form_prepare_new_object($configuration);
}
$configuration['models'] = isset($configuration['models']) ? $configuration['models'] : array();
// Make sure the models actually exist.
foreach ($configuration['models'] as $key => $model) {
if (!islandora_object_load($model)) {
unset($configuration['models'][$key]);
}
}
// No need to persist the 'objects' within the configuration.
unset($configuration['objects']);
// Required for step hooks.
$form_state['islandora'] = array(
'step_id' => NULL,
'objects' => array($object),
'objects' => $objects,
'shared_storage' => $configuration,
'step_storage' => array(),
);
@ -132,6 +142,8 @@ function islandora_ingest_form_get_last_step_id(array &$form_state) {
function islandora_ingest_form_prepare_new_object(array $configuration) {
module_load_include('inc', 'islandora', 'includes/utilities');
if (empty($configuration['object'])) {
$message = islandora_deprecated('7.x-1.2', t('Please use "objects" as the default ingest form configuration property.'));
trigger_error(filter_xss($message), E_USER_DEPRECATED);
// ID is more specific than namespace so it will take precedence.
$id = isset($configuration['namespace']) ? $configuration['namespace'] : 'islandora';
$id = isset($configuration['id']) ? $configuration['id'] : $id;
@ -307,35 +319,6 @@ function islandora_ingest_form_decrement_step(array &$form_state) {
}
}
/**
* Build a list of steps given only configuration.
*
* XXX: This is used to give an indication of whether there are any steps for a
* given configuration.
*
* @param array $configuration
* The list of key/value pairs of configuration.
*/
function islandora_ingest_get_approximate_steps(array $configuration) {
try {
// @todo, we need to expand the configuration before we can validate it?
// I think this need some thinking.
islandora_ingest_form_validate_configuration($configuration);
}
catch (InvalidArgumentException $e) {
// Don't log or display exception.
return array();
}
$stubbed_form_state = array(
'islandora' => array(
'shared_storage' => $configuration,
),
);
$steps = islandora_ingest_form_get_steps($stubbed_form_state);
drupal_static_reset('islandora_ingest_form_get_steps');
return $steps;
}
/**
* Executes the current step.
*
@ -387,7 +370,15 @@ function islandora_ingest_form_execute_step(array $form, array &$form_state, $st
function islandora_ingest_form_execute_form_step(array $form, array &$form_state, array $step) {
$args = array($form, &$form_state);
$args = isset($step['args']) ? array_merge($args, $step['args']) : $args;
$shared_storage = islandora_ingest_form_get_shared_storage($form_state);
// Build the form step.
$form = call_user_func_array($step['form_id'], $args);
// Since the list of steps depends on the shared storage we will rebuild the
// list of steps if the shared storage has changed. This must be done before
// stepifying, so the prev/next buttons get updated.
if ($shared_storage != islandora_ingest_form_get_shared_storage($form_state)) {
drupal_static_reset('islandora_ingest_form_get_steps');
}
return islandora_ingest_form_stepify($form, $form_state, $step);
}
@ -473,6 +464,10 @@ function islandora_ingest_form_undo_callback_step(array $form, array &$form_stat
function islandora_ingest_form_stepify(array $form, array &$form_state, $step) {
$first_form_step = islandora_ingest_form_on_first_form_step($form_state);
$last_form_step = islandora_ingest_form_on_last_form_step($form_state);
$form['form_step_id'] = array(
'#type' => 'hidden',
'#value' => islandora_ingest_form_get_current_step_id($form_state),
);
$form['prev'] = $first_form_step ? NULL : islandora_ingest_form_previous_button($form_state);
$form['next'] = $last_form_step ? islandora_ingest_form_ingest_button($form_state) : islandora_ingest_form_next_button($form_state);
// Allow for a hook_form_FORM_ID_alter().
@ -557,7 +552,7 @@ function islandora_ingest_form_previous_button(array &$form_state) {
$prev_form_step = islandora_ingest_form_get_previous_form_step($form_state);
$form_id = $prev_form_step['form_id'];
$submit_callback = $form_id . '_undo_submit';
$submit = function_exists($submit_callback) ? array($submit_callback, 'islandora_ingest_form_previous_submit') : array('islandora_ingest_form_previous_submit');
$submit = function_exists($submit_callback) ? array('islandora_ingest_form_previous_submit', $submit_callback) : array('islandora_ingest_form_previous_submit');
return array(
'#type' => 'submit',
'#value' => t('Previous'),
@ -648,7 +643,7 @@ function islandora_ingest_form_next_submit(array $form, array &$form_state) {
*/
function islandora_ingest_form_stash_info(array &$form_state) {
$storage = &islandora_ingest_form_get_step_storage($form_state);
if ($storage) {
if ($storage && isset($form_state['values'])) {
$storage['values'] = $form_state['values'];
unset($form_state['values']);
}
@ -754,7 +749,7 @@ function &islandora_ingest_form_get_objects(array &$form_state) {
*/
function islandora_ingest_form_get_object(array &$form_state) {
$objects = &islandora_ingest_form_get_objects($form_state);
return current($objects);
return reset($objects);
}
/**
@ -854,3 +849,39 @@ function islandora_ingest_form_get_steps(array &$form_state) {
uasort($steps, 'drupal_sort_weight');
return $steps;
}
/**
* Filter the ingest steps to only steps of type 'form'.
*
* @param array $form_state
* The Drupal form state.
*
* @return array
* The list of sorted ingest form steps as defined by all implementers
* of ISLANDORA_INGEST_STEP_HOOK.
*/
function islandora_ingest_form_get_form_steps(array &$form_state) {
$steps = islandora_ingest_form_get_steps($form_state);
$form_step_filter = function($o) {
return $o['type'] == 'form';
};
return array_filter($steps, $form_step_filter);
}
/**
* Filter the ingest steps to only steps of type 'form'.
*
* @param array $form_state
* The Drupal form state.
*
* @return array
* The list of sorted ingest callback steps as defined by all implementers
* of ISLANDORA_INGEST_STEP_HOOK.
*/
function islandora_ingest_form_get_callback_steps(array &$form_state) {
$steps = islandora_ingest_form_get_steps($form_state);
$callback_step_filter = function($o) {
return $o['type'] == 'callback';
};
return array_filter($steps, $callback_step_filter);
}

18
includes/mime_detect.inc

@ -148,7 +148,7 @@ class MimeDetect {
"jp2" => "image/jp2",
"png" => "image/png",
"tiff" => "image/tiff",
"tif" => "image/tif",
"tif" => "image/tiff",
"djvu" => "image/vnd.djvu",
"djv" => "image/vnd.djvu",
"wbmp" => "image/vnd.wap.wbmp",
@ -194,6 +194,11 @@ class MimeDetect {
'bin' => 'application/octet-stream',
);
protected $protectedFileExtensions;
protected $extensionExceptions = array(
// XXX: Deprecated... Only here due to old 'tif' => 'image/tif' mapping...
// The correct MIMEtype is 'image/tiff'.
'image/tif' => 'tif',
);
protected $systemTypes;
protected $systemExts;
protected $etcMimeTypes = '/etc/mime.types';
@ -205,6 +210,7 @@ class MimeDetect {
// Populate the reverse shortlist:
$this->protectedFileExtensions = array_flip($this->protectedMimeTypes);
$this->protectedFileExtensions += $this->extensionExceptions;
// Pick up a local mime.types file if it is available.
if (is_readable('mime.types')) {
@ -366,4 +372,14 @@ class MimeDetect {
return $out;
}
/**
* Gets MIME type array.
*
* @return array
* Returns associative array with exts and mimetypes.
*/
public function getMimeTypes() {
return $this->protectedMimeTypes;
}
}

4
includes/object_properties.form.inc

@ -12,13 +12,13 @@
* The Drupal form.
* @param array $form_state
* The Drupal form state.
* @param FedoraObject $object
* @param AbstractObject $object
* The object whose properties this form will modify.
*
* @return array
* The drupal form definition.
*/
function islandora_object_properties_form(array $form, array &$form_state, FedoraObject $object) {
function islandora_object_properties_form(array $form, array &$form_state, AbstractObject $object) {
drupal_set_title($object->label);
$form_state['object'] = $object;
return array(

10
includes/solution_packs.inc

@ -180,12 +180,12 @@ function islandora_solution_pack_form_submit(array $form, array &$form_state) {
/**
* Batch operation to ingest/reingest required object(s).
*
* @param NewFedoraObject $object
* @param AbstractObject $object
* The object to ingest/reingest.
* @param array $context
* The context of this batch operation.
*/
function islandora_solution_pack_batch_operation_reingest_object(NewFedoraObject $object, array &$context) {
function islandora_solution_pack_batch_operation_reingest_object(AbstractObject $object, array &$context) {
$existing_object = islandora_object_load($object->id);
$deleted = FALSE;
if ($existing_object) {
@ -367,7 +367,7 @@ function islandora_uninstall_solution_pack($module) {
/**
* Function to check the status of an object against an object model array.
*
* @param NewFedoraObject $object_definition
* @param AbstractObject $object_definition
* A new fedora object that defines what the object should contain.
*
* @return string
@ -378,7 +378,7 @@ function islandora_uninstall_solution_pack($module) {
* @see islandora_solution_pack_form()
* @see islandora_install_solution_pack()
*/
function islandora_check_object_status(NewFedoraObject $object_definition) {
function islandora_check_object_status(AbstractObject $object_definition) {
$existing_object = islandora_object_load($object_definition->id);
if (!$existing_object) {
return array('status' => 'missing', 'status_friendly' => t('Missing'));
@ -627,7 +627,7 @@ function theme_islandora_viewers_table($variables) {
* Array or string with data the module needs in order to render a full viewer
* @param string $variable_id
* The id of the Drupal variable the viewer settings are saved in
* @param FedoraObject $fedora_object
* @param AbstractObject $fedora_object
* The tuque object representing the fedora object being displayed
*
* @return string

4
includes/tuque_wrapper.inc

@ -34,7 +34,7 @@ $islandora_module_path = drupal_get_path('module', 'islandora');
/**
* Allow modules to alter an object before a mutable event occurs.
*/
function islandora_alter_object(AbstractFedoraObject $object, array &$context) {
function islandora_alter_object(AbstractObject $object, array &$context) {
module_load_include('inc', 'islandora', 'includes/utilities');
drupal_alter(islandora_build_hook_list('islandora_object', $object->models), $object, $context);
}
@ -42,7 +42,7 @@ function islandora_alter_object(AbstractFedoraObject $object, array &$context) {
/**
* Allow modules to alter a datastream before a mutable event occurs.
*/
function islandora_alter_datastream(AbstractFedoraObject $object, AbstractDatastream $datastream, array &$context) {
function islandora_alter_datastream(AbstractObject $object, AbstractDatastream $datastream, array &$context) {
module_load_include('inc', 'islandora', 'includes/utilities');
$types = array();
foreach ($object->models as $model) {

64
includes/utilities.inc

@ -256,8 +256,8 @@ function islandora_get_namespace($id) {
*/
function islandora_namespace_accessible($id) {
if (variable_get('islandora_namespace_restriction_enforced', FALSE)) {
$namespace = islandora_get_namespace($id) . ':';
$allowed_namespaces = explode(" ", variable_get('islandora_pids_allowed', 'default: demo: changeme: islandora: ilives: islandora-book: books: newspapers: '));
$namespace = islandora_get_namespace($id);
$allowed_namespaces = islandora_get_allowed_namespaces();
return in_array($namespace, $allowed_namespaces);
}
return TRUE;
@ -271,14 +271,14 @@ function islandora_namespace_accessible($id) {
* This function gets its info from the RELS-EXT directly rather than through an
* risearch.
*
* @param FedoraObject $object
* @param AbstractObject $object
* The object whose parents will be returned.
*
* @return array
* An array of FedoraObject's that the given object has a
* (isMemberOf, isMemberOfCollection) relationship with.
*/
function islandora_get_parents_from_rels_ext(FedoraObject $object) {
function islandora_get_parents_from_rels_ext(AbstractObject $object) {
try {
$collections = array_merge(
$object->relationships->get(FEDORA_RELS_EXT_URI, 'isMemberOfCollection'),
@ -298,7 +298,7 @@ function islandora_get_parents_from_rels_ext(FedoraObject $object) {
/**
* Gets the datastreams requirments that are missing.
*
* @param FedoraObject $object
* @param AbstractObject $object
* The object which models will be used to determine what datastreams it
* should have.
*
@ -306,7 +306,7 @@ function islandora_get_parents_from_rels_ext(FedoraObject $object) {
* The DS-COMPOSITE-MODEL defined datastreams that are required for the given
* object, but not already present.
*/
function islandora_get_missing_datastreams_requirements(FedoraObject $object) {
function islandora_get_missing_datastreams_requirements(AbstractObject $object) {
module_load_include('inc', 'islandora', 'includes/utilities');
$datastreams = islandora_get_datastreams_requirements($object);
foreach ($datastreams as $dsid => $requirements) {
@ -331,7 +331,7 @@ function islandora_get_missing_datastreams_requirements(FedoraObject $object) {
*
* @see islandora_get_required_datastreams_from_content_model()
*
* @param FedoraObject $object
* @param AbstractObject $object
* The object which models will be used to determine what datastreams it
* should have.
*
@ -339,7 +339,7 @@ function islandora_get_missing_datastreams_requirements(FedoraObject $object) {
* The DS-COMPOSITE-MODEL defined datastreams that are required for the given
* object.
*/
function islandora_get_datastreams_requirements(FedoraObject $object) {
function islandora_get_datastreams_requirements(AbstractObject $object) {
return islandora_get_datastreams_requirements_from_models($object->models);
}
@ -375,7 +375,7 @@ function islandora_get_datastreams_requirements_from_models(array $models) {
*
* @todo Add support for fetching the schema information.
*
* @param FedoraObject $object
* @param AbstractObject $object
* The content model whose DS-COMPOSITE-MODEL datastream will be used to
* determine what datastreams are required.
*
@ -388,7 +388,7 @@ function islandora_get_datastreams_requirements_from_models(array $models) {
* - "mime": A array containing MIME-types the stream may have.
* - "optional": A boolean indicating if the given stream is optional.
*/
function islandora_get_datastreams_requirements_from_content_model(FedoraObject $object) {
function islandora_get_datastreams_requirements_from_content_model(AbstractObject $object) {
if (empty($object[DS_COMP_STREAM])) {
return array();
}
@ -636,6 +636,9 @@ function islandora_system_settings_form_default_value($name, $default_value, arr
* is optional.
*/
function islandora_get_comp_ds_mappings($pid) {
$message = islandora_deprecated('7.x-1.2', t('Refactor to use the more flexible islandora_get_datastreams_requirements_from_content_model().'));
trigger_error(filter_xss($message), E_USER_DEPRECATED);
$cm_object = islandora_object_load($pid);
if (!isset($cm_object) || !isset($cm_object['DS-COMPOSITE-MODEL'])) {
return FALSE;
@ -709,7 +712,13 @@ function islandora_get_allowed_namespaces() {
$matches = array();
$allowed_namespaces = variable_get('islandora_pids_allowed', 'default: demo: changeme: islandora:');
preg_match_all('/([A-Za-z0-9-\.]+):/', $allowed_namespaces, $matches);
return $matches[1];
$accessible_namespaces = $matches[1];
// Ensure that the "islandora" namespace is explicitly allowed
// no matter what happens.
if (!in_array('islandora', $accessible_namespaces)) {
$accessible_namespaces[] = 'islandora';
}
return $accessible_namespaces;
}
/**
@ -817,3 +826,36 @@ function islandora_content_model_select_table_form_element($drupal_variable, $de
return $element;
}
/**
* Convience function for generating a E_USER_DEPRECATED message.
*
* To utilitize this function pass the results to trigger_error() like so:
*
* @code
* $message = islandora_deprecated('7.x-1.1', t('Use more cowbell.'))
* trigger_error(filter_xss($message), E_USER_DEPRECATED)
* @endcode
*
* @param string $release
* The release the calling function was depreciated in.
* @param string $solution
* A message describing an alternative solution to the deprecated function.
* It's assumed to be already passed though the t() function.
*
* @return string
* The deprecated message.
*/
function islandora_deprecated($release, $solution = NULL) {
$bt = debug_backtrace();
assert($bt[0]['function'] == __FUNCTION__);
$function = $bt[1]['function'];
$message = t('@function() has been deprecated. As of @release, please update your code before the next release.', array(
'@function' => $function,
'@release' => $release,
));
if (isset($solution)) {
$message .= "<br/>\n" . $solution;
}
return $message;
}

70
islandora.api.php

@ -8,7 +8,7 @@
/**
* Generate a repository objects view.
*
* @param FedoraObject $object
* @param AbstractObject $object
* The object to display
* @param object $user
* The user accessing the object.
@ -29,7 +29,7 @@ function hook_islandora_view_object($object, $user, $page_number, $page_size) {
* Content models PIDs have colons and hyphens changed to underscores, to
* create the hook name.
*
* @param FedoraObject $object
* @param AbstractObject $object
* A Tuque FedoraObject
*
* @return array
@ -42,8 +42,8 @@ function hook_CMODEL_PID_islandora_view_object($object) {
/**
* Alter display output after it has been generated.
*
* @param FedoraObject $object
* A Tuque FedoraObject being operated on.
* @param AbstractObject $object
* A Tuque AbstractObject being operated on.
* @param array $rendered
* The array of rendered views.
*/
@ -55,8 +55,8 @@ function hook_islandora_view_object_alter(&$object, &$rendered) {
*
* @see hook_islandora_view_object_alter()
*
* @param FedoraObject $object
* A Tuque FedoraObject being operated on.
* @param AbstractObject $object
* A Tuque AbstractObject being operated on.
* @param array $rendered
* The array of rendered views.
*/
@ -66,7 +66,7 @@ function hook_CMODEL_PID_islandora_view_object_alter(&$object, &$rendered) {
/**
* Generate an object's management display.
*
* @param FedoraObject $object
* @param AbstractObject $object
* A Tuque FedoraObject
*
* @return array
@ -81,7 +81,7 @@ function hook_islandora_edit_object($object) {
* Content models PIDs have colons and hyphens changed to underscores, to
* create the hook name.
*
* @param FedoraObject $object
* @param AbstractObject $object
* A Tuque FedoraObject
*
* @return array
@ -93,7 +93,7 @@ function hook_CMODEL_PID_islandora_edit_object($object) {
/**
* Allow management display output to be altered.
*
* @param FedoraObject $object
* @param AbstractObject $object
* A Tuque FedoraObject
* @param array $rendered
* an arr of rendered views
@ -110,7 +110,7 @@ function hook_islandora_edit_object_alter(&$object, &$rendered) {
* Changing object properties such as "label", or "state", are considered
* modifications, where as manipulating an object's datstreams are not.
*
* @param AbstractFedoraObject $object
* @param AbstractObject $object
* The object to alter.
* @param array $context
* An associative array containing:
@ -130,7 +130,7 @@ function hook_islandora_edit_object_alter(&$object, &$rendered) {
*
* @see FedoraApiM::modifyObject()
*/
function hook_islandora_object_alter(AbstractFedoraObject $object, array &$context) {
function hook_islandora_object_alter(AbstractObject $object, array &$context) {
}
/**
@ -138,7 +138,7 @@ function hook_islandora_object_alter(AbstractFedoraObject $object, array &$conte
*
* @see hook_islandora_object_alter()
*/
function hook_CMODEL_PID_islandora_object_alter(AbstractFedoraObject $object, array &$context) {
function hook_CMODEL_PID_islandora_object_alter(AbstractObject $object, array &$context) {
}
/**
@ -151,15 +151,15 @@ function hook_CMODEL_PID_islandora_object_alter(AbstractFedoraObject $object, ar
* immediately, instead it will be triggered for all datastreams at the time
* of the NewFedoraObject's ingest.
*
* Purging datastreams from a NewFedoraObject will not trigger this alter hook
* Purging datastreams from a AbstractObject will not trigger this alter hook
* at all.
*
* Changing datastream's properties such as "label", or "state", are considered
* modifications, as well as changing the datastreams content.
*
* @param AbstractFedoraObject $object
* @param AbstractObject $object
* The object to the datastream belong to.
* @param AbstractFedoraDatastream $datastream
* @param AbstractDatastream $datastream
* The datastream to alter.
* @param array $context
* An associative array containing:
@ -179,7 +179,7 @@ function hook_CMODEL_PID_islandora_object_alter(AbstractFedoraObject $object, ar
*
* @see FedoraApiM::modifyDatastream()
*/
function hook_islandora_datastream_alter(AbstractFedoraObject $object, AbstractFedoraDatastream $datastream, array &$context) {
function hook_islandora_datastream_alter(AbstractObject $object, AbstractDatastream $datastream, array &$context) {
}
/**
@ -187,7 +187,7 @@ function hook_islandora_datastream_alter(AbstractFedoraObject $object, AbstractF
*
* @see hook_islandora_datastream_alter()
*/
function hook_CMODEL_PID_DSID_islandora_datastream_alter(AbstractFedoraObject $object, AbstractFedoraDatastream $datastream, array &$context) {
function hook_CMODEL_PID_DSID_islandora_datastream_alter(AbstractObject $object, AbstractDatastream $datastream, array &$context) {
}
/**
@ -200,10 +200,10 @@ function hook_CMODEL_PID_DSID_islandora_datastream_alter(AbstractFedoraObject $o
* If ingested directly via the FedoraApiM object this will not be called as we
* don't have access to the ingested object at that time.
*
* @param FedoraObject $object
* @param AbstractObject $object
* The object that was ingested.
*/
function hook_islandora_object_ingested(FedoraObject $object) {
function hook_islandora_object_ingested(AbstractObject $object) {
}
/**
@ -211,7 +211,7 @@ function hook_islandora_object_ingested(FedoraObject $object) {
*
* @see hook_islandora_object_ingested()
*/
function hook_CMODEL_PID_islandora_object_ingested(FedoraObject $object) {
function hook_CMODEL_PID_islandora_object_ingested(AbstractObject $object) {
}
/**
@ -222,13 +222,13 @@ function hook_CMODEL_PID_islandora_object_ingested(FedoraObject $object) {
* Changing object properties such as "label", or "state", are considered
* modifications, where as manipulating an object's datstreams are not.
*
* @param FedoraObject $object
* @param AbstractObject $object
* The object that was ingested.
*
* @todo We should also include what changes were made in a additional
* parameter.
*/
function hook_islandora_object_modified(FedoraObject $object) {
function hook_islandora_object_modified(AbstractObject $object) {
}
/**
@ -236,7 +236,7 @@ function hook_islandora_object_modified(FedoraObject $object) {
*
* @see hook_islandora_object_modified()
*/
function hook_CMODEL_PID_islandora_object_modified(FedoraObject $object) {
function hook_CMODEL_PID_islandora_object_modified(AbstractObject $object) {
}
/**
@ -268,12 +268,12 @@ function hook_CMODEL_PID_islandora_object_purged($pid) {
* If ingested directly via the FedoraApiM object this will not be called as we
* don't have access to the ingested datastream at that time.
*
* @param FedoraObject $object
* @param AbstractObject $object
* The object the datastream belongs to.
* @param FedoraDatastream $datastream
* @param AbstractDatastream $datastream
* The ingested datastream.
*/
function hook_islandora_datastream_ingested(FedoraObject $object, FedoraDatastream $datastream) {
function hook_islandora_datastream_ingested(AbstractObject $object, AbstractDatastream $datastream) {
}
/**
@ -281,7 +281,7 @@ function hook_islandora_datastream_ingested(FedoraObject $object, FedoraDatastre
*
* @see hook_islandora_object_ingested()
*/
function hook_CMODEL_PID_DSID_islandora_datastream_ingested(FedoraObject $object, FedoraDatastream $datastream) {
function hook_CMODEL_PID_DSID_islandora_datastream_ingested(AbstractObject $object, AbstractDatastream $datastream) {
}
/**
@ -292,15 +292,15 @@ function hook_CMODEL_PID_DSID_islandora_datastream_ingested(FedoraObject $object
* Changing datastream properties such as "label", or "state", are considered
* modifications, as well as the datastreams content.
*
* @param FedoraObject $object
* @param AbstractObject $object
* The object the datastream belongs to.
* @param FedoraDatastream $datastream
* @param AbstractDatastream $datastream
* The datastream that was ingested.
*
* @todo We should also include what changes were made in a additional
* parameter.
*/
function hook_islandora_datastream_modified(FedoraObject $object, FedoraDatastream $datastream) {
function hook_islandora_datastream_modified(AbstractObject $object, AbstractDatastream $datastream) {
}
/**
@ -308,7 +308,7 @@ function hook_islandora_datastream_modified(FedoraObject $object, FedoraDatastre
*
* @see hook_islandora_datastream_modified()
*/
function hook_CMODEL_PID_islandora_datastream_modified(FedoraObject $object, FedoraDatastream $datastream) {
function hook_CMODEL_PID_islandora_datastream_modified(AbstractObject $object, AbstractDatastream $datastream) {
}
/**
@ -317,12 +317,12 @@ function hook_CMODEL_PID_islandora_datastream_modified(FedoraObject $object, Fed
* This hook is called after an datastream has been successfully purged, or
* when its state has been changed to "Deleted".
*
* @param FedoraObject $object
* @param AbstractObject $object
* The object the datastream belonged to.
* @param string $dsid
* The ID of the datastream that was purged/deleted.
*/
function hook_islandora_datastream_purged(FedoraObject $object, $dsid) {
function hook_islandora_datastream_purged(AbstractObject $object, $dsid) {
}
/**
@ -330,13 +330,13 @@ function hook_islandora_datastream_purged(FedoraObject $object, $dsid) {
*
* @see hook_islandora_datastream_purged()
*/
function hook_CMODEL_PID_islandora_datastream_purged(FedoraObject $object, $dsid) {
function hook_CMODEL_PID_islandora_datastream_purged(AbstractObject $object, $dsid) {
}
/**
* Register a datastream edit route/form.
*
* @param FedoraObject $object
* @param AbstractObject $object
* The object to check.
* @param string $dsid
* todo

3
islandora.info

@ -11,8 +11,9 @@ files[] = includes/dublin_core.inc
files[] = includes/tuque.inc
files[] = includes/tuque_wrapper.inc
files[] = includes/object.entity_controller.inc
files[] = tests/web_test_case.inc
files[] = tests/islandora_web_test_case.inc
files[] = tests/authtokens.test
files[] = tests/hooks.test
files[] = tests/ingest.test
files[] = tests/islandora_manage_permissions.test
php = 5.3

123
islandora.module

@ -52,6 +52,9 @@ define('ISLANDORA_DATASTREAM_MODIFIED_HOOK', 'islandora_datastream_modified');
define('ISLANDORA_DATASTREAM_PURGED_HOOK', 'islandora_datastream_purged');
define('ISLANDORA_INGEST_STEP_HOOK', 'islandora_ingest_steps');
// Autocomplete paths.
define('ISLANDORA_CONTENT_MODELS_AUTOCOMPLETE', 'islandora/autocomplete/content-models');
/**
* Implements hook_menu().
*
@ -246,6 +249,15 @@ function islandora_menu() {
'access arguments' => array(FEDORA_VIEW_OBJECTS, 2),
'load arguments' => array(2),
);
$items[ISLANDORA_CONTENT_MODELS_AUTOCOMPLETE] = array(
'title' => 'Autocomplete callback',
'description' => 'Autocomplete a Fedora content model PID.',
'file' => 'includes/content_model.autocomplete.inc',
'page callback' => 'islandora_content_model_autocomplete',
'page arguments' => array(3),
'access arguments' => array('administer site configuration'),
'type' => MENU_CALLBACK,
);
return $items;
}
@ -370,7 +382,7 @@ function islandora_forms($form_id) {
* @global $user
*
* @param mixed $object
* The FedoraObject or FedoraDatastream to test for accessibility, if NULL
* The AbstractObject or AbstractDatastream to test for accessibility, if NULL
* is given the object is assumed to not exist or be inaccessible.
* @param array $permissions
* The required user permissions.
@ -448,7 +460,7 @@ function islandora_user_access($object, array $permissions, $content_models = ar
*
* @param string $perm
* User permission to test for.
* @param FedoraObject $object
* @param AbstractObject $object
* The object to test, if NULL given the object doesn't exist or is
* inaccessible.
*
@ -474,10 +486,10 @@ function islandora_object_access_callback($perm, $object = NULL) {
*
* @param string $perm
* The user permission to test for.
* @param FedoraObject $object
* @param AbstractObject $object
* The object to test, if NULL given the object doesn't exist or is
* inaccessible.
* @param FedoraDatastream $datastream
* @param AbstractDatastream $datastream
* The datastream to test, if NULL given the datastream doesn't exist
* or is inaccessible.
* @param StdObject $account
@ -525,7 +537,7 @@ function islandora_object_datastream_tokened_access_callback($perm, $object = NU
*
* @param array $perms
* Array of user permission to test for.
* @param FedoraObject $object
* @param AbstractObject $object
* The object to test, if NULL given the object doesn't exist or is
* inaccessible.
*
@ -551,13 +563,13 @@ function islandora_object_manage_access_callback($perms, $object = NULL) {
/**
* Renders the given objects manage overview page.
*
* @param FedoraObject $object
* @param AbstractObject $object
* The object to manage.
*
* @return string
* The HTML repersentation of the manage object page.
*/
function islandora_manage_overview_object(FedoraObject $object) {
function islandora_manage_overview_object(AbstractObject $object) {
module_load_include('inc', 'islandora', 'includes/utilities');
$output = array();
foreach (islandora_build_hook_list(ISLANDORA_OVERVIEW_HOOK, $object->models) as $hook) {
@ -578,14 +590,14 @@ function islandora_manage_overview_object(FedoraObject $object) {
/**
* Renders the default manage object page for the given object.
*
* @param FedoraObject $object
* @param AbstractObject $object
* The object used to render the manage object page.
*
* @return array
* The default rendering of the object manage page, indexed at
* 'Default Edit output'.
*/
function islandora_default_islandora_manage_overview_object(FedoraObject $object) {
function islandora_default_islandora_manage_overview_object(AbstractObject $object) {
$output = theme('islandora_default_overview', array('islandora_object' => $object));
return array('Default overview output' => $output);
}
@ -599,13 +611,13 @@ function islandora_default_islandora_manage_overview_object(FedoraObject $object
* If no modules implement 'ISLANDORA_EDIT_HOOK' then this function returns the
* default manage view.
*
* @param FedoraObject $object
* @param AbstractObject $object
* The object to manage.
*
* @return string
* The HTML repersentation of the manage object page.
*/
function islandora_edit_object(FedoraObject $object) {
function islandora_edit_object(AbstractObject $object) {
module_load_include('inc', 'islandora', 'includes/breadcrumb');
module_load_include('inc', 'islandora', 'includes/utilities');
drupal_set_title($object->label);
@ -629,14 +641,14 @@ function islandora_edit_object(FedoraObject $object) {
/**
* Renders the default manage object page for the given object.
*
* @param FedoraObject $object
* @param AbstractObject $object
* The object used to render the manage object page.
*
* @return array
* The default rendering of the object manage page, indexed at
* 'Default Edit output'.
*/
function islandora_default_islandora_edit_object(FedoraObject $object) {
function islandora_default_islandora_edit_object(AbstractObject $object) {
$output = theme('islandora_default_edit', array('islandora_object' => $object));
return array('Default Edit output' => $output);
}
@ -661,13 +673,13 @@ function islandora_view_default_object() {
* If no modules implement the hook then the default view object page
* will be rendered.
*
* @param FedoraObject $object
* @param AbstractObject $object
* The object to view.
*
* @return string
* The html repersentation of this object.
*/
function islandora_view_object(FedoraObject $object) {
function islandora_view_object(AbstractObject $object) {
module_load_include('inc', 'islandora', 'includes/breadcrumb');
module_load_include('inc', 'islandora', 'includes/utilities');
drupal_set_title($object->label);
@ -697,7 +709,7 @@ function islandora_view_object(FedoraObject $object) {
/**
* Renders the default view object page for the given object.
*
* @param FedoraObject $object
* @param AbstractObject $object
* The object used to render the view object page.
*
* @return array
@ -849,7 +861,7 @@ function islandora_tokened_datastream_load($datastream_id, $map) {
*
* @param mixed $object_id
* The object to load the datastream from. This can be a Fedora PID or
* an instantiated IslandoraFedoraObject as it implements __toString()
* an instantiated IslandoraAbstractObject as it implements __toString()
* returning the PID.
*
* @return FedoraDatastream
@ -872,7 +884,7 @@ function islandora_datastream_load($datastream_id, $object_id) {
* attribute, as in:
* <content_model name="Collection" version="2" ...
*
* @param FedoraObject $object
* @param AbstractObject $object
* The Object the datastream belongs to.
* @param string $dsid
* The ID of the datastream.
@ -941,26 +953,70 @@ function islandora_islandora_undeletable_datastreams(array $models) {
/**
* Ingest the given object.
*
* @param NewFedoraObject $object
* @param AbstractObject $object
* An ingestable FedoraObject.
*
* @return FedoraObject
* The ingested FedoraObject.
*/
function islandora_add_object(NewFedoraObject &$object) {
function islandora_add_object(AbstractObject &$object) {
return $object->repository->ingestObject($object);
}
/**
* Creates a new object with the same properties as the old.
*
* @todo Make Tuque objects support cloneing.
*
* @param AbstractObject $object
* An existing or new Fedora Object.
*
* @return AbstractObject
* The new Fedora Object with properties identical to the object given. This
* returned object is not automatically ingested.
*/
function islandora_copy_object(AbstractObject $object) {
$clone = $object->repository->constructObject($object->id);
$object_properties = array(
'state',
'createdDate',
'lastModifiedDate',
'label',
'owner',
'logMessage',
);
// Copy Properties.
foreach ($object_properties as $property) {
if (isset($object->$property)) {
$clone->$property = $object->$property;
}
}
// Copy Datastreams.
foreach ($object as $dsid => $datastream) {
if (empty($clone[$dsid])) {
$clone->ingestDatastream($datastream);
}
else {
// Get the content into a file, and add the file.
$temp_file = drupal_tempnam('temporary://', 'datastream');
$datastream->getContent($temp_file);
$clone[$dsid]->setContentFromFile($temp_file);
drupal_unlink($temp_file);
}
}
return $clone;
}
/**
* Delete's or purges the given object.
*
* @param FedoraObject $object
* @param AbstractObject $object
* An object to delete.
*
* @return bool
* TRUE if successful, FALSE otherwise.
*/
function islandora_delete_object(FedoraObject &$object) {
function islandora_delete_object(AbstractObject &$object) {
try {
$object->repository->purgeObject($object->id);
$object = NULL;
@ -979,13 +1035,13 @@ function islandora_delete_object(FedoraObject &$object) {
* Which types are undefined, but more than likely because of the hooks
* there will be several kinds.
*
* @param FedoraDatastream $datastream
* @param AbstractDatastream $datastream
* The datastream to delete.
*
* @return bool
* TRUE if successful, FALSE otherwise.
*/
function islandora_delete_datastream(FedoraDatastream &$datastream) {
function islandora_delete_datastream(AbstractDatastream &$datastream) {
$object = $datastream->parent;
return $object->purgeDatastream($datastream->id);
}
@ -1065,7 +1121,7 @@ function islandora_entity_property_info() {
* Modules can either implement preprocess functions to append content onto the
* 'content' variable, or override the display by providing a theme suggestion.
*
* @param FedoraObject $object
* @param AbstractObject $object
* The object.
*
* @return array
@ -1097,3 +1153,20 @@ function islandora_download_clip(AbstractObject $object) {
}
exit();
}
/**
* Implements hook_file_mimetype_mapping_alter().
*
* Grab custom islandora mime type list
* and add any missing ext/mimes to the drupal mapping
*/
function islandora_file_mimetype_mapping_alter(&$mapping) {
$mime_detect = new MimeDetect();
$types = $mime_detect->getMimeTypes();
$diff = array_diff_key($types, $mapping['extensions']);
foreach ($diff as $ext => $mime) {
$mapping['mimetypes'][] = $mime;
end($mapping['mimetypes']);
$mapping['extensions'][$ext] = key($mapping['mimetypes']);
}
}

6
islandora.rules.inc

@ -80,7 +80,7 @@ function islandora_rules_action_info() {
/**
* Checks that there is a relationship match on the given object.
*
* Takes a subject (either a FedoraObject or a FedoraDatastream), as well as
* Takes a subject (either a AbstractObject or a FedoraDatastream), as well as
* the parameters for FedoraRelsExt::get() or FedoraRelsInt::get(), to try to
* find a match.
*
@ -94,7 +94,7 @@ function islandora_object_has_relationship($sub, $pred_uri, $pred, $object, $typ
/**
* Remove a relationship from the given object.
*
* Takes a subject (either a FedoraObject or a FedoraDatastream), as well as
* Takes a subject (either a AbstractObject or a FedoraDatastream), as well as
* the parameters for FedoraRelsExt::remove() or FedoraRelsInt::remove(), to
* try to find a match.
*
@ -107,7 +107,7 @@ function islandora_object_remove_relationship($sub, $pred_uri, $pred, $object, $
/**
* Add a relationship to the given object.
*
* Takes a subject (either a FedoraObject or a FedoraDatastream), as well as
* Takes a subject (either a AbstractObject or a FedoraDatastream), as well as
* the parameters for FedoraRelsExt::add() or FedoraRelsInt::add(), and adds
* the represented relationship.
*

4
tests/README.txt → tests/README.md

@ -1,4 +1,4 @@
You can define your own configurations specific to your enviroment by copying
default.test_config.ini to test_config.ini, making your changes in the copied
file. These test need write access to the system's $FEDORA_HOME/server/config
directory as well as the filter-drupal.xml file.
file. These test need write access to the system's $FEDORA_HOME/server/config
directory as well as the filter-drupal.xml file.

118
tests/ingest.test

@ -0,0 +1,118 @@
<?php
/**
* @file
* Tests to see if the hooks get called when appropriate.
*
* In the test module 'islandora_hooks_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_hooks_test.module.
*/
class IslandoraIngestsTestCase extends IslandoraWebTestCase {
/**
* Gets info to display to describe this test.
*
* @see IslandoraWebTestCase::getInfo()
*/
public static function getInfo() {
return array(
'name' => 'Islandora Ingestion',
'description' => 'Ensure that the ingest forms function correctly.',
'group' => 'Islandora',
);
}
/**
* Creates an admin user and a connection to a fedora repository.
*
* @see IslandoraWebTestCase::setUp()
*/
public function setUp() {
parent::setUp('islandora_ingest_test');
$this->repository = $this->admin->repository;
$this->purgeTestObjects();
}
/**
* Free any objects/resources created for this test.
*
* @see IslandoraWebTestCase::tearDown()
*/
public function tearDown() {
$this->purgeTestObjects();
unset($this->repository);
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.
}
}
}
/**
* Test Ingest Steps.
*/
public function testIngest() {
// Login the Admin user.
$this->drupalLogin($this->admin);
// First step in form.
$this->drupalGet('test/ingest');
// Default model selected, has no additional steps.
$this->assertFieldByName('ingest', 'Ingest');
// Select a model with additional steps.
$edit = array(
'model' => 'test:testcmodel',
);
$this->drupalPostAJAX(NULL, $edit, 'model');
// Form now reflexts multiple steps.
$this->assertFieldByName('label', '');
$this->assertFieldByName('next', 'Next');
// Move to next step.
$edit = array(
'label' => 'foobar',
'model' => 'test:testcmodel',
);
$this->drupalPost(NULL, $edit, t('Next'));
$this->assertFieldByName('form_step_id', 'islandora_ingest_test_testcmodel');
$this->assertFieldByName('ingest', 'Ingest');
// Move back to first step.
$this->drupalPost(NULL, array(), t('Previous'));
// Try a different model that has an additional step.
$edit = array(
'model' => 'test:testcmodel2',
);
$this->drupalPostAJAX(NULL, $edit, 'model');
$edit = array(
'label' => 'foobar',
'model' => 'test:testcmodel2',
);
$this->drupalPost(NULL, $edit, t('Next'));
$this->assertFieldByName('form_step_id', 'islandora_ingest_test_testcmodel2');
$this->assertFieldByName('ingest', 'Ingest');
// Ingest the thing.
$this->drupalPost(NULL, array(), t('Ingest'));
// Test that the thing got made.
$object = islandora_object_load('test:test');
$this->assertEqual($object->label, 'foobar', 'Ingest Object matches submitted form values.');
$this->assertEqual($object->models, array('test:testcmodel2', 'fedora-system:FedoraObject-3.0'), 'Ingest Object matches submitted form values.');
}
}

14
tests/islandora_hooks_test.module

@ -8,7 +8,7 @@
/**
* Implements hook_islandora_object_alter().
*/
function islandora_hooks_test_islandora_object_alter(AbstractFedoraObject $object, array &$context) {
function islandora_hooks_test_islandora_object_alter(AbstractObject $object, array &$context) {
switch ($context['action']) {
case 'ingest':
if ($object->id == 'test:testIngestedObjectHook') {
@ -54,7 +54,7 @@ function islandora_hooks_test_islandora_object_alter(AbstractFedoraObject $objec
/**
* Implements hook_islandora_object_alter().
*/
function islandora_hooks_test_islandora_datastream_alter(AbstractFedoraObject $object, AbstractFedoraDatastream $datastream, array &$context) {
function islandora_hooks_test_islandora_datastream_alter(AbstractObject $object, AbstractDatastream $datastream, array &$context) {
switch ($context['action']) {
case 'ingest':
if ($object->id == 'test:testIngestedDatastreamHook') {
@ -100,7 +100,7 @@ function islandora_hooks_test_islandora_datastream_alter(AbstractFedoraObject $o
/**
* Implements hook_islandora_object_ingested().
*/
function islandora_hooks_test_islandora_object_ingested(FedoraObject $object) {
function islandora_hooks_test_islandora_object_ingested(AbstractObject $object) {
if ($object->id == 'test:testIngestedObjectHook') {
$_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_INGESTED_HOOK] = TRUE;
}
@ -109,7 +109,7 @@ function islandora_hooks_test_islandora_object_ingested(FedoraObject $object) {
/**
* Implements hook_islandora_object_modified().
*/
function islandora_hooks_test_islandora_object_modified(FedoraObject $object) {
function islandora_hooks_test_islandora_object_modified(AbstractObject $object) {
if ($object->id == 'test:testModifiedObjectHook') {
$_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_MODIFIED_HOOK] = TRUE;
}
@ -127,7 +127,7 @@ function islandora_hooks_test_islandora_object_purged($pid) {
/**
* Implements hook_islandora_datastream_ingested().
*/
function islandora_hooks_test_islandora_datastream_ingested(FedoraObject $object, FedoraDatastream $datastream) {
function islandora_hooks_test_islandora_datastream_ingested(AbstractObject $object, AbstractDatastream $datastream) {
if ($object->id == 'test:testIngestedDatastreamHook' && $datastream->id == "TEST") {
$_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_INGESTED_HOOK] = TRUE;
}
@ -136,7 +136,7 @@ function islandora_hooks_test_islandora_datastream_ingested(FedoraObject $object
/**
* Implements hook_islandora_datastream_modified().
*/
function islandora_hooks_test_islandora_datastream_modified(FedoraObject $object, FedoraDatastream $datastream) {
function islandora_hooks_test_islandora_datastream_modified(AbstractObject $object, AbstractDatastream $datastream) {
if ($object->id == 'test:testModifiedDatastreamHook' && $datastream->id == "TEST") {
$_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_MODIFIED_HOOK] = TRUE;
}
@ -145,7 +145,7 @@ function islandora_hooks_test_islandora_datastream_modified(FedoraObject $object
/**
* Implements hook_islandora_datastream_purged().
*/
function islandora_hooks_test_islandora_datastream_purged(FedoraObject $object, $dsid) {
function islandora_hooks_test_islandora_datastream_purged(AbstractObject $object, $dsid) {
if ($object->id == 'test:testPurgedDatastreamHook' && $dsid == "TEST") {
$_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_PURGED_HOOK] = TRUE;
}

7
tests/islandora_ingest_test.info

@ -0,0 +1,7 @@
name = Islandora Testing
description = Required for testing islandora web-test case.
core = 7.x
package = Testing
hidden = TRUE
dependencies[] = islandora
files[] = islandora_test.module

166
tests/islandora_ingest_test.module

@ -0,0 +1,166 @@
<?php
/**
* @file
* Implements hooks that get tested by islandora_hooks.test
*/
/**
* Implements hook menu.
*/
function islandora_ingest_test_menu() {
return array(
'test/ingest' => array(
'title' => 'Ingest Form',
'page callback' => 'islandora_ingest_test_ingest',
'type' => MENU_LOCAL_ACTION,
'access callback' => TRUE,
),
);
}
/**
* Render the ingest form.
*/
function islandora_ingest_test_ingest() {
$connection = islandora_get_tuque_connection();
$object = $connection->repository->constructObject('test:test');
$object->label = 'New Object';
$configuration = array(
'objects' => array($object),
);
module_load_include('inc', 'islandora', 'includes/ingest.form');
return drupal_get_form('islandora_ingest_form', $configuration);
}
/**
* Implements hook_islandora_ingest_steps().
*/
function islandora_ingest_test_islandora_ingest_steps(array &$form_state) {
return array(
'islandora_ingest_test' => array(
'type' => 'form',
'form_id' => 'islandora_ingest_test_set_label_form',
'weight' => -50,
'module' => 'islandora_ingest_test',
),
);
}
/**
* Implements hook_MODEL_PID_islandora_ingest_steps().
*/
function islandora_ingest_test_test_testcmodel_islandora_ingest_steps(array &$form_state) {
return array(
'islandora_ingest_test_testcmodel' => array(
'type' => 'form',
'form_id' => 'islandora_ingest_test_testcmodel_form',
'weight' => -30,
'module' => 'islandora_ingest_test',
),
);
}
/**
* Implements hook_MODEL_PID_islandora_ingest_steps().
*/
function islandora_ingest_test_test_testcmodel2_islandora_ingest_steps(array &$form_state) {
return array(
'islandora_ingest_test_testcmodel2' => array(
'type' => 'form',
'form_id' => 'islandora_ingest_test_testcmodel2_form',
'weight' => -40,
'module' => 'islandora_ingest_test',
),
);
}
/**
* Sets the label of the ingestable object.
*
* @param array $form
* The Drupal form.
* @param array $form_state
* The Drupal form state.
*
* @return array
* The Drupal form definition.
*/
function islandora_ingest_test_set_label_form(array $form, array &$form_state) {
$models = array('test:nomorestepscmodel', 'test:testcmodel', 'test:testcmodel2');
$model = isset($form_state['values']['model']) ? $form_state['values']['model'] : reset($models);
$shared_storage = &islandora_ingest_form_get_shared_storage($form_state);
$shared_storage['models'] = array($model);
return array(
'#prefix' => '<div id="islandora-select-content-model-wrapper">',
'#suffix' => '</div>',
'label' => array(
'#type' => 'textfield',
'#title' => t('Label'),
),
'model' => array(
'#type' => 'select',
'#title' => t('Select a Content Model to Ingest'),
'#options' => array_combine($models, $models),
'#default' => $model,
'#ajax' => array(
'callback' => 'islandora_ingest_test_model_ajax_callback',
'wrapper' => 'islandora-select-content-model-wrapper',
'method' => 'replace',
'effect' => 'fade',
),
),
);
}
/**
* Updates the model field.
*/
function islandora_ingest_test_model_ajax_callback(array $form, array &$form_state) {
return $form;
}
/**
* Sets the label of the ingestable object.
*
* @param array $form
* The Drupal form.
* @param array $form_state
* The Drupal form state.
*/
function islandora_ingest_test_set_label_form_submit(array $form, array &$form_state) {
$object = islandora_ingest_form_get_object($form_state);
$object->label = $form_state['values']['label'];
unset($object->models);
$object->models = array($form_state['values']['model']);
}
/**
* Test the First content model.
*/
function islandora_ingest_test_testcmodel_form(array $form, array &$form_state) {
return array(
);
}
/**
* Test the CModel submit.
*/
function islandora_ingest_test_testcmodel_form_submit(array $form, array &$form_state) {
}
/**
* Test the second content model.
*/
function islandora_ingest_test_testcmodel2_form(array $form, array &$form_state) {
return array(
);
}
/**
* Test the CModel submit.
*/
function islandora_ingest_test_testcmodel2_form_submit(array $form, array &$form_state) {
}

125
tests/web_test_case.inc → tests/islandora_web_test_case.inc

@ -28,7 +28,7 @@ class IslandoraWebTestCase extends DrupalWebTestCase {
$this->backUpDrupalFilter();
$this->setUpDrupalFilter();
}
$this->createAdminUser();
$this->admin = $this->createAdminUser();
}
/**
@ -90,15 +90,44 @@ class IslandoraWebTestCase extends DrupalWebTestCase {
* Creates the a full fedora admin user with a repository connection.
*/
protected function createAdminUser() {
$this->admin = new stdClass();
$this->admin->uid = 1;
$this->admin->name = $this->configuration['admin_user'];
$this->admin->pass = $this->configuration['admin_pass'];
$roles = user_roles();
$index = array_search('administrator', $roles);
$user = $this->drupalCreateUser();
$user->roles[$index] = 'administrator';
$user->name = $this->configuration['admin_user'];
$user->pass = $this->configuration['admin_pass'];
$user = user_save($user);
$url = variable_get('islandora_base_url', $this->configuration['fedora_url']);
$connection = islandora_get_tuque_connection($this->admin, $url);
$this->admin->repository = $connection->repository;
return $this->admin;
$connection = islandora_get_tuque_connection($user, $url);
$user->repository = $connection->repository;
return $user;
}
/**
* Logs in the given user, handles the special case where the user is admin.
*
* @see DrupalWebTestCase::drupalLogin()
*/
protected function drupalLogin(stdClass $account) {
if ($account->uid == $this->admin->uid) {
// Create password for Drupal.
$edit = array('pass' => user_password());
$account = user_save($account, $edit);
// Raw password is used to login.
$account->pass_raw = $edit['pass'];
// We must login before changing the password for fedora.
parent::drupalLogin($account);
$account->name = $this->configuration['admin_user'];
$account->pass = $this->configuration['admin_pass'];
// Save the fedora admin credentials for later GET/POST requests.
$account = user_save($account);
}
else {
parent::drupalLogin($account);
}
}
/**
* Stores the content of the Drupal Filter for later restoration.
*/
@ -126,4 +155,84 @@ class IslandoraWebTestCase extends DrupalWebTestCase {
unset($this->configuration);
parent::tearDown();
}
/**
* Asserts that the given datastreams exist on the object.
*
* @param AbstractObject $object
* The PID of the object
* @param array $datastreams
* An array of strings containing datastream names
*/
public function assertDatastreams($object, array $datastreams) {
if (!is_object($object)) {
$this->fail("Failed. Object passed in is invalid.");
return;
}
foreach ($datastreams as $datastream) {
if (isset($object[$datastream])) {
$this->pass("Loaded datastream {$datastream} from PID {$object->id}");
}
else {
$this->fail("Failed to load datastream {$datastream} from PID {$object->id}");
}
}
}
/**
* Gets a tuque object from a path.
*
* @param string $path
* A full or partial path to an islandora object.
*
* @return AbstractObject
* The pid of the object or FALSE if a PID is not found.
*/
public function getObjectFromPath($path) {
$path_parts = explode('/', $path);
$array_length = count($path_parts);
for ($i = 0; $i < $array_length; $i++) {
if ($path_parts[$i] == 'islandora' && isset($path_parts[$i + 1]) && $path_parts[$i + 1] == 'object') {
if (isset($path_parts[$i + 2])) {
return islandora_object_load(urldecode($path_parts[$i + 2]));
}
}
}
$this->fail("Failed to parse path : $path.");
return FALSE;
}
/**
* Deletes an object using the PID. This does the deletion using the UI.
*
* @param string $pid
* The PID of the collection to be deleted
*/
public function deleteObject($pid) {
$current_user = $this->loggedInUser;
$user = $this->drupalCreateUser(array(
'manage object properties',
'delete fedora objects and datastreams',
'view fedora repository objects',
));
$this->drupalLogin($user);
$path = 'islandora/object/' . $pid . '/manage/properties';
$edit = array();
$this->drupalPost($path, $edit, t('Delete'));
$this->drupalPost($this->url, $edit, t('Delete'));
$object = islandora_object_load($pid);
$this->drupalGet("islandora/object/$pid");
$this->assertResponse(404, "Object $pid successfully deleted.");
if ($current_user) {
$this->drupalLogin($current_user);
}
else {
$this->drupalLogout();
}
}
}

18
tests/scripts/travis_setup.sh

@ -11,12 +11,16 @@ cd islandora_tomcat
export CATALINA_HOME='.'
./bin/startup.sh
cd $HOME
pyrus channel-discover pear.drush.org
pyrus channel-discover pear.phpqatools.org
pyrus channel-discover pear.netpirates.net
pyrus install drush/drush
pyrus install pear/PHP_CodeSniffer
pyrus install pear.phpunit.de/phpcpd
pear upgrade –force Console_Getopt
pear upgrade –force pear
pear upgrade-all
pear channel-discover pear.drush.org
pear channel-discover pear.drush.org
pear channel-discover pear.phpqatools.org
pear channel-discover pear.netpirates.net
pear install pear/PHP_CodeSniffer
pear install pear.phpunit.de/phpcpd
pear install drush/drush
phpenv rehash
drush dl --yes drupal
cd drupal-*
@ -33,4 +37,4 @@ drush en --yes simpletest
drush en --yes potx
drush en --user=1 --yes islandora
drush cc all
sleep 4
sleep 20

Loading…
Cancel
Save