Browse Source

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

pull/354/head
phil 12 years ago
parent
commit
caa781183c
  1. 19
      .travis.yml
  2. 21
      README.md
  3. 164
      build.xml
  4. 3
      build/Doxyfile
  5. 39
      css/islandora.objects.css
  6. 4
      includes/add_datastream.form.inc
  7. 2
      includes/admin.form.inc
  8. 65
      includes/breadcrumb.inc
  9. 352
      includes/ingest.form.inc
  10. 49
      includes/ingest.menu.inc
  11. 6
      includes/object_properties.form.inc
  12. 115
      includes/solution_packs.inc
  13. 22
      includes/tuque_wrapper.inc
  14. 191
      includes/utilities.inc
  15. 50
      islandora.api.php
  16. 5
      islandora.install
  17. 151
      islandora.module
  18. 3
      tests/README.txt
  19. 12
      tests/hooks.test
  20. 3
      tests/islandora_hooks_test.info
  21. 0
      tests/islandora_hooks_test.module
  22. 114
      tests/islandora_manage_permissions.test
  23. 14
      tests/scripts/line_endings.sh
  24. 36
      tests/scripts/travis_setup.sh
  25. 6
      tests/travis.test_config.ini
  26. 5
      tests/web_test_case.inc
  27. 17
      theme/islandora-objects-grid.tpl.php
  28. 29
      theme/islandora-objects-list.tpl.php
  29. 21
      theme/islandora-objects.tpl.php
  30. 61
      theme/theme.inc

19
.travis.yml

@ -0,0 +1,19 @@
language: php
php:
- 5.3.3
- 5.4
branches:
only:
- 7.x
env:
- FEDORA_VERSION="3.5"
before_install:
- export ISLANDORA_DIR=$TRAVIS_BUILD_DIR
- $TRAVIS_BUILD_DIR/tests/scripts/travis_setup.sh
- cd $HOME/drupal-*
script:
- ant -buildfile sites/all/modules/islandora/build.xml lint
- $ISLANDORA_DIR/tests/scripts/line_endings.sh sites/all/modules/islandora
- drush coder-review --reviews=production,security,style,i18n,potx,sniffer islandora
- phpcpd --names *.module,*.inc,*.test sites/all/modules/islandora
- drush test-run --uri=http://localhost:8081 Islandora

21
README.txt → README.md

@ -1,16 +1,10 @@
CONTENTS OF THIS FILE BUILD STATUS
--------------------- ------------
Current build status:
* summary [![Build Status](https://travis-ci.org/Islandora/islandora.png?branch=7.x)](https://travis-ci.org/Islandora/islandora)
* requirements
* installation
* configuration
* customization
* troubleshooting
* faq
* contact
* sponsors
CI Server:
http://jenkins.discoverygarden.ca
SUMMARY SUMMARY
------- -------
@ -41,7 +35,7 @@ should be copied into the Fedora global XACML policies folder. This will allow
CONFIGURATION CONFIGURATION
------------- -------------
The islandora_drupal_filter passes the username of 'anonymous' through to The islandora_drupal_filter passes the username of 'anonymous' through to
Fedora for unauthenticated Drupal Users. A user with the name of 'anonymous' Fedora for unauthenticated Drupal Users. A user with the name of 'anonymous'
may have XACML policies applied to them that are meant to be applied to Drupal may have XACML policies applied to them that are meant to be applied to Drupal
users that are not logged in or vice-versa. This is a potential security issue users that are not logged in or vice-versa. This is a potential security issue
@ -53,6 +47,7 @@ Drupal's cron will can be ran to remove expired authentication tokens.
CUSTOMIZATION CUSTOMIZATION
------------- -------------
[Customize ingest forms](http://github.com/Islandora/islandora/wiki/Multi-paged-Ingest-Forms)
TROUBLESHOOTING TROUBLESHOOTING
--------------- ---------------

164
build.xml

@ -1,110 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project name="islandora" default="build"> <project name="islandora" default="build">
<target name="build" <target name="build" depends="clean,prepare,lint,phploc,code_sniff,phpcpd,pdepend,doxygen,phpcb,test" />
depends="prepare,lint,doxygen,phploc,pdepend,phpcs-ci,phpcpd,phpcb"/>
<target name="clean" description="Cleanup build artifacts"> <target name="clean" description="Cleanup build artifacts">
<delete dir="${basedir}/build/api"/> <delete dir="${basedir}/build/test" />
<delete dir="${basedir}/build/code-browser"/> <delete dir="${basedir}/build/logs" />
<delete dir="${basedir}/build/coverage"/> <delete dir="${basedir}/build/pdepend" />
<delete dir="${basedir}/build/logs"/> <delete dir="${basedir}/build/api" />
<delete dir="${basedir}/build/pdepend"/> <delete dir="${basedir}/build/code-browser" />
</target> </target>
<target name="prepare" depends="clean" <target name="prepare" description="Prepares workspace for artifacts" >
description="Prepare for build"> <mkdir dir="${basedir}/build/test" />
<mkdir dir="${basedir}/build/api"/> <mkdir dir="${basedir}/build/logs" />
<mkdir dir="${basedir}/build/code-browser"/> <mkdir dir="${basedir}/build/pdepend" />
<mkdir dir="${basedir}/build/coverage"/> <mkdir dir="${basedir}/build/api" />
<mkdir dir="${basedir}/build/logs"/> <mkdir dir="${basedir}/build/code-browser" />
<mkdir dir="${basedir}/build/pdepend"/> </target>
</target>
<target name="lint"> <target name="lint" description="Perform syntax check of sourcecode files">
<apply executable="php" failonerror="true"> <apply executable="php" failonerror="true">
<arg value="-l" /> <arg value="-l" />
<fileset dir="${basedir}"> <fileset dir="${basedir}">
<include name="**/*.php" /> <include name="**/*.php" />
<modified /> <include name="**/*.inc" />
</fileset> <include name="**/*.module" />
</apply> <include name="**/*.install" />
</target> <include name="**/*.test" />
<modified />
</fileset>
</apply>
</target>
<target name="phploc" description="Measure project size using PHPLOC"> <target name="phploc" description="Measure project size using PHPLOC">
<exec executable="phploc"> <exec executable="phploc">
<arg value="--log-csv" /> <arg line="--log-csv ${basedir}/build/logs/phploc.csv --exclude build --exclude css --exclude images --exclude xml --names *.php,*.module,*.inc,*.test,*.install ${basedir}" />
<arg value="${basedir}/build/logs/phploc.csv" /> </exec>
<arg path="${basedir}" /> </target>
</exec>
</target>
<target name="pdepend" <target name="code_sniff" description="Checks the code for Drupal coding standard violations" >
description="Calculate software metrics using PHP_Depend"> <exec executable="phpcs">
<exec executable="pdepend"> <arg line="--standard=Drupal --report=checkstyle --report-file=${basedir}/build/logs/checkstyle.xml --extensions=php,inc,test,module,install --ignore=build/,xml/,images/,css/ ${basedir}" />
<arg value="--jdepend-xml=${basedir}/build/logs/jdepend.xml" /> </exec>
<arg value="--jdepend-chart=${basedir}/build/pdepend/dependencies.svg" /> </target>
<arg value="--overview-pyramid=${basedir}/build/pdepend/overview-pyramid.svg" />
<arg path="${basedir}" />
</exec>
</target>
<target name="phpcs" <target name="phpcpd" description="Copy/Paste code detection">
description="Find coding standard violations using PHP_CodeSniffer and print human readable output. Intended for usage on the command line before committing."> <exec executable="phpcpd">
<exec executable="phpcs"> <arg line="--log-pmd ${basedir}/build/logs/pmd-cpd.xml --exclude build --exclude css --exclude images --exclude xml --names *.php,*.module,*.inc,*.test,*.install ${basedir}" />
<arg value="--standard=Drupal" /> </exec>
<arg value="--extensions=php" /> </target>
<arg value="--ignore=build/" />
<arg path="${basedir}" />
</exec>
</target>
<target name="phpcs-ci" <target name="pdepend" description="Calculate software metrics using PHP_Depend">
description="Find coding standard violations using PHP_CodeSniffer creating a log file for the continuous integration server"> <exec executable="pdepend">
<exec executable="phpcs" output="/dev/null"> <arg line="--jdepend-xml=${basedir}/build/logs/jdepend.xml --jdepend-chart=${basedir}/build/pdepend/dependencies.svg --overview-pyramid=${basedir}/build/pdepend/overview-pyramid.svg ${basedir}"/>
<arg value="--report=checkstyle" /> </exec>
<arg value="--extensions=php" /> </target>
<arg value="--ignore=build/" />
<arg value="--report-file=${basedir}/build/logs/checkstyle.xml" />
<arg value="--standard=Drupal" />
<arg path="${basedir}" />
</exec>
</target>
<target name="phpcpd" description="Find duplicate code using PHPCPD"> <target name="doxygen" description="Generate API documentation with doxygen" depends="prepare">
<exec executable="phpcpd"> <exec executable="bash">
<arg value="--log-pmd" /> <arg line='-c "sed -i s/PROJECT_NUMBER\ \ \ \ \ \ \ \ \ =/PROJECT_NUMBER\ \ \ \ \ \ \ \ \ =\ `git log -1 --pretty=format:%h`/ build/Doxyfile"'/>
<arg value="${basedir}/build/logs/pmd-cpd.xml" /> </exec>
<arg path="${basedir}" /> <exec executable="doxygen">
</exec> <arg line="${basedir}/build/Doxyfile" />
</target> </exec>
<exec executable="git">
<arg line="checkout ${basedir}/build/Doxyfile"/>
</exec>
</target>
<target name="doxygen" description="Generate API documentation with doxygen" depends="prepare"> <target name="phpcb" description="Aggregate tool output with PHP_CodeBrowser">
<echo file="${basedir}/build/Doxyfile" append="true" message="PROJECT_NUMBER = "/> <exec executable="phpcb">
<exec executable="git" output="${basedir}/build/Doxyfile" append="true"> <arg line="--log ${basedir}/build/logs --source ${basedir} --output ${basedir}/build/code-browser"/>
<arg value="log" /> </exec>
<arg value="-1" /> </target>
<arg value="--pretty=format:%h" />
</exec>
<exec executable="doxygen">
<arg path="${basedir}/build/Doxyfile" />
</exec>
<exec executable="git">
<arg value="checkout" />
<arg path="${basedir}/build/Doxyfile" />
</exec>
</target>
<target name="phpcb" <target name="test">
description="Aggregate tool output with PHP_CodeBrowser"> <exec executable="bash">
<exec executable="phpcb"> <arg line='-c "php ../../../../scripts/run-tests.sh --xml ${basedir}/build/test Islandora"' />
<arg value="--log" /> </exec>
<arg path="${basedir}/build/logs" /> </target>
<arg value="--source" />
<arg path="${basedir}" />
<arg value="--output" />
<arg path="${basedir}/build/code-browser" />
</exec>
</target>
</project> </project>

3
build/Doxyfile

@ -27,6 +27,9 @@ DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = Islandora 7.x PROJECT_NAME = Islandora 7.x
# Put the git hash here using sed before generating the documentation.
PROJECT_NUMBER =
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put. # base path where the generated documentation will be put.
# If a relative path is entered, it will be relative to the location # If a relative path is entered, it will be relative to the location

39
css/islandora.objects.css

@ -0,0 +1,39 @@
/**
* @file
* Styles for rendering grids/lists of objects.
*/
.islandora-objects-display-switch {
float: right;
}
.islandora-objects-grid-item {
display: inline-block;
width: 20%;
min-width: 100px;
min-height: 180px;
display: -moz-inline-stack;
display: inline-block;
vertical-align: top;
margin: 1.5em 1.84%;
zoom: 1;
*display: inline;
_height: 180px;
}
.islandora-objects-list-item {
padding-bottom: 1.5em;
border-bottom: 1px solid #ddd;
}
.islandora-objects-list-item .islandora-object-thumb {
clear: left;
float: left;
padding: 3px 0 0;
text-align: center;
width: 100px;
}
.islandora-objects-list-item .islandora-object-caption, .islandora-objects-list-item .islandora-object-description {
margin: 0 0 0 130px;
padding-top: 2px;
padding-bottom: 2px;
}
.islandora-object-thumb img {
width: 100%;
}

4
includes/add_datastream.form.inc

@ -39,7 +39,7 @@ function islandora_add_datastream_form(array $form, array &$form_state, FedoraOb
'#collapsed' => FALSE, '#collapsed' => FALSE,
'dsid' => array( 'dsid' => array(
'#title' => 'Datastream ID', '#title' => 'Datastream ID',
'#description' => t("An ID for this stream that is unique to this object. Must start with a letter and contain only alphanumeric characters and dashes and underscores. Datastreams that are defined by the content model don't currently exist: <b>@unused_dsids</b>.", array('@unused_dsids' => $unused_datastreams)), '#description' => t("An ID for this stream that is unique to this object. Must start with a letter and contain only alphanumeric characters, dashes and underscores. The following datastreams are defined by this content model but don't currently exist: <b>@unused_dsids</b>.", array('@unused_dsids' => $unused_datastreams)),
), ),
'#type' => 'textfield', '#type' => 'textfield',
'#size' => 64, '#size' => 64,
@ -57,7 +57,7 @@ function islandora_add_datastream_form(array $form, array &$form_state, FedoraOb
'#required' => TRUE, '#required' => TRUE,
'#size' => 64, '#size' => 64,
'#maxlength' => 64, '#maxlength' => 64,
'#description' => t('A Human readable label'), '#description' => t('A human-readable label'),
'#type' => 'textfield', '#type' => 'textfield',
'#element_validate' => array('islandora_add_datastream_form_field_does_not_contain_a_forward_slash'), '#element_validate' => array('islandora_add_datastream_form_field_does_not_contain_a_forward_slash'),
), ),

2
includes/admin.form.inc

@ -146,7 +146,7 @@ function islandora_repository_admin(array $form, array &$form_state) {
'#type' => 'textfield', '#type' => 'textfield',
'#title' => t('PID namespaces allowed in this Drupal install'), '#title' => t('PID namespaces allowed in this Drupal install'),
'#default_value' => variable_get('islandora_pids_allowed', 'default: demo: changeme: ilives: islandora-book: books: newspapers: '), '#default_value' => variable_get('islandora_pids_allowed', 'default: demo: changeme: ilives: islandora-book: books: newspapers: '),
'#description' => t('A space separated list of PID namespaces that users are permitted to access from this Drupal installation. <br /> This could be more than a simple namespace ie demo:mydemos. <br /> islandora: is reserved and is always allowed.'), '#description' => t('A list of PID namespaces, separated by spaces, that users are permitted to access from this Drupal installation. <br /> This could be more than a simple namespace, e.g. <b>demo:mydemos</b>. <br /> The namespace <b>islandora:</b> is reserved, and is always allowed.'),
'#weight' => 0, '#weight' => 0,
); );
} }

65
includes/breadcrumb.inc

@ -25,13 +25,8 @@
* drupal_set_breadcrumb(). * drupal_set_breadcrumb().
*/ */
function islandora_get_breadcrumbs($object) { function islandora_get_breadcrumbs($object) {
$breadcrumbs = array(); $breadcrumbs = islandora_get_breadcrumbs_recursive($object->id, $object->repository);
islandora_get_breadcrumbs_recursive($object->id, $breadcrumbs, $object->repository); array_pop($breadcrumbs);
if (isset($breadcrumbs[0])) {
// Remove the actual object.
unset($breadcrumbs[0]);
}
$breadcrumbs = array_reverse($breadcrumbs);
return $breadcrumbs; return $breadcrumbs;
} }
@ -40,30 +35,33 @@ function islandora_get_breadcrumbs($object) {
* *
* @todo Make fully recursive... * @todo Make fully recursive...
* *
* @todo Could use some clean up, can't be called multiple times safely due to
* the use of static variables.
*
* @param string $pid * @param string $pid
* THe object id whose parent will be fetched for the next link. * The object id whose parent will be fetched for the next link.
* @param array $breadcrumbs
* The list of existing bread-crumb links in reverse order.
* @param FedoraRepository $repository * @param FedoraRepository $repository
* The fedora repository. * The fedora repository.
* @param array $context
* An associative array of context for internal use when recursing. Currently
* only used to track a single value:
* - level: The number of child-parent relationships to follow. Defaults to
* 10.
*
* @return array
* An array of links representing the breadcrumb trail, "root" first.
*/ */
function islandora_get_breadcrumbs_recursive($pid, array &$breadcrumbs, FedoraRepository $repository) { function islandora_get_breadcrumbs_recursive($pid, FedoraRepository $repository, array &$context = NULL) {
// Before executing the query, we have a base case of accessing the top-level // Before executing the query, we have a base case of accessing the top-level
// collection. // collection.
static $max_level = 10; if ($context === NULL) {
static $level = -1; $context['level'] = 10;
if (count($breadcrumbs) === 0) {
$level = $max_level;
} }
$root = variable_get('islandora_repository_pid', 'islandora:root'); $root = variable_get('islandora_repository_pid', 'islandora:root');
if ($pid == $root) { if ($pid == $root) {
$breadcrumbs[] = l(menu_get_active_title(), 'islandora'); $item = menu_get_item('islandora');
$breadcrumbs[] = l(t('Home'), '<front>'); return array(
l(t('Home'), '<front>'),
l($item['title'], 'islandora'),
);
} }
else { else {
$query_string = 'select $parentObject $title $content from <#ri> $query_string = 'select $parentObject $title $content from <#ri>
@ -82,7 +80,7 @@ function islandora_get_breadcrumbs_recursive($pid, array &$breadcrumbs, FedoraRe
order by $title desc'; order by $title desc';
$results = $repository->ri->itqlQuery($query_string); $results = $repository->ri->itqlQuery($query_string);
if (count($results) > 0 && $level > 0) { if (count($results) > 0 && $context['level'] > 0) {
$parent = $results[0]['parentObject']['value']; $parent = $results[0]['parentObject']['value'];
$this_title = $results[0]['title']['value']; $this_title = $results[0]['title']['value'];
@ -90,16 +88,23 @@ function islandora_get_breadcrumbs_recursive($pid, array &$breadcrumbs, FedoraRe
$this_title = t('-'); $this_title = t('-');
} }
$breadcrumbs[] = l($this_title, "islandora/object/$pid"); $context['level']--;
return array_merge(
$level--; islandora_get_breadcrumbs_recursive($parent, $repository, $context),
islandora_get_breadcrumbs_recursive($parent, $breadcrumbs, $repository); array(
l($this_title, "islandora/object/$pid"),
)
);
} }
else { else {
// Add an non-link, as we don't know how to get back to the root. // Add an non-link, as we don't know how to get back to the root, and
$breadcrumbs[] = '...'; // render the last two links and break (on the next pass).
// And render the last two links and break (on the next pass). return array_merge(
islandora_get_breadcrumbs_recursive($root, $breadcrumbs, $repository); islandora_get_breadcrumbs_recursive($root, $repository, $context),
array(
'...',
)
);
} }
} }
} }

352
includes/ingest.form.inc

@ -26,6 +26,8 @@
* be related. * be related.
* - models: An array of content model PIDs, to which the new object might * - models: An array of content model PIDs, to which the new object might
* subscribe * subscribe
* - parent: The parent of the child to be ingested. This is needed for XACML
* to correctly apply the parent's POLICY to children.
* *
* @return array * @return array
* The form definition of the current step. * The form definition of the current step.
@ -35,7 +37,7 @@ function islandora_ingest_form(array $form, array &$form_state, array $configura
islandora_ingest_form_init_form_state_storage($form_state, $configuration); islandora_ingest_form_init_form_state_storage($form_state, $configuration);
return islandora_ingest_form_execute_step($form, $form_state); return islandora_ingest_form_execute_step($form, $form_state);
} }
catch(Exception $e) { catch (Exception $e) {
drupal_set_message($e->getMessage(), 'error'); drupal_set_message($e->getMessage(), 'error');
return array(array( return array(array(
'#markup' => l(t('Back'), 'javascript:window.history.back();', array('external' => TRUE)))); '#markup' => l(t('Back'), 'javascript:window.history.back();', array('external' => TRUE))));
@ -82,9 +84,42 @@ function islandora_ingest_form_init_form_state_storage(array &$form_state, array
'shared_storage' => $configuration, 'shared_storage' => $configuration,
'step_storage' => array(), 'step_storage' => array(),
); );
// Must be called after $form_state['islandora'] is initialized, otherwise,
// the values in 'islandora' would not be availible to the step hooks.
$form_state['islandora']['step_id'] = islandora_ingest_form_get_first_step_id($form_state);
} }
} }
/**
* Get the first step ID.
*
* @param array $form_state
* The Drupal form state.
*
* @return string
* The 'id' of the very first step.
*/
function islandora_ingest_form_get_first_step_id(array &$form_state) {
$steps = islandora_ingest_form_get_steps($form_state);
$keys = array_keys($steps);
return array_shift($keys);
}
/**
* Get the last step ID.
*
* @param array $form_state
* The Drupal form state.
*
* @return string
* The 'id' of the very last step.
*/
function islandora_ingest_form_get_last_step_id(array &$form_state) {
$steps = islandora_ingest_form_get_steps($form_state);
$keys = array_keys($steps);
return array_pop($keys);
}
/** /**
* Prepares a new object based on the given configuration. * Prepares a new object based on the given configuration.
* *
@ -96,27 +131,29 @@ function islandora_ingest_form_init_form_state_storage(array &$form_state, array
*/ */
function islandora_ingest_form_prepare_new_object(array $configuration) { function islandora_ingest_form_prepare_new_object(array $configuration) {
module_load_include('inc', 'islandora', 'includes/utilities'); module_load_include('inc', 'islandora', 'includes/utilities');
// ID is more specific than namespace so it will take precedence. if (empty($configuration['object'])) {
$id = isset($configuration['namespace']) ? $configuration['namespace'] : 'islandora'; // ID is more specific than namespace so it will take precedence.
$id = isset($configuration['id']) ? $configuration['id'] : $id; $id = isset($configuration['namespace']) ? $configuration['namespace'] : 'islandora';
$label = isset($configuration['label']) ? $configuration['label'] : 'New Object'; $id = isset($configuration['id']) ? $configuration['id'] : $id;
$relationship_map = function($o) { $label = isset($configuration['label']) ? $configuration['label'] : 'New Object';
return array('relationship' => 'isMemberOfCollection', 'pid' => $o); $relationship_map = function($o) {
}; return array('relationship' => 'isMemberOfCollection', 'pid' => $o);
$relationships = empty($configuration['collections']) ? array() : array_map($relationship_map, $configuration['collections']); };
return islandora_prepare_new_object($id, $label, array(), array(), $relationships); $relationships = empty($configuration['collections']) ? array() : array_map($relationship_map, $configuration['collections']);
return islandora_prepare_new_object($id, $label, array(), array(), $relationships);
}
return $configuration['object'];
} }
/** /**
* Gets the given/current step. * Gets the given/current step.
* *
* The current step is returned if no step ID is given. If the current step is * If the current step is not defined it's assumed that all steps have executed.
* not defined it's assume to be the first step.
* *
* @param array $form_state * @param array $form_state
* The Drupal form state. * The Drupal form state.
* @param string $step_id * @param string $step_id
* The ID of the step. * The ID of the step. The current step is returned if no step ID is given.
* *
* @return array * @return array
* The given/current step if found, NULL otherwise. * The given/current step if found, NULL otherwise.
@ -130,10 +167,48 @@ function islandora_ingest_form_get_step(array &$form_state, $step_id = NULL) {
return NULL; return NULL;
} }
/**
* Gets the next step.
*
* If the current step is not defined it's assumed that all steps have executed.
*
* @param array $form_state
* The Drupal form state.
* @param string $step
* The step relative to the result, if not provided the current step is used.
*
* @return string
* The next step if found, NULL otherwise.
*/
function islandora_ingest_form_get_next_step(array &$form_state, array $step = NULL) {
$step = isset($step) ? $step : islandora_ingest_form_get_step($form_state);
$next_step_id = islandora_ingest_form_get_next_step_id($form_state, $step['id']);
return isset($next_step_id) ? islandora_ingest_form_get_step($form_state, $next_step_id) : NULL;
}
/**
* Gets the previous step.
*
* If the current step is not defined it's assumed that all steps have executed.
*
* @param array $form_state
* The Drupal form state.
* @param string $step
* The step relative to the result, if not provided the current step is used.
*
* @return string
* The next step if found, NULL otherwise.
*/
function islandora_ingest_form_get_previous_step(array &$form_state, array $step = NULL) {
$step = isset($step) ? $step : islandora_ingest_form_get_step($form_state);
$previous_step_id = islandora_ingest_form_get_previous_step_id($form_state, $step['id']);
return isset($previous_step_id) ? islandora_ingest_form_get_step($form_state, $previous_step_id) : NULL;
}
/** /**
* Gets the ID of the current step. * Gets the ID of the current step.
* *
* If a current step is not defined, its assumed to be the first step. * If the current step is not defined it's assumed that all steps have executed.
* *
* @param array $form_state * @param array $form_state
* The Drupal form state. * The Drupal form state.
@ -142,26 +217,25 @@ function islandora_ingest_form_get_step(array &$form_state, $step_id = NULL) {
* The step ID. * The step ID.
*/ */
function islandora_ingest_form_get_current_step_id(array &$form_state) { function islandora_ingest_form_get_current_step_id(array &$form_state) {
if (empty($form_state['islandora']['step_id'])) {
$steps = islandora_ingest_form_get_steps($form_state);
return array_shift(array_keys($steps));
}
return $form_state['islandora']['step_id']; return $form_state['islandora']['step_id'];
} }
/** /**
* Gets the ID of the next step. * Gets the ID of the next step.
* *
* If a current step is not defined, its assumed to be the first step. * If the current step is not defined it's assumed that all steps have executed.
* *
* @param array $form_state * @param array $form_state
* The Drupal form state. * The Drupal form state.
* @param string $step_id
* The ID of the step relative to the result, if not provided the current
* step_id is used.
* *
* @return string * @return string
* The next step ID if found, NULL otherwise. * The next step ID if found, NULL otherwise.
*/ */
function islandora_ingest_form_get_next_step_id(array &$form_state) { function islandora_ingest_form_get_next_step_id(array &$form_state, $step_id = NULL) {
$step_id = islandora_ingest_form_get_current_step_id($form_state); $step_id = isset($step_id) ? $step_id : islandora_ingest_form_get_current_step_id($form_state);
$step_ids = array_keys(islandora_ingest_form_get_steps($form_state)); $step_ids = array_keys(islandora_ingest_form_get_steps($form_state));
$index = array_search($step_id, $step_ids); $index = array_search($step_id, $step_ids);
$count = count($step_ids); $count = count($step_ids);
@ -174,16 +248,25 @@ function islandora_ingest_form_get_next_step_id(array &$form_state) {
/** /**
* Gets the ID of the previous step. * Gets the ID of the previous step.
* *
* If a current step is not defined, its assumed to be the first step. * If the current step is not defined it's assumed that all steps have executed.
* In such cases the last step will be returned.
* *
* @param array $form_state * @param array $form_state
* The Drupal form state. * The Drupal form state.
* @param string $step_id
* The ID of the step relative to the result, if not provided the current
* step_id is used.
* *
* @return string * @return string
* The previous step ID if found, NULL otherwise. * The previous step ID if found, NULL otherwise.
*/ */
function islandora_ingest_form_get_previous_step_id(array &$form_state) { function islandora_ingest_form_get_previous_step_id(array &$form_state, $step_id = NULL) {
$step_id = islandora_ingest_form_get_current_step_id($form_state); $step_id = isset($step_id) ? $step_id : islandora_ingest_form_get_current_step_id($form_state);
// If the current step is not defined it's assumed that all steps have
// executed. So return the very last step.
if ($step_id == NULL) {
return islandora_ingest_form_get_last_step_id($form_state);
}
$step_ids = array_keys(islandora_ingest_form_get_steps($form_state)); $step_ids = array_keys(islandora_ingest_form_get_steps($form_state));
$index = array_search($step_id, $step_ids); $index = array_search($step_id, $step_ids);
if ($index !== FALSE && --$index >= 0) { if ($index !== FALSE && --$index >= 0) {
@ -203,11 +286,9 @@ function islandora_ingest_form_increment_step(array &$form_state) {
// of the current step could have added/removed a step. // of the current step could have added/removed a step.
drupal_static_reset('islandora_ingest_form_get_steps'); drupal_static_reset('islandora_ingest_form_get_steps');
$next_step_id = islandora_ingest_form_get_next_step_id($form_state); $next_step_id = islandora_ingest_form_get_next_step_id($form_state);
if (isset($next_step_id)) { islandora_ingest_form_stash_info($form_state);
islandora_ingest_form_stash_info($form_state); $form_state['islandora']['step_id'] = $next_step_id;
$form_state['islandora']['step_id'] = $next_step_id; islandora_ingest_form_grab_info($form_state);
islandora_ingest_form_grab_info($form_state);
}
} }
/** /**
@ -218,6 +299,7 @@ function islandora_ingest_form_increment_step(array &$form_state) {
*/ */
function islandora_ingest_form_decrement_step(array &$form_state) { function islandora_ingest_form_decrement_step(array &$form_state) {
$previous_step_id = islandora_ingest_form_get_previous_step_id($form_state); $previous_step_id = islandora_ingest_form_get_previous_step_id($form_state);
// Don't decrement passed the first step.
if (isset($previous_step_id)) { if (isset($previous_step_id)) {
islandora_ingest_form_stash_info($form_state); islandora_ingest_form_stash_info($form_state);
$form_state['islandora']['step_id'] = $previous_step_id; $form_state['islandora']['step_id'] = $previous_step_id;
@ -229,16 +311,18 @@ function islandora_ingest_form_decrement_step(array &$form_state) {
* Build a list of steps given only configuration. * Build a list of steps given only configuration.
* *
* XXX: This is used to give an indication of whether there are any steps for a * XXX: This is used to give an indication of whether there are any steps for a
* given list of content models. * given configuration.
* *
* @param array $configuration * @param array $configuration
* The list of key/value pairs of configuration. * The list of key/value pairs of configuration.
*/ */
function islandora_ingest_get_approximate_steps(array $configuration) { function islandora_ingest_get_approximate_steps(array $configuration) {
try { try {
// @todo, we need to expand the configuration before we can validate it?
// I think this need some thinking.
islandora_ingest_form_validate_configuration($configuration); islandora_ingest_form_validate_configuration($configuration);
} }
catch(InvalidArgumentException $e) { catch (InvalidArgumentException $e) {
// Don't log or display exception. // Don't log or display exception.
return array(); return array();
} }
@ -266,16 +350,19 @@ function islandora_ingest_get_approximate_steps(array $configuration) {
* @return array * @return array
* The form definition of the current step. * The form definition of the current step.
*/ */
function islandora_ingest_form_execute_step(array $form, array &$form_state) { function islandora_ingest_form_execute_step(array $form, array &$form_state, $step_id = NULL) {
// Load any required files for the current step. // Load any required files for the current step.
islandora_ingest_form_load_include($form_state); islandora_ingest_form_load_include($form_state);
$step = islandora_ingest_form_get_step($form_state); $step = isset($step_id) ? islandora_ingest_form_get_step($form_state) : islandora_ingest_form_get_step($form_state, $step_id);
switch ($step['type']) { switch ($step['type']) {
case 'callback':
// Execute all the consecutive callbacks, and move then attempt to process
// the next step.
islandora_ingest_form_execute_consecutive_callback_steps($form, $form_state, $step);
return islandora_ingest_form_execute_step($form, $form_state);
case 'form': case 'form':
$args = array($form, &$form_state); return islandora_ingest_form_execute_form_step($form, $form_state, $step);
$args = isset($step['args']) ? array_merge($args, $step['args']) : $args;
$form = call_user_func_array($step['form_id'], $args);
return islandora_ingest_form_stepify($form, $form_state, $step);
case 'batch': case 'batch':
// @todo Implement if possible. // @todo Implement if possible.
@ -284,6 +371,94 @@ function islandora_ingest_form_execute_step(array $form, array &$form_state) {
return array(); return array();
} }
/**
* Execute the given 'form' step.
*
* Assumes the given step is a 'form' step.
*
* @param array $form
* The Drupal form.
* @param array $form_state
* The Drupal form state.
*
* @return array
* The form definition of the given step.
*/
function islandora_ingest_form_execute_form_step(array $form, array &$form_state, array $step) {
$args = array($form, &$form_state);
$args = isset($step['args']) ? array_merge($args, $step['args']) : $args;
$form = call_user_func_array($step['form_id'], $args);
return islandora_ingest_form_stepify($form, $form_state, $step);
}
/**
* Execute the given 'callback' step and any consecutive 'callback' steps.
*
* Assumes the given step is a 'callback' step.
*
* @param array $form
* The Drupal form.
* @param array $form_state
* The Drupal form state.
*/
function islandora_ingest_form_execute_consecutive_callback_steps(array $form, array &$form_state, array $step) {
do {
islandora_ingest_form_execute_callback_step($form, $form_state, $step);
islandora_ingest_form_increment_step($form_state);
$step = islandora_ingest_form_get_step($form_state);
} while (isset($step) && $step['type'] == 'callback');
}
/**
* Execute the given 'callback' step.
*
* Assumes the given step is a 'callback' step.
*
* @param array $form
* The Drupal form.
* @param array $form_state
* The Drupal form state.
*/
function islandora_ingest_form_execute_callback_step(array $form, array &$form_state, array $step) {
$args = array(&$form_state);
$args = isset($step['do_function']['args']) ? array_merge($args, $step['do_function']['args']) : $args;
call_user_func_array($step['do_function']['function'], $args);
}
/**
* Undo the given 'callback' step and any consecutive 'callback' steps.
*
* Assumes the given $step is a 'callback' step.
*
* @param array $form
* The Drupal form.
* @param array $form_state
* The Drupal form state.
*/
function islandora_ingest_form_undo_consecutive_callback_steps(array $form, array &$form_state, array $step) {
do {
islandora_ingest_form_undo_callback_step($form, $form_state, $step);
islandora_ingest_form_decrement_step($form_state);
$step = islandora_ingest_form_get_step($form_state);
} while (isset($step) && $step['type'] == 'callback');
}
/**
* Undo the given 'callback' step.
*
* Assumes the given $step is a 'callback' step.
*
* @param array $form
* The Drupal form.
* @param array $form_state
* The Drupal form state.
*/
function islandora_ingest_form_undo_callback_step(array $form, array &$form_state, array $step) {
$args = array(&$form_state);
$args = isset($step['undo_function']['args']) ? array_merge($args, $step['undo_function']['args']) : $args;
call_user_func_array($step['undo_function']['function'], $args);
}
/** /**
* Append Prev/Next buttons submit/validation handlers etc. * Append Prev/Next buttons submit/validation handlers etc.
* *
@ -293,22 +468,20 @@ function islandora_ingest_form_execute_step(array $form, array &$form_state) {
* The Drupal form state. * The Drupal form state.
* *
* @return array * @return array
* The stepified drupal form definition for the given step. * The stepified Drupal form definition for the given step.
*/ */
function islandora_ingest_form_stepify(array $form, array &$form_state, $step) { function islandora_ingest_form_stepify(array $form, array &$form_state, $step) {
$first_step = islandora_ingest_form_on_first_step($form_state); $first_form_step = islandora_ingest_form_on_first_form_step($form_state);
$last_step = islandora_ingest_form_on_last_step($form_state); $last_form_step = islandora_ingest_form_on_last_form_step($form_state);
$form['prev'] = $first_step ? NULL : islandora_ingest_form_previous_button($form_state); $form['prev'] = $first_form_step ? NULL : islandora_ingest_form_previous_button($form_state);
$form['next'] = $last_step ? islandora_ingest_form_ingest_button($form_state) : islandora_ingest_form_next_button($form_state); $form['next'] = $last_form_step ? islandora_ingest_form_ingest_button($form_state) : islandora_ingest_form_next_button($form_state);
// Allow for a hook_form_FORM_ID_alter(). // Allow for a hook_form_FORM_ID_alter().
drupal_alter(array('form_' . $step['form_id'], 'form'), $form, $form_state, $step['form_id']); drupal_alter(array('form_' . $step['form_id'], 'form'), $form, $form_state, $step['form_id']);
return $form; return $form;
} }
/** /**
* Checks if we are on the first step. * Checks if we are on the first form step.
* *
* @param array $form_state * @param array $form_state
* The Drupal form state. * The Drupal form state.
@ -316,14 +489,12 @@ function islandora_ingest_form_stepify(array $form, array &$form_state, $step) {
* @return bool * @return bool
* TRUE if we are currently on the first step, FALSE otherwise. * TRUE if we are currently on the first step, FALSE otherwise.
*/ */
function islandora_ingest_form_on_first_step(array &$form_state) { function islandora_ingest_form_on_first_form_step(array &$form_state) {
$step_id = islandora_ingest_form_get_current_step_id($form_state); return !islandora_ingest_form_get_previous_form_step($form_state);
$step_ids = array_keys(islandora_ingest_form_get_steps($form_state));
return array_search($step_id, $step_ids) == 0;
} }
/** /**
* Checks if we are on the last step. * Checks if we are on the last form step.
* *
* @param array $form_state * @param array $form_state
* The Drupal form state. * The Drupal form state.
@ -331,11 +502,42 @@ function islandora_ingest_form_on_first_step(array &$form_state) {
* @return bool * @return bool
* TRUE if we are currently on the last step, FALSE otherwise. * TRUE if we are currently on the last step, FALSE otherwise.
*/ */
function islandora_ingest_form_on_last_step(array &$form_state) { function islandora_ingest_form_on_last_form_step(array &$form_state) {
$step_id = islandora_ingest_form_get_current_step_id($form_state); return !islandora_ingest_form_get_next_form_step($form_state);
$step_ids = array_keys(islandora_ingest_form_get_steps($form_state)); }
$count = count($step_ids);
return array_search($step_id, $step_ids) == --$count; /**
* Get the previous form step relative to the current step.
*
* @param array $form_state
* The Drupal form state.
*
* @return array
* The previous form step if one exists, NULL otherwise.
*/
function islandora_ingest_form_get_previous_form_step(array &$form_state) {
$step = NULL;
do {
$step = islandora_ingest_form_get_previous_step($form_state, $step);
} while (isset($step) && $step['type'] != 'form');
return $step;
}
/**
* Get the next form step relative to the current step.
*
* @param array $form_state
* The Drupal form state.
*
* @return array
* The next form step if one exists, NULL otherwise.
*/
function islandora_ingest_form_get_next_form_step(array &$form_state) {
$step = NULL;
do {
$step = islandora_ingest_form_get_next_step($form_state, $step);
} while (isset($step) && $step['type'] != 'form');
return $step;
} }
/** /**
@ -350,13 +552,12 @@ function islandora_ingest_form_on_last_step(array &$form_state) {
* The previous button for the ingest form. * The previous button for the ingest form.
*/ */
function islandora_ingest_form_previous_button(array &$form_state) { function islandora_ingest_form_previous_button(array &$form_state) {
// Before we move back to the previous step we should tell the previous step // Before we move back to the previous step we should tell the previous steps
// to undo whatever its submit handler did. // to undo whatever its submit handler did.
$prev_step_id = islandora_ingest_form_get_previous_step_id($form_state); $prev_form_step = islandora_ingest_form_get_previous_form_step($form_state);
$prev_step = islandora_ingest_form_get_step($form_state, $prev_step_id); $form_id = $prev_form_step['form_id'];
$form_id = $prev_step['form_id'];
$submit_callback = $form_id . '_undo_submit'; $submit_callback = $form_id . '_undo_submit';
$submit = function_exists($submit_callback) ? array($submit_callback, 'islandora_ingest_form_previous_submit') : array('islandora_ingest_form_undo_submit'); $submit = function_exists($submit_callback) ? array($submit_callback, 'islandora_ingest_form_previous_submit') : array('islandora_ingest_form_previous_submit');
return array( return array(
'#type' => 'submit', '#type' => 'submit',
'#value' => t('Previous'), '#value' => t('Previous'),
@ -387,6 +588,11 @@ function islandora_ingest_form_previous_button(array &$form_state) {
*/ */
function islandora_ingest_form_previous_submit(array $form, array &$form_state) { function islandora_ingest_form_previous_submit(array $form, array &$form_state) {
islandora_ingest_form_decrement_step($form_state); islandora_ingest_form_decrement_step($form_state);
$step = islandora_ingest_form_get_step($form_state);
// Undo all callbacks that occured after the previous step.
if ($step['type'] == 'callback') {
islandora_ingest_form_undo_consecutive_callback_steps($form, $form_state, $step);
}
$form_state['rebuild'] = TRUE; $form_state['rebuild'] = TRUE;
} }
@ -442,8 +648,10 @@ function islandora_ingest_form_next_submit(array $form, array &$form_state) {
*/ */
function islandora_ingest_form_stash_info(array &$form_state) { function islandora_ingest_form_stash_info(array &$form_state) {
$storage = &islandora_ingest_form_get_step_storage($form_state); $storage = &islandora_ingest_form_get_step_storage($form_state);
$storage['values'] = $form_state['values']; if ($storage) {
unset($form_state['values']); $storage['values'] = $form_state['values'];
unset($form_state['values']);
}
} }
/** /**
@ -489,12 +697,17 @@ function islandora_ingest_form_ingest_button(array &$form_state) {
* *
* Attempts to ingest every object built by the previous steps. * Attempts to ingest every object built by the previous steps.
* *
* @param array $form
* The Drupal form.
* @param array $form_state * @param array $form_state
* The Drupal form state. * The Drupal form state.
*/ */
function islandora_ingest_form_submit(array $form, array &$form_state) { function islandora_ingest_form_submit(array $form, array &$form_state) {
// Execute any remaining callbacks.
islandora_ingest_form_increment_step($form_state);
$step = islandora_ingest_form_get_step($form_state);
if (isset($step) && $step['type'] == 'callback') {
islandora_ingest_form_execute_consecutive_callback_steps($form, $form_state, $step);
}
// Ingest the objects.
foreach ($form_state['islandora']['objects'] as $object) { foreach ($form_state['islandora']['objects'] as $object) {
try { try {
islandora_add_object($object); islandora_add_object($object);
@ -503,7 +716,7 @@ function islandora_ingest_form_submit(array $form, array &$form_state) {
catch (Exception $e) { catch (Exception $e) {
// If post hooks throws it may already exist at this point but may be // If post hooks throws it may already exist at this point but may be
// invalid, so don't say failed. // invalid, so don't say failed.
watchdog('islandora', $e->getMessage(), NULL, WATCHDOG_ERROR); watchdog('islandora', 'Exception Message: @exception.', array('@exception' => $e->getMessage()), WATCHDOG_ERROR);
drupal_set_message(t('A problem occured while ingesting "@label" (ID: @pid), please notifiy the administrator.', array('@label' => $object->label, '@pid' => $object->id)), 'error'); drupal_set_message(t('A problem occured while ingesting "@label" (ID: @pid), please notifiy the administrator.', array('@label' => $object->label, '@pid' => $object->id)), 'error');
} }
} }
@ -563,7 +776,8 @@ function &islandora_ingest_form_get_step_storage(array &$form_state, $step_id =
} }
return $form_state['islandora']['step_storage'][$step_id]; return $form_state['islandora']['step_storage'][$step_id];
} }
return NULL; $undefined_step_storage = array();
return $undefined_step_storage;
} }
/** /**
@ -621,6 +835,8 @@ function islandora_ingest_form_get_steps(array &$form_state) {
$shared_storage = &islandora_ingest_form_get_shared_storage($form_state); $shared_storage = &islandora_ingest_form_get_shared_storage($form_state);
foreach (islandora_build_hook_list(ISLANDORA_INGEST_STEP_HOOK, $shared_storage['models']) as $hook) { foreach (islandora_build_hook_list(ISLANDORA_INGEST_STEP_HOOK, $shared_storage['models']) as $hook) {
// Required for pass by reference. // Required for pass by reference.
// @todo Change this around so that it isn't passed by reference, there
// Is an alter below that can handle that requirement.
foreach (module_implements($hook) as $module) { foreach (module_implements($hook) as $module) {
$function = $module . '_' . $hook; $function = $module . '_' . $hook;
$module_steps = (array) $function($form_state); $module_steps = (array) $function($form_state);
@ -631,6 +847,10 @@ function islandora_ingest_form_get_steps(array &$form_state) {
foreach (islandora_build_hook_list(ISLANDORA_INGEST_STEP_HOOK, $shared_storage['models']) as $hook) { foreach (islandora_build_hook_list(ISLANDORA_INGEST_STEP_HOOK, $shared_storage['models']) as $hook) {
drupal_alter($hook, $steps, $form_state); drupal_alter($hook, $steps, $form_state);
} }
// Add any defaults.
foreach ($steps as $key => &$step) {
$step['id'] = $key;
}
uasort($steps, 'drupal_sort_weight'); uasort($steps, 'drupal_sort_weight');
return $steps; return $steps;
} }

49
includes/ingest.menu.inc

@ -1,49 +0,0 @@
<?php
/**
* @file
* Ingest Menu callback hooks.
*/
/**
* Menu callback, Renders the multi-page ingest form if possible.
*
* @return string
* HTML representing the mult-page ingest form.
*/
function islandora_ingest_callback() {
module_load_include('inc', 'islandora', 'includes/ingest.form');
try {
$configuration = islandora_ingest_get_configuration();
return drupal_get_form('islandora_ingest_form', $configuration);
}
catch(Exception $e) {
$redirect = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '<front>';
// Redirect back to referer or top level collection.
drupal_goto($redirect);
}
}
/**
* Fetches the ingest configuration from the $_GET parameters.
*
* Generic parameters as accepted by all ingest processes, other modules may
* add to this list.
* id -> The pid of the object to create. optional.
* models -> Comma delimited list of all the content models the created object
* should have.
* collections -> Comma delimited list of all the collections the created
* object should belong to.
*
* @return array
* The configuration options used to build the multi-paged ingest process.
*/
function islandora_ingest_get_configuration() {
$configuration = $_GET;
unset($configuration['q']);
$convert_to_array_keys = array_intersect(array('models', 'collections'), array_keys($configuration));
foreach ($convert_to_array_keys as $key) {
$configuration[$key] = explode(',', $configuration[$key]);
}
return $configuration;
}

6
includes/object_properties.form.inc

@ -30,7 +30,7 @@ function islandora_object_properties_form(array $form, array &$form_state, Fedor
'#title' => t('Item Label'), '#title' => t('Item Label'),
'#default_value' => $object->label, '#default_value' => $object->label,
'#required' => 'TRUE', '#required' => 'TRUE',
'#description' => t('A Human readable label'), '#description' => t('A human-readable label'),
// Double the normal length. // Double the normal length.
'#size' => 120, '#size' => 120,
// Max length for a Fedora Label. // Max length for a Fedora Label.
@ -43,14 +43,14 @@ function islandora_object_properties_form(array $form, array &$form_state, Fedor
'#title' => t('Owner'), '#title' => t('Owner'),
'#default_value' => $object->owner, '#default_value' => $object->owner,
'#required' => FALSE, '#required' => FALSE,
'#description' => t('The owner id'), '#description' => t("The owner's account name"),
'#type' => 'textfield', '#type' => 'textfield',
), ),
'object_state' => array( 'object_state' => array(
'#title' => t('State'), '#title' => t('State'),
'#default_value' => $object->state, '#default_value' => $object->state,
'#required' => TRUE, '#required' => TRUE,
'#description' => t('The items state one of active, inactive or deleted'), '#description' => t("The object's state (active, inactive or deleted)"),
'#type' => 'select', '#type' => 'select',
'#options' => array('A' => 'Active', 'I' => 'Inactive', 'D' => 'Deleted'), '#options' => array('A' => 'Active', 'I' => 'Inactive', 'D' => 'Deleted'),
), ),

115
includes/solution_packs.inc

@ -187,30 +187,48 @@ function islandora_solution_pack_form_submit(array $form, array &$form_state) {
*/ */
function islandora_solution_pack_batch_operation_reingest_object(NewFedoraObject $object, array &$context) { function islandora_solution_pack_batch_operation_reingest_object(NewFedoraObject $object, array &$context) {
$existing_object = islandora_object_load($object->id); $existing_object = islandora_object_load($object->id);
$deleted = FALSE;
if ($existing_object) { if ($existing_object) {
$deleted = islandora_delete_object($existing_object); $deleted = islandora_delete_object($existing_object);
if (!$deleted) { if (!$deleted) {
$object_link = l($existing_object->label, "islandora/object/{$existing_object->id}"); $object_link = l($existing_object->label, "islandora/object/{$existing_object->id}");
drupal_set_message(t('Failed to purge existing object !object_link.', array( drupal_set_message(filter_xss(t('Failed to purge existing object !object_link.', array(
'!object_link' => $object_link, '!object_link' => $object_link,
)), 'error'); ))), 'error');
// Failed to purge don't attempt to ingest. // Failed to purge don't attempt to ingest.
return; return;
} }
} }
// Object was deleted or did not exist. // Object was deleted or did not exist.
$pid = $object->id; $pid = $object->id;
$label = $object->label; $label = $object->label;
$action = $deleted ? 'reinstalled' : 'installed';
$object_link = l($label, "islandora/object/{$pid}"); $object_link = l($label, "islandora/object/{$pid}");
$object = islandora_add_object($object); $object = islandora_add_object($object);
$msg = $object ? "Successfully $action !object_link." : "Failed to $action @label identified by @pid."; $params = array(
'@pid' => $pid,
'@label' => $label,
'!object_link' => $object_link,
);
$msg = '';
if ($object) {
if ($deleted) {
$msg = t('Successfully reinstalled !object_link.', $params);
}
else {
$msg = t('Successfully installed !object_link.', $params);
}
}
elseif ($deleted) {
$msg = t('Failed to reinstall @label, identified by @pid.', $params);
}
else {
$msg = t('Failed to install @label, identified by @pid.', $params);
}
$status = $object ? 'status' : 'error'; $status = $object ? 'status' : 'error';
drupal_set_message(t($msg, array( drupal_set_message(filter_xss($msg), $status);
'@pid' => $pid,
'@label' => $label,
'!object_link' => $object_link,
)), $status);
} }
/** /**
@ -237,33 +255,37 @@ function islandora_install_solution_pack($module, $op = 'install') {
islandora_uninstall_solution_pack($module); islandora_uninstall_solution_pack($module);
return; return;
} }
$t = get_t();
// Some general replacements.
$admin_link = l($t('Solution Pack admin'), 'admin/islandora/solution_packs');
$config_link = l($t('Islandora configuration'), 'admin/islandora/configure');
$t_params = array(
'@module' => $module,
'!config_link' => $config_link,
'!admin_link' => $admin_link,
);
module_load_include('module', 'islandora', 'islandora'); module_load_include('module', 'islandora', 'islandora');
module_load_include('inc', 'islandora', 'includes/utilities'); module_load_include('inc', 'islandora', 'includes/utilities');
module_load_include('module', $module, $module); module_load_include('module', $module, $module);
$info_file = drupal_get_path('module', $module) . "/{$module}.info"; $info_file = drupal_get_path('module', $module) . "/{$module}.info";
$info_array = drupal_parse_info_file($info_file); $info_array = drupal_parse_info_file($info_file);
$module_name = $info_array['name']; $module_name = $info_array['name'];
$admin_link = l(t('Solution Pack admin'), 'admin/islandora/solution_packs');
$config_link = l(t('Islandora configuration'), 'admin/islandora/configure');
if (!islandora_describe_repository()) { if (!islandora_describe_repository()) {
$msg = '@module: Did not install any objects. Could not connect to the '; $msg = $t('@module: Did not install any objects. Could not connect to the repository. Please check the settings on the !config_link page and install the required objects manually on the !admin_link page.', $t_params);
$msg .= 'repository. Please check the settings on the !config_link page '; drupal_set_message(filter_xss($msg), 'error');
$msg .= 'and install the required objects manually on the !admin_link page.';
drupal_set_message(st($msg, array(
'@module' => $module_name,
'!config_link' => $config_link,
'@admin_link' => $admin_link,
)), 'error');
return; return;
} }
$connection = islandora_get_tuque_connection(); $connection = islandora_get_tuque_connection();
$required_objects = module_invoke($module, 'islandora_required_objects', $connection); $required_objects = module_invoke($module, 'islandora_required_objects', $connection);
$objects = $required_objects[$module]['objects']; $objects = $required_objects[$module]['objects'];
$status_messages = array( $status_messages = array(
'up_to_date' => 'The object already exists and is up-to-date', 'up_to_date' => $t('The object already exists and is up-to-date.', $t_params),
'missing_datastream' => 'The object already exists but is missing a datastream. Please reinstall the object on the !admin_link page', 'missing_datastream' => $t('The object already exists but is missing a datastream. Please reinstall the object on the !admin_link page.', $t_params),
'out_of_date' => 'The object already exists but is out-of-date. Please update the object on the !admin_link page', 'out_of_date' => $t('The object already exists but is out-of-date. Please update the object on the !admin_link page.', $t_params),
'modified_datastream' => 'The object already exists but datastreams are modified. Please reinstall the object on the !admin_link page', 'modified_datastream' => $t('The object already exists but datastreams are modified. Please reinstall the object on the !admin_link page.', $t_params),
); );
foreach ($objects as $object) { foreach ($objects as $object) {
$query = $connection->api->a->findObjects('query', 'pid=' . $object->id); $query = $connection->api->a->findObjects('query', 'pid=' . $object->id);
@ -272,26 +294,25 @@ function islandora_install_solution_pack($module, $op = 'install') {
$object_link = l($label, "islandora/object/{$object->id}"); $object_link = l($label, "islandora/object/{$object->id}");
if ($already_exists) { if ($already_exists) {
$object_status = islandora_check_object_status($object); $object_status = islandora_check_object_status($object);
$status_msg = $status_messages[$object_status['status']]; $here_params = array(
drupal_set_message(st("@module: Did not install !object_link. $status_msg.", array( '!summary' => $t("@module: Did not install !object_link.", array(
'@module' => $module_name,
'!object_link' => $object_link, '!object_link' => $object_link,
'!admin_link' => $admin_link, ) + $t_params),
)), 'warning'); '!description' => $status_messages[$object_status['status']],
);
drupal_set_message(filter_xss(format_string('!summary !description', $here_params)), 'warning');
} }
else { else {
$object = islandora_add_object($object); $object = islandora_add_object($object);
if ($object) { if ($object) {
drupal_set_message(t('@module: Successfully installed. !object_link.', array( drupal_set_message(filter_xss($t('@module: Successfully installed. !object_link.', array(
'@module' => $module_name,
'!object_link' => $object_link, '!object_link' => $object_link,
)), 'status'); ) + $t_params)), 'status');
} }
else { else {
drupal_set_message(t('@module: Failed to install. @label.', array( drupal_set_message($t('@module: Failed to install. @label.', array(
'@module' => $module_name,
'@label' => $label, '@label' => $label,
)), 'warning'); ) + $t_params), 'warning');
} }
} }
} }
@ -307,21 +328,20 @@ function islandora_install_solution_pack($module, $op = 'install') {
* directly for each solution pack. * directly for each solution pack.
*/ */
function islandora_uninstall_solution_pack($module) { function islandora_uninstall_solution_pack($module) {
$t = get_t();
module_load_include('module', 'islandora', 'islandora'); module_load_include('module', 'islandora', 'islandora');
module_load_include('inc', 'islandora', 'includes/utilities'); module_load_include('inc', 'islandora', 'includes/utilities');
module_load_include('module', $module, $module); module_load_include('module', $module, $module);
$config_link = l(t('Islandora configuration'), 'admin/islandora/configure'); $config_link = l($t('Islandora configuration'), 'admin/islandora/configure');
$info_file = drupal_get_path('module', $module) . "/{$module}.info"; $info_file = drupal_get_path('module', $module) . "/{$module}.info";
$info_array = drupal_parse_info_file($info_file); $info_array = drupal_parse_info_file($info_file);
$module_name = $info_array['name']; $module_name = $info_array['name'];
if (!islandora_describe_repository()) { if (!islandora_describe_repository()) {
$msg = '@module: Did not uninstall any objects. Could not connect to the '; $msg = $t('@module: Did not uninstall any objects. Could not connect to the repository. Please check the settings on the !config_link page and uninstall the required objects manually if necessary.', array(
$msg .= 'repository. Please check the settings on the !config_link page '; '@module' => $module_name,
$msg .= 'and uninstall the required objects manually if necessary.'; '!config_link' => $config_link,
drupal_set_message(st($msg, array( ));
'@module' => $module_name, drupal_set_message(filter_xss($msg), 'error');
'!config_link' => $config_link,
)), 'error');
return; return;
} }
$connection = islandora_get_tuque_connection(); $connection = islandora_get_tuque_connection();
@ -334,12 +354,13 @@ function islandora_uninstall_solution_pack($module) {
}; };
$existing_objects = array_filter($objects, $filter); $existing_objects = array_filter($objects, $filter);
foreach ($existing_objects as $object) { foreach ($existing_objects as $object) {
$msg = '@module: Did not remove !object_link. It may be used by other sites.';
$object_link = l($object->label, "islandora/object/{$object->id}"); $object_link = l($object->label, "islandora/object/{$object->id}");
drupal_set_message(st($msg, array( $msg = $t('@module: Did not remove !object_link. It may be used by other sites.', array(
'!object_link' => $object_link, '!object_link' => $object_link,
'@module' => $module_name, '@module' => $module_name,
)), 'warning'); ));
drupal_set_message(filter_xss($msg), 'warning');
} }
} }

22
includes/tuque_wrapper.inc

@ -35,22 +35,20 @@ $islandora_module_path = drupal_get_path('module', 'islandora');
* Allow modules to alter an object before a mutable event occurs. * Allow modules to alter an object before a mutable event occurs.
*/ */
function islandora_alter_object(AbstractFedoraObject $object, array &$context) { function islandora_alter_object(AbstractFedoraObject $object, array &$context) {
$types = array('islandora_object'); module_load_include('inc', 'islandora', 'includes/utilities');
foreach ($object->models as $model) { drupal_alter(islandora_build_hook_list('islandora_object', $object->models), $object, $context);
$types[] = "{$model}_islandora_object";
}
drupal_alter($types, $object, $context);
} }
/** /**
* Allow modules to alter a datastream before a mutable event occurs. * Allow modules to alter a datastream before a mutable event occurs.
*/ */
function islandora_alter_datastream(AbstractFedoraObject $object, AbstractDatastream $datastream, array &$context) { function islandora_alter_datastream(AbstractFedoraObject $object, AbstractDatastream $datastream, array &$context) {
$types = array('islandora_datastream'); module_load_include('inc', 'islandora', 'includes/utilities');
$types = array();
foreach ($object->models as $model) { foreach ($object->models as $model) {
$types[] = "{$model}_{$datastream->id}_islandora_datastream"; $types[] = "{$model}_{$datastream->id}";
} }
drupal_alter($types, $object, $datastream, $context); drupal_alter(islandora_build_hook_list('islandora_datastream', $types), $object, $datastream, $context);
} }
/** /**
@ -207,7 +205,7 @@ class IslandoraFedoraApiM extends FedoraApiM {
} }
return $ret; return $ret;
} }
catch(Exception $e) { catch (Exception $e) {
watchdog('islandora', 'Failed to modify datastream @dsid from @pid</br>code: @code<br/>message: @msg', array( watchdog('islandora', 'Failed to modify datastream @dsid from @pid</br>code: @code<br/>message: @msg', array(
'@pid' => $pid, '@pid' => $pid,
'@dsid' => $dsid, '@dsid' => $dsid,
@ -241,7 +239,7 @@ class IslandoraFedoraApiM extends FedoraApiM {
} }
return $ret; return $ret;
} }
catch(Exception $e) { catch (Exception $e) {
watchdog('islandora', 'Failed to modify object: @pid</br>code: @code<br/>message: @msg', array( watchdog('islandora', 'Failed to modify object: @pid</br>code: @code<br/>message: @msg', array(
'@pid' => $pid, '@pid' => $pid,
'@code' => $e->getCode(), '@code' => $e->getCode(),
@ -283,7 +281,7 @@ class IslandoraFedoraApiM extends FedoraApiM {
return $ret; return $ret;
} }
} }
catch(Exception $e) { catch (Exception $e) {
watchdog('islandora', 'Failed to purge datastream @dsid from @pid</br>code: @code<br/>message: @msg', array( watchdog('islandora', 'Failed to purge datastream @dsid from @pid</br>code: @code<br/>message: @msg', array(
'@pid' => $pid, '@pid' => $pid,
'@dsid' => $dsid, '@dsid' => $dsid,
@ -327,7 +325,7 @@ class IslandoraFedoraApiM extends FedoraApiM {
return $ret; return $ret;
} }
} }
catch(Exception $e) { catch (Exception $e) {
watchdog('islandora', 'Failed to purge object @pid</br>code: @code<br/>message: @msg', array( watchdog('islandora', 'Failed to purge object @pid</br>code: @code<br/>message: @msg', array(
'@pid' => $pid, '@pid' => $pid,
'@code' => $e->getCode(), '@code' => $e->getCode(),

191
includes/utilities.inc

@ -204,13 +204,13 @@ function islandora_escape_pid_for_function($pid) {
// Apparently, case doesn't matter for function calls in PHP, so let's not // Apparently, case doesn't matter for function calls in PHP, so let's not
// really worry about changing the case. // really worry about changing the case.
return str_replace( return str_replace(
// Any PID characters which are not valid in the name of a PHP function. // Any PID characters which are not valid in the name of a PHP function.
array( array(
':', ':',
'-', '-',
), ),
'_', '_',
$pid $pid
); );
} }
@ -380,18 +380,13 @@ function islandora_get_datastreams_requirements_from_models(array $models) {
* determine what datastreams are required. * determine what datastreams are required.
* *
* @return array * @return array
* The DS-COMPOSITE-MODEL defined datastreams that are required for the given * An associative array mapping datastream IDs to associative arrays
* object. * containing the values parsed from the DS-COMPOSITE-MODEL on the given
* * object--of the form:
* @code * - DSID: A datastream ID being described.
* array( * - "id": A string containing ID of the datastream.
* 'DC' => array( * - "mime": A array containing MIME-types the stream may have.
* 'id' => 'DC', * - "optional": A boolean indicating if the given stream is optional.
* 'mime' => 'text/xml',
* 'optional' => FALSE,
* )
* )
* @endcode
*/ */
function islandora_get_datastreams_requirements_from_content_model(FedoraObject $object) { function islandora_get_datastreams_requirements_from_content_model(FedoraObject $object) {
if (empty($object[DS_COMP_STREAM])) { if (empty($object[DS_COMP_STREAM])) {
@ -465,20 +460,43 @@ function islandora_prepare_new_object($namespace = NULL, $label = NULL, $datastr
if (isset($ds['control_group']) && in_array($ds['control_group'], $groups)) { if (isset($ds['control_group']) && in_array($ds['control_group'], $groups)) {
$control_group = $ds['control_group']; $control_group = $ds['control_group'];
} }
$ds_uri = FALSE;
$as_file = FALSE;
if (file_valid_uri($ds['datastream_file'])) { if (file_valid_uri($ds['datastream_file'])) {
// A local file with as a Drupal file/stream wrapper URI.
$datastream_file = $ds['datastream_file']; $datastream_file = $ds['datastream_file'];
$ds_uri = TRUE; $as_file = TRUE;
}
elseif (is_readable($ds['datastream_file'])) {
// A local file as a filesystem path.
$datastream_file = drupal_realpath($ds['datastream_file']);
$as_file = TRUE;
} }
else { else {
$datastream_file = url($ds['datastream_file'], array('absolute' => TRUE)); $scheme = parse_url($ds['datastream_file'], PHP_URL_SCHEME);
if (in_array($scheme, stream_get_wrappers())) {
// A URI which gets handled by one of the PHP-native stream wrappers.
$datastream_file = $ds['datastream_file'];
$as_file = TRUE;
}
else {
// Schema does not match available php stream wrapper. Attempt to
// set datastream_file by url for the given scheme. Https (SSL) can
// cause this to fail, and trigger an output log in watchdog.
$datastream_file = url($ds['datastream_file'], array('absolute' => TRUE));
watchdog('islandora',
'Attempting to ingest %file in islandora_prepare_new_object(), but it does not appear to be readable. We will pass the path through url(), and pass along as such.',
array('%file' => $datastream_file),
WATCHDOG_WARNING);
}
} }
$datastream = $object->constructDatastream($dsid, $control_group); $datastream = $object->constructDatastream($dsid, $control_group);
$datastream->label = $label; $datastream->label = $label;
$datastream->mimetype = $mimetype; $datastream->mimetype = $mimetype;
switch ($control_group) { switch ($control_group) {
case 'M': case 'M':
if ($ds_uri) { if ($as_file) {
$datastream->setContentFromFile($datastream_file); $datastream->setContentFromFile($datastream_file);
} }
else { else {
@ -490,8 +508,10 @@ function islandora_prepare_new_object($namespace = NULL, $label = NULL, $datastr
$datastream->setContentFromString(file_get_contents($datastream_file)); $datastream->setContentFromString(file_get_contents($datastream_file));
break; break;
} }
$object->ingestDatastream($datastream); $object->ingestDatastream($datastream);
} }
return $object; return $object;
} }
@ -505,8 +525,9 @@ function islandora_display_repository_inaccessible_message() {
$text = t('Islandora configuration'); $text = t('Islandora configuration');
$link = l($text, 'admin/islandora/configure', array('attributes' => array('title' => $text))); $link = l($text, 'admin/islandora/configure', array('attributes' => array('title' => $text)));
$message = t('Could not connect to the repository. Please check the settings on the !link page.', $message = t('Could not connect to the repository. Please check the settings on the !link page.',
array('!link' => $link)); array('!link' => $link));
drupal_set_message($message, 'error', FALSE); drupal_set_message(check_plain($message), 'error', FALSE);
} }
/** /**
@ -595,33 +616,24 @@ function islandora_system_settings_form_default_value($name, $default_value, arr
/** /**
* Returns basic information about DS-COMPOSITE-MODEL. * Returns basic information about DS-COMPOSITE-MODEL.
* *
* @deprecated
* The pre-existing--and more flexible--
* islandora_get_datastreams_requirements_from_content_model() should be
* preferred, as it addresses the case where a stream can be allowed to have
* one of a set of mimetypes (this functions appears to only return the last
* declared mimetype for a given datastream).
*
* @param string $pid * @param string $pid
* PID of content model containing DS_COMP stream. * The PID of content model containing DS_COMP stream.
* *
* @return array * @return array
* array of values in the following form * An associative array mapping datastream IDs to an associative array
* * representing the parsed DS-COMPOSITE-MODEL of the form:
* [DC] => Array * - DSID: A string containing the datastream ID.
* ( * - "mimetype": A string containing the last mimetype declared for the
* [mimetype] => text/xml * given datastream ID.
* ) * - "optional": An optional boolean indicating that the given datastream
* * is optional.
* [MODS] => Array
* (
* [optional] => true
* [mimetype] => text/xml
* )
*
* [RELS-EXT] => Array
* (
* [mimetype] => application/rdf+xml
* )
*
* [RELS-INT] => Array
* (
* [optional] => true
* [mimetype] => application/rdf+xml
* )
*/ */
function islandora_get_comp_ds_mappings($pid) { function islandora_get_comp_ds_mappings($pid) {
$cm_object = islandora_object_load($pid); $cm_object = islandora_object_load($pid);
@ -718,14 +730,24 @@ function islandora_get_allowed_namespaces() {
function islandora_get_content_models($ignore_system_namespace = TRUE) { function islandora_get_content_models($ignore_system_namespace = TRUE) {
module_load_include('inc', 'islandora', 'includes/utilities'); module_load_include('inc', 'islandora', 'includes/utilities');
$tuque = islandora_get_tuque_connection(); $tuque = islandora_get_tuque_connection();
$query = 'select $object $label from <#ri> $query = "PREFIX fm: <" . FEDORA_MODEL_URI . ">
where ($object <fedora-model:label> $label PREFIX fr: <" . FEDORA_RELS_EXT_URI . ">
and ($object <fedora-model:hasModel> <info:fedora/fedora-system:ContentModel-3.0> SELECT ?object ?label
or $object <fedora-rels-ext:isMemberOfCollection> <info:fedora/islandora:ContentModelsCollection>) FROM <#ri>
and $object <fedora-model:state> <info:fedora/fedora-system:def/model#Active>) WHERE {
order by $label'; {?object fm:hasModel <info:fedora/fedora-system:ContentModel-3.0>;
fm:state fm:Active
}
UNION{
?object fr:isMemberOfCollection <info:fedora/islandora:ContentModelsCollection>;
fm:state fm:Active
}
OPTIONAL{
?object fm:label ?label
}
}";
$content_models = array(); $content_models = array();
$results = $tuque->repository->ri->itqlQuery($query, 'unlimited'); $results = $tuque->repository->ri->sparqlQuery($query, 'unlimited');
foreach ($results as $result) { foreach ($results as $result) {
$content_model = $result['object']['value']; $content_model = $result['object']['value'];
$label = $result['label']['value']; $label = $result['label']['value'];
@ -738,3 +760,60 @@ function islandora_get_content_models($ignore_system_namespace = TRUE) {
} }
return $content_models; return $content_models;
} }
/**
* Returns Drupal tableselect element allowing selection of Content Models.
*
* @param string $drupal_variable
* the name of the Drupal variable holding selected content models
* Content models held in this variable will appear at the top of
* the displayed list
* @param array $default_values_array
* default values to display if $drupal_variable is unset
*
* @return array
* Drupal form element allowing content model selection
*/
function islandora_content_model_select_table_form_element($drupal_variable, $default_values_array = array('')) {
$defaults = array();
$rows = array();
$content_models = array();
$options = islandora_get_content_models(TRUE);
foreach ($options as $option) {
$content_models[$option['pid']] = $option['label'];
}
$selected = array_values(variable_get($drupal_variable, $default_values_array));
$comparator = function ($a, $b) use ($selected) {
$a_val = $b_val = 0;
if (in_array($a, $selected)) {
$a_val = 1;
}
if (in_array($b, $selected)) {
$b_val = 1;
}
return $b_val - $a_val;
};
uksort($content_models, $comparator);
foreach ($content_models as $pid => $label) {
$rows[$pid] = array(
'pid' => $pid,
'title' => $label,
);
$defaults[$pid] = in_array($pid, $selected);
}
$header = array(
'pid' => array('data' => t('PID')),
'title' => array('data' => t('Content Model')),
);
// Build and return table element.
$element = array(
'#type' => 'tableselect',
'#header' => $header,
'#options' => $rows,
'#default_value' => $defaults,
'#empty' => t("There are no content models in this Fedora Repository."),
);
return $element;
}

50
islandora.api.php

@ -45,11 +45,24 @@ function hook_CMODEL_PID_islandora_view_object($object) {
* @param FedoraObject $object * @param FedoraObject $object
* A Tuque FedoraObject being operated on. * A Tuque FedoraObject being operated on.
* @param array $rendered * @param array $rendered
* An arr of rendered views. * The array of rendered views.
*/ */
function hook_islandora_view_object_alter(&$object, &$rendered) { function hook_islandora_view_object_alter(&$object, &$rendered) {
} }
/**
* Alter display output if the object has the given model.
*
* @see hook_islandora_view_object_alter()
*
* @param FedoraObject $object
* A Tuque FedoraObject being operated on.
* @param array $rendered
* The array of rendered views.
*/
function hook_CMODEL_PID_islandora_view_object_alter(&$object, &$rendered) {
}
/** /**
* Generate an object's management display. * Generate an object's management display.
* *
@ -291,7 +304,7 @@ function hook_islandora_datastream_modified(FedoraObject $object, FedoraDatastre
} }
/** /**
* Notify modules that the given datastream was ingested. * Notify modules that the given datastream was modified.
* *
* @see hook_islandora_datastream_modified() * @see hook_islandora_datastream_modified()
*/ */
@ -373,15 +386,26 @@ function hook_islandora_undeletable_datastreams(array $models) {
* @return array * @return array
* An associative array of associative arrays which define each step in the * An associative array of associative arrays which define each step in the
* ingest process. Each step should consist of a unique name mapped to an * ingest process. Each step should consist of a unique name mapped to an
* array of properties (keys) including: * array of properties (keys) which take different paramaters based upon type:
* - type: The type of step. Currently, only "form" is implemented. * - type: Type of step. Only "form" and "callback" are implemented so far.
* - weight: The "weight" of this step--heavier(/"larger") values sink to the * Required "form" type specific parameters:
* end of the process while smaller(/"lighter") values are executed first.
* - form_id: The form building function to call to get the form structure * - form_id: The form building function to call to get the form structure
* for this step. * for this step.
* - args: An array of arguments to pass to the form building function. * - args: An array of arguments to pass to the form building function.
* And may optionally include both: * Required "callback" type specific parameters:
* - do_function: An associate array including:
* - 'function': The callback function to be called.
* - 'args': An array of arguments to pass to the callback function.
* - undo_function: An associate array including:
* - 'function': The callback function to be called to reverse the
* executed action in the ingest steps.
* - 'args': An array of arguments to pass to the callback function.
* Shared parameters between both types:
* - weight: The "weight" of this step--heavier(/"larger") values sink to the
* end of the process while smaller(/"lighter") values are executed first.
* Both types may optionally include:
* - module: A module from which we want to load an include. * - module: A module from which we want to load an include.
* "Form" type may optionally include:
* - file: A file to include (relative to the module's path, including the * - file: A file to include (relative to the module's path, including the
* file's extension). * file's extension).
*/ */
@ -393,6 +417,18 @@ function hook_islandora_ingest_steps(array $form_state) {
'form_id' => 'my_cool_form', 'form_id' => 'my_cool_form',
'args' => array('arg_one', 'numero deux'), 'args' => array('arg_one', 'numero deux'),
), ),
'my_cool_step_callback' => array(
'type' => 'callback',
'weight' => 2,
'do_function' => array(
'function' => 'my_cool_execute_function',
'args' => array('arg_one', 'numero deux'),
),
'undo_function' => array(
'function' => 'my_cool_undo_function',
'args' => array('arg_one', 'numero deux'),
),
),
); );
} }
/** /**

5
islandora.install

@ -10,13 +10,14 @@
*/ */
function islandora_requirements($phase) { function islandora_requirements($phase) {
$requirements = array(); $requirements = array();
// Ensure translations don't break at install time
// Ensure translations don't break at install time.
$t = get_t(); $t = get_t();
if (!class_exists('XSLTProcessor', FALSE)) { if (!class_exists('XSLTProcessor', FALSE)) {
$requirements['islandora_xsltprocessor']['title'] = $t('Islandora XSLTProcessor Prerequisite'); $requirements['islandora_xsltprocessor']['title'] = $t('Islandora XSLTProcessor Prerequisite');
$requirements['islandora_xsltprocessor']['value'] = $t('Not installed'); $requirements['islandora_xsltprocessor']['value'] = $t('Not installed');
$link = l($t('PHP XSL extension'), 'http://us2.php.net/manual/en/book.xsl.php', array('attributes' => array('target'=>'_blank'))); $link = l($t('PHP XSL extension'), 'http://us2.php.net/manual/en/book.xsl.php', array('attributes' => array('target' => '_blank')));
$requirements['islandora_xsltprocessor']['description'] = $t('The !xsllink is required. Check your installed PHP extensions and php.ini file.', array('!xsllink' => $link)); $requirements['islandora_xsltprocessor']['description'] = $t('The !xsllink is required. Check your installed PHP extensions and php.ini file.', array('!xsllink' => $link));
$requirements['islandora_xsltprocessor']['severity'] = REQUIREMENT_ERROR; $requirements['islandora_xsltprocessor']['severity'] = REQUIREMENT_ERROR;
} }

151
islandora.module

@ -120,7 +120,7 @@ function islandora_menu() {
FEDORA_METADATA_EDIT, FEDORA_METADATA_EDIT,
FEDORA_ADD_DS, FEDORA_ADD_DS,
FEDORA_PURGE, FEDORA_PURGE,
FEDORA_INGEST FEDORA_INGEST,
), 2), ), 2),
); );
@ -238,12 +238,13 @@ function islandora_menu() {
'access arguments' => array(FEDORA_VIEW_OBJECTS, 2), 'access arguments' => array(FEDORA_VIEW_OBJECTS, 2),
'load arguments' => array(2), 'load arguments' => array(2),
); );
$items['islandora/ingest'] = array( $items['islandora/object/%islandora_object/download_clip'] = array(
'title' => 'Add an Object', 'page callback' => 'islandora_download_clip',
'page callback' => 'islandora_ingest_callback', 'page arguments' => array(2),
'file' => 'includes/ingest.menu.inc', 'type' => MENU_CALLBACK,
'type' => MENU_SUGGESTED_ITEM, 'access callback' => 'islandora_object_access_callback',
'access arguments' => array(FEDORA_INGEST), 'access arguments' => array(FEDORA_VIEW_OBJECTS, 2),
'load arguments' => array(2),
); );
return $items; return $items;
} }
@ -286,6 +287,29 @@ function islandora_theme() {
'file' => 'theme/theme.inc', 'file' => 'theme/theme.inc',
'variables' => array('object' => NULL, 'content' => array()), 'variables' => array('object' => NULL, 'content' => array()),
), ),
// Render a bunch of objects as either a grid or a list.
'islandora_objects' => array(
'file' => 'theme/theme.inc',
'template' => 'theme/islandora-objects',
'variables' => array(
'objects' => NULL,
'display' => NULL,
'page_size' => 20,
'limit' => 10,
),
),
// Render a bunch of objects as a grid.
'islandora_objects_grid' => array(
'file' => 'theme/theme.inc',
'template' => 'theme/islandora-objects-grid',
'variables' => array('objects' => NULL),
),
// Render a bunch of objects as a list.
'islandora_objects_list' => array(
'file' => 'theme/theme.inc',
'template' => 'theme/islandora-objects-list',
'variables' => array('objects' => NULL),
),
); );
} }
@ -334,6 +358,88 @@ function islandora_forms($form_id) {
return $forms; return $forms;
} }
/**
* Checks whether the user can access the given object.
*
* Checks for repository access, object/datastream existance, namespace access,
* user permissions, content models.
*
* Will check the given user or the user repersented by the GET token parameter,
* failing that it will use the global user.
*
* @global $user
*
* @param mixed $object
* The FedoraObject or FedoraDatastream to test for accessibility, if NULL
* is given the object is assumed to not exist or be inaccessible.
* @param array $permissions
* The required user permissions.
* @param array $content_models
* The required content models.
* @param bool $access_any
* (optional) TRUE to grant access if any single requirement is met from both
* the permissions and content models parameters. FALSE if all requirements
* must be met from both the permissions and content model parameters.
* @param object $account
* (optional) The account to check, if not given check the GET parameters for
* a token to restore the user. If no GET parameter is present use currently
* logged in user.
*
* @return bool
* TRUE if the user is allowed to access this object/datastream, FALSE
* otherwise.
*/
function islandora_user_access($object, array $permissions, $content_models = array(), $access_any = TRUE, $account = NULL) {
module_load_include('inc', 'islandora', 'includes/utilities');
$is_repository_accessible = &drupal_static(__FUNCTION__);
// If the repository is inaccessible then access always fails.
if (!isset($is_repository_accessible)) {
$is_repository_accessible = islandora_describe_repository();
if (!$is_repository_accessible) {
// Only display the inaccessible message once.
islandora_display_repository_inaccessible_message();
return FALSE;
}
}
if (!$is_repository_accessible || !is_object($object)) {
return FALSE;
}
// Determine the user account to test against.
if (!isset($account)) {
$token = filter_input(INPUT_GET, 'token', FILTER_SANITIZE_STRING);
if ($token) {
module_load_include('inc', 'islandora', 'includes/authtokens');
$user = islandora_validate_object_token($object->id, $datastream->id, $token);
if ($user) {
$account = user_load($user->uid);
}
}
else {
global $user;
$account = $user;
}
}
// Determine what has been passed as $object.
if (is_subclass_of($object, 'FedoraObject')) {
$object = $object;
}
elseif (is_subclass_of($object, 'FedoraDatastream')) {
$datastream = $object;
$object = $datastream->parent;
}
// Check for access.
$accessible_namespace = islandora_namespace_accessible($object->id);
if ($access_any) {
$has_required_permissions = islandora_user_access_any($permissions, $account);
$has_required_content_models = empty($content_models) ? TRUE : count(array_intersect($object->models, $content_models)) > 0;
}
else {
$has_required_permissions = islandora_user_access_all($permissions, $account);
$has_required_content_models = count(array_diff($content_models, $object->models)) == 0;
}
return $accessible_namespace && $has_required_permissions && $has_required_content_models;
}
/** /**
* Checks whether the user can access the given object. * Checks whether the user can access the given object.
* *
@ -570,7 +676,8 @@ function islandora_view_object(FedoraObject $object) {
$page_number = (empty($_GET['page'])) ? '1' : $_GET['page']; $page_number = (empty($_GET['page'])) ? '1' : $_GET['page'];
$page_size = (empty($_GET['pagesize'])) ? '10' : $_GET['pagesize']; $page_size = (empty($_GET['pagesize'])) ? '10' : $_GET['pagesize'];
$output = array(); $output = array();
foreach (islandora_build_hook_list(ISLANDORA_VIEW_HOOK, $object->models) as $hook) { $hooks = islandora_build_hook_list(ISLANDORA_VIEW_HOOK, $object->models);
foreach ($hooks as $hook) {
// @todo Remove page number and size from this hook, implementers of the // @todo Remove page number and size from this hook, implementers of the
// hook should use drupal page handling directly. // hook should use drupal page handling directly.
$temp = module_invoke_all($hook, $object, $page_number, $page_size); $temp = module_invoke_all($hook, $object, $page_number, $page_size);
@ -583,7 +690,7 @@ function islandora_view_object(FedoraObject $object) {
$output = islandora_default_islandora_view_object($object); $output = islandora_default_islandora_view_object($object);
} }
arsort($output); arsort($output);
drupal_alter(ISLANDORA_VIEW_HOOK, $object, $output); drupal_alter($hooks, $object, $output);
return implode('', $output); return implode('', $output);
} }
@ -859,7 +966,7 @@ function islandora_delete_object(FedoraObject &$object) {
$object = NULL; $object = NULL;
return TRUE; return TRUE;
} }
catch(Exception $e) { catch (Exception $e) {
// Exception message gets logged in Tuque Wrapper. // Exception message gets logged in Tuque Wrapper.
return FALSE; return FALSE;
} }
@ -964,7 +1071,29 @@ function islandora_entity_property_info() {
* @return array * @return array
* A renderable array. * A renderable array.
*/ */
function islandora_print_object(FedoraObject $object) { function islandora_print_object(AbstractObject $object) {
drupal_set_title($object->label); drupal_set_title($object->label);
return theme('islandora_object_print', array('object' => $object)); return theme('islandora_object_print', array('object' => $object));
} }
/**
* Menu callback downloads the given clip.
*/
function islandora_download_clip(AbstractObject $object) {
if (isset($_GET['clip'])) {
$is_https = isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on';
$http_protocol = $is_https ? 'https' : 'http';
$url = $http_protocol . '://' . $_SERVER['HTTP_HOST'] . $_GET['clip'];
$filename = $object->label;
header("Content-Disposition: attachment; filename=\"{$filename}.jpg\"");
header("Content-type: image/jpeg");
header("Content-Transfer-Encoding: binary");
$ch = curl_init();
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_URL, $url);
$response = curl_exec($ch);
curl_close($ch);
}
exit();
}

3
tests/README.txt

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

12
tests/hooks.test

@ -32,7 +32,7 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase {
* @see IslandoraWebTestCase::setUp() * @see IslandoraWebTestCase::setUp()
*/ */
public function setUp() { public function setUp() {
parent::setUp('islandora_hooks_test', 'devel'); parent::setUp('islandora_hooks_test');
$this->repository = $this->admin->repository; $this->repository = $this->admin->repository;
$this->purgeTestObjects(); $this->purgeTestObjects();
} }
@ -67,7 +67,7 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase {
$object->label = "Don't Block"; $object->label = "Don't Block";
$this->repository->purgeObject($object->id); $this->repository->purgeObject($object->id);
} }
catch(Exception $e) { catch (Exception $e) {
// Meh... Either it didn't exist or the purge failed. // Meh... Either it didn't exist or the purge failed.
} }
} }
@ -95,7 +95,7 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase {
$this->fail('Blocked ingest should throw an Exception.'); $this->fail('Blocked ingest should throw an Exception.');
$this->repository->purgeObject($object->id); $this->repository->purgeObject($object->id);
} }
catch(Exception $e) { catch (Exception $e) {
$this->pass('Ingest blocked and exception thrown.'); $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->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.'); $this->assertFalse($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_INGESTED_HOOK], 'Did not called ISLANDORA_OBJECT_INGESTED_HOOK when blocking ingesting via FedoraRepository::ingestObject.');
@ -115,7 +115,7 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase {
$object->label = 'block'; $object->label = 'block';
$this->fail('Blocked modify should throw an Exception.'); $this->fail('Blocked modify should throw an Exception.');
} }
catch(Exception $e) { catch (Exception $e) {
$this->pass('Modify blocked and exception thrown.'); $this->pass('Modify blocked and exception thrown.');
$this->assertNotEqual($object->label, 'block', 'Modification did not stick.'); $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->assert($_SESSION['islandora_hooks']['alter'][ISLANDORA_OBJECT_MODIFIED_HOOK], 'Called "hook_islandora_object_alter" when blocking modifying via set magic functions.');
@ -149,7 +149,7 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase {
$this->repository->purgeObject($object->id); $this->repository->purgeObject($object->id);
$this->fail('Blocked modify should throw an Exception.'); $this->fail('Blocked modify should throw an Exception.');
} }
catch(Exception $e) { catch (Exception $e) {
$this->pass('Modify blocked and exception thrown.'); $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->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.'); $this->assertFalse($_SESSION['islandora_hooks']['hook'][ISLANDORA_OBJECT_PURGED_HOOK], 'Called ISLANDORA_OBJECT_PURGED_HOOK when blocking purge via FedoraRepository::purgeObject.');
@ -191,7 +191,7 @@ class IslandoraHooksTestCase extends IslandoraWebTestCase {
$ds->label = 'block'; $ds->label = 'block';
$this->fail('Blocked modify should throw an Exception.'); $this->fail('Blocked modify should throw an Exception.');
} }
catch(Exception $e) { catch (Exception $e) {
$this->pass('Modify blocked and exception thrown.'); $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->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->assertFALSE($_SESSION['islandora_hooks']['hook'][ISLANDORA_DATASTREAM_MODIFIED_HOOK], 'Called ISLANDORA_DATASTREAM_MODIFIED_HOOK when blocking modifying via set magic functions.');

3
tests/islandora_test.info → tests/islandora_hooks_test.info

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

0
tests/islandora_test.module → tests/islandora_hooks_test.module

114
tests/islandora_manage_permissions.test

@ -1,7 +1,17 @@
<?php <?php
/**
* @file
* Tests islandora permissions, and permission related funcitons.
*/
class IslandoraPermissionsTestCase extends IslandoraWebTestCase { class IslandoraPermissionsTestCase extends IslandoraWebTestCase {
/**
* Gets info to display to describe this test.
*
* @see IslandoraWebTestCase::getInfo()
*/
public static function getInfo() { public static function getInfo() {
return array( return array(
'name' => 'Islandora Manage Permissions', 'name' => 'Islandora Manage Permissions',
@ -10,69 +20,117 @@ class IslandoraPermissionsTestCase extends IslandoraWebTestCase {
); );
} }
/**
* Prepares enviroment for testing.
*
* @see IslandoraWebTestCase::setUp()
*/
public function setUp() { public function setUp() {
parent::setUp(array('islandora')); parent::setUp(array('islandora'));
} }
/**
* Test manage permissions.
*/
public function testManagePermissions() { public function testManagePermissions() {
// Test permission FEDORA_VIEW_OBJECTS.
// Create a user with permission.
// permission FEDORA_VIEW_OBJECTS
// create a user with permission
$user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS)); $user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS));
// log the user in // Log the user in.
$this->drupalLogin($user); $this->drupalLogin($user);
$this->clickLink(t('Islandora Repository')); $this->clickLink(t('Islandora Repository'));
$this->assertNoLink('Manage', 'Manage tab is not on current page.'); $this->assertNoLink('Manage', 'Manage tab is not on current page.');
// Test permission FEDORA_VIEW_OBJECTS, FEDORA_MANAGE_PROPERTIES.
// permission FEDORA_VIEW_OBJECTS, FEDORA_MANAGE_PROPERTIES
$user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS, FEDORA_MANAGE_PROPERTIES)); $user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS, FEDORA_MANAGE_PROPERTIES));
// log the user in
$this->drupalLogin($user); $this->drupalLogin($user);
$this->clickLink(t('Islandora Repository')); $this->clickLink(t('Islandora Repository'));
$this->assertLink('Manage', 0, 'Manage tab is on current page.'); $this->assertLink('Manage', 0, 'Manage tab is on current page.');
$this->clickLink(t('Manage')); $this->clickLink(t('Manage'));
$this->assertLink('Properties', 0, 'Properties tab is on current page.'); $this->assertLink('Properties', 0, 'Properties tab is on current page.');
$this->assertNoLink('Datastreams', 'Datastreams tab is not on current page.'); $this->assertNoLink('Datastreams', 'Datastreams tab is not on current page.');
$this->assertNoLink('Collection','Collection tab is not on current page.'); $this->assertNoLink('Collection', 'Collection tab is not on current page.');
// Test permission FEDORA_VIEW_OBJECTS, FEDORA_ADD_DS.
// permission FEDORA_VIEW_OBJECTS, FEDORA_ADD_DS
$user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS, FEDORA_ADD_DS)); $user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS, FEDORA_ADD_DS));
// log the user in
$this->drupalLogin($user); $this->drupalLogin($user);
$this->clickLink(t('Islandora Repository')); $this->clickLink(t('Islandora Repository'));
$this->assertLink('Manage', 0, 'Manage tab is on current page.'); $this->assertLink('Manage', 0, 'Manage tab is on current page.');
$this->clickLink(t('Manage')); $this->clickLink(t('Manage'));
$this->assertLink('Datastreams', 0, 'Datastreams tab is on current page.'); $this->assertLink('Datastreams', 0, 'Datastreams tab is on current page.');
$this->assertNoLink('Properties', 'Properties tab is not on current page.'); $this->assertNoLink('Properties', 'Properties tab is not on current page.');
$this->assertNoLink('Collection','Collection tab is not on current page.'); $this->assertNoLink('Collection', 'Collection tab is not on current page.');
// Test permission FEDORA_VIEW_OBJECTS, FEDORA_METADATA_EDIT.
// permission FEDORA_VIEW_OBJECTS, FEDORA_METADATA_EDIT
$user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS, FEDORA_METADATA_EDIT)); $user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS, FEDORA_METADATA_EDIT));
// log the user in $this->drupalLogin($user);
$this->drupalLogin($user);
$this->clickLink(t('Islandora Repository')); $this->clickLink(t('Islandora Repository'));
$this->assertLink('Manage', 0, 'Manage tab is on current page.'); $this->assertLink('Manage', 0, 'Manage tab is on current page.');
$this->clickLink(t('Manage')); $this->clickLink(t('Manage'));
$this->assertLink('Datastreams', 0, 'Datastreams tab is on current page.'); $this->assertLink('Datastreams', 0, 'Datastreams tab is on current page.');
$this->assertNoLink('Properties', 'Properties tab is not on current page.'); $this->assertNoLink('Properties', 'Properties tab is not on current page.');
$this->assertNoLink('Collection','Collection tab is not on current page.'); $this->assertNoLink('Collection', 'Collection tab is not on current page.');
// Test permission FEDORA_VIEW_OBJECTS, FEDORA_PURGE.
// permission FEDORA_VIEW_OBJECTS, FEDORA_PURGE
$user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS, FEDORA_PURGE)); $user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS, FEDORA_PURGE));
// log the user in
$this->drupalLogin($user); $this->drupalLogin($user);
$this->clickLink(t('Islandora Repository')); $this->clickLink(t('Islandora Repository'));
$this->assertLink('Manage', 0, 'Manage tab is on current page.'); $this->assertLink('Manage', 0, 'Manage tab is on current page.');
$this->clickLink(t('Manage')); $this->clickLink(t('Manage'));
$this->assertLink('Datastreams', 0, 'Datastreams tab is on current page.'); $this->assertLink('Datastreams', 0, 'Datastreams tab is on current page.');
$this->assertNoLink('Properties', 'Properties tab is not on current page.'); $this->assertNoLink('Properties', 'Properties tab is not on current page.');
$this->assertNoLink('Collection','Collection tab is not on current page.'); $this->assertNoLink('Collection', 'Collection tab is not on current page.');
} }
} /**
* Test generic access functions.
*
* Note that we can't test with the Global user as SimpleTest doesn't support
* it. Therefore we can't test the authtoken support.
*/
public function testAccessFunctions() {
$object = islandora_object_load(variable_get('islandora_repository_pid', 'islandora:root'));
// Test islandora_user_access().
// Test no object/permissions.
$ret = islandora_user_access(NULL, array());
$this->assertFalse($ret, 'User access denied when no object/permissions are provided.');
// Test with object no permissions.
$ret = islandora_user_access($object, array());
$this->assertFalse($ret, 'User access denied when no permissions are provided.');
// Test access with matching permission.
$user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS));
$ret = islandora_user_access($object, array(FEDORA_VIEW_OBJECTS), array(), TRUE, $user);
$this->assertTrue($ret, 'User access granted when permissions match.');
// Test access with matching permission but access any is FALSE.
$user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS));
$ret = islandora_user_access($object, array(FEDORA_VIEW_OBJECTS, FEDORA_PURGE), array(), FALSE, $user);
$this->assertFalse($ret, 'User access denied for matching permission but with access any set to FALSE.');
// Test access with non-matching permission.
$user = $this->drupalCreateUser(array(FEDORA_PURGE));
$ret = islandora_user_access($object, array(FEDORA_VIEW_OBJECTS), array(), TRUE, $user);
$this->assertFalse($ret, 'User access denied when permissions did not match.');
// Test access with both permissions and content model.
$user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS));
$model = $object->models;
$model = reset($model);
$ret = islandora_user_access($object, array(FEDORA_VIEW_OBJECTS), array($model), TRUE, $user);
$this->assertTrue($ret, 'User access granted for matching permission and model.');
// Test access with matching permissions and non-matching content model.
$user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS));
$ret = islandora_user_access($object, array(FEDORA_VIEW_OBJECTS), array('islandora:obviouslyNotACModel'), TRUE, $user);
$this->assertFalse($ret, 'User access denied for matching permission and non-matching model.');
// Test access with all matching permissions and one matching model but
// access any is FALSE.
$user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS, FEDORA_PURGE));
$model = $object->models;
$model = reset($model);
$ret = islandora_user_access($object, array(FEDORA_VIEW_OBJECTS, FEDORA_PURGE), array($model, 'islandora:obviouslyNotACModel'), FALSE, $user);
$this->assertFalse($ret, 'User access denied for all matching permissions and one matching model but with access any set to FALSE.');
$ret = islandora_user_access($object, array(FEDORA_VIEW_OBJECTS, FEDORA_PURGE), array($model), FALSE, $user);
$this->assertTrue($ret, 'User access granted for all matching permissions and matching models with access any set to FALSE.');
// Test passing in a Datastream.
$user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS, FEDORA_PURGE));
$ret = islandora_user_access($object['DC'], array(FEDORA_VIEW_OBJECTS), array(), TRUE, $user);
$this->assertTrue($ret, 'User access granted for matching permissions, with a datastream given instead of an object.');
}
}

14
tests/scripts/line_endings.sh

@ -0,0 +1,14 @@
#!/bin/bash
RETURN=0
FILES=`find -L $1 -name "*.info" -o -name "*.txt" -o -name "*.md"`
echo "Testing for files with DOS line endings..."
for FILE in $FILES
do
file $FILE | grep CRLF
if [ $? == 0 ]
then
RETURN=1
fi
done
exit $RETURN

36
tests/scripts/travis_setup.sh

@ -0,0 +1,36 @@
#!/bin/bash
mysql -u root -e 'create database drupal;'
mysql -u root -e "create database fedora;"
mysql -u root -e "GRANT ALL PRIVILEGES ON fedora.* To 'fedora'@'localhost' IDENTIFIED BY 'fedora';"
mysql -u root -e "GRANT ALL PRIVILEGES ON drupal.* To 'drupal'@'localhost' IDENTIFIED BY 'drupal';"
cd $HOME
git clone git://github.com/Islandora/tuque.git
git clone -b $FEDORA_VERSION git://github.com/Islandora/islandora_tomcat.git
cd islandora_tomcat
export CATALINA_HOME='.'
./bin/startup.sh
cd $HOME
pyrus channel-discover pear.drush.org
pyrus channel-discover pear.phpqatools.org
pyrus channel-discover pear.netpirates.net
pyrus install drush/drush
pyrus install pear/PHP_CodeSniffer
pyrus install pear.phpunit.de/phpcpd
phpenv rehash
drush dl --yes drupal
cd drupal-*
drush si standard --db-url=mysql://drupal:drupal@localhost/drupal --yes
drush runserver --php-cgi=$HOME/.phpenv/shims/php-cgi localhost:8081 &>/dev/null &
ln -s $ISLANDORA_DIR sites/all/modules/islandora
mv sites/all/modules/islandora/tests/travis.test_config.ini sites/all/modules/islandora/tests/test_config.ini
mkdir sites/all/libraries
ln -s $HOME/tuque sites/all/libraries/tuque
drush dl --yes coder
drush dl --yes potx
drush en --yes coder_review
drush en --yes simpletest
drush en --yes potx
drush en --user=1 --yes islandora
drush cc all
sleep 4

6
tests/travis.test_config.ini

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

5
tests/web_test_case.inc

@ -18,6 +18,11 @@ class IslandoraWebTestCase extends DrupalWebTestCase {
// Always enable islandora. // Always enable islandora.
$args[] = 'islandora'; $args[] = 'islandora';
parent::setUp($args); parent::setUp($args);
// Its possible test are running before class autoloading.
module_load_include('inc', 'islandora', 'includes/tuque');
module_load_include('inc', 'islandora', 'includes/tuque_wrapper');
$this->configuration = $this->getTestConfiguration(); $this->configuration = $this->getTestConfiguration();
if ($this->configuration['use_drupal_filter']) { if ($this->configuration['use_drupal_filter']) {
$this->backUpDrupalFilter(); $this->backUpDrupalFilter();

17
theme/islandora-objects-grid.tpl.php

@ -0,0 +1,17 @@
<?php
/**
* @file
* Render a bunch of objects in a list or grid view.
*/
?>
<div class="islandora-objects-grid clearfix">
<?php foreach($objects as $object): ?>
<div class="islandora-objects-grid-item clearfix">
<dl class="islandora-object <?php print $object['class']; ?>">
<dt class="islandora-object-thumb"><?php print $object['thumb']; ?></dt>
<dd class="islandora-object-caption"><?php print $object['link']; ?></dd>
</dl>
</div>
<?php endforeach; ?>
</div>

29
theme/islandora-objects-list.tpl.php

@ -0,0 +1,29 @@
<?php
/**
* @file
* Render a bunch of objects in a list or grid view.
*/
?>
<div class="islandora-objects-list">
<?php $row_field = 0; ?>
<?php foreach($objects as $object): ?>
<?php $first = ($row_field == 0) ? 'first' : ''; ?>
<div class="islandora-objects-list-item clearfix">
<dl class="islandora-object <?php print $object['class']; ?>">
<dt class="islandora-object-thumb">
<?php print $object['thumb']; ?>
</dt>
<dd class="islandora-object-caption <?php print $object['class']?> <?php print $first; ?>">
<strong>
<?php print $object['link']; ?>
</strong>
</dd>
<dd class="islandora-object-description">
<?php print $object['description']; ?>
</dd>
</dl>
</div>
<?php $row_field++; ?>
<?php endforeach; ?>
</div>

21
theme/islandora-objects.tpl.php

@ -0,0 +1,21 @@
<?php
/**
* @file
* Render a bunch of objects in a list or grid view.
*/
?>
<div class="islandora-objects clearfix">
<span class="islandora-objects-display-switch">
<?php
print theme('links', array(
'links' => $display_links,
'attributes' => array('class' => array('links', 'inline')),
)
);
?>
</span>
<?php print $pager; ?>
<?php print $content; ?>
<?php print $pager; ?>
</div>

61
theme/theme.inc

@ -157,3 +157,64 @@ function islandora_preprocess_islandora_object_print(array &$variables) {
function theme_islandora_object_print(array &$variables) { function theme_islandora_object_print(array &$variables) {
return drupal_render($variables['content']); return drupal_render($variables['content']);
} }
/**
* Implements hook_preprocess_theme().
*/
function islandora_preprocess_islandora_objects(array &$variables) {
module_load_include('inc', 'islandora_paged_content', 'includes/utilities');
$display = (empty($_GET['display'])) ? 'grid' : $_GET['display'];
$grid_display = $display == 'grid';
$list_display = !$grid_display;
$query_params = drupal_get_query_parameters($_GET);
$variables['display_links'] = array(
array(
'title' => t('Grid view'),
'href' => url($_GET['q'], array('absolute' => TRUE)),
'attributes' => array(
'class' => $grid_display ? 'active' : '',
),
'query' => array('display' => 'grid') + $query_params,
),
array(
'title' => t('List view'),
'href' => url($_GET['q'], array('absolute' => TRUE)),
'attributes' => array(
'class' => $list_display ? 'active' : '',
),
'query' => array('display' => 'list') + $query_params,
),
);
// Pager.
$objects = $variables['objects'];
$limit = $variables['limit'];
$page_size = $variables['page_size'];
$page = pager_default_initialize(count($objects), $limit);
$objects = array_slice($objects, $page * $limit, $limit);
$variables['pager'] = theme('pager', array('quantity' => 10));
// Content.
$map_objects = function($o) {
$o = islandora_object_load($o);
$url = "islandora/object/{$o->id}";
$link_options = array('html' => TRUE, 'attributes' => array('title' => $o->label));
$img = theme_image(array('path' => url("$url/datastream/TN/view"), 'attributes' => array()));
$description = NULL;
$dc = DublinCore::importFromXMLString($o['DC']->content);
if ($dc) {
$dc = $dc->asArray();
$description = $dc['dc:description']['value'];
}
return array(
'label' => $o->label,
'class' => drupal_strtolower(preg_replace('/[^A-Za-z0-9]/', '-', $o->id)),
'link' => l($o->label, $url, $link_options),
'thumb' => l($img, $url, $link_options),
'description' => $description,
);
};
$objects = array_map($map_objects, $objects);
$theme = $grid_display ? 'islandora_objects_grid' : 'islandora_objects_list';
$variables['content'] = theme($theme, array('objects' => $objects));
$module_path = drupal_get_path('module', 'islandora');
drupal_add_css("$module_path/css/islandora.objects.css");
}

Loading…
Cancel
Save