Browse Source

Created hooks and implemented them as part of the tuque wrapper classes.

hook_islandora_object_alter(AbstractFedoraObject $object, array &$context)
 hook_CMODEL_PID_islandora_object_alter(AbstractFedoraObject $object, array &$context)
 hook_islandora_datastream_alter(AbstractFedoraObject $object, AbstractFedoraDatastream $datastream, array &$context)
 hook_CMODEL_PID_DSID_islandora_datastream_altezr(AbstractFedoraObject $object, AbstractFedoraDatastream $datastream, array &$context)
 hook_islandora_object_ingested(FedoraObject $object)
 hook_CMODEL_PID_islandora_object_ingested(FedoraObject $object)
 hook_islandora_object_modified(FedoraObject $object)
 hook_CMODEL_PID_islandora_object_modified(FedoraObject $object)
 hook_islandora_object_purged($pid)
 hook_CMODEL_PID_islandora_object_purged($pid)
 hook_islandora_datastream_ingested(FedoraObject $object, FedoraDatastream $datastream)
 hook_CMODEL_PID_DSID_islandora_datastream_ingested(FedoraObject $object, FedoraDatastream $datastream)
 hook_islandora_datastream_modified(FedoraObject $object, FedoraDatastream $datastream)
 hook_CMODEL_PID_islandora_datastream_modified(FedoraObject $object, FedoraDatastream $datastream)
 hook_islandora_datastream_purged(FedoraObject $object, $dsid)
 hook_CMODEL_PID_islandora_datastream_purged(FedoraObject $object, $dsid)

Also updated the testing scripts to support different configurations, as well
wrote tests for all the implemented hooks. This requires the latest version
of Tuque so be sure to update.
pull/243/head
Nigel Banks 12 years ago
parent
commit
7ec10d2c11
  1. 1
      .gitignore
  2. 78
      includes/IslandoraTuqueWrapper.inc
  3. 2
      includes/islandora_tuque.inc
  4. 360
      includes/islandora_tuque_wrapper.inc
  5. 65
      includes/utilities.inc
  6. 334
      islandora.api.php
  7. 5
      islandora.info
  8. 198
      islandora.module
  9. 3
      tests/README
  10. 6
      tests/default.test_config.ini
  11. 48
      tests/islandora_authtokens.test
  12. 213
      tests/islandora_hooks.test
  13. 7
      tests/islandora_hooks_test.info
  14. 152
      tests/islandora_hooks_test.module
  15. 108
      tests/islandora_web_test_case.inc
  16. 4
      tests/test_config.ini

1
.gitignore vendored

@ -1,2 +1,3 @@
cache.properties
.DS_Store
tests/test_config.ini

78
includes/IslandoraTuqueWrapper.inc

@ -1,78 +0,0 @@
<?php
/**
* @file
*
* Wrapper around the tuque library, allows for autoloading of Islandora Tuque
* Objects.
*
* @todo Overload functions and apply pre/post hooks.
*/
$islandora_module_path = drupal_get_path('module', 'islandora');
//do this until we expost these in a module or library
@include_once 'sites/all/libraries/tuque/Datastream.php';
@include_once 'sites/all/libraries/tuque/FedoraApi.php';
@include_once 'sites/all/libraries/tuque/FedoraApiSerializer.php';
@include_once 'sites/all/libraries/tuque/Object.php';
@include_once 'sites/all/libraries/tuque/RepositoryConnection.php';
@include_once 'sites/all/libraries/tuque/Cache.php';
@include_once 'sites/all/libraries/tuque/RepositoryException.php';
@include_once 'sites/all/libraries/tuque/Repository.php';
@include_once 'sites/all/libraries/tuque/FedoraRelationships.php';
@include_once "$islandora_module_path/libraries/tuque/Datastream.php";
@include_once "$islandora_module_path/libraries/tuque/FedoraApi.php";
@include_once "$islandora_module_path/libraries/tuque/FedoraApiSerializer.php";
@include_once "$islandora_module_path/libraries/tuque/Object.php";
@include_once "$islandora_module_path/libraries/tuque/RepositoryConnection.php";
@include_once "$islandora_module_path/libraries/tuque/Cache.php";
@include_once "$islandora_module_path/libraries/tuque/RepositoryException.php";
@include_once "$islandora_module_path/libraries/tuque/Repository.php";
@include_once "$islandora_module_path/libraries/tuque/FedoraRelationships.php";
class IslandoraFedoraRepository extends FedoraRepository {
protected $queryClass = 'IslandoraRepositoryQuery';
protected $newObjectClass = 'IslandoraNewFedoraObject';
protected $objectClass = 'IslandoraFedoraObject';
}
class IslandoraRepositoryQuery extends RepositoryQuery {}
class IslandoraNewFedoraObject extends NewFedoraObject {
protected $newFedoraDatastreamClass = 'IslandoraNewFedoraDatastream';
protected $fedoraDatastreamClass = 'IslandoraFedoraDatastream';
protected $fedoraRelsExtClass = 'IslandoraFedoraRelsExt';
}
class IslandoraFedoraObject extends FedoraObject {
protected $newFedoraDatastreamClass = 'IslandoraNewFedoraDatastream';
protected $fedoraDatastreamClass = 'IslandoraFedoraDatastream';
protected $fedoraRelsExtClass = 'IslandoraFedoraRelsExt';
}
class IslandoraRepositoryConnection extends RepositoryConnection {}
class IslandoraFedoraApi extends FedoraApi {}
class IslandoraSimpleCache extends SimpleCache {}
class IslandoraNewFedoraDatastream extends NewFedoraDatastream {
protected $fedoraRelsIntClass = 'IslandoraFedoraRelsInt';
protected $fedoraDatastreamVersionClass = 'IslandoraFedoraDatastreamVersion';
}
class IslandoraFedoraDatastream extends FedoraDatastream {
protected $fedoraRelsIntClass = 'IslandoraFedoraRelsInt';
protected $fedoraDatastreamVersionClass = 'IslandoraFedoraDatastreamVersion';
}
class IslandoraFedoraDatastreamVersion extends FedoraDatastreamVersion {
protected $fedoraRelsIntClass = 'IslandoraFedoraRelsInt';
protected $fedoraDatastreamVersionClass = 'IslandoraFedoraDatastreamVersion';
}
class IslandoraFedoraRelsExt extends FedoraRelsExt {}
class IslandoraFedoraRelsInt extends FedoraRelsInt {}

2
includes/IslandoraTuque.inc → includes/islandora_tuque.inc

@ -78,7 +78,7 @@ class IslandoraTuque {
}
if (self::exists()) {
module_load_include('inc', 'islandora', 'includes/IslandoraTuqueWrapper');
module_load_include('inc', 'islandora', 'includes/islandora_tuque_wrapper');
$this->connection = new IslandoraRepositoryConnection($url, $user_string, $pass_string);
$this->connection->reuseConnection = TRUE;
$this->api = new IslandoraFedoraApi($this->connection);

360
includes/islandora_tuque_wrapper.inc

@ -0,0 +1,360 @@
<?php
/**
* @file
* Wrapper around the tuque library, allows for autoloading of Islandora Tuque
* Objects.
*
* @todo Overload functions and apply pre/post hooks.
*/
$islandora_module_path = drupal_get_path('module', 'islandora');
// @todo this until we expost these in a module or library
@include_once 'sites/all/libraries/tuque/Datastream.php';
@include_once 'sites/all/libraries/tuque/FedoraApi.php';
@include_once 'sites/all/libraries/tuque/FedoraApiSerializer.php';
@include_once 'sites/all/libraries/tuque/Object.php';
@include_once 'sites/all/libraries/tuque/RepositoryConnection.php';
@include_once 'sites/all/libraries/tuque/Cache.php';
@include_once 'sites/all/libraries/tuque/RepositoryException.php';
@include_once 'sites/all/libraries/tuque/Repository.php';
@include_once 'sites/all/libraries/tuque/FedoraRelationships.php';
@include_once "$islandora_module_path/libraries/tuque/Datastream.php";
@include_once "$islandora_module_path/libraries/tuque/FedoraApi.php";
@include_once "$islandora_module_path/libraries/tuque/FedoraApiSerializer.php";
@include_once "$islandora_module_path/libraries/tuque/Object.php";
@include_once "$islandora_module_path/libraries/tuque/RepositoryConnection.php";
@include_once "$islandora_module_path/libraries/tuque/Cache.php";
@include_once "$islandora_module_path/libraries/tuque/RepositoryException.php";
@include_once "$islandora_module_path/libraries/tuque/Repository.php";
@include_once "$islandora_module_path/libraries/tuque/FedoraRelationships.php";
/**
* Allow modules to alter an object before a mutable event occurs.
*/
function islandora_alter_object(AbstractFedoraObject $object, array &$context) {
$types = array('islandora_object');
foreach ($object->models as $model) {
$types[] = "{$model}_islandora_object";
}
drupal_alter($types, $object, $context);
}
/**
* Allow modules to alter a datastream before a mutable event occurs.
*/
function islandora_alter_datastream(AbstractFedoraObject $object, AbstractDatastream $datastream, array &$context) {
$types = array('islandora_datastream');
foreach ($object->models as $model) {
$types[] = "{$model}_{$datastream->id}_islandora_datastream";
}
drupal_alter($types, $object, $datastream, $context);
}
/**
* Constructs a list of hooks from the given paramenters and invokes them.
*/
function islandora_invoke_object_hooks($hook, array $models) {
module_load_include('inc', 'islandora', 'includes/utilities');
return islandora_invoke_hook_list($hook, $models, array_slice(func_get_args(), 2));
}
/**
* Constructs a list of hooks from the given paramenters and invokes them.
*/
function islandora_invoke_datastream_hooks($hook, array $models, $dsid) {
module_load_include('inc', 'islandora', 'includes/utilities');
$refinements = array();
foreach ($models as $model) {
$refinements[] = "{$model}_{$dsid}";
}
return islandora_invoke_hook_list($hook, $refinements, array_slice(func_get_args(), 3));
}
class IslandoraFedoraRepository extends FedoraRepository {
protected $queryClass = 'IslandoraRepositoryQuery';
protected $newObjectClass = 'IslandoraNewFedoraObject';
protected $objectClass = 'IslandoraFedoraObject';
/**
* Ingest the given object.
*
* @see FedoraRepository::ingestObject()
*/
public function ingestObject(NewFedoraObject &$object) {
$context = array(
'action' => 'ingest',
'block' => FALSE,
);
islandora_alter_object($object, $context);
try {
if ($context['block']) {
throw new Exception('Ingest Object was blocked.');
}
$ret = parent::ingestObject($object);
islandora_invoke_object_hooks(ISLANDORA_OBJECT_INGESTED_HOOK, $object->models, $object);
// Call the ingested datastream hooks for NewFedoraObject's after the
// object had been ingested.
foreach ($object as $dsid => $datastream) {
islandora_invoke_datastream_hooks(ISLANDORA_DATASTREAM_INGESTED_HOOK, $object->models, $dsid, $object, $datastream);
}
return $ret;
}
catch (Exception $e) {
watchdog('islandora', 'Failed to ingest object: @pid</br>code: @code<br/>message: @msg', array(
'@pid' => $object->id,
'@code' => $e->getCode(),
'@msg' => $e->getMessage()), WATCHDOG_ERROR);
throw $e;
}
}
}
class IslandoraRepositoryQuery extends RepositoryQuery {}
class IslandoraNewFedoraObject extends NewFedoraObject {
protected $newFedoraDatastreamClass = 'IslandoraNewFedoraDatastream';
protected $fedoraDatastreamClass = 'IslandoraFedoraDatastream';
protected $fedoraRelsExtClass = 'IslandoraFedoraRelsExt';
}
class IslandoraFedoraObject extends FedoraObject {
protected $newFedoraDatastreamClass = 'IslandoraNewFedoraDatastream';
protected $fedoraDatastreamClass = 'IslandoraFedoraDatastream';
protected $fedoraRelsExtClass = 'IslandoraFedoraRelsExt';
/**
* Ingest the given datastream.
*
* @see FedoraObject::ingestDatastream()
*/
public function ingestDatastream(&$datastream) {
$object = $datastream->parent;
$context = array(
'action' => 'ingest',
'block' => FALSE,
);
islandora_alter_datastream($object, $datastream, $context);
try {
if ($context['block']) {
throw new Exception('Ingest Datastream was blocked.');
}
$ret = parent::ingestDatastream($datastream);
islandora_invoke_datastream_hooks(ISLANDORA_DATASTREAM_INGESTED_HOOK, $object->models, $datastream->id, $object, $datastream);
return $ret;
}
catch (Exception $e) {
watchdog('islandora', 'Failed to ingest object: @pid</br>code: @code<br/>message: @msg', array(
'@pid' => $object->id,
'@dsid' => $datastream->id,
'@code' => $e->getCode(),
'@msg' => $e->getMessage()), WATCHDOG_ERROR);
throw $e;
}
}
}
class IslandoraRepositoryConnection extends RepositoryConnection {}
class IslandoraFedoraApi extends FedoraApi {
/**
* Instantiate a IslandoraFedoraApi object.
*
* @see FedoraApi::__construct()
*/
public function __construct(IslandoraRepositoryConnection $connection, FedoraApiSerializer $serializer = NULL) {
if (!$serializer) {
$serializer = new FedoraApiSerializer();
}
$this->a = new FedoraApiA($connection, $serializer);
$this->m = new IslandoraFedoraApiM($connection, $serializer);
$this->connection = $connection;
}
}
class IslandoraFedoraApiM extends FedoraApiM {
/**
* Update a datastream.
*
* Either changing its metadata, updaing the datastream contents or both.
*
* @throws Exception
* If the modify datastream request was block by some module.
*
* @see FedoraApiM::modifyDatastream
*/
public function modifyDatastream($pid, $dsid, $params = array()) {
$object = islandora_object_load($pid);
$datastream = $object[$dsid];
$context = array(
'action' => 'modify',
'block' => FALSE,
'params' => $params,
);
islandora_alter_datastream($object, $datastream, $context);
try {
if ($context['block']) {
throw new Exception('Modify Datastream was blocked.');
}
$ret = parent::modifyDatastream($pid, $dsid, $params);
islandora_invoke_datastream_hooks(ISLANDORA_DATASTREAM_MODIFIED_HOOK, $object->models, $dsid, $object, $datastream);
if (isset($params['dsState']) && $params['dsState'] == 'D') {
islandora_invoke_datastream_hooks(ISLANDORA_DATASTREAM_PURGED_HOOK, $object->models, $dsid, $object, $dsid);
}
return $ret;
}
catch(Exception $e) {
watchdog('islandora', 'Failed to modify datastream @dsid from @pid</br>code: @code<br/>message: @msg', array(
'@pid' => $pid,
'@dsid' => $dsid,
'@code' => $e->getCode(),
'@msg' => $e->getMessage()), WATCHDOG_ERROR);
throw $e;
}
}
/**
* Update Fedora Object parameters.
*
* @see FedoraApiM::modifyObject
*/
public function modifyObject($pid, $params = NULL) {
$object = islandora_object_load($pid);
$context = array(
'action' => 'modify',
'block' => FALSE,
'params' => $params,
);
islandora_alter_object($object, $context);
try {
if ($context['block']) {
throw new Exception('Modify Object was blocked.');
}
$ret = parent::modifyObject($pid, $params);
islandora_invoke_object_hooks(ISLANDORA_OBJECT_MODIFIED_HOOK, $object->models, $object);
if (isset($params['state']) && $params['state'] == 'D') {
islandora_invoke_object_hooks(ISLANDORA_OBJECT_PURGED_HOOK, $object->models, $object->id);
}
return $ret;
}
catch(Exception $e) {
watchdog('islandora', 'Failed to modify object: @pid</br>code: @code<br/>message: @msg', array(
'@pid' => $pid,
'@code' => $e->getCode(),
'@msg' => $e->getMessage()), WATCHDOG_ERROR);
throw $e;
}
}
/**
* Purge a datastream from from Fedora.
*
* @see FedoraApiM::purgeDatastream
*/
public function purgeDatastream($pid, $dsid, $params = array()) {
$object = islandora_object_load($pid);
$context = array(
'action' => 'purge',
'purge' => TRUE,
'delete' => FALSE,
'block' => FALSE,
);
islandora_alter_datastream($object, $object[$dsid], $context);
try {
$action = $context['block'] ? 'block' : FALSE;
$action = (!$action && $context['delete']) ? 'delete' : $action;
$action = !$action ? 'purge' : $action;
switch ($action) {
case 'block':
throw new Exception('Purge Datastream was blocked.');
break;
case 'delete':
$object[$dsid]->state = 'D';
return array();
default:
$ret = parent::purgeDatastream($pid, $dsid, $params);
islandora_invoke_datastream_hooks(ISLANDORA_DATASTREAM_PURGED_HOOK, $object->models, $dsid, $object, $dsid);
return $ret;
}
}
catch(Exception $e) {
watchdog('islandora', 'Failed to purge datastream @dsid from @pid</br>code: @code<br/>message: @msg', array(
'@pid' => $pid,
'@dsid' => $dsid,
'@code' => $e->getCode(),
'@msg' => $e->getMessage()), WATCHDOG_ERROR);
throw $e;
}
}
/**
* Purge an object.
*
* @see FedoraApiM::purgeObject
*/
public function purgeObject($pid, $log_message = NULL) {
$object = islandora_object_load($pid);
$context = array(
'action' => 'purge',
'purge' => TRUE,
'delete' => FALSE,
'block' => FALSE,
);
islandora_alter_object($object, $context);
try {
$action = $context['block'] ? 'block' : FALSE;
$action = (!$action && $context['delete']) ? 'delete' : $action;
$action = !$action ? 'purge' : $action;
$models = $object->models;
switch ($action) {
case 'block':
throw new Exception('Purge object was blocked.');
break;
case 'delete':
$object->state = 'D';
return '';
default:
$ret = parent::purgeObject($pid, $log_message);
islandora_invoke_object_hooks(ISLANDORA_OBJECT_PURGED_HOOK, $models, $pid);
return $ret;
}
}
catch(Exception $e) {
watchdog('islandora', 'Failed to purge object @pid</br>code: @code<br/>message: @msg', array(
'@pid' => $pid,
'@code' => $e->getCode(),
'@msg' => $e->getMessage()), WATCHDOG_ERROR);
throw $e;
}
}
}
class IslandoraSimpleCache extends SimpleCache {}
class IslandoraNewFedoraDatastream extends NewFedoraDatastream {
protected $fedoraRelsIntClass = 'IslandoraFedoraRelsInt';
protected $fedoraDatastreamVersionClass = 'IslandoraFedoraDatastreamVersion';
}
class IslandoraFedoraDatastream extends FedoraDatastream {
protected $fedoraRelsIntClass = 'IslandoraFedoraRelsInt';
protected $fedoraDatastreamVersionClass = 'IslandoraFedoraDatastreamVersion';
}
class IslandoraFedoraDatastreamVersion extends FedoraDatastreamVersion {
protected $fedoraRelsIntClass = 'IslandoraFedoraRelsInt';
protected $fedoraDatastreamVersionClass = 'IslandoraFedoraDatastreamVersion';
}
class IslandoraFedoraRelsExt extends FedoraRelsExt {}
class IslandoraFedoraRelsInt extends FedoraRelsInt {}

65
includes/utilities.inc

@ -112,29 +112,66 @@ function islandora_describe_repository($url = NULL) {
}
/**
* Build a list of all the hooks to call.
* Build and invoke a list of hooks by combining the given hook and refinements.
*
* The given hook will be called as MODULE_HOOK, and for each hook refinement
* as MODULE_REFINEMENT_HOOK. Any additional arguments passed to this function
* will be passed as arguments to module_invoke_all().
*
* Concatenates the each pid (escaped) to the hook name, for calling in
* module_invoke_all().
* @see islandora_build_hook_list()
* To see how the hook list is generated.
*
* @param string $hook
* A hook to call.
* @param array $pids
* An array of PIDs (probably content models).
* @param array $refinements
* An array of strings, that will be escaped and concatinated with the given
* hook. This will most likely be PIDs/DSIDs/Labels etc. We often refine our
* hooks using an objects model.
* @param array $args
* Any arguments to pass onto module_invoke_all().
*
* @return array
* An array with each PID escaped and concatenated with the base hook name,
* in addition to the base hook name at the end.
* The merged results from all the hooks.
*/
function islandora_build_hook_list($hook, $pids = array()) {
$hooks = array();
$pids = array_unique($pids);
foreach ($pids as $pid) {
$hooks[] = islandora_escape_pid_for_function($pid) . '_' . $hook;
function islandora_invoke_hook_list($hook, array $refinements, array $args) {
dsm(func_get_args());
$return = array();
foreach (islandora_build_hook_list($hook, $refinements) as $hook) {
array_unshift($args, $hook);
$result = call_user_func_array('module_invoke_all', $args);
$return = array_merge_recursive($return, $result);
array_shift($args);
}
$hooks[] = $hook;
return $return;
}
/**
* Build a list of all the hooks to call.
*
* Concatenates each hook $refinement (escaped) to the hook name, for calling
* with module_invoke_all().
*
* Any non-valid PHP function characters in the given refinements are
* converted to "_" characters.
*
* @param string $hook
* The base hook to concatenate.
* @param array $refinements
* An array of strings, that will be escaped and concatinated with the given
* hook. This will most likely be PIDs/DSIDs/Labels etc. We often refine our
* hooks using an objects model.
*
* @return array
* An array with each refinement escaped and concatenated with the base hook
* name, in addition to the base hook name.
*/
function islandora_build_hook_list($hook, $refinements = array()) {
$refinements = array_unique($refinements);
$hooks = array($hook);
foreach ($refinements as $refinement) {
$refinement = preg_replace('/[^a-zA-Z0-9_]/', '_', $refinement);
$hooks[] = "{$refinement}_{$hook}";
}
return $hooks;
}

334
islandora.api.php

@ -2,24 +2,26 @@
/**
* @file
* This file lists and documents all available hook functions to manipulate data.
* This file documents all available hook functions to manipulate data.
*/
/**
* Generate a repository objects view.
*
* @param FedoraObject $fedora_object
* A Tuque FedoraObject being operated on.
* @param FedoraObject $object
* The object to display
* @param object $user
* The user accessing the object.
* @param string $page_number
* The page in the content.
* @param string $page_size: The size of the page.
* @param string $page_size
* The size of the page.
*
* @return array
* An array whose values are markup.
*/
function hook_islandora_view_object($fedora_object, $user, $page_number, $page_size) {}
function hook_islandora_view_object($object, $user, $page_number, $page_size) {
}
/**
* Generate an object's display for the given content model.
@ -27,35 +29,38 @@ function hook_islandora_view_object($fedora_object, $user, $page_number, $page_s
* Content models PIDs have colons and hyphens changed to underscores, to
* create the hook name.
*
* @param type $fedora_object
* @param FedoraObject $object
* A Tuque FedoraObject
*
* @return array
* An array whose values are markup.
*/
function hook_CMODEL_PID_islandora_view_object($fedora_object) {}
function hook_CMODEL_PID_islandora_view_object($object) {
}
/**
* Alter display output after it has been generated.
*
* @param FedoraObject $fedora_object
* @param FedoraObject $object
* A Tuque FedoraObject being operated on.
* @param array $arr
* @param array $rendered
* An arr of rendered views.
*/
function hook_islandora_view_object_alter(&$fedora_object, &$arr) {}
function hook_islandora_view_object_alter(&$object, &$rendered) {
}
/**
* Generate an object's management display.
*
* @param type $fedora_object
* @param FedoraObject $object
* A Tuque FedoraObject
*
* @return array
* An array whose values are markup.
*/
function hook_islandora_edit_object($fedora_object) {}
function hook_islandora_edit_object($object) {
}
/**
* Generate an object's management display for the given content model.
@ -63,148 +68,305 @@ function hook_islandora_edit_object($fedora_object) {}
* Content models PIDs have colons and hyphens changed to underscores, to
* create the hook name.
*
* @param type $fedora_object
* @param FedoraObject $object
* A Tuque FedoraObject
*
* @return array
* An array whose values are markup.
*/
function hook_CMODEL_PID_islandora_edit_object($fedora_object) {}
function hook_CMODEL_PID_islandora_edit_object($object) {
}
/**
* Allow management display output to be altered.
*
* @param type $fedora_object
* @param FedoraObject $object
* A Tuque FedoraObject
* @param type $arr
* @param array $rendered
* an arr of rendered views
*/
function hook_islandora_edit_object_alter(&$fedora_object, &$arr) {}
function hook_islandora_edit_object_alter(&$object, &$rendered) {
}
/**
* Allows modules to alter the object or block/modify the given action.
*
* This alter hook will be called before any object is ingested, modified or
* purged.
*
* Changing object properties such as "label", or "state", are considered
* modifications, where as manipulating an object's datstreams are not.
*
* @param AbstractFedoraObject $object
* The object to alter.
* @param array $context
* The context for the alter action, this will always contain at the
* following properties.
*
* @code
* array(
* // Either 'ingest', 'purge', 'modify'.
* 'action' => 'ingest',
* // Either TRUE or FALSE, if TRUE the action won't take place.
* // Set by the implementing alter hook.
* 'block' => FALSE,
* )
* @endcode
*
* When the action is "purge" two additional boolean properties are present
* 'delete' defaults to FALSE, and 'purge' defaults to TRUE. If only purge
* is set to TRUE the object will be 'purged' if delete is set to TRUE and
* block is not then the object state will be set to 'Deleted'. If 'block'
* is set to TRUE the object will not be deleted or purged.
*/
function hook_islandora_object_alter(AbstractFedoraObject $object, array &$context) {
}
/**
* Allows modules to add to an objects ingest process.
* Allows modules to alter the object or block/modify the given action.
*
* @param FedoraObject $fedora_object
* A Tuque FedoraObject.
* @see hook_islandora_object_alter()
*/
function hook_islandora_ingest_post_ingest($fedora_object) {}
function hook_CMODEL_PID_islandora_object_alter(AbstractFedoraObject $object, array &$context) {
}
/**
* Allow modules to add to the ingest process of a specific content model.
* Allows modules to alter the datastream or block/modify the given action.
*
* This alter hook will be called before any datastream is ingested, modified or
* purged.
*
* Adding datastreams to NewFedoraObject's will not trigger this alter hook
* 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
* at all.
*
* Changing datastream's properties such as "label", or "state", are considered
* modifications, as well as changing the datastreams content.
*
* @param AbstractFedoraObject $object
* The object to the datastream belong to.
* @param AbstractFedoraDatastream $datastream
* The datastream to alter.
* @param array $context
* The context for the alter action, this will always contain at the
* following properties.
*
* @code
* array(
* // Either 'ingest', 'purge', 'modify'.
* 'action' => 'ingest',
* // Either TRUE or FALSE, if TRUE the action won't take place.
* // Set by the implementing alter hook.
* 'block' => FALSE,
* )
* @endcode
*
* When the action is "purge" two additional boolean properties are present
* 'delete' (defaults to FALSE), and 'purge' (defaults to TRUE). If only purge
* is set to TRUE the datastream will be 'purged' if delete is set to TRUE and
* block is not then the datastream state will be set to 'Deleted'. If 'block'
* is set to TRUE the datastream will not be deleted or purged.
*
* When the action is "modify" there is an additional property "params" that
* contains the modifications about to take place.
*/
function hook_CMODEL_PID_islandora_ingest_post_ingest($fedora_object) {}
function hook_islandora_datastream_alter(AbstractFedoraObject $object, AbstractFedoraDatastream $datastream, array &$context) {
}
/**
* Allows modules to alter the datastream or block/modify the given action.
*
* @see hook_islandora_datastream_alter()
*/
function hook_CMODEL_PID_DSID_islandora_datastream_alter(AbstractFedoraObject $object, AbstractFedoraDatastream $datastream, array &$context) {
}
/**
* Allows modules to add to a repository objects view/edit(/misc) process.
* Notify modules that the given object was ingested.
*
* If you implement this hook you must also register your module with
* hook_islandora_hook_info().
* This hook is called after an object has been successfully ingested via a
* FedoraRepository object.
*
* @param FedoraObject $fedora_object
* A Tuque FedoraObject.
* @note
* 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.
*
* @return array|null
* An associative array with 'deleted' mapped to TRUE--indicating that the
* object should just be marked as deleted, instead of actually being
* purged--or NULL/no return if we just need to do something before the
* is purged.
* @param FedoraObject $object
* The object that was ingested.
*/
function hook_islandora_pre_purge_object($fedora_object) {}
function hook_islandora_object_ingested(FedoraObject $object) {
}
/**
* Allow modules to react to the purge process of a specific content model.
* Notify modules that the given object was ingested.
*
* @see hook_islandora_pre_purge_object()
* @see hook_islandora_object_ingested()
*/
function hook_CMODEL_PID_islandora_pre_purge_object($fedora_object) {}
function hook_CMODEL_PID_islandora_object_ingested(FedoraObject $object) {
}
/**
* Register potential ingest routes.
* Notify modules that the given object was modified.
*
* Implementations should return an array containing possible routes.
* This hook is called after an object has been successfully modified.
*
* Changing object properties such as "label", or "state", are considered
* modifications, where as manipulating an object's datstreams are not.
*
* @param FedoraObject $object
* The object that was ingested.
*
* @todo We should also include what changes were made in a additional
* parameter.
*/
function hook_islandora_ingest_registry($collection_object) {
$reg = array(
array(
'name' => t('Ingest route name'),
'url' => 'ingest_route/url',
'weight' => 0,
),
);
return $reg;
function hook_islandora_object_modified(FedoraObject $object) {
}
/**
* Register a datastream edit route/form.
* Notify modules that the given object was ingested.
*
* @param $islandora_object
* @param $ds_id
* @see hook_islandora_object_modified()
*/
function hook_islandora_edit_datastream_registry($islandora_object, $ds_id) {}
function hook_CMODEL_PID_islandora_object_modified(FedoraObject $object) {
}
/**
* Alter an object before it gets used further down the stack.
* Notify modules that the given object was purged/deleted.
*
* @param type $object
* A Tuque FedoraObject
* This hook is called after an object has been successfully purged, or
* when its state has been changed to "Deleted".
*
* @param string $pid
* The ID of the object that was purged/deleted.
*/
function hook_islandora_object_alter($fedora_object) {}
function hook_islandora_object_purged($pid) {
}
/**
* Allow modification of an object before ingesting.
* Notify modules that the given object was purged/deleted.
*
* @param type $islandora_object
* A Tuque FedoraObject
* @see hook_islandora_object_purged()
*/
function hook_islandora_ingest_pre_ingest($islandora_object) {}
function hook_CMODEL_PID_islandora_object_purged($pid) {
}
/**
* Allow modification of objects of a certain content model before ingesting.
* Notify modules that the given datastream was ingested.
*
* This hook is called after the datastream has been successfully ingested.
*
* @note
* 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.
*
* @see hook_islandora_ingest_pre_ingest()
* @param FedoraObject $object
* The object the datastream belongs to.
* @param FedoraDatastream $datastream
* The ingested datastream.
*/
function hook_CMODEL_PID_islandora_ingest_pre_ingest($islandora_object) {}
function hook_islandora_datastream_ingested(FedoraObject $object, FedoraDatastream $datastream) {
}
/**
* Allow modules to setup for the purge of a datastream.
* Notify modules that the given datastream was ingested.
*
* @param object $datastream
* A Tuque FedoraDatastream object.
* @see hook_islandora_object_ingested()
*/
function hook_islandora_pre_purge_datastream($datastream) {}
function hook_CMODEL_PID_DSID_islandora_datastream_ingested(FedoraObject $object, FedoraDatastream $datastream) {
}
/**
* Allow modules to react after a datastream is purged.
* Notify modules that the given datastream was modified.
*
* @param object $object
* A Tuque FedoraObject.
* This hook is called after an datastream has been successfully modified.
*
* Changing datastream properties such as "label", or "state", are considered
* modifications, as well as the datastreams content.
*
* @param FedoraObject $object
* The object the datastream belongs to.
* @param FedoraDatastream $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) {
}
/**
* Notify modules that the given datastream was ingested.
*
* @see hook_islandora_datastream_modified()
*/
function hook_CMODEL_PID_islandora_datastream_modified(FedoraObject $object, FedoraDatastream $datastream) {
}
/**
* Notify modules that the given datastream was purged/deleted.
*
* This hook is called after an datastream has been successfully purged, or
* when its state has been changed to "Deleted".
*
* @param FedoraObject $object
* The object the datastream belonged to.
* @param string $dsid
* A id of the former datastream.
* The ID of the datastream that was purged/deleted.
*/
function hook_islandora_datastream_purged(FedoraObject $object, $dsid) {
}
/**
* Notify modules that the given datastream was purged/deleted.
*
* @see hook_islandora_datastream_purged()
*/
function hook_CMODEL_PID_islandora_datastream_purged(FedoraObject $object, $dsid) {
}
/**
* Register potential ingest routes.
*
* Implementations should return an array containing possible routes.
*/
function hook_islandora_post_purge_datastream($object, $dsid) {}
function hook_islandora_ingest_registry($collection_object) {
$reg = array(
array(
'name' => t('Ingest route name'),
'url' => 'ingest_route/url',
'weight' => 0,
),
);
return $reg;
}
/**
* Allow modules to react post-purge.
* Register a datastream edit route/form.
*
* @param string $object_id
* The former object's PID.
* @param array $content_models
* An array containing the models to which the former object.
* @param FedoraObject $object
* The object to check.
* @param string $dsid
* todo
*/
function hook_islandora_post_purge_object($object_id, $content_models) {}
function hook_islandora_edit_datastream_registry($object, $dsid) {
}
/**
* Registry hook for required objects.
*
* Solution packs can include data to create certain objects that describe or
* help the objects it would create. This includes collection objects and content
* models.
* help the objects it would create. This includes collection objects and
* content models.
*
* @see islandora_solution_packs_admin()
* @see islandora_install_solution_pack()
* @example islandora_islandora_required_objects()
*/
function hook_islandora_required_objects() {}
function hook_islandora_required_objects() {
}
/**
* Registry hook for viewers that can be implemented by solution packs.
@ -215,13 +377,14 @@ function hook_islandora_required_objects() {}
* @see islandora_get_viewers()
* @see islandora_get_viewer_callback()
*/
function hook_islandora_viewer_info() {}
function hook_islandora_viewer_info() {
}
/**
* Returns a list of datastreams that are determined to be undeletable.
*/
function hook_islandora_undeletable_datastreams(array $models) {}
function hook_islandora_undeletable_datastreams(array $models) {
}
/**
* Define steps used in the islandora_ingest_form() ingest process.
@ -265,4 +428,5 @@ function hook_islandora_ingest_steps(array $form_state) {
*
* @see hook_islandora_ingest_steps()
*/
function hook_CMODEL_PID_islandora_ingest_steps(array $form_state) {}
function hook_CMODEL_PID_islandora_ingest_steps(array $form_state) {
}

5
islandora.info

@ -8,8 +8,9 @@ stylesheets[all][] = css/islandora.base.css
stylesheets[all][] = css/islandora.theme.css
files[] = includes/MimeDetect.inc
files[] = includes/DublinCore.inc
files[] = includes/IslandoraTuque.inc
files[] = includes/IslandoraTuqueWrapper.inc
files[] = includes/islandora_tuque.inc
files[] = includes/islandora_tuque_wrapper.inc
files[] = tests/islandora_web_test_case.inc
files[] = tests/islandora_authtokens.test
files[] = tests/islandora_hooks.test
php = 5.3

198
islandora.module

@ -37,14 +37,14 @@ define('FEDORA_MANAGE_PROPERTIES', 'manage object properties');
// Hooks
define('ISLANDORA_VIEW_HOOK', 'islandora_view_object');
define('ISLANDORA_EDIT_HOOK', 'islandora_edit_object');
define('ISLANDORA_PRE_INGEST_HOOK', 'islandora_ingest_pre_ingest');
define('ISLANDORA_POST_INGEST_HOOK', 'islandora_ingest_post_ingest');
define('ISLANDORA_PRE_PURGE_OBJECT_HOOK', 'islandora_pre_purge_object');
define('ISLANDORA_POST_PURGE_OBJECT_HOOK', 'islandora_post_purge_object');
// @todo Add Documentation.
define('ISLANDORA_OBJECT_INGESTED_HOOK', 'islandora_object_ingested');
define('ISLANDORA_OBJECT_MODIFIED_HOOK', 'islandora_object_modified');
define('ISLANDORA_OBJECT_PURGED_HOOK', 'islandora_object_purged');
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_PRE_PURGE_DATASTREAM_HOOK', 'islandora_pre_purge_datastream');
define('ISLANDORA_POST_PURGE_DATASTREAM_HOOK', 'islandora_post_purge_datastream');
define('ISLANDORA_EDIT_DATASTREAM_HOOK', 'islandora_edit_datastream');
/**
* Implements hook_menu().
@ -541,7 +541,7 @@ function islandora_default_islandora_view_object($object) {
* A IslandoraTuque instance
*/
function islandora_get_tuque_connection($user = NULL, $url = NULL) {
module_load_include('inc', 'islandora', 'includes/IslandoraTuque');
module_load_include('inc', 'islandora', 'includes/islandora_tuque');
$tuque = &drupal_static(__FUNCTION__);
if (!$tuque) {
if (IslandoraTuque::exists()) {
@ -578,9 +578,7 @@ function islandora_object_load($object_id) {
$tuque = islandora_get_tuque_connection();
if ($tuque) {
try {
$object = $tuque->repository->getObject(urldecode($object_id));
drupal_alter('islandora_object', $object);
return $object;
return $tuque->repository->getObject(urldecode($object_id));
} catch (Exception $e) {
if ($e->getCode() == '404') {
return FALSE;
@ -744,124 +742,33 @@ function islandora_islandora_undeletable_datastreams(array $models) {
}
/**
* Ingest the given object into Fedora calling its pre/post hooks as well.
*
* @todo will be cleaned up in the future
* Ingest the given object.
*
* @param NewFedoraObject $object
* An ingestable FedoraObject.
*
* @return FedoraObject
* The ingested FedoraObject, after running the pre/post ingest hooks.
* Returns FALSE if the ingest failed.
* The ingested FedoraObject.
*/
function islandora_add_object(NewFedoraObject &$object) {
islandora_pre_add_object($object);
try {
$object->repository->ingestObject($object);
islandora_post_add_object($object);
return $object;
} catch (Exception $e) {
watchdog('islandora', 'Failed to ingest object: @pid</br>code: @code<br/>message: @msg', array(
'@pid' => $object->id,
'@code' => $e->getCode(),
'@msg' => $e->getMessage()), WATCHDOG_ERROR);
}
return FALSE;
}
/**
* Calls the ISLANDORA_PRE_INGEST_HOOK hooks.
*
* @param NewFedoraObject $object
* An ingestable FedoraObject.
*/
function islandora_pre_add_object(NewFedoraObject $object) {
module_load_include('inc', 'islandora', 'includes/utilities');
foreach (islandora_build_hook_list(ISLANDORA_PRE_INGEST_HOOK, $object->models) as $hook) {
module_invoke_all($hook, $object);
}
}
/**
* Calls the ISLANDORA_POST_INGEST_HOOK hooks.
*
* @param FedoraObject $object
* A recently ingestable FedoraObject.
*/
function islandora_post_add_object(FedoraObject $object) {
foreach (islandora_build_hook_list(ISLANDORA_POST_INGEST_HOOK, $object->models) as $hook) {
module_invoke_all($hook, $object);
}
return $object->repository->ingestObject($object);
}
/**
* Deletes the given object into Fedora calling its pre/post hooks as well.
* Delete's or purges the given object.
*
* @param FedoraObject $object
* An object to delete.
*
* @return FedoraObject
* @return bool
* The ingested FedoraObject, after running the pre/post ingest hooks.
*/
function islandora_delete_object(FedoraObject &$object) {
$object_id = $object->id;
$models = $object->models;
$action = islandora_pre_delete_object($object);
switch ($action) {
case 'blocked':
// Do nothing.
return FALSE;
case 'delete':
// Change the state to deleted.
$object->delete();
islandora_post_delete_object($object_id, $models);
return TRUE;
default:
// Purge
$object->repository->purgeObject($object_id);
islandora_post_delete_object($object_id, $models);
$object = NULL;
return TRUE;
}
}
/**
* Calls the ISLANDORA_PRE_PURGE_OBJECT_HOOK hooks.
*
* @param FedoraObject $object
* The object that is about to be deleted.
*/
function islandora_pre_delete_object(FedoraObject $object) {
module_load_include('inc', 'islandora', 'includes/utilities');
$results = array();
foreach (islandora_build_hook_list(ISLANDORA_PRE_PURGE_OBJECT_HOOK, $object->models) as $hook) {
$results = array_merge_recursive($results, module_invoke_all($hook, $object));
}
$action = (isset($results['block']) && $results['block']) ? 'block' : FALSE;
$action = (!$action && isset($results['delete']) && $results['delete']) ? 'delete' : $action;
$action = !$action ? 'purge' : $action;
return $action;
return $object->repository->purgeObject($object->id);
}
/**
* Calls the ISLANDORA_POST_PURGE_OBJECT_HOOK hooks.
*
* @param string $object_id
* The object id of an the recently deleted object.
* @param array $models
* The list of content models the delete object subsribed to.
*/
function islandora_post_delete_object($object_id, array $models) {
module_load_include('inc', 'islandora', 'includes/utilities');
foreach (islandora_build_hook_list(ISLANDORA_POST_PURGE_OBJECT_HOOK, $models) as $hook) {
module_invoke_all($hook, $object_id, $models);
}
}
/**
* Delete's/Purges the given datastream.
* Delete's or purges the given datastream.
*
* @throws Exception
* Which types are undefined, but more than likely because of the hooks
@ -870,79 +777,12 @@ function islandora_post_delete_object($object_id, array $models) {
* @param FedoraDatastream $datastream
* The datastream to delete.
*
* @return boolean
* TRUE is returned if the datastream was Deleted/Purged, FALSE if it was
* blocked.
* @return bool
* TRUE if successful, FALSE otherwise.
*/
function islandora_delete_datastream(FedoraDatastream &$datastream) {
$datastream_id = $datastream->id;
$object = $datastream->parent;
$action = islandora_pre_delete_datastream($datastream);
switch ($action) {
case 'blocked':
// Do nothing.
return FALSE;
case 'delete':
// Change the state to deleted.
$object[$datastream_id]->state = 'D';
// @todo Differentiate between delete/purge in the hooks.
islandora_post_delete_datastream($object, $datastream_id);
return TRUE;
default:
// Purge
$object->purgeDatastream($datastream_id);
islandora_post_delete_datastream($object, $datastream_id);
$datastream = NULL;
return TRUE;
}
}
/**
* The default behaviour is to 'purge' the datastream but this can be overridden
* by modules that implement the 'islandora_pre_purge_datastream' hook.
*
* @todo make this an alter.
*
* The returned array can include a 'block' => TRUE
* pair which will prevent the datastream from being deleted if it particularly
* needed for a certain function. Returning 'delete' => TRUE will cause the
* datastream to be put into a deleted state.
*
* @param FedoraDatastream $datastream
* The datastream to delete.
*
* @return string
* The action to take when deleting the given datastream, either 'purge',
* 'delete', or 'block'.
*/
function islandora_pre_delete_datastream(FedoraDatastream $datastream) {
module_load_include('inc', 'islandora', 'includes/utilities');
$results = array();
foreach (islandora_build_hook_list(ISLANDORA_PRE_PURGE_DATASTREAM_HOOK, $datastream->parent->models) as $hook) {
// Not sure this will work the greatest, probably an alter would be better..
$results = array_merge_recursive($results, module_invoke_all($hook, $datastream));
}
$action = (isset($results['block']) && $results['block']) ? 'block' : FALSE;
$action = (!$action && isset($results['delete']) && $results['delete']) ? 'delete' : $action;
$action = !$action ? 'purge' : $action;
return $action;
}
/**
* Calls the post purge datastream hooks.
*
* @todo Should differentiate between purging/deleting.
*
* @param FedoraObject $object
* The parent object of the deleted datastream.
* @param string $datastream_id
* The datastream id of the deleted datastream.
*/
function islandora_post_delete_datastream(FedoraObject $object, $datastream_id) {
module_load_include('inc', 'islandora', 'includes/utilities');
foreach (islandora_build_hook_list(ISLANDORA_POST_PURGE_DATASTREAM_HOOK, $object->models) as $hook) {
module_invoke_all($hook, $object, $datastream_id);
}
return $object->purgeDatastream($datastream->id);
}
/**

3
tests/README

@ -0,0 +1,3 @@
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.

6
tests/default.test_config.ini

@ -0,0 +1,6 @@
[fedora]
fedora_url = "http://localhost:8080/fedora"
use_drupal_filter = TRUE
drupal_filter_file = "/usr/local/fedora/server/config/filter-drupal.xml"
admin_user = "fedoraAdmin"
admin_pass = "fedoraAdmin"

48
tests/islandora_authtokens.test

@ -1,7 +1,15 @@
<?php
/**
* @file
* Test Authentication Tokens.
*/
class IslandoraAuthtokensTestCase extends IslandoraWebTestCase {
/**
* Get test information for display.
*/
public static function getInfo() {
return array(
'name' => 'Islandora Authorization Tokens',
@ -10,45 +18,50 @@ class IslandoraAuthtokensTestCase extends IslandoraWebTestCase {
);
}
/**
* Set up data for the tests.
*/
public function setUp() {
parent::setUp(array('islandora'));
parent::setUp();
}
/**
* Test redeeming invalid tokens.
*/
public function testRedeemInvalidToken() {
module_load_include('inc', 'islandora', 'includes/islandora_authtokens');
// get a token
$token = islandora_get_object_token('test:pid', 'woot', 1);
$this->assertTrue($token, 'Token was generated correctly.', 'Unit Tests');
// redeem a token that doesn't exist with real pid and dsid
// Redeem a token that doesn't exist with real pid and dsid.
$account = islandora_validate_object_token('test:pid', 'woot', 'foo');
$this->assertFalse($account, 'Redeeming an token that doesn\'t exist returns FALSE', 'Unit Tests');
}
/**
* Test redeeming valid tokens.
*/
public function testRedeemValidToken() {
module_load_include('inc', 'islandora', 'includes/islandora_authtokens');
// change the current user
// Change the current user.
global $user;
$user_backup = $user;
$test_account = $this->drupalCreateUser();
$user = $test_account;
$token = islandora_get_object_token('test:pid', 'woot', 1);
// logout again
// Logout again.
$user = $user_backup;
$token_account = islandora_validate_object_token('test:pid', 'woot', $token);
$this->assertEqual($token_account->uid, $test_account->uid, 'UID from token is correct', 'Unit Tests');
$this->assertEqual($token_account->pass, $test_account->pass, 'Pass from token is correct', 'Unit Tests');
$this->assertEqual($token_account->name, $test_account->name, 'Name from token is correct', 'Unit Tests');
}
/**
* Test tokened datastream view without XACML.
*/
public function testTokenedViewDatastreamWithoutXacml() {
// ingest the fixture
// Ingest the fixture.
$fixture_path = drupal_get_path('module', 'islandora') . '/tests/fixtures/bug.jp2';
$tuque = islandora_get_tuque_connection();
$newpid = "{$this->randomName()}:{$this->randomName()}";
@ -67,8 +80,8 @@ class IslandoraAuthtokensTestCase extends IslandoraWebTestCase {
$this->drupalGet("islandora/object/{$newpid}/datastream/JP2/view");
$this->assertResponse(200, 'Page loaded as the authorized user');
// do some voodoo to get a token as the user we are connecting as
// to do this we need to change the user we are logged in as
// Do some voodoo to get a token as the user we are connecting as
// to do this we need to change the user we are logged in as.
module_load_include('inc', 'islandora', 'includes/islandora_authtokens');
global $user;
$backup = $user;
@ -84,11 +97,14 @@ class IslandoraAuthtokensTestCase extends IslandoraWebTestCase {
$this->drupalGet("islandora/object/{$newpid}/datastream/JP2/view", array('query' => array('token' => $token)));
$this->assertResponse(403, 'Token is unable to be reused');
// delete fixture object
// Delete fixture object.
$tuque->repository->purgeObject($newpid);
}
/**
* This will test something someday.
*/
public function testTokenedViewDatastreamWithXacml() {
// we need to add this test.
// We need to add this test.
}
}

213
tests/islandora_hooks.test

@ -0,0 +1,213 @@
<?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 IslandoraHooksTestCase extends IslandoraWebTestCase {
/**
* Gets info to display to describe this test.
*
* @see IslandoraWebTestCase::getInfo()
*/
public static function getInfo() {
return array(
'name' => 'Islandora Hooks',
'description' => 'Ensure that the hooks for ingestion/purge/modification are called at the appropriate times.',
'group' => 'Islandora',
);
}
/**
* Creates an admin user and a connection to a fedora repository.
*
* @see IslandoraWebTestCase::setUp()
*/
public function setUp() {
parent::setUp('islandora_hooks_test', 'devel');
$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:testIngestedObjectHook',
'test:testBlockedIngestedObjectHook',
'test:testModifiedObjectHook',
'test:testPurgedObjectHook',
'test:testIngestedDatastreamHook',
'test:testModifiedDatastreamHook',
'test:testPurgedDatastreamHook',
);
foreach ($objects as $object) {
try {
$object = $this->repository->getObject($object);
$object->label = "Don't Block";
$this->repository->purgeObject($object->id);
}
catch(Exception $e) {
// Meh... Either it didn't exist or the purge failed.
}
}
}
/**
* Test ALL THE HOOKS!.
*/
public function testHooks() {
// Test ingesting with FedoraRepository::ingestObject().
$object = $this->repository->constructObject('test:testIngestedObjectHook');
$_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_INGESTED_HOOK] = FALSE;
$_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_INGESTED_HOOK] = FALSE;
$this->repository->ingestObject($object);
$this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_INGESTED_HOOK], 'Called "hook_islandora_object_alter" when ingesting via FedoraRepository::ingestObject.');
$this->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_INGESTED_HOOK], 'Called ISLANDORA_OBJECT_INGESTED_HOOK when ingesting via FedoraRepository::ingestObject.');
$this->repository->purgeObject($object->id);
// Test blocking the ingest.
$object = $this->repository->constructObject('test:testIngestedObjectHook');
$object->label = 'block';
try {
$_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_INGESTED_HOOK] = FALSE;
$_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_INGESTED_HOOK] = FALSE;
$this->repository->ingestObject($object);
$this->fail('Blocked ingest should throw an Exception.');
$this->repository->purgeObject($object->id);
}
catch(Exception $e) {
$this->pass('Ingest blocked and exception thrown.');
$this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_INGESTED_HOOK], 'Called "hook_islandora_object_alter" when blocking ingesting via FedoraRepository::ingestObject.');
$this->assertFalse($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_INGESTED_HOOK], 'Did not called ISLANDORA_OBJECT_INGESTED_HOOK when blocking ingesting via FedoraRepository::ingestObject.');
}
// Test modifying via set magic functions.
$object = $this->repository->constructObject('test:testModifiedObjectHook');
$this->repository->ingestObject($object);
$_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_MODIFIED_HOOK] = FALSE;
$_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_MODIFIED_HOOK] = FALSE;
$object->label = "New Label!";
$this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_MODIFIED_HOOK], 'Called "hook_islandora_object_alter" when modifying via set magic functions.');
$this->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_MODIFIED_HOOK], 'Called ISLANDORA_OBJECT_MODIFIED_HOOK when modifying via set magic functions.');
// Test blocking the modification.
try {
$_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_MODIFIED_HOOK] = FALSE;
$_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_MODIFIED_HOOK] = FALSE;
$object->label = 'block';
$this->fail('Blocked modify should throw an Exception.');
}
catch(Exception $e) {
$this->pass('Modify blocked and exception thrown.');
$this->assertNotEqual($object->label, 'block', 'Modification did not stick.');
$this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_MODIFIED_HOOK], 'Called "hook_islandora_object_alter" when blocking modifying via set magic functions.');
$this->assertFALSE($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_MODIFIED_HOOK], 'Called ISLANDORA_OBJECT_MODIFIED_HOOK when blocking modifying via set magic functions.');
}
$this->repository->purgeObject($object->id);
// Test purging with FedoraRepository::purgeObject().
$object = $this->repository->constructObject('test:testPurgedObjectHook');
$this->repository->ingestObject($object);
$_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_PURGED_HOOK] = FALSE;
$_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_PURGED_HOOK] = FALSE;
$this->repository->purgeObject($object->id);
$this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_PURGED_HOOK], 'Called "hook_islandora_object_alter" when purging via FedoraRepository::purgeObject.');
$this->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_PURGED_HOOK], 'Called ISLANDORA_OBJECT_PURGED_HOOK when purging via FedoraRepository::purgeObject.');
// Test deleting.
$object = $this->repository->constructObject('test:testPurgedObjectHook');
$this->repository->ingestObject($object);
$_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_PURGED_HOOK] = FALSE;
$_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_PURGED_HOOK] = FALSE;
$object->delete();
$this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_PURGED_HOOK], 'Called "hook_islandora_object_alter" when deleting via FedoraObject::delete.');
$this->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_PURGED_HOOK], 'Called ISLANDORA_OBJECT_PURGED_HOOK when purging via FedoraObject::delete.');
$this->repository->purgeObject($object->id);
// Test alter blocking.
$object = $this->repository->constructObject('test:testPurgedObjectHook');
$this->repository->ingestObject($object);
try {
$_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_PURGED_HOOK] = FALSE;
$_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_PURGED_HOOK] = FALSE;
$object->label = 'block';
$this->repository->purgeObject($object->id);
$this->fail('Blocked modify should throw an Exception.');
}
catch(Exception $e) {
$this->pass('Modify blocked and exception thrown.');
$this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_PURGED_HOOK], 'Called "hook_islandora_object_alter" when blocking purge via FedoraRepository::purgeObject.');
$this->assertFalse($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_PURGED_HOOK], 'Called ISLANDORA_OBJECT_PURGED_HOOK when blocking purge via FedoraRepository::purgeObject.');
}
// Test alter delete.
$_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_PURGED_HOOK] = FALSE;
$_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_PURGED_HOOK] = FALSE;
$object->label = 'delete';
$this->repository->purgeObject($object->id);
$this->assertEqual($object->state, 'D', '"hook_islandora_object_alter" prevented purge and deleted the object.');
$this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_PURGED_HOOK], 'Called "hook_islandora_object_alter" when preventing purge and deleting.');
$this->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_PURGED_HOOK], 'Called ISLANDORA_OBJECT_PURGED_HOOK when preventing purge and deleting.');
$object->label = 'Something other than delete';
$this->repository->purgeObject($object->id);
// Test ingesting with FedoraRepository::ingestObject().
$object = $this->repository->constructObject('test:testIngestedDatastreamHook');
$this->repository->ingestObject($object);
$ds = $object->constructDatastream('TEST');
$_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_INGESTED_HOOK] = FALSE;
$_SESSION['islandora_hooks']['alter'][ISLANDORA_DATASTREAM_INGESTED_HOOK] = FALSE;
$object->ingestDatastream($ds);
$this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_DATASTREAM_INGESTED_HOOK], 'Called "hook_islandora_datastream_alter" when ingesting via FedoraObject::ingestDatastream.');
$this->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_INGESTED_HOOK], 'Called ISLANDORA_DATASTREAM_INGESTED_HOOK when ingesting via FedoraObject::ingestDatastream.');
$this->repository->purgeObject($object->id);
// Test modifying a datastream.
$object = $this->repository->constructObject('test:testModifiedDatastreamHook');
$this->repository->ingestObject($object);
$ds = $object->constructDatastream('TEST');
$object->ingestDatastream($ds);
$_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_MODIFIED_HOOK] = FALSE;
$_SESSION['islandora_hooks']['alter'][ISLANDORA_DATASTREAM_MODIFIED_HOOK] = FALSE;
$ds->label = "New Label!";
$this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_DATASTREAM_MODIFIED_HOOK], 'Called "hook_islandora_datastream_alter" when modifying via set magic functions.');
$this->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_MODIFIED_HOOK], 'Called ISLANDORA_DATASTREAM_MODIFIED_HOOK when modifying via set magic functions.');
// Test blocking modifying.
try {
$_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_MODIFIED_HOOK] = FALSE;
$_SESSION['islandora_hooks']['alter'][ISLANDORA_DATASTREAM_MODIFIED_HOOK] = FALSE;
$ds->label = 'block';
$this->fail('Blocked modify should throw an Exception.');
}
catch(Exception $e) {
$this->pass('Modify blocked and exception thrown.');
$this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_DATASTREAM_MODIFIED_HOOK], 'Called "hook_islandora_datastream_alter" when blocking modifying via set magic functions.');
$this->assertFALSE($_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_MODIFIED_HOOK], 'Called ISLANDORA_DATASTREAM_MODIFIED_HOOK when blocking modifying via set magic functions.');
}
$this->repository->purgeObject($object->id);
// Test purging with FedoraRepository::purgeObject().
$object = $this->repository->constructObject('test:testPurgedDatastreamHook');
$this->repository->ingestObject($object);
$ds = $object->constructDatastream('TEST');
$object->ingestDatastream($ds);
$_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_PURGED_HOOK] = FALSE;
$_SESSION['islandora_hooks']['alter'][ISLANDORA_DATASTREAM_PURGED_HOOK] = FALSE;
$object->purgeDatastream($ds->id);
$this->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_DATASTREAM_PURGED_HOOK], 'Called "hook_islandora_datastream_alter" when purging via FedoraObject::purgeDatastream.');
$this->assert($_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_PURGED_HOOK], 'Called ISLANDORA_DATASTREAM_PURGED_HOOK when purging via FedoraObject::purgeDatastream.');
$this->repository->purgeObject($object->id);
}
}

7
tests/islandora_hooks_test.info

@ -0,0 +1,7 @@
name = Islandora Hook testing
description = Tests Hooks. Do not enable.
core = 7.x
package = Testing
hidden = TRUE
dependencies[] = islandora
files[] = islandora_hooks_test.module

152
tests/islandora_hooks_test.module

@ -0,0 +1,152 @@
<?php
/**
* @file
* Implements hooks that get tested by islandora_hooks.test
*/
/**
* Implements hook_islandora_object_alter().
*/
function islandora_hooks_test_islandora_object_alter(AbstractFedoraObject $object, array &$context) {
switch ($context['action']) {
case 'ingest':
if ($object->id == 'test:testIngestedObjectHook') {
$_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_INGESTED_HOOK] = TRUE;
if ($object->label == 'block') {
$context['block'] = TRUE;
}
}
break;
case 'modify':
if ($object->id == 'test:testModifiedObjectHook') {
$_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_MODIFIED_HOOK] = TRUE;
if (isset($context['params']['label']) && $context['params']['label'] == 'block') {
$context['block'] = TRUE;
}
}
elseif ($object->id == 'test:testPurgedObjectHook') {
$_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_PURGED_HOOK] = TRUE;
if (isset($context['params']['label']) && $context['params']['label'] == 'block') {
$context['block'] = TRUE;
}
elseif (isset($context['params']['label']) && $context['params']['label'] == 'delete') {
$context['delete'] = TRUE;
}
}
break;
case 'purge':
if ($object->id == 'test:testPurgedObjectHook') {
$_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_PURGED_HOOK] = TRUE;
if ($object->label == 'block') {
$context['block'] = TRUE;
}
elseif ($object->label == 'delete') {
$context['delete'] = TRUE;
}
}
break;
}
}
/**
* Implements hook_islandora_object_alter().
*/
function islandora_hooks_test_islandora_datastream_alter(AbstractFedoraObject $object, AbstractFedoraDatastream $datastream, array &$context) {
switch ($context['action']) {
case 'ingest':
if ($object->id == 'test:testIngestedDatastreamHook') {
$_SESSION['islandora_hooks']['alter'][ISLANDORA_DATASTREAM_INGESTED_HOOK] = TRUE;
if ($datastream->label == 'block') {
$context['block'] = TRUE;
}
}
break;
case 'modify':
if ($object->id == 'test:testModifiedDatastreamHook') {
$_SESSION['islandora_hooks']['alter'][ISLANDORA_DATASTREAM_MODIFIED_HOOK] = TRUE;
if (isset($context['params']['dsLabel']) && $context['params']['dsLabel'] == 'block') {
$context['block'] = TRUE;
}
}
elseif ($object->id == 'test:testPurgedDatastreamHook') {
$_SESSION['islandora_hooks']['alter'][ISLANDORA_DATASTREAM_PURGED_HOOK] = TRUE;
if (isset($context['params']['dsLabel']) && $context['params']['dsLabel'] == 'block') {
$context['block'] = TRUE;
}
elseif (isset($context['params']['dsLabel']) && $context['params']['dsLabel'] == 'delete') {
$context['delete'] = TRUE;
}
}
break;
case 'purge':
if ($object->id == 'test:testPurgedDatastreamHook') {
$_SESSION['islandora_hooks']['alter'][ISLANDORA_DATASTREAM_PURGED_HOOK] = TRUE;
if ($datastream->label == 'block') {
$context['block'] = TRUE;
}
elseif ($datastream->label == 'delete') {
$context['delete'] = TRUE;
}
}
break;
}
}
/**
* Implements hook_islandora_object_ingested().
*/
function islandora_hooks_test_islandora_object_ingested(FedoraObject $object) {
if ($object->id == 'test:testIngestedObjectHook') {
$_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_INGESTED_HOOK] = TRUE;
}
}
/**
* Implements hook_islandora_object_modified().
*/
function islandora_hooks_test_islandora_object_modified(FedoraObject $object) {
if ($object->id == 'test:testModifiedObjectHook') {
$_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_MODIFIED_HOOK] = TRUE;
}
}
/**
* Implements hook_islandora_object_purged().
*/
function islandora_hooks_test_islandora_object_purged($pid) {
if ($pid == 'test:testPurgedObjectHook') {
$_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_PURGED_HOOK] = TRUE;
}
}
/**
* Implements hook_islandora_datastream_ingested().
*/
function islandora_hooks_test_islandora_datastream_ingested(FedoraObject $object, FedoraDatastream $datastream) {
if ($object->id == 'test:testIngestedDatastreamHook' && $datastream->id == "TEST") {
$_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_INGESTED_HOOK] = TRUE;
}
}
/**
* Implements hook_islandora_datastream_modified().
*/
function islandora_hooks_test_islandora_datastream_modified(FedoraObject $object, FedoraDatastream $datastream) {
if ($object->id == 'test:testModifiedDatastreamHook' && $datastream->id == "TEST") {
$_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_MODIFIED_HOOK] = TRUE;
}
}
/**
* Implements hook_islandora_datastream_purged().
*/
function islandora_hooks_test_islandora_datastream_purged(FedoraObject $object, $dsid) {
if ($object->id == 'test:testPurgedDatastreamHook' && $dsid == "TEST") {
$_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_PURGED_HOOK] = TRUE;
}
}

108
tests/islandora_web_test_case.inc

@ -1,36 +1,124 @@
<?php
/**
* @file
* Defines the class IslandoraWebTestCase, which allows tests to access Fedora.
*/
class IslandoraWebTestCase extends DrupalWebTestCase {
/**
* Sets up the Drupal filter to access this test Drupal instances database.
*
* @see DrupalWebTestCase::setUp()
*/
public function setUp() {
$args = func_get_args();
call_user_func_array(array('parent', 'setUp'), $args);
$args = (isset($args[0]) && is_array($args[0])) ? $args[0] : $args;
// Always enable islandora.
$args[] = 'islandora';
parent::setUp($args);
$this->configuration = $this->getTestConfiguration();
if ($this->configuration['use_drupal_filter']) {
$this->backUpDrupalFilter();
$this->setUpDrupalFilter();
}
$this->createAdminUser();
}
$islandora_path = drupal_get_path('module', 'islandora');
$this->config_info = parse_ini_file("$islandora_path/tests/test_config.ini");
$connection_info = Database::getConnectionInfo('default');
/**
* Parses and returns the settings from the test configuration file.
*
* If no install specific test_config.ini file is found, it will use the
* assumed default configs found in default.test_config.ini.
*
* @return array
* The test configuration.
*
* @see parse_ini_file()
*/
protected function getTestConfiguration() {
$path = drupal_get_path('module', 'islandora');
if (file_exists("$path/tests/test_config.ini")) {
$this->pass('Using custom test configuration.');
return parse_ini_file("$path/tests/test_config.ini");
}
elseif (file_exists("$path/tests/default.test_config.ini")) {
$this->pass('Using default test configuration.');
return parse_ini_file("$path/tests/default.test_config.ini");
}
throw new Exception('Required default.test_config.ini/test_config.ini file not found');
}
$this->original_drupal_fiter = file_get_contents($this->config_info['filter_drupal_file']);
/**
* Stores the content of the Drupal Filter for later restoration.
*/
protected function backUpDrupalFilter() {
if (file_exists($this->configuration['filter_drupal_file'])) {
$this->originalDrupalFilterContent = file_get_contents($this->configuration['filter_drupal_file']);
}
else {
throw new Exception('Failed to find the required Drupal Filter configuration file.');
}
}
/**
* Sets up a drupal filter that can read for the tests users table.
*/
protected function setUpDrupalFilter() {
$connection_info = Database::getConnectionInfo('default');
$drupal_filter_dom = new DomDocument();
$drupal_filter_dom->loadXML($this->original_drupal_fiter);
$drupal_filter_dom->loadXML($this->originalDrupalFilterContent);
$drupal_filter_xpath = new DOMXPath($drupal_filter_dom);
$server = $connection_info['default']['host'];
$dbname = $connection_info['default']['database'];
$user = $connection_info['default']['username'];
$password = $connection_info['default']['password'];
$port = $connection_info['default']['port'] ? $connection_info['default']['port'] : '3306';
$prefix = $connection_info['default']['prefix']['default'];
$results = $drupal_filter_xpath->query("/FilterDrupal_Connection/connection[@server='$server' and @dbname='$dbname' and @user='$user' and @password='$password' and @port='$port']/sql");
$results->item(0)->nodeValue = "SELECT DISTINCT u.uid AS userid, u.name AS Name, u.pass AS Pass, r.name AS Role FROM ({$prefix}users u LEFT JOIN {$prefix}users_roles ON u.uid={$prefix}users_roles.uid) LEFT JOIN {$prefix}role r ON r.rid={$prefix}users_roles.rid WHERE u.name=? AND u.pass=?;";
file_put_contents($this->configuration['drupal_filter_file'], $drupal_filter_dom->saveXML());
}
file_put_contents($this->config_info['filter_drupal_file'], $drupal_filter_dom->saveXML());
/**
* 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'];
$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;
}
/**
* Stores the content of the Drupal Filter for later restoration.
*/
protected function restoreDrupalFilter() {
$file = $this->configuration['filter_drupal_file'];
if (isset($this->originalDrupalFilterContent)) {
file_put_contents($file, $this->originalDrupalFilterContent);
}
elseif (file_exists($file)) {
// Remove if there was never an original.
drupal_unlink($file);
}
}
/**
* Restores the original Drupal filter, frees any allocated resources.
*
* @see DrupalWebTestCase::tearDown()
*/
public function tearDown() {
file_put_contents($this->config_info['filter_drupal_file'], $this->original_drupal_fiter);
if ($this->configuration['use_drupal_filter']) {
$this->restoreDrupalFilter();
}
unset($this->admin);
unset($this->configuration);
parent::tearDown();
}
}

4
tests/test_config.ini

@ -1,4 +1,6 @@
[fedora]
filter_drupal_file = "/usr/local/fedora/server/config/filter-drupal.xml"
fedora_url = "http://localhost:8080/fedora"
use_drupal_filter = FALSE
drupal_filter_file = "/home/nbanks/projects/default/repository/server/config/filter-drupal.xml"
admin_user = "fedoraAdmin"
admin_pass = "fedoraAdmin"

Loading…
Cancel
Save