Browse Source

Merge pull request #193 from adam-vessey/7.x-alter-hook-defs

Alter hook calls and update documentation to reflect it.
pull/196/head
Jonathan Green 12 years ago
parent
commit
7984b26ff8
  1. 114
      includes/islandora.ingest.inc
  2. 50
      includes/utilities.inc
  3. 196
      islandora.api.php
  4. 133
      islandora.module

114
includes/islandora.ingest.inc

@ -2,7 +2,7 @@
/**
* @file
* This file contains ingest callback functions
* This file contains ingest callback functions.
*/
/**
@ -16,23 +16,69 @@ function islandora_ingest_get_information(AbstractFedoraObject $collection_objec
}
/**
* @TODO: needs documentation
* Get an ingestable object.
*
* @deprecated
* Deprecated in favour of the more flexible
* islandora_ingest_new_object_prepare()--which this function has been made
* to call behind the scenes anyway.
*
* @param array $content_models
* An array of content models to which the new object should subscribe, where
* each content model is described by an associative array containing:
* - pid: The Fedora PID of the content model.
* @param string $collection_pid
* The collection to which the new object should belong.
* @param string $relationship
* The relationship this object will have to the collection.
* @param string $namespace
* The namespace in which the PID for the new object will be created.
*
* @return NewFedoraObject
* A NewFedoraObject which may be adjusted before ingesting.
*/
function islandora_ingest_get_object($content_models, $collection_pid, $relationship, $namespace) {
module_load_include('inc', 'islandora', 'includes/tuque');
global $user;
$connection = new IslandoraTuque($user);
$object = $connection->repository->constructObject($namespace);
foreach ($content_models as $content_model) {
$object->relationships->add(FEDORA_MODEL_URI, 'hasModel', $content_model['pid']);
$models = array();
foreach ($content_models as $relation) {
$models[] = $relation['pid'];
}
$object->relationships->add(FEDORA_RELS_EXT_URI, $relationship, $collection_pid);
module_invoke_all('islandora_ingest_pre_ingest', $object, $content_models, $collection_pid);
return $object;
return islandora_ingest_new_object_prepare($namespace, NULL, array(), $models, array(
array(
'pid' => $collection_pid,
'relationship' => $relationship,
),
), $collection_pid);
}
/**
* @TODO: needs documentation
* Prepare an ingestable object.
*
* @param string $namespace
* The namespace in which the PID for the new object will be created.
* @param string $label
* An optional label to apply to the object.
* @param array $datastreams
* A array of datastreams to add, where each datastream definition is an
* associative array containing:
* - dsid: The datastream ID.
* - label: An optional label for the datastream.
* - mimetype: A MIMEtype for the datastream; defaults to text/xml.
* - control_group: One of X, M, R and E; defaults to M.
* - datastream_file: A web-accessible path, for which we try to get an
* absolute path using url().
* @param array $content_models
* An array of content model PIDs to which the new object should subscribe.
* @param array $relationships
* An array of relationships, where each relationship is an associative array
* containing:
* - relationship: The predicate for the relationship, from the Fedora
* RELS-EXT namespace.
* - pid: The object for the relationship, to which we are creating the
* relationhsip.
*
* @return NewFedoraObject
* An ingestable NewFedoraObject.
*/
function islandora_ingest_new_object_prepare($namespace = NULL, $label = NULL, $datastreams = array(), $content_models = array(), $relationships = array(), $collection_pid = NULL) {
// include Tuque library
@ -86,20 +132,56 @@ function islandora_ingest_new_object_prepare($namespace = NULL, $label = NULL, $
$object->ingestDatastream($datastream);
}
module_invoke_all('islandora_ingest_pre_ingest', $object, $content_models, $collection_pid);
module_load_include('inc', 'islandora', 'includes/utilities');
foreach (islandora_build_hook_list('islandora_ingest_pre_ingest', $content_models) as $hook) {
module_invoke_all($hook, $object, $content_models, $collection_pid);
}
return $object;
}
/**
* @TODO: needs documentation
* Ingest the given object into Fedora.
*
* @param NewFedoraObject $object
* An ingestable FedoraObject.
*
* @return FedoraObject
* The ingested FedoraObject, after running the post ingest hooks.
*/
function islandora_ingest_add_object(&$object) {
$object->repository->ingestObject($object);
module_invoke_all('islandora_ingest_post_ingest', $object);
module_load_include('inc', 'islandora', 'includes/utilities');
foreach (islandora_build_hook_list(ISLANDORA_POST_INGEST_HOOK, $object->models) as $hook) {
module_invoke_all($hook, $object);
}
return $object;
}
/**
* Ingest an object.
*
* @param array $object_model
* An associative array containing the necessary parameters to create the
* desired object:
* - pid: The PID with which the object will be created.
* - label: An optional label to apply to the object.
* - datastreams: Same as the "datastreams" array accepted by
* islandora_ingest_new_object_prepare().
* - cmodel: Either an array of content models as accepted by
* islandora_ingest_new_object_prepare(), or a single content model PID to add
* to the object.
* - parent: Either an array of parents, or a single parent PID to which to
* relate to; uses isMemberOfCollection by default.
* - relationships: An array of relationships as accepted by
* islandora_ingest_new_object_prepare().
*
* @return FedoraObject
* An FedoraObject which has been ingested into Fedora.
*/
function islandora_ingest_new_object($object_model) {
// prepare variables
// namespace

50
includes/utilities.inc

@ -8,6 +8,8 @@
/**
* Convert bytes to human readable format
*
* XXX: Shouldn't Drupal's format_size() be preferred?
*
* @param integer bytes Size in bytes to convert
* @return string
*/
@ -103,4 +105,50 @@ function islandora_describe_repository($url) {
catch (RepositoryException $e) {
return FALSE;
}
}
}
/**
* Build a list of all the hooks to call.
*
* Concatenates the each pid (escaped) to the hook name, for calling in
* module_invoke_all().
*
* @param string $hook
* A hook to call.
* @param array $pids
* An array of PIDs (probably content models).
*
* @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.
*/
function islandora_build_hook_list($hook, $pids = array()) {
$hooks = array();
foreach ($pids as $model) {
$hooks[] = islandora_escape_pid_for_function($model) . '_' . $hook;
}
$hooks[] = $hook;
return $hooks;
}
/**
* Escape a Fedora PID to be valid inside of a PHP function name.
*
* Originally intended to allow inclusion of a PID in a module_invoke_all()
* call.
*/
function islandora_escape_pid_for_function($pid) {
// Apparently, case doesn't matter for function calls in PHP, so let's not
// really worry about changing the case.
return str_replace(
// Any PID characters which are not valid in the name of a PHP function.
array(
':',
'-',
),
'_',
$pid
);
}

196
islandora.api.php

@ -6,120 +6,192 @@
*/
/**
* remove a datastream from a repository object
* @param object $fedora_object
* tuque FedoraObject
* @param string $datastream_id
* Generate a repository objects view.
*
* @param FedoraObject $fedora_object
* A Tuque FedoraObject being operated on.
* @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.
*
* @return array
* An array whose values are markup.
*/
function hook_islandora_purge_datastream($fedora_object, $datastream_id) {}
function hook_islandora_view_object($fedora_object, $user, $page_number, $page_size) {}
/**
* Generate an object's display for the given content model.
*
* @param type $object
* tuque FedoraObject
* Content models PIDs have colons and hyphens changed to underscores, to
* create the hook name.
*
* @param type $fedora_object
* A Tuque FedoraObject
*
* @return array
* An array whose values are markup.
*/
function hook_islandora_purge_object($islandora_object) {}
function hook_CMODEL_PID_islandora_view_object($fedora_object) {}
/**
* allows modules to add to a repository objects display. If you implement this
* hook you should also register your module for view with the get types hook.
*
* islandora gets all displays back in an array and iterates over them. the order
* they are displayed is based on the order of the key of the array that each
* module returns.
*
* your module may also want to register a varible that says whether or not it
* should be part of the default display. Modules can also add secondary tabs as
* a way to add there output to an islandora display. the basic image module has
* samples of both (the secondary tabs examples are commented out)
* Alter display output after it has been generated.
*
* @param type $islandora_object
* tuque FedoraObject
* @param FedoraObject $fedora_object
* A Tuque FedoraObject being operated on.
* @param array $arr
* An arr of rendered views.
*/
function hook_islandora_view_object($islandora_object) {}
function hook_islandora_view_object_alter(&$fedora_object, &$arr) {}
/**
* returns an array listing object types provided by sub modules
* Ex. array($types['islandora:collectionCModel'][ISLANDORA_VIEW_HOOK] = variable_get('islandora_basic_collection_use_for_default_tab', TRUE);
* $types['islandora:collectionCModel'][ISLANDORA_EDIT_HOOK] = FALSE;
* Generate an object's management display.
*
* @param type $fedora_object
* A Tuque FedoraObject
*
* @return array
* An array whose values are markup.
*/
function hook_islandora_get_types() {}
function hook_islandora_edit_object($fedora_object) {}
/**
* allows modules to define an object edit page by cmodel
* Generate an object's management display for the given content model.
*
* your module should return true for ISLANDORA_EDIT_HOOK in its get_types function
* Content models PIDs have colons and hyphens changed to underscores, to
* create the hook name.
*
* islandora provides a default implementation that should work for most use cases
* @param string $islandora_object
* @return string
* @param type $fedora_object
* A Tuque FedoraObject
*
* @return array
* An array whose values are markup.
*/
function hook_islandora_edit_object($islandora_object) {}
function hook_CMODEL_PID_islandora_edit_object($fedora_object) {}
/**
* allows modules to alter the fedora object before it is pass through the edit
* hooks
* @param type $islandora_object
* a tugue FedoraObject
* Allow management display output to be altered.
*
* @param type $fedora_object
* A Tuque FedoraObject
* @param type $arr
* an arr of rendered views
*/
function hook_islandora_edit_object_alter($islandora_object) {}
function hook_islandora_edit_object_alter(&$fedora_object, &$arr) {}
/**
* Allows modules to add to an objects ingest process.
*
* @param FedoraObject $fedora_object
* A Tuque FedoraObject.
*/
function hook_islandora_ingest_post_ingest($fedora_object) {}
/**
* creates and populates a php Fedora object.
* Allow modules to add to the ingest process of a specific content model.
*/
function hook_islandora_preingest_alter() {}
function hook_CMODEL_PID_islandora_ingest_post_ingest($fedora_object) {}
/**
* modules can implement this hook to add or remove datastreams after an
* object has been ingested.
* Allows modules to add to a repository objects view/edit(/misc) process.
*
* Each module should check for the newly ingested repository objects content
* model to make sure it is a type of object they want to act on.
* If you implement this hook you must also register your module with
* hook_islandora_hook_info().
*
* @param type $islandora_object
* tugue FeodoraObject
* @param FedoraObject $fedora_object
* A Tuque FedoraObject.
*
* @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.
*/
function hook_islandora_pre_purge_object($fedora_object) {}
/**
* Allow modules to react to the purge process of a specific content model.
*
* @see hook_islandora_pre_purge_object()
*/
function hook_islandora_postingest($islandora_object) {}
function hook_CMODEL_PID_islandora_pre_purge_object($fedora_object) {}
/**
* Register potential ingest routes. Implementations should return an array containing possible routes.
* Ex. array(
* array('name' => t('Ingest Route Name'), 'url' => 'ingest_route/url', 'weight' => 0),
* );
* Register potential ingest routes.
*
* Implementations should return an array containing possible routes.
*/
function hook_islandora_ingest_registry($collection_object) {}
function hook_islandora_ingest_registry($collection_object) {
$reg = array(
array(
'name' => t('Ingest Route Name'),
'url' => 'ingest_route/url',
'weight' => 0,
),
);
return $reg
}
/**
* Register a datastream edit route/form.
*
* @param $islandora_object
* @param $ds_id
*/
function hook_islandora_edit_datastream_registry($islandora_object, $ds_id) {}
/**
* alter an object before it gets used further down the stack
* Alter an object before it gets used further down the stack.
*
* @param type $object
* a tuque FedoraObject
* A Tuque FedoraObject
*/
function hook_islandora_object_alter($fedora_object) {}
/**
* insert or remove rendered elements by implementing this function
* in your module
* @param type $arr
* an arr of rendered views
*/
function hook_islandora_display_alter($arr) {}
/**
* Allow modification of an object before ingesting.
*
* @param type $islandora_object
* a tuque FedoraObject
* A Tuque FedoraObject
* @param array $content_models
* @param string $collection_pid
*/
function hook_islandora_ingest_pre_ingest($islandora_object, $content_models, $collection_pid) {}
/**
* Allow modification of objects of a certain content model before ingesting.
*
* @see hook_islandora_ingest_pre_ingest()
*/
function hook_CMODEL_PID_islandora_ingest_pre_ingest($islandora_object, $content_models, $collection_pid) {}
/**
* Allow modules to setup for the purge of a datastream.
*
* @param object $datastream
* A Tuque FedoraDatastream object.
*/
function hook_islandora_pre_purge_datastream($datastream) {}
/**
* Allow modules to react after a datastream is purged.
*
* @param object $object
* A Tuque FedoraObject.
* @param string $dsid
* A id of the former datastream.
*/
function hook_islandora_post_purge_datastream($object, $dsid) {}
/**
* Allow modules to react post-purge.
*
* @param string $object_id
* The former object's PID.
* @param array $content_models
* An array containing the models to which the former object.
*/
function hook_islandora_post_purge_object($object_id, $content_models) {}

133
islandora.module

@ -31,9 +31,11 @@ define('FEDORA_PURGE', 'delete fedora objects and datastreams');
define('FEDORA_MODIFY_STATE', 'modify fedora state');
define('FEDORA_MANAGE', 'manage fedora items');
// hooks
// Hooks
define('ISLANDORA_VIEW_HOOK', 'islandora_view_object');
define('ISLANDORA_EDIT_HOOK', 'islandora_edit_object');
define('ISLANDORA_POST_INGEST_HOOK', 'islandora_ingest_post_ingest');
define('ISLANDORA_PRE_PURGE_OBJECT_HOOK', 'islandora_pre_purge_object');
/**
* Implements hook_menu().
@ -249,14 +251,6 @@ function islandora_access_callback($object = NULL, $perm = NULL) {
return ($namespace_access && user_access($perm));
}
/**
* returns an array listing object types provided by sub modules
* @return array
*/
function islandora_get_types() {
return module_invoke_all('islandora_get_types');
}
function islandora_init() {
if (path_is_admin(current_path())) {
drupal_add_css(drupal_get_path('module', 'islandora') . '/css/islandora.admin.css');
@ -287,14 +281,30 @@ function islandora_edit_object($object) {
if (!$object) {
return drupal_not_found();
}
drupal_alter('islandora_edit_object', $object);
$arr = module_invoke_all('islandora_edit_object', $object);
$output = "";
foreach ($arr as $key => $value) {
$output .= $value; //if we have multiple modules handle one cmodel we need to iterate over multiple
module_load_include('inc', 'islandora', 'includes/utilities');
// Accumulate the output.
$output = array();
// Call cmodel oriented variants first.
foreach (islandora_build_hook_list(ISLANDORA_EDIT_HOOK, $object->models) as $hook) {
$temp = module_invoke_all($hook, $object);
if (!empty($temp)) {
$output = array_merge_recursive($output, $temp);
}
}
//we could do another module invoke all here to build the edit tab with a default implemented in this module?
return $output;
// Add in the default, if we did not get any results.
if (empty($output)) {
$output = islandora_default_islandora_edit_object($object);
}
arsort($output);
drupal_alter(ISLANDORA_EDIT_HOOK, $object, $output);
return implode('', $output);
}
/**
@ -314,23 +324,25 @@ function islandora_edit_properties($object_id) {
}
/**
* builds a default page for the edit tab
* Builds a default page for the edit tab.
*
* @param object $fedora_object
* A tuque Fedora Object
*/
function islandora_islandora_edit_object($fedora_object) {
$supported_models = islandora_get_types();
$output = "";
foreach ($fedora_object->models as $model) {
if (isset($supported_models[$model][ISLANDORA_EDIT_HOOK]) && $supported_models[$model][ISLANDORA_EDIT_HOOK] == TRUE) {//another module is handling the view
return;
}
}
$output = theme('islandora_default_edit', array('islandora_object' => $fedora_object));
return array('Default edit output' => $output);
function islandora_default_islandora_edit_object($fedora_object) {
$output = theme('islandora_default_edit', array(
'islandora_object' => $fedora_object,
));
return array('Default Edit output' => $output);
}
/**
* Page callback for the path "islandora".
*
* Redirects to the view of the object indicated by the Drupal variable
* islandora_repository_pid.
*/
function islandora_view_default_object() {
$pid = variable_get('islandora_repository_pid', 'islandora:root');
drupal_goto("islandora/object/$pid");
@ -346,6 +358,8 @@ function islandora_view_default_object() {
*/
function islandora_view_object($fedora_object = NULL) {
module_load_include('inc', 'islandora', 'includes/breadcrumb');
module_load_include('inc', 'islandora', 'includes/utilities');
global $user;
if (!$fedora_object) {
@ -358,37 +372,38 @@ function islandora_view_object($fedora_object = NULL) {
$page_number = (empty($_GET['page'])) ? '1' : $_GET['page'];
$page_size = (empty($_GET['pagesize'])) ? '10' : $_GET['pagesize'];
drupal_alter('islandora_object', $fedora_object); //modify object if required before it is passed along
$arr = module_invoke_all('islandora_view_object', $fedora_object, $user, $page_number, $page_size); //allow submodules to decide how to handle content base on object type
if (empty($arr)) {
//TODO: make sure we iterate over the array as they will be more then one cmodel per object
drupal_set_message(t('there was an error loading the view for Islandora object "%s"', array('%s' => $fedora_object->label)), 'error');
return "";
// Accumulate the output.
$output = array();
// Call cmodel oriented variants first.
foreach (islandora_build_hook_list(ISLANDORA_VIEW_HOOK, $fedora_object->models) as $hook) {
$temp = module_invoke_all($hook, $fedora_object, $user, $page_number, $page_size);
if (!empty($temp)) {
$output = array_merge_recursive($output, $temp);
}
}
arsort($arr);
drupal_alter('islandora_display', $arr);
$output = "";
foreach ($arr as $key => $value) {
$output .= $value; //if we have multiple modules handle one cmodel we need to iterate over multiple
// Add in the default, if we did not get any results.
if (empty($output)) {
$output = islandora_default_islandora_view_object($fedora_object);
}
return $output;
arsort($output);
drupal_alter(ISLANDORA_VIEW_HOOK, $fedora_object, $output);
return implode('', $output);
}
/**
* The default view hook. If there are no modules registered to handle this objects cmodels or there are
* If there are no modules registered to handle this objects cmodels or there are
* not any cmodels specified this will create a default display.
*
* @param string $object_id
* @return string
* @param FedoraObject $object
* The object whose display we are to render.
* @return array
*/
function islandora_islandora_view_object($object) {
$supported_models = islandora_get_types();
$output = "";
foreach ($object->models as $model) {
if (isset($supported_models[$model][ISLANDORA_VIEW_HOOK]) && (boolean) $supported_models[$model][ISLANDORA_VIEW_HOOK] === TRUE) { //another module is handling the view
return;
}
}
function islandora_default_islandora_view_object($object) {
$output = theme('islandora_default', array('islandora_object' => $object));
return array('Default output' => $output);
}
@ -460,7 +475,7 @@ function islandora_permission() {
*/
function islandora_object_load($object_id) {
module_load_include('inc', 'islandora', 'includes/tuque');
static $islandora_tuque = NULL;
$islandora_tuque = &drupal_static(__FUNCTION__);
if (!$islandora_tuque) {
$islandora_tuque = new IslandoraTuque();
@ -472,6 +487,8 @@ function islandora_object_load($object_id) {
} catch (Exception $e) {
return NULL;
}
drupal_alter('islandora_object', $fedora_object);
return $fedora_object;
}
else {
@ -500,8 +517,19 @@ function islandora_object_purge($object_id) {
drupal_set_message(t('Could not remove object, object not found'));
return;
}
module_load_include('inc', 'islandora', 'includes/utilities');
$content_models = $object->models;
$arr = module_invoke_all('islandora_pre_purge_object', $object); // notify modules of pending deletion
$arr = array();
foreach (islandora_build_hook_list(ISLANDORA_PRE_PURGE_OBJECT_HOOK, $object->models) as $hook) {
$temp = module_invoke_all($hook, $object);
if (!empty($temp)) {
$arr = array_merge_recursive($arr, $temp);
}
}
if (isset($arr['delete']) && $arr['delete']) {
try {
$object->delete();
@ -518,6 +546,7 @@ function islandora_object_purge($object_id) {
return "";
}
}
module_invoke_all('islandora_post_purge_object', $object_id, $content_models); // notify modules post deletion
}

Loading…
Cancel
Save