Browse Source

fixed conflicts

pull/253/head
phil 12 years ago
parent
commit
604bf37404
  1. 3
      .gitignore
  2. 78
      includes/IslandoraTuqueWrapper.inc
  3. 0
      includes/dublin_core.inc
  4. 31
      includes/islandora_object.entity_controller.inc
  5. 1
      includes/islandora_tuque.inc
  6. 360
      includes/islandora_tuque_wrapper.inc
  7. 0
      includes/mime_detect.inc
  8. 9
      includes/solution_packs.inc
  9. 125
      includes/utilities.inc
  10. 311
      islandora.api.php
  11. 10
      islandora.info
  12. 249
      islandora.module
  13. 115
      islandora.rules.inc
  14. 25
      policies/permit-getDatastream-unrestricted.xml
  15. 25
      policies/permit-getDatastreamHistory-unrestricted.xml
  16. 3
      tests/README
  17. 6
      tests/default.test_config.ini
  18. 48
      tests/islandora_authtokens.test
  19. 213
      tests/islandora_hooks.test
  20. 7
      tests/islandora_hooks_test.info
  21. 152
      tests/islandora_hooks_test.module
  22. 108
      tests/islandora_web_test_case.inc
  23. 4
      tests/test_config.ini
  24. 3
      theme/islandora-object-edit.tpl.php
  25. 4
      theme/islandora-object.tpl.php

3
.gitignore vendored

@ -20,3 +20,6 @@ tests/islandora_web_test_case.inc~
theme/islandora-object.tpl.php~ theme/islandora-object.tpl.php~
theme/islandora.theme.inc~ theme/islandora.theme.inc~
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 {}

0
includes/DublinCore.inc → includes/dublin_core.inc

31
includes/islandora_object.entity_controller.inc

@ -0,0 +1,31 @@
<?php
/**
* Very basic entity controller...
*/
class IslandoraObjectEntityController implements DrupalEntityControllerInterface {
public function __construct($entityType) {
// No-op...
}
public function load($ids = array(), $conditions = array()) {
if (!empty($conditions)) {
throw new Exception('Conditions not implemented.');
}
$loaded = array();
foreach ($ids as $id) {
$load = islandora_object_load($id);
if ($load) {
$loaded[] = $load;
}
}
return $loaded;
}
public function resetCache(array $ids = NULL) {
// no-op
}
}

1
includes/IslandoraTuque.inc → includes/islandora_tuque.inc

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

0
includes/MimeDetect.inc → includes/mime_detect.inc

9
includes/solution_packs.inc

@ -622,11 +622,14 @@ function theme_islandora_viewers_table($variables) {
* Array or string with data the module needs in order to render a full viewer * Array or string with data the module needs in order to render a full viewer
* @param string $variable_id * @param string $variable_id
* The id of the Drupal variable the viewer settings are saved in * The id of the Drupal variable the viewer settings are saved in
* @param FedoraObject $fedora_object
* The tuque object representing the fedora object being displayed
* @return * @return
* The callback to the viewer module. Returns a rendered viewer. Returns FALSE * The callback to the viewer module. Returns a rendered viewer. Returns FALSE
* if no viewer is set. * if no viewer is set.
*/ */
function islandora_get_viewer($params = NULL, $variable_id = NULL) {
function islandora_get_viewer($params = NULL, $variable_id = NULL, $fedora_object = NULL) {
// get viewer from settings // get viewer from settings
$settings = variable_get($variable_id, array()); $settings = variable_get($variable_id, array());
// make sure a viewer is set // make sure a viewer is set
@ -636,10 +639,10 @@ function islandora_get_viewer($params = NULL, $variable_id = NULL) {
if ($viewer_id AND $params !== NULL) { if ($viewer_id AND $params !== NULL) {
$callback = islandora_get_viewer_callback($viewer_id); $callback = islandora_get_viewer_callback($viewer_id);
// call callback function // call callback function
return $callback($params); return $callback($params, $fedora_object);
} }
} }
return NULL; return FALSE;
} }
/** /**

125
includes/utilities.inc

@ -112,29 +112,65 @@ 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 * @see islandora_build_hook_list()
* module_invoke_all(). * To see how the hook list is generated.
* *
* @param string $hook * @param string $hook
* A hook to call. * A hook to call.
* @param array $pids * @param array $refinements
* An array of PIDs (probably content models). * 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 * @return array
* An array with each PID escaped and concatenated with the base hook name, * The merged results from all the hooks.
* in addition to the base hook name at the end.
*/ */
function islandora_build_hook_list($hook, $pids = array()) { function islandora_invoke_hook_list($hook, array $refinements, array $args) {
$hooks = array(); $return = array();
foreach (islandora_build_hook_list($hook, $refinements) as $hook) {
$pids = array_unique($pids); array_unshift($args, $hook);
foreach ($pids as $pid) { $result = call_user_func_array('module_invoke_all', $args);
$hooks[] = islandora_escape_pid_for_function($pid) . '_' . $hook; $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; return $hooks;
} }
@ -440,3 +476,64 @@ function islandora_display_repository_inaccessible_message() {
array('!link' => $link)); array('!link' => $link));
drupal_set_message($message, 'error', FALSE); drupal_set_message($message, 'error', FALSE);
} }
/**
* Create a message stating if the given executable is available.
*
* If the both the version and required version are given then only if the
* version is equal to or greater than the required version the executable
* will be considered correct.
*
* @param string $path
* The absolute path to an executable to check for availability.
* @param string $version
* The version of exectuable.
* @param string $required_version
* The required version of exectuable.
*
* @return string
* A message in html detailing if the given executable is accessible.
*/
function islandora_executable_available_message($path, $version = NULL, $required_version = NULL) {
$available = is_executable($path);
if ($available) {
$image = theme_image(array('path' => 'misc/watchdog-ok.png', 'attributes' => array()));
$message = t('Executable found at @path', array('@path' => $path));
if ($version) {
$message .= t('<br/>Version: @version', array('@version' => $version));
}
if ($required_version) {
$message .= t('<br/>Required Version: @version', array('@version' => $required_version));
if (version_compare($version, $required_version) < 0) {
$image = theme_image(array('path' => 'misc/watchdog-error.png', 'attributes' => array()));
}
}
}
else {
$image = theme_image(array('path' => 'misc/watchdog-error.png', 'attributes' => array()));
$message = t('Unable to locate executable at @path', array('@path' => $path));
}
return $image . $message;
}
/**
* Create a message stating if the given directory exists.
*
* @param string $path
* The absolute path to an executable to check for availability.
*
* @return string
* A message in HTML detailing if the given directory is exists.
*/
function islandora_directory_exists_message($path) {
$available = is_dir($path);
if ($available) {
$image = theme_image(array('path' => 'misc/watchdog-ok.png', 'attributes' => array()));
$message = t('Directory found at @path', array('@path' => $path));
}
else {
$image = theme_image(array('path' => 'misc/watchdog-error.png', 'attributes' => array()));
$message = t('Unable to locate directory at @path', array('@path' => $path));
}
return $image . $message;
}

311
islandora.api.php

@ -2,24 +2,26 @@
/** /**
* @file * @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. * Generate a repository objects view.
* *
* @param FedoraObject $fedora_object * @param FedoraObject $object
* A Tuque FedoraObject being operated on. * The object to display
* @param object $user * @param object $user
* The user accessing the object. * The user accessing the object.
* @param string $page_number * @param string $page_number
* The page in the content. * 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 * @return array
* An array whose values are markup. * 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. * 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 * Content models PIDs have colons and hyphens changed to underscores, to
* create the hook name. * create the hook name.
* *
* @param type $fedora_object * @param FedoraObject $object
* A Tuque FedoraObject * A Tuque FedoraObject
* *
* @return array * @return array
* An array whose values are markup. * 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. * Alter display output after it has been generated.
* *
* @param FedoraObject $fedora_object * @param FedoraObject $object
* A Tuque FedoraObject being operated on. * A Tuque FedoraObject being operated on.
* @param array $arr * @param array $rendered
* An arr of rendered views. * 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. * Generate an object's management display.
* *
* @param type $fedora_object * @param FedoraObject $object
* A Tuque FedoraObject * A Tuque FedoraObject
* *
* @return array * @return array
* An array whose values are markup. * 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. * Generate an object's management display for the given content model.
@ -63,148 +68,282 @@ function hook_islandora_edit_object($fedora_object) {}
* Content models PIDs have colons and hyphens changed to underscores, to * Content models PIDs have colons and hyphens changed to underscores, to
* create the hook name. * create the hook name.
* *
* @param type $fedora_object * @param FedoraObject $object
* A Tuque FedoraObject * A Tuque FedoraObject
* *
* @return array * @return array
* An array whose values are markup. * 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. * Allow management display output to be altered.
* *
* @param type $fedora_object * @param FedoraObject $object
* A Tuque FedoraObject * A Tuque FedoraObject
* @param type $arr * @param array $rendered
* an arr of rendered views * 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
* An associative array containing:
* - action: A string either 'ingest', 'purge', 'modify'.
* - block: Either TRUE or FALSE, if TRUE the action won't take place.
* Defaults to FALSE.
* - purge: Either TRUE or FALSE, only present when the action is 'purge'.
* If 'delete' or 'block' is set to TRUE, they will take precedence.
* Defaults to TRUE.
* - delete: Either TRUE or FALSE, only present when the action is 'purge'.
* If TRUE it will cause the object's state to be set to 'D' instead.
* If 'block' is set to TRUE, it will take precedence.
* Defaults to FALSE,
* - params: An associative array, only present when the action is 'modify'.
* The key value pairs repersent what values will be changed. The params
* will match the same params as passed to FedoraApiM::modifyObject().
*
* @see FedoraApiM::modifyObject()
*/
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 * @see hook_islandora_object_alter()
* A Tuque FedoraObject. */
function hook_CMODEL_PID_islandora_object_alter(AbstractFedoraObject $object, array &$context) {
}
/**
* 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
* An associative array containing:
* - action: A string either 'ingest', 'purge', 'modify'.
* - block: Either TRUE or FALSE, if TRUE the action won't take place.
* Defaults to FALSE.
* - purge: Either TRUE or FALSE, only present when the action is 'purge'.
* If 'delete' or 'block' is set to TRUE, they will take precedence.
* Defaults to TRUE.
* - delete: Either TRUE or FALSE, only present when the action is 'purge'.
* If TRUE it will cause the object's state to be set to 'D' instead.
* If 'block' is set to TRUE, it will take precedence.
* Defaults to FALSE,
* - params: An associative array, only present when the action is 'modify'.
* The key value pairs repersent what values will be changed. The params
* will match the same params as passed to FedoraApiM::modifyDatastream().
*
* @see FedoraApiM::modifyDatastream()
*/ */
function hook_islandora_ingest_post_ingest($fedora_object) {} function hook_islandora_datastream_alter(AbstractFedoraObject $object, AbstractFedoraDatastream $datastream, 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.
*
* @see hook_islandora_datastream_alter()
*/ */
function hook_CMODEL_PID_islandora_ingest_post_ingest($fedora_object) {} 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 * This hook is called after an object has been successfully ingested via a
* hook_islandora_hook_info(). * FedoraRepository object.
* *
* @param FedoraObject $fedora_object * @note
* A Tuque FedoraObject. * 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 * @param FedoraObject $object
* An associative array with 'deleted' mapped to TRUE--indicating that the * The object that was ingested.
* 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.
*/ */
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) { function hook_islandora_object_modified(FedoraObject $object) {
$reg = array(
array(
'name' => t('Ingest route name'),
'url' => 'ingest_route/url',
'weight' => 0,
),
);
return $reg;
} }
/** /**
* Register a datastream edit route/form. * Notify modules that the given object was ingested.
* *
* @param $islandora_object * @see hook_islandora_object_modified()
* @param $ds_id
*/ */
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 * This hook is called after an object has been successfully purged, or
* A Tuque FedoraObject * 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 * @see hook_islandora_object_purged()
* A Tuque FedoraObject */
function hook_CMODEL_PID_islandora_object_purged($pid) {
}
/**
* 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.
*
* @param FedoraObject $object
* The object the datastream belongs to.
* @param FedoraDatastream $datastream
* The ingested datastream.
*/
function hook_islandora_datastream_ingested(FedoraObject $object, FedoraDatastream $datastream) {
}
/**
* Notify modules that the given datastream was ingested.
*
* @see hook_islandora_object_ingested()
*/ */
function hook_islandora_ingest_pre_ingest($islandora_object) {} function hook_CMODEL_PID_DSID_islandora_datastream_ingested(FedoraObject $object, FedoraDatastream $datastream) {
}
/** /**
* Allow modification of objects of a certain content model before ingesting. * Notify modules that the given datastream was modified.
* *
* @see hook_islandora_ingest_pre_ingest() * 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_CMODEL_PID_islandora_ingest_pre_ingest($islandora_object) {} function hook_islandora_datastream_modified(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 * @see hook_islandora_datastream_modified()
* A Tuque FedoraDatastream object.
*/ */
function hook_islandora_pre_purge_datastream($datastream) {} function hook_CMODEL_PID_islandora_datastream_modified(FedoraObject $object, FedoraDatastream $datastream) {
}
/** /**
* Allow modules to react after a datastream is purged. * 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 object $object * @param FedoraObject $object
* A Tuque FedoraObject. * The object the datastream belonged to.
* @param string $dsid * @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_islandora_post_purge_datastream($object, $dsid) {} function hook_CMODEL_PID_islandora_datastream_purged(FedoraObject $object, $dsid) {
}
/** /**
* Allow modules to react post-purge. * Register a datastream edit route/form.
* *
* @param string $object_id * @param FedoraObject $object
* The former object's PID. * The object to check.
* @param array $content_models * @param string $dsid
* An array containing the models to which the former object. * todo
*/ */
function hook_islandora_post_purge_object($object_id, $content_models) {} function hook_islandora_edit_datastream_registry($object, $dsid) {
}
/** /**
* Registry hook for required objects. * Registry hook for required objects.
* *
* Solution packs can include data to create certain objects that describe or * Solution packs can include data to create certain objects that describe or
* help the objects it would create. This includes collection objects and content * help the objects it would create. This includes collection objects and
* models. * content models.
* *
* @see islandora_solution_packs_admin() * @see islandora_solution_packs_admin()
* @see islandora_install_solution_pack() * @see islandora_install_solution_pack()
* @example islandora_islandora_required_objects() * @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. * Registry hook for viewers that can be implemented by solution packs.
@ -215,13 +354,14 @@ function hook_islandora_required_objects() {}
* @see islandora_get_viewers() * @see islandora_get_viewers()
* @see islandora_get_viewer_callback() * @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. * 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. * Define steps used in the islandora_ingest_form() ingest process.
@ -265,4 +405,5 @@ function hook_islandora_ingest_steps(array $form_state) {
* *
* @see hook_islandora_ingest_steps() * @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) {
}

10
islandora.info

@ -6,11 +6,13 @@ core = 7.x
configure = admin/islandora/configure configure = admin/islandora/configure
stylesheets[all][] = css/islandora.base.css stylesheets[all][] = css/islandora.base.css
stylesheets[all][] = css/islandora.theme.css stylesheets[all][] = css/islandora.theme.css
files[] = includes/MimeDetect.inc files[] = includes/mime_detect.inc
files[] = includes/DublinCore.inc files[] = includes/dublin_core.inc
files[] = includes/IslandoraTuque.inc files[] = includes/islandora_tuque.inc
files[] = includes/IslandoraTuqueWrapper.inc files[] = includes/islandora_tuque_wrapper.inc
files[] = includes/islandora_object.entity_controller.inc
files[] = tests/islandora_web_test_case.inc files[] = tests/islandora_web_test_case.inc
files[] = tests/islandora_authtokens.test files[] = tests/islandora_authtokens.test
files[] = tests/islandora_manage_permissions.test files[] = tests/islandora_manage_permissions.test
files[] = tests/islandora_hooks.test
php = 5.3 php = 5.3

249
islandora.module

@ -41,10 +41,15 @@ define('ISLANDORA_PRE_INGEST_HOOK', 'islandora_ingest_pre_ingest');
define('ISLANDORA_POST_INGEST_HOOK', 'islandora_ingest_post_ingest'); define('ISLANDORA_POST_INGEST_HOOK', 'islandora_ingest_post_ingest');
define('ISLANDORA_PRE_PURGE_OBJECT_HOOK', 'islandora_pre_purge_object'); define('ISLANDORA_PRE_PURGE_OBJECT_HOOK', 'islandora_pre_purge_object');
define('ISLANDORA_POST_PURGE_OBJECT_HOOK', 'islandora_post_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_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(). * Implements hook_menu().
@ -485,7 +490,10 @@ function islandora_default_islandora_manage_overview_object(FedoraObject $object
* The HTML repersentation of the manage object page. * The HTML repersentation of the manage object page.
*/ */
function islandora_edit_object(FedoraObject $object) { function islandora_edit_object(FedoraObject $object) {
module_load_include('inc', 'islandora', 'includes/breadcrumb');
module_load_include('inc', 'islandora', 'includes/utilities'); module_load_include('inc', 'islandora', 'includes/utilities');
drupal_set_title($object->label);
drupal_set_breadcrumb(islandora_get_breadcrumbs($object));
$output = array(); $output = array();
foreach (islandora_build_hook_list(ISLANDORA_EDIT_HOOK, $object->models) as $hook) { foreach (islandora_build_hook_list(ISLANDORA_EDIT_HOOK, $object->models) as $hook) {
$temp = module_invoke_all($hook, $object); $temp = module_invoke_all($hook, $object);
@ -546,6 +554,7 @@ function islandora_view_default_object() {
function islandora_view_object(FedoraObject $object) { function islandora_view_object(FedoraObject $object) {
module_load_include('inc', 'islandora', 'includes/breadcrumb'); module_load_include('inc', 'islandora', 'includes/breadcrumb');
module_load_include('inc', 'islandora', 'includes/utilities'); module_load_include('inc', 'islandora', 'includes/utilities');
drupal_set_title($object->label);
drupal_set_breadcrumb(islandora_get_breadcrumbs($object)); drupal_set_breadcrumb(islandora_get_breadcrumbs($object));
// Optional pager parameters // Optional pager parameters
$page_number = (empty($_GET['page'])) ? '1' : $_GET['page']; $page_number = (empty($_GET['page'])) ? '1' : $_GET['page'];
@ -596,7 +605,6 @@ function islandora_default_islandora_view_object($object) {
* A IslandoraTuque instance * A IslandoraTuque instance
*/ */
function islandora_get_tuque_connection($user = NULL, $url = NULL) { function islandora_get_tuque_connection($user = NULL, $url = NULL) {
module_load_include('inc', 'islandora', 'includes/IslandoraTuque');
$tuque = &drupal_static(__FUNCTION__); $tuque = &drupal_static(__FUNCTION__);
if (!$tuque) { if (!$tuque) {
if (IslandoraTuque::exists()) { if (IslandoraTuque::exists()) {
@ -633,9 +641,7 @@ function islandora_object_load($object_id) {
$tuque = islandora_get_tuque_connection(); $tuque = islandora_get_tuque_connection();
if ($tuque) { if ($tuque) {
try { try {
$object = $tuque->repository->getObject(urldecode($object_id)); return $tuque->repository->getObject(urldecode($object_id));
drupal_alter('islandora_object', $object);
return $object;
} catch (Exception $e) { } catch (Exception $e) {
if ($e->getCode() == '404') { if ($e->getCode() == '404') {
return FALSE; return FALSE;
@ -799,124 +805,33 @@ function islandora_islandora_undeletable_datastreams(array $models) {
} }
/** /**
* Ingest the given object into Fedora calling its pre/post hooks as well. * Ingest the given object.
*
* @todo will be cleaned up in the future
* *
* @param NewFedoraObject $object * @param NewFedoraObject $object
* An ingestable FedoraObject. * An ingestable FedoraObject.
* *
* @return FedoraObject * @return FedoraObject
* The ingested FedoraObject, after running the pre/post ingest hooks. * The ingested FedoraObject.
* Returns FALSE if the ingest failed.
*/ */
function islandora_add_object(NewFedoraObject &$object) { function islandora_add_object(NewFedoraObject &$object) {
islandora_pre_add_object($object); return $object->repository->ingestObject($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. * Delete's or purges the given object.
*
* @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);
}
}
/**
* Deletes the given object into Fedora calling its pre/post hooks as well.
* *
* @param FedoraObject $object * @param FedoraObject $object
* An object to delete. * An object to delete.
* *
* @return FedoraObject * @return bool
* The ingested FedoraObject, after running the pre/post ingest hooks. * The ingested FedoraObject, after running the pre/post ingest hooks.
*/ */
function islandora_delete_object(FedoraObject &$object) { function islandora_delete_object(FedoraObject &$object) {
$object_id = $object->id; return $object->repository->purgeObject($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;
}
/**
* 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 * @throws Exception
* Which types are undefined, but more than likely because of the hooks * Which types are undefined, but more than likely because of the hooks
@ -925,87 +840,81 @@ function islandora_post_delete_object($object_id, array $models) {
* @param FedoraDatastream $datastream * @param FedoraDatastream $datastream
* The datastream to delete. * The datastream to delete.
* *
* @return boolean * @return bool
* TRUE is returned if the datastream was Deleted/Purged, FALSE if it was * TRUE if successful, FALSE otherwise.
* blocked.
*/ */
function islandora_delete_datastream(FedoraDatastream &$datastream) { function islandora_delete_datastream(FedoraDatastream &$datastream) {
$datastream_id = $datastream->id;
$object = $datastream->parent; $object = $datastream->parent;
$action = islandora_pre_delete_datastream($datastream); return $object->purgeDatastream($datastream->id);
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 * Implements hook_cron()
* 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 * Removes expired authentication tokens.
* The action to take when deleting the given datastream, either 'purge',
* 'delete', or 'block'.
*/ */
function islandora_pre_delete_datastream(FedoraDatastream $datastream) { function islandora_cron() {
module_load_include('inc', 'islandora', 'includes/utilities'); module_load_include('inc', 'islandora', 'includes/islandora_authtokens');
$results = array(); islandora_remove_expired_tokens();
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. * Implements hook_entity_info().
*
* @todo Should differentiate between purging/deleting.
* *
* @param FedoraObject $object * Some boiler-plate for Tokens (the module, not our authentication work-
* The parent object of the deleted datastream. * around).
* @param string $datastream_id
* The datastream id of the deleted datastream.
*/ */
function islandora_post_delete_datastream(FedoraObject $object, $datastream_id) { function islandora_entity_info() {
module_load_include('inc', 'islandora', 'includes/utilities'); $entities = array();
foreach (islandora_build_hook_list(ISLANDORA_POST_PURGE_DATASTREAM_HOOK, $object->models) as $hook) {
module_invoke_all($hook, $object, $datastream_id); $entities['islandora_object'] = array(
} 'label' => t('Islandora Object'),
'controller class' => 'IslandoraObjectEntityController',
'fieldable' => FALSE,
'entity keys' => array(
'id' => 'id',
'label' => 'label',
),
);
return $entities;
} }
/** /**
* Implements hook_cron() * Implements hook_entity_property_info().
* *
* Removes expired authentication tokens. * Details the tokens which will be available on the given object.
*/ */
function islandora_cron() { function islandora_entity_property_info() {
module_load_include('inc', 'islandora', 'includes/islandora_authtokens'); $info = array();
islandora_remove_expired_tokens();
$p = &$info['islandora_object']['properties'];
$p['id'] = array(
'type' => 'text',
'label' => t('ID'),
'description' => t('The identifier of the object.'),
);
$p['label'] = array(
'type' => 'text',
'label' => t('Object Label'),
'description' => t('The label of the object.'),
);
$p['owner'] = array(
'type' => 'text',
'label' => t('Object Owner'),
'description' => t('The name of the owner of the object.'),
);
$p['state'] = array(
'type' => 'text',
'label' => t('Object State'),
'description' => t('An initial representing the state of the object.'),
);
$p['models'] = array(
'type' => 'list<text>',
'label' => t('Content Models'),
'description' => t('The list of content models which the object has.'),
);
return $info;
} }

115
islandora.rules.inc

@ -0,0 +1,115 @@
<?php
/**
* Helper function to get reused "parameter" array.
*/
function islandora_rules_relationship_parameter_array() {
$to_return = array(
'subject' => array(
'type' => 'islandora_object',
'label' => t('Subject'),
'description' => t('An object of which we should check the ' .
'relationships (The "subject" of the relationship).'),
),
'pred_uri' => array(
'type' => 'text',
'label' => t('Predicate URI'),
'description' => t('The URI namespace to which the predicate belongs.'),
),
'pred' => array(
'type' => 'text',
'label' => t('Predicate'),
'description' => t('The predicate of the relationship.'),
),
'object' => array(
'type' => 'text',
'label' => t('Object'),
'description' => t('The object of the relationship.'),
'allow null' => TRUE,
'default value' => NULL,
),
'type' => array(
'type' => 'integer',
'label' => t('Object type in the relationship'),
'description' => t('0=URI, 1=plain literal'),
'default value' => 0,
),
);
return $to_return;
}
/**
* Implements hook_rules_condition_info().
*/
function islandora_rules_condition_info() {
$cond = array();
$cond['islandora_object_has_relationship'] = array(
'label' => t('Check object for a relationship'),
'group' => t('Islandora'),
'parameter' => islandora_rules_relationship_parameter_array(),
);
return $cond;
}
/**
* Implements hook_rules_action_info().
*/
function islandora_rules_action_info() {
$cond = array();
$cond['islandora_object_remove_relationship'] = array(
'label' => t('Remove a relationship from an object'),
'group' => t('Islandora'),
'parameter' => islandora_rules_relationship_parameter_array(),
);
$cond['islandora_object_add_relationship'] = array(
'label' => t('Add a relationship to an object'),
'group' => t('Islandora'),
'parameter' => islandora_rules_relationship_parameter_array(),
);
return $cond;
}
/**
* Checks that there is a relationship match on the given object.
*
* Takes a subject (either a FedoraObject or a FedoraDatastream), as well as
* the parameters for FedoraRelsExt::get() or FedoraRelsInt::get(), to try to
* find a match.
*
* @see FedoraRelsExt::get()
*/
function islandora_object_has_relationship($sub, $pred_uri, $pred, $object, $type) {
$relationships = $sub->relationships->get($pred_uri, $pred, $object, $type);
return !empty($relationships);
}
/**
* Remove a relationship from the given object.
*
* Takes a subject (either a FedoraObject or a FedoraDatastream), as well as
* the parameters for FedoraRelsExt::remove() or FedoraRelsInt::remove(), to
* try to find a match.
*
* @see FedoraRelsExt::get()
*/
function islandora_object_remove_relationship($sub, $pred_uri, $pred, $object, $type) {
$sub->relationships->remove($pred_uri, $pred, $object, $type);
}
/**
* Add a relationship to the given object.
*
* Takes a subject (either a FedoraObject or a FedoraDatastream), as well as
* the parameters for FedoraRelsExt::add() or FedoraRelsInt::add(), and adds
* the represented relationship.
*
* @see FedoraRelsExt::get()
*/
function islandora_object_add_relationship($sub, $pred_uri, $pred, $object, $type) {
$sub->relationships->add($pred_uri, $pred, $object, $type);
}

25
policies/permit-getDatastream-unrestricted.xml

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<Policy xmlns="urn:oasis:names:tc:xacml:1.0:policy"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
PolicyId="permit-getDatastreamHistory-to-authenticated"
RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
<Description>Note that other policies may provide exceptions to this broad policy. This policy assumes api-m users have to be authenticated</Description>
<Target>
<Subjects>
<AnySubject/>
</Subjects>
<Resources>
<AnyResource/>
</Resources>
<Actions>
<Action>
<ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">urn:fedora:names:fedora:2.1:action:id-getDatastream</AttributeValue>
<ActionAttributeDesignator DataType="http://www.w3.org/2001/XMLSchema#string"
AttributeId="urn:fedora:names:fedora:2.1:action:id"/>
</ActionMatch>
</Action>
</Actions>
</Target>
<Rule RuleId="1" Effect="Permit"/>
</Policy>

25
policies/permit-getDatastreamHistory-unrestricted.xml

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<Policy xmlns="urn:oasis:names:tc:xacml:1.0:policy"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
PolicyId="permit-getDatastreamHistory-to-authenticated"
RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable">
<Description>Note that other policies may provide exceptions to this broad policy. This policy assumes api-m users have to be authenticated</Description>
<Target>
<Subjects>
<AnySubject/>
</Subjects>
<Resources>
<AnyResource/>
</Resources>
<Actions>
<Action>
<ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">urn:fedora:names:fedora:2.1:action:id-getDatastreamHistory</AttributeValue>
<ActionAttributeDesignator DataType="http://www.w3.org/2001/XMLSchema#string"
AttributeId="urn:fedora:names:fedora:2.1:action:id"/>
</ActionMatch>
</Action>
</Actions>
</Target>
<Rule RuleId="1" Effect="Permit"/>
</Policy>

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 <?php
/**
* @file
* Test Authentication Tokens.
*/
class IslandoraAuthtokensTestCase extends IslandoraWebTestCase { class IslandoraAuthtokensTestCase extends IslandoraWebTestCase {
/**
* Get test information for display.
*/
public static function getInfo() { public static function getInfo() {
return array( return array(
'name' => 'Islandora Authorization Tokens', 'name' => 'Islandora Authorization Tokens',
@ -10,45 +18,50 @@ class IslandoraAuthtokensTestCase extends IslandoraWebTestCase {
); );
} }
/**
* Set up data for the tests.
*/
public function setUp() { public function setUp() {
parent::setUp(array('islandora')); parent::setUp();
} }
/**
* Test redeeming invalid tokens.
*/
public function testRedeemInvalidToken() { public function testRedeemInvalidToken() {
module_load_include('inc', 'islandora', 'includes/islandora_authtokens'); module_load_include('inc', 'islandora', 'includes/islandora_authtokens');
// get a token
$token = islandora_get_object_token('test:pid', 'woot', 1); $token = islandora_get_object_token('test:pid', 'woot', 1);
$this->assertTrue($token, 'Token was generated correctly.', 'Unit Tests'); $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'); $account = islandora_validate_object_token('test:pid', 'woot', 'foo');
$this->assertFalse($account, 'Redeeming an token that doesn\'t exist returns FALSE', 'Unit Tests'); $this->assertFalse($account, 'Redeeming an token that doesn\'t exist returns FALSE', 'Unit Tests');
} }
/**
* Test redeeming valid tokens.
*/
public function testRedeemValidToken() { public function testRedeemValidToken() {
module_load_include('inc', 'islandora', 'includes/islandora_authtokens'); module_load_include('inc', 'islandora', 'includes/islandora_authtokens');
// Change the current user.
// change the current user
global $user; global $user;
$user_backup = $user; $user_backup = $user;
$test_account = $this->drupalCreateUser(); $test_account = $this->drupalCreateUser();
$user = $test_account; $user = $test_account;
$token = islandora_get_object_token('test:pid', 'woot', 1); $token = islandora_get_object_token('test:pid', 'woot', 1);
// logout again // Logout again.
$user = $user_backup; $user = $user_backup;
$token_account = islandora_validate_object_token('test:pid', 'woot', $token); $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->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->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'); $this->assertEqual($token_account->name, $test_account->name, 'Name from token is correct', 'Unit Tests');
} }
/**
* Test tokened datastream view without XACML.
*/
public function testTokenedViewDatastreamWithoutXacml() { public function testTokenedViewDatastreamWithoutXacml() {
// ingest the fixture // Ingest the fixture.
$fixture_path = drupal_get_path('module', 'islandora') . '/tests/fixtures/bug.jp2'; $fixture_path = drupal_get_path('module', 'islandora') . '/tests/fixtures/bug.jp2';
$tuque = islandora_get_tuque_connection(); $tuque = islandora_get_tuque_connection();
$newpid = "{$this->randomName()}:{$this->randomName()}"; $newpid = "{$this->randomName()}:{$this->randomName()}";
@ -67,8 +80,8 @@ class IslandoraAuthtokensTestCase extends IslandoraWebTestCase {
$this->drupalGet("islandora/object/{$newpid}/datastream/JP2/view"); $this->drupalGet("islandora/object/{$newpid}/datastream/JP2/view");
$this->assertResponse(200, 'Page loaded as the authorized user'); $this->assertResponse(200, 'Page loaded as the authorized user');
// do some voodoo to get a token as the user we are connecting 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 // to do this we need to change the user we are logged in as.
module_load_include('inc', 'islandora', 'includes/islandora_authtokens'); module_load_include('inc', 'islandora', 'includes/islandora_authtokens');
global $user; global $user;
$backup = $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->drupalGet("islandora/object/{$newpid}/datastream/JP2/view", array('query' => array('token' => $token)));
$this->assertResponse(403, 'Token is unable to be reused'); $this->assertResponse(403, 'Token is unable to be reused');
// delete fixture object // Delete fixture object.
$tuque->repository->purgeObject($newpid); $tuque->repository->purgeObject($newpid);
} }
/**
* This will test something someday.
*/
public function testTokenedViewDatastreamWithXacml() { 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 <?php
/**
* @file
* Defines the class IslandoraWebTestCase, which allows tests to access Fedora.
*/
class IslandoraWebTestCase extends DrupalWebTestCase { class IslandoraWebTestCase extends DrupalWebTestCase {
/**
* Sets up the Drupal filter to access this test Drupal instances database.
*
* @see DrupalWebTestCase::setUp()
*/
public function setUp() { public function setUp() {
$args = func_get_args(); $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"); * Parses and returns the settings from the test configuration file.
$connection_info = Database::getConnectionInfo('default'); *
* 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 = new DomDocument();
$drupal_filter_dom->loadXML($this->original_drupal_fiter); $drupal_filter_dom->loadXML($this->originalDrupalFilterContent);
$drupal_filter_xpath = new DOMXPath($drupal_filter_dom); $drupal_filter_xpath = new DOMXPath($drupal_filter_dom);
$server = $connection_info['default']['host']; $server = $connection_info['default']['host'];
$dbname = $connection_info['default']['database']; $dbname = $connection_info['default']['database'];
$user = $connection_info['default']['username']; $user = $connection_info['default']['username'];
$password = $connection_info['default']['password']; $password = $connection_info['default']['password'];
$port = $connection_info['default']['port'] ? $connection_info['default']['port'] : '3306'; $port = $connection_info['default']['port'] ? $connection_info['default']['port'] : '3306';
$prefix = $connection_info['default']['prefix']['default']; $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 = $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=?;"; $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() { 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(); parent::tearDown();
} }
} }

4
tests/test_config.ini

@ -1,4 +0,0 @@
[fedora]
filter_drupal_file = "/usr/local/fedora/server/config/filter-drupal.xml"
admin_user = "fedoraAdmin"
admin_pass = "fedoraAdmin"

3
theme/islandora-object-edit.tpl.php

@ -20,7 +20,4 @@
* *
*/ */
?> ?>
<?php drupal_set_title($islandora_object->label); ?>
<?php print (theme_table($variables['datastream_table'])); ?> <?php print (theme_table($variables['datastream_table'])); ?>

4
theme/islandora-object.tpl.php

@ -58,10 +58,6 @@
* *
*/ */
?> ?>
<?php if (isset($islandora_object_label)): ?>
<?php drupal_set_title("$islandora_object_label"); ?>
<?php endif; ?>
<div class="islandora-object islandora"> <div class="islandora-object islandora">
<h2><?php print t('Details'); ?></h2> <h2><?php print t('Details'); ?></h2>
<dl class="islandora-object-tn"> <dl class="islandora-object-tn">

Loading…
Cancel
Save