diff --git a/README.md b/README.md
index 28908c694..caf380265 100644
--- a/README.md
+++ b/README.md
@@ -63,7 +63,47 @@ By default, objects with the [Fedora state](https://wiki.duraspace.org/display/F
* A [detailed tutorial](https://github.com/Islandora/islandora/wiki/Multi-paged-Ingest-Forms) on extending the multi-page ingest forms is available on the Github (developers') Wiki.
* Additional modules developed by members of the Islandora community to extend Islandora can be found on the curated [Islandora Awesome](https://github.com/Islandora-Labs/islandora_awesome) list.
-## Documentation
+### Image Server configuration
+
+
+#### Drupal
+
+In Administration » Islandora » Image Server configuration
+
+Choose the type of image server (Djatoka or IIIF).
+
+Set the URL.
+
+#### Djatoka
+
+![Configuration](https://user-images.githubusercontent.com/2857697/63660444-1a24c400-c77c-11e9-831d-5f3fc71b085e.png)
+
+#### IIIF
+
+![Configuration](https://user-images.githubusercontent.com/2857697/63660476-43455480-c77c-11e9-8460-c3d2639e7575.png)
+
+If using IIIF choose to send token as a header and choose the token to use.
+
+Any [IIIF](http://iiif.io) image server can be used with the IIIF tile source. The IIIF tile source provides a templated identifier which the IIIF server must be configured to resolve. This could be the full URL to the datastream to be displayed or something more complex.
+
+The [Cantaloupe 🍈](https://medusa-project.github.io/cantaloupe/) IIIF image server can be configured to resolve these identifiers using the [`HttpResolver`](https://medusa-project.github.io/cantaloupe/manual/3.3/resolvers.html#HttpResolver) with no prefix specified.
+
+#### Apache Reverse Proxy
+
+Reverse proxy config: We make the assumption that we (reverse) proxy Djatoka, to fix the same-origin issue.
+
+For Apache, with Drupal running on the same box as Apache, a couple lines like:
+
+```
+ProxyPass /adore-djatoka http://localhost:8080/adore-djatoka
+ProxyPassReverse /adore-djatoka http://localhost:8080/adore-djatoka
+```
+
+in the Apache config somewhere (either the main apache.conf, httpd.conf, or in and arbitrarily named `*.conf` in your Apache's conf.d directory should suffice to establish the reverse proxy.
+
+In Debian derived systems one will need to create location entries for each proxy or remove the Deny from All in mod_proxy's conf file.
+
+# Documentation
Further documentation for this module is available at [our documentation wiki](https://wiki.duraspace.org/display/ISLANDORA/Islandora+Core+Module).
diff --git a/includes/dublin_core.inc b/includes/dublin_core.inc
index cff1bebed..924d97067 100644
--- a/includes/dublin_core.inc
+++ b/includes/dublin_core.inc
@@ -13,6 +13,11 @@
*/
class DublinCore {
+ /**
+ * Dublin Core fields.
+ *
+ * @var array|\DublinCore
+ */
public $dc = array(
'dc:title' => array(),
'dc:creator' => array(),
@@ -30,6 +35,12 @@ class DublinCore {
'dc:coverage' => array(),
'dc:rights' => array(),
);
+
+ /**
+ * Owner name.
+ *
+ * @var string
+ */
public $owner;
/**
diff --git a/includes/imageserver.inc b/includes/imageserver.inc
new file mode 100644
index 000000000..f1d55ccfc
--- /dev/null
+++ b/includes/imageserver.inc
@@ -0,0 +1,335 @@
+ islandora_imageserver_get_type_selectbox(FALSE),
+ 'url' => array(
+ '#prefix' => '
',
+ '#suffix' => '
',
+ '#type' => 'textfield',
+ '#title' => t('Image Server Base URL'),
+ '#title_display' => 'invisible',
+ '#default_value' => $settings['url'],
+ '#description' => t('The location of the image server.
!confirmation_message', array(
+ '!confirmation_message' => islandora_imageserver_admin_form_access_message($form_state),
+ )),
+ '#ajax' => array(
+ 'callback' => 'islandora_imageserver_admin_ajax_url',
+ 'wrapper' => 'islandora-imageserver-path-wrapper',
+ ),
+ ),
+ 'iiif' => array(
+ '#type' => 'fieldset',
+ '#title' => t('IIIF Image Server Settings'),
+ '#description' => t('Settings for IIIF Image Server'),
+ '#states' => array(
+ 'visible' => array(
+ ':input[name="type"]' => array('value' => 'iiif'),
+ ),
+ ),
+ 'iiif_token_header' => array(
+ '#type' => 'checkbox',
+ '#title' => t('Add token as header'),
+ '#default_value' => $settings['iiif_token_header'],
+ '#description' => t('Instead of sending the token as a query parameter, it will be sent in the X-ISLANDORA-TOKEN header.'),
+ ),
+ 'iiif_identifier' => array(
+ '#type' => 'textfield',
+ '#title' => t('IIIF Identifier'),
+ '#default_value' => $settings['iiif_identifier'],
+ '#element_validate' => array('token_element_validate'),
+ '#token_types' => array('islandora'),
+ ),
+ 'islandora_imageserver_iiif_token_tree' => array(
+ '#type' => 'fieldset',
+ '#title' => t('Replacement patterns'),
+ '#collapsible' => TRUE,
+ '#collapsed' => TRUE,
+ '#description' => theme('token_tree', array(
+ 'token_types' => array('islandora'),
+ 'global_types' => FALSE,
+ )),
+ ),
+ ),
+ 'actions' => array(
+ '#type' => 'actions',
+ 'save' => array(
+ '#type' => 'submit',
+ '#value' => t('Save configuration'),
+ '#weight' => 0,
+ ),
+ 'reset' => array(
+ '#type' => 'submit',
+ '#value' => t('Reset to defaults'),
+ '#weight' => 1,
+ '#submit' => array('islandora_imageserver_admin_submit_reset'),
+ ),
+ ),
+ );
+ return $form;
+}
+
+/**
+ * Redirect to Reset form.
+ *
+ * @param array $form
+ * Drupal form.
+ * @param array $form_state
+ * Drupal form state.
+ */
+function islandora_imageserver_admin_submit_reset(array $form, array &$form_state) {
+ $form_state['redirect'] = 'admin/islandora/image_server/reset';
+}
+
+/**
+ * Settings reset confirmation form.
+ *
+ * @param array $form
+ * The Drupal form.
+ * @param array $form_state
+ * The Drupal $form_state.
+ *
+ * @return mixed
+ * The created form.
+ */
+function islandora_imageserver_admin_reset_confirm_form(array $form, array &$form_state) {
+ return confirm_form(
+ $form,
+ t("Do you really want to reset the Image Server settings?"),
+ 'admin/islandora/image_server',
+ t("This action cannot be undone."),
+ t("Reset")
+ );
+}
+
+/**
+ * Implements hook_form_submit().
+ */
+function islandora_imageserver_admin_reset_confirm_form_submit(array $form, array &$form_state) {
+ variable_del('islandora_imageserver_settings');
+ drupal_set_message(t('Settings reset.'), 'status');
+ $form_state['redirect'] = 'admin/islandora/image_server';
+}
+
+/**
+ * Implements hook_form_submit().
+ */
+function islandora_imageserver_admin_form_submit(array $form, array &$form_state) {
+ $type = $form_state['values']['type'];
+ $settings = islandora_imageserver_get_settings();
+ $settings['type'] = $type;
+ $settings['url'] = rtrim($form_state['values']['url'], '/');
+ if ($type == 'iiif') {
+ $settings['iiif_token_header'] = (bool) $form_state['values']['iiif_token_header'];
+ $settings['iiif_identifier'] = $form_state['values']['iiif_identifier'];
+ }
+ else {
+ $settings['iiif_token_header'] = FALSE;
+ $settings['iiif_identifier'] = ISLANDORA_IMAGESERVER_DEFAULT_TOKEN;
+ }
+ variable_set('islandora_imageserver_settings', $settings);
+ drupal_set_message(t("Settings saved successfully."), 'status');
+}
+
+/**
+ * Callback to check URL.
+ *
+ * @param array $form
+ * Drupal form.
+ * @param array $form_state
+ * Drupal form state.
+ *
+ * @return mixed
+ * The form element.
+ */
+function islandora_imageserver_admin_ajax_url(array $form, array $form_state) {
+ return $form['url'];
+}
+
+/**
+ * Gets a message which describes if Adore-Djatoka is accessible.
+ *
+ * @param array $form_state
+ * The current form state.
+ *
+ * @see islandora_imageserver_get_settings()
+ *
+ * @return string
+ * A message describing the accessibility of the Adore-Djatoka image resolver.
+ */
+function islandora_imageserver_admin_form_access_message(array &$form_state) {
+ $confirmation_message = '';
+
+ $type = islandora_imageserver_get_default_value($form_state, 'type');
+ $url = islandora_imageserver_get_default_value($form_state, 'url');
+
+ if ($type == 'djatoka') {
+ $url = url($url, array(
+ 'absolute' => TRUE,
+ 'query' => array(
+ 'url_ver' => 'Z39.88-2004',
+ 'rft_id' => 'http://memory.loc.gov/gmd/gmd433/g4330/g4330/np000066.jp2',
+ 'svc_id' => 'info:lanl-repo/svc/getRegion',
+ 'svc_val_fmt' => 'info:ofi/fmt:kev:mtx:jpeg2000',
+ 'svc.format' => 'image/jpeg',
+ 'svc.level' => '1',
+ ),
+ ));
+ }
+ elseif ($type == 'iiif') {
+ $url = url(rtrim($url, '/'),
+ array(
+ 'absolute' => TRUE,
+ )
+ );
+ }
+ else {
+ // None, so don't confirm.
+ return "";
+ }
+
+ if (isset($url) && !empty($url)) {
+ $result = drupal_http_request($url);
+ if ($result->code == 200) {
+ $confirmation_message = theme_image(array(
+ 'path' => 'misc/watchdog-ok.png',
+ 'attributes' => array(),
+ ));
+ $confirmation_message .= t('Successfully connected to image server.');
+ }
+ else {
+ $confirmation_message = theme_image(array(
+ 'path' => 'misc/watchdog-error.png',
+ 'attributes' => array(),
+ ));
+ $confirmation_message .= t('Unable to connect to image server at !path', array(
+ '!path' => $url,
+ ));
+ }
+ }
+ return $confirmation_message;
+}
+
+/**
+ * Get image server settings.
+ *
+ * @return array
+ * Configuration to access the image server.
+ */
+function islandora_imageserver_get_settings() {
+ $defaults = islandora_imageserver_get_default_settings();
+
+ $settings = variable_get('islandora_imageserver_settings', array()) + $defaults;
+
+ return $settings;
+}
+
+/**
+ * Return the default image server settings.
+ *
+ * @return array
+ * The settings.
+ */
+function islandora_imageserver_get_default_settings() {
+ return array(
+ 'type' => 'none',
+ 'url' => '',
+ 'iiif_token_header' => FALSE,
+ 'iiif_identifier' => ISLANDORA_IMAGESERVER_DEFAULT_TOKEN,
+ );
+}
+
+/**
+ * Utility to check form_state or return the default.
+ *
+ * @param array $form_state
+ * Drupal form state.
+ * @param string $name
+ * Name of the form element/settings key.
+ *
+ * @return mixed
+ * The Form value or currently saved value.
+ */
+function islandora_imageserver_get_default_value(array &$form_state, $name) {
+ $settings = islandora_imageserver_get_settings();
+ return isset($form_state['values'][$name]) ? $form_state['values'][$name] : $settings[$name];
+}
+
+/**
+ * Generate a replacement string using tokens.
+ *
+ * @param string $string_token
+ * The replacement token to generate.
+ * @param string $pid
+ * The pid of the object.
+ * @param string $dsid
+ * The dsid to return.
+ * @param string $authtoken
+ * The authentication token.
+ *
+ * @return mixed
+ * The token replaced string.
+ */
+function islandora_imageserver_get_identifier($string_token, $pid, $dsid, $authtoken) {
+ $settings = islandora_imageserver_get_settings();
+ if ($settings['type'] == 'djatoka') {
+ // We use the token_replace to generate the rft_id.
+ $string_token = '[islandora:url_token]';
+ }
+ $parts = array(
+ 'islandora' => array(
+ 'pid' => $pid,
+ 'dsid' => $dsid,
+ 'token' => $authtoken,
+ ),
+ );
+ return token_replace($string_token, $parts);
+}
+
+/**
+ * Create the select box form element with the currently configured type.
+ *
+ * @param bool $disabled
+ * Whether the element should be disabled.
+ *
+ * @return array
+ * The form element.
+ */
+function islandora_imageserver_get_type_selectbox($disabled = TRUE) {
+ $settings = islandora_imageserver_get_settings();
+ $description = $disabled ? t("Configured at Admin ≫ Islandora ≫ Image server configuration.") : t("Select the image server to configure.");
+ return array(
+ '#type' => 'select',
+ '#title' => t('Image Server'),
+ '#description' => $description,
+ '#default_value' => $settings['type'],
+ '#disabled' => $disabled,
+ '#options' => array(
+ 'none' => t('No image server configured'),
+ 'iiif' => t('IIIF image server'),
+ 'djatoka' => t('Adore-Djatoka image server'),
+ ),
+ );
+}
diff --git a/includes/mime_detect.inc b/includes/mime_detect.inc
index 818e150be..9baedbc2a 100644
--- a/includes/mime_detect.inc
+++ b/includes/mime_detect.inc
@@ -59,7 +59,17 @@ class MimeDetect {
* $this->get_extension('image/jpeg') will always return 'jpg'.
*/
protected $protectedMimeTypes = array();
+ /**
+ * Protected file extensions.
+ *
+ * @var array
+ */
protected $protectedFileExtensions;
+ /**
+ * Extension exceptions.
+ *
+ * @var array
+ */
protected $extensionExceptions = array(
// XXX: Deprecated... Only here due to old 'tif' => 'image/tif' mapping...
// The correct MIMEtype is 'image/tiff'.
diff --git a/includes/tuque_wrapper.inc b/includes/tuque_wrapper.inc
index 3b08a9fda..285cecfa9 100644
--- a/includes/tuque_wrapper.inc
+++ b/includes/tuque_wrapper.inc
@@ -80,8 +80,23 @@ function islandora_invoke_datastream_hooks($hook, array $models, $dsid) {
* Implementation of the FedoraRepository class.
*/
class IslandoraFedoraRepository extends FedoraRepository {
+ /**
+ * Class name.
+ *
+ * @var string
+ */
protected $queryClass = 'IslandoraRepositoryQuery';
+ /**
+ * Class name.
+ *
+ * @var string
+ */
protected $newObjectClass = 'IslandoraNewFedoraObject';
+ /**
+ * Class name.
+ *
+ * @var string
+ */
protected $objectClass = 'IslandoraFedoraObject';
/**
@@ -179,8 +194,23 @@ class IslandoraRepositoryQuery extends RepositoryQuery {}
* Implementation of NewFedoraObject class.
*/
class IslandoraNewFedoraObject extends NewFedoraObject {
+ /**
+ * Class name.
+ *
+ * @var string
+ */
protected $newFedoraDatastreamClass = 'IslandoraNewFedoraDatastream';
+ /**
+ * Class name.
+ *
+ * @var string
+ */
protected $fedoraDatastreamClass = 'IslandoraFedoraDatastream';
+ /**
+ * Class name.
+ *
+ * @var string
+ */
protected $fedoraRelsExtClass = 'IslandoraFedoraRelsExt';
}
@@ -188,8 +218,23 @@ class IslandoraNewFedoraObject extends NewFedoraObject {
* Implementation, magic functions for a FedoraObject class.
*/
class IslandoraFedoraObject extends FedoraObject {
+ /**
+ * Class name.
+ *
+ * @var string
+ */
protected $newFedoraDatastreamClass = 'IslandoraNewFedoraDatastream';
+ /**
+ * Class name.
+ *
+ * @var string
+ */
protected $fedoraDatastreamClass = 'IslandoraFedoraDatastream';
+ /**
+ * Class name.
+ *
+ * @var string
+ */
protected $fedoraRelsExtClass = 'IslandoraFedoraRelsExt';
/**
@@ -568,7 +613,17 @@ class IslandoraSimpleCache extends SimpleCache {}
* Implementation of NewFedoraDatastream class.
*/
class IslandoraNewFedoraDatastream extends NewFedoraDatastream {
+ /**
+ * Class name.
+ *
+ * @var string
+ */
protected $fedoraRelsIntClass = 'IslandoraFedoraRelsInt';
+ /**
+ * Class name.
+ *
+ * @var string
+ */
protected $fedoraDatastreamVersionClass = 'IslandoraFedoraDatastreamVersion';
}
@@ -576,7 +631,17 @@ class IslandoraNewFedoraDatastream extends NewFedoraDatastream {
* Implementation and magic functions for FedoraDatastream class.
*/
class IslandoraFedoraDatastream extends FedoraDatastream {
+ /**
+ * Class name.
+ *
+ * @var string
+ */
protected $fedoraRelsIntClass = 'IslandoraFedoraRelsInt';
+ /**
+ * Class name.
+ *
+ * @var string
+ */
protected $fedoraDatastreamVersionClass = 'IslandoraFedoraDatastreamVersion';
/**
@@ -650,7 +715,17 @@ class IslandoraFedoraDatastream extends FedoraDatastream {
* Implementation of FedoraDatastreamVersion class.
*/
class IslandoraFedoraDatastreamVersion extends FedoraDatastreamVersion {
+ /**
+ * Class name.
+ *
+ * @var string
+ */
protected $fedoraRelsIntClass = 'IslandoraFedoraRelsInt';
+ /**
+ * Class name.
+ *
+ * @var string
+ */
protected $fedoraDatastreamVersionClass = 'IslandoraFedoraDatastreamVersion';
}
diff --git a/includes/utilities.inc b/includes/utilities.inc
index b14053304..10ac2d1f3 100644
--- a/includes/utilities.inc
+++ b/includes/utilities.inc
@@ -267,9 +267,9 @@ function islandora_escape_pid_for_function($pid) {
* below are fine.
*
* @code
- * 'islandora',
- * 'islandora:',
- * 'islandora:1234',
+ * 'islandora',
+ * 'islandora:',
+ * 'islandora:1234',
* @endcode
*
* @return string
@@ -291,9 +291,9 @@ function islandora_get_namespace($id) {
* below are fine.
*
* @code
- * 'islandora',
- * 'islandora:',
- * 'islandora:1234',
+ * 'islandora',
+ * 'islandora:',
+ * 'islandora:1234',
* @endcode
*
* @return bool
diff --git a/islandora.install b/islandora.install
index cc0cc49fc..357c8c1fd 100644
--- a/islandora.install
+++ b/islandora.install
@@ -61,6 +61,7 @@ function islandora_uninstall() {
'islandora_breadcrumbs_backends',
'islandora_render_context_ingeststep',
'islandora_deny_inactive_and_deleted',
+ 'islandora_imageserver_settings',
);
array_walk($variables, 'variable_del');
}
@@ -144,3 +145,68 @@ function islandora_update_7002() {
// Removing as the deprecation has been removed.
variable_del('islandora_deprecation_return_false_when_datastream_exists');
}
+
+/**
+ * Implements hook_update_N().
+ *
+ * Try to auto-configure the image server settings in core based on
+ * the Internet Archive Bookreader and/or Openseadragon settings.
+ */
+function islandora_update_7003() {
+ module_load_include('inc', 'islandora', 'includes/imageserver');
+ if (islandora_imageserver_get_settings()['type'] != 'none') {
+ return t('Settings have already been configured manually.');
+ }
+ if (module_exists('islandora_openseadragon')) {
+ $openseadragon_settings = array(
+ 'type' => variable_get('islandora_openseadragon_tilesource', 'djatoka'),
+ );
+ if ($openseadragon_settings['type'] == 'djatoka') {
+ $openseadragon_settings['url'] = variable_get('islandora_openseadragon_djatoka_url', 'adore-djatoka/resolver');
+ }
+ else {
+ $openseadragon_settings['url'] = variable_get('islandora_openseadragon_iiif_url', 'iiif');
+ $openseadragon_settings['iiif_token_header'] = variable_get('islandora_openseadragon_iiif_token_header', FALSE);
+ $openseadragon_settings['iiif_identifier'] = str_replace('[islandora_openseadragon:', '[islandora:', variable_get('islandora_openseadragon_iiif_identifier', '[islandora_openseadragon:url_token]'));
+ }
+ }
+ if (module_exists('islandora_internet_archive_bookreader')) {
+ $iabv_settings = array(
+ 'type' => variable_get('islandora_internet_archive_bookreader_pagesource', 'djatoka'),
+ );
+ if ($iabv_settings['type'] == 'djatoka') {
+ $iabv_settings['url'] = variable_get('islandora_paged_content_djatoka_url', 'http://localhost:8080/adore-djatoka');
+ }
+ else {
+ $iabv_settings['url'] = variable_get('islandora_internet_archive_bookreader_iiif_url', 'iiif');
+ $iabv_settings['iiif_token_header'] = variable_get('islandora_internet_archive_bookreader_iiif_token_header', FALSE);
+ $iabv_settings['iiif_identifier'] = str_replace('[islandora_iareader:', '[islandora:', variable_get('islandora_internet_archive_bookreader_iiif_identifier', '[islandora_iareader:url_token]'));
+ }
+ }
+ if (isset($openseadragon_settings) && isset($iabv_settings)) {
+ if (count(array_diff($openseadragon_settings, $iabv_settings)) == 0) {
+ // Settings are the same, use for core imageserver variables.
+ $new_settings = $openseadragon_settings;
+ }
+ else {
+ // We could not migrate your settings to the new place. This stops the
+ // other two modules from deleting your settings.
+ throw new DrupalUpdateException('Islandora image server settings could NOT be configured automatically, please set them manually at Admin -> Islandora -> Image Server configuration and then run updates again.');
+ }
+ }
+ elseif (isset($openseadragon_settings)) {
+ $new_settings = $openseadragon_settings;
+ }
+ elseif (isset($iabv_settings)) {
+ $new_settings = $iabv_settings;
+ }
+ if (isset($new_settings)) {
+ if ($new_settings['type'] == 'djatoka' && !preg_match('~resolver$~', $new_settings['url'])) {
+ // IABV javascript added resolver to URL, Openseadragon did not.
+ $new_settings['url'] = rtrim($new_settings['url'], '/') . '/resolver';
+ }
+ // We have migrated your settings to the new place.
+ variable_set('islandora_imageserver_settings', $new_settings);
+ return t("Islandora image server settings configured automatically.");
+ }
+}
diff --git a/islandora.module b/islandora.module
index 3e53ebac0..0e8b3d12e 100644
--- a/islandora.module
+++ b/islandora.module
@@ -72,6 +72,8 @@ define('ISLANDORA_MIME_TYPES_AUTOCOMPLETE', 'islandora/autocomplete/mime-types')
const ISLANDORA_BREADCRUMB_LEGACY_BACKEND = 'islandora_breadcrumbs_legacy_sparql';
+const ISLANDORA_IMAGESERVER_DEFAULT_TOKEN = "[islandora:url_token]";
+
/**
* Implements hook_menu().
*
@@ -417,6 +419,24 @@ function islandora_menu() {
'type' => MENU_SUGGESTED_ITEM,
'access arguments' => array(ISLANDORA_MANAGE_DELETED_OBJECTS),
);
+ $items['admin/islandora/image_server'] = array(
+ 'title' => 'Image server configuration',
+ 'description' => 'Define the settings for your local image server',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('islandora_imageserver_admin_form'),
+ 'access arguments' => array('administer site configuration'),
+ 'type' => MENU_NORMAL_ITEM,
+ 'file' => 'includes/imageserver.inc',
+ );
+ $items['admin/islandora/image_server/reset'] = array(
+ 'title' => 'Image server configuration reset confirmation',
+ 'description' => 'Image server configuration reset confirmation',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('islandora_imageserver_admin_reset_confirm_form'),
+ 'access arguments' => array('administer site configuration'),
+ 'type' => MENU_CALLBACK,
+ 'file' => 'includes/imageserver.inc',
+ );
return $items;
}
@@ -2230,3 +2250,90 @@ function islandora_islandora_solution_pack_child_relationships($cmodels) {
// exist when the hook is called, even if no module responds.
return array('predicate' => array(), 'prefix' => array());
}
+
+/**
+ * Implements hook_token_info().
+ */
+function islandora_token_info() {
+ $info = array();
+
+ $info['types']['islandora'] = array(
+ 'name' => t('Islandora'),
+ 'description' => t('Tokens for building IIIF identifer in Islandora.'),
+ 'needs-data' => 'islandora',
+ );
+
+ $info['tokens']['islandora']['pid'] = array(
+ 'name' => t('PID'),
+ 'description' => t('The objects PID.'),
+ );
+
+ $info['tokens']['islandora']['dsid'] = array(
+ 'name' => t('DSID'),
+ 'description' => t('The objects DSID.'),
+ );
+
+ $info['tokens']['islandora']['url'] = array(
+ 'name' => t('URL'),
+ 'description' => t('The URL to the object in Islandora.'),
+ );
+
+ $info['tokens']['islandora']['url_token'] = array(
+ 'name' => t('URL with Token'),
+ 'description' => t('The URL to the object in Islandora with token in the query string.'),
+ );
+
+ $info['tokens']['islandora']['token'] = array(
+ 'name' => t('Token'),
+ 'description' => t('The token that can be used to access the object in Islandora.'),
+ );
+
+ return $info;
+}
+
+/**
+ * Implements hook_tokens().
+ */
+function islandora_tokens($type, $tokens, array $data = array(), array $options = array()) {
+ $replacements = array();
+
+ if ($type != 'islandora' || !isset($data['islandora'])) {
+ return $replacements;
+ }
+
+ $pid = $data['islandora']['pid'];
+ $dsid = $data['islandora']['dsid'];
+ $token = $data['islandora']['token'];
+
+ foreach ($tokens as $name => $original) {
+ if ($name == 'pid') {
+ $replacements[$original] = $pid;
+ }
+ elseif ($name == 'dsid') {
+ $replacements[$original] = $dsid;
+ }
+ elseif ($name == 'token') {
+ $replacements[$original] = $token;
+ }
+ elseif ($name == 'url' || $name == 'url_token') {
+ $options = array(
+ 'absolute' => TRUE,
+ 'language' => language_default(),
+ 'https' => (function_exists('drupal_is_https') ?
+ drupal_is_https() :
+ (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on')
+ ),
+ );
+
+ if ($name == 'url_token') {
+ $options['query'] = array(
+ 'token' => $token,
+ );
+ }
+
+ $replacements[$original] = url("islandora/object/{$pid}/datastream/{$dsid}/view", $options);
+ }
+ }
+
+ return $replacements;
+}
diff --git a/tests/includes/utilities.inc b/tests/includes/utilities.inc
index 2549d21b5..c90291390 100644
--- a/tests/includes/utilities.inc
+++ b/tests/includes/utilities.inc
@@ -19,12 +19,32 @@
*/
class IslandoraTestUtilities extends IslandoraTestUtilityClass {
+ /**
+ * The test configuration.
+ *
+ * @var array
+ */
protected $configuration;
+ /**
+ * The parameters.
+ *
+ * @var array
+ */
protected $params;
+ /**
+ * Test results.
+ *
+ * @var array
+ */
public $results = array();
+ /**
+ * A repository object.
+ *
+ * @var \FedoraRepository
+ */
protected $repository;
/**