diff --git a/.gitignore b/.gitignore
index 1133add7..6ef50997 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
cache.properties
.DS_Store
+tests/test_config.ini
\ No newline at end of file
diff --git a/includes/IslandoraTuqueWrapper.inc b/includes/IslandoraTuqueWrapper.inc
deleted file mode 100644
index 2692c24c..00000000
--- a/includes/IslandoraTuqueWrapper.inc
+++ /dev/null
@@ -1,78 +0,0 @@
-connection = new IslandoraRepositoryConnection($url, $user_string, $pass_string);
$this->connection->reuseConnection = TRUE;
$this->api = new IslandoraFedoraApi($this->connection);
diff --git a/includes/islandora_tuque_wrapper.inc b/includes/islandora_tuque_wrapper.inc
new file mode 100644
index 00000000..8bd3c3e6
--- /dev/null
+++ b/includes/islandora_tuque_wrapper.inc
@@ -0,0 +1,360 @@
+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: @pidcode: @code
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: @pidcode: @code
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 @pidcode: @code
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: @pidcode: @code
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 @pidcode: @code
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 @pidcode: @code
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 {}
diff --git a/includes/utilities.inc b/includes/utilities.inc
index b2006722..ac63f35c 100644
--- a/includes/utilities.inc
+++ b/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;
}
diff --git a/islandora.api.php b/islandora.api.php
index f017f937..4fe2ea4f 100644
--- a/islandora.api.php
+++ b/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,20 +377,21 @@ 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.
*
* @param array $form_state
* An array containing the form_state, on which infomation from step storage
- * might be extracted. Note that the
+ * might be extracted. Note that the
*
* @return array
* An associative array of associative arrays which define each step in the
@@ -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) {
+}
diff --git a/islandora.info b/islandora.info
index d883aa49..518a1434 100644
--- a/islandora.info
+++ b/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
diff --git a/islandora.module b/islandora.module
index 05b55cc8..bccf7322 100644
--- a/islandora.module
+++ b/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: @pidcode: @code
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);
}
/**
diff --git a/tests/README b/tests/README
new file mode 100644
index 00000000..797d788b
--- /dev/null
+++ b/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.
\ No newline at end of file
diff --git a/tests/default.test_config.ini b/tests/default.test_config.ini
new file mode 100644
index 00000000..f07fb4c3
--- /dev/null
+++ b/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"
diff --git a/tests/islandora_authtokens.test b/tests/islandora_authtokens.test
index 953964c4..326225f2 100644
--- a/tests/islandora_authtokens.test
+++ b/tests/islandora_authtokens.test
@@ -1,7 +1,15 @@
'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.
}
-}
\ No newline at end of file
+}
diff --git a/tests/islandora_hooks.test b/tests/islandora_hooks.test
new file mode 100644
index 00000000..0a667fee
--- /dev/null
+++ b/tests/islandora_hooks.test
@@ -0,0 +1,213 @@
+ '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);
+ }
+
+}
diff --git a/tests/islandora_hooks_test.info b/tests/islandora_hooks_test.info
new file mode 100644
index 00000000..9d211978
--- /dev/null
+++ b/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
diff --git a/tests/islandora_hooks_test.module b/tests/islandora_hooks_test.module
new file mode 100644
index 00000000..315b88ee
--- /dev/null
+++ b/tests/islandora_hooks_test.module
@@ -0,0 +1,152 @@
+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;
+ }
+}
diff --git a/tests/islandora_web_test_case.inc b/tests/islandora_web_test_case.inc
index d47dc214..cc5b8c67 100644
--- a/tests/islandora_web_test_case.inc
+++ b/tests/islandora_web_test_case.inc
@@ -1,36 +1,124 @@
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();
}
-}
\ No newline at end of file
+}
diff --git a/tests/test_config.ini b/tests/test_config.ini
index 1d6eb7d6..350dd60b 100644
--- a/tests/test_config.ini
+++ b/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"