diff --git a/includes/solution_packs.inc b/includes/solution_packs.inc
index d6fab446..6b5310e2 100644
--- a/includes/solution_packs.inc
+++ b/includes/solution_packs.inc
@@ -9,157 +9,143 @@
/**
* Solution pack admin page callback.
+ *
+ * @return string
+ * The html repersentation of all solution pack forms for required objects.
*/
function islandora_solution_packs_admin() {
module_load_include('inc', 'islandora', 'includes/utilities');
- drupal_add_css(drupal_get_path('module', 'islandora') . '/css/islandora.admin.css');
if (!islandora_describe_repository()) {
- $message = t('Could not connect to the repository. Please check the settings on the ' .
- 'Islandora configuration page.',
- array('@config_url' => url('admin/islandora/configure')));
- drupal_set_message($message, 'error');
+ islandora_display_repository_inaccessible_message();
+ return '';
}
- $enabled_solution_packs = module_invoke_all('islandora_required_objects');
+
+ $connection = islandora_get_tuque_connection();
+ drupal_add_css(drupal_get_path('module', 'islandora') . '/css/islandora.admin.css');
$output = '';
+ $enabled_solution_packs = module_invoke_all('islandora_required_objects', $connection);
foreach ($enabled_solution_packs as $solution_pack_module => $solution_pack_info) {
- $objects = array();
- foreach ($solution_pack_info as $field => $value) {
- switch ($field) {
- case 'title':
- $solution_pack_name = $value;
- break;
- case 'objects':
- $objects = $value;
- break;
- }
- }
- $form_array = drupal_get_form('islandora_solution_pack_form_' . $solution_pack_module, $solution_pack_module, $solution_pack_name, $objects);
- $output .= drupal_render($form_array);
+ // @todo We should probably get the title of the solution pack from the
+ // systems table for consistency in the interface.
+ $solution_pack_name = $solution_pack_info['title'];
+ $objects = array_filter($solution_pack_info['objects']);
+ $form = drupal_get_form('islandora_solution_pack_form_' . $solution_pack_module, $solution_pack_module, $solution_pack_name, $objects);
+ $output .= drupal_render($form);
}
return $output;
}
/**
- * Solution pack admin page
+ * A solution pack form for the given module, it lists all the given objects and
+ * their status, allowing the user to re-ingest them.
+ *
+ * @param array $form
+ * The Drupal form definition.
+ * @param array $form_state
+ * The Drupal form state.
+ * @param string $solution_pack_module
+ * The module which requires the given objects.
+ * @param string $solution_pack_name
+ * The name of the solution pack to display to the users.
+ * @param array $objects
+ * An array of NewFedoraObjects which describe the state in which objects
+ * should exist.
+ *
+ * @return array
+ * The Drupal form definition.
*/
-function islandora_solution_pack_form($form, &$form_state, $solution_pack_module, $solution_pack_name, $objects = array()) {
- global $base_url;
- $needs_update = FALSE;
- $needs_install = FALSE;
- $could_not_connect = FALSE;
- $form = array();
-
- $form['solution_pack'] = array(
- '#type' => 'fieldset',
- '#collapsible' => FALSE,
- '#collapsed' => FALSE,
- '#attributes' => array('class' => array('islandora-solution-pack-fieldset')),
+function islandora_solution_pack_form(array $form, array &$form_state, $solution_pack_module, $solution_pack_name, $objects = array()) {
+ // The order is important in terms of severity of the status, where higher
+ // index indicates the status is more serious, this will be used to determine
+ // what messages get displayed to the user.
+ $ok_image = theme_image(array('path' => 'misc/watchdog-ok.png', 'attributes' => array()));
+ $warning_image = theme_image(array('path' => 'misc/watchdog-warning.png', 'attributes' => array()));
+ $status_info = array(
+ 'up_to_date' => array(
+ 'solution_pack' => t('All required objects are installed and up-to-date.'),
+ 'image' => $ok_image,
+ 'button' => t("Force reinstall objects"),
+ ),
+ 'modified_datastream' => array(
+ 'solution_pack' => t('Some objects must be reinstalled. See objects list for details.'),
+ 'image' => $warning_image,
+ 'button' => t("Reinstall objects")
+ ),
+ 'out_of_date' => array(
+ 'solution_pack' => t('Some objects must be reinstalled. See objects list for details.'),
+ 'image' => $warning_image,
+ 'button' => t("Reinstall objects")
+ ),
+ 'missing_datastream' => array(
+ 'solution_pack' => t('Some objects must be reinstalled. See objects list for details.'),
+ 'image' => $warning_image,
+ 'button' => t("Reinstall objects")
+ ),
+ 'missing' => array(
+ 'solution_pack' => t( 'Some objects are missing and must be installed. See objects list for details.'),
+ 'image' => $warning_image,
+ 'button' => t("Install objects")
+ ),
);
-
- // adding values
- $form['solution_pack']['solution_pack_module'] = array(
- '#type' => 'value',
- '#value' => $solution_pack_module,
- );
- $form['solution_pack']['solution_pack_name'] = array(
- '#type' => 'value',
- '#value' => $solution_pack_name,
- );
- $form['solution_pack']['objects'] = array(
- '#type' => 'value',
- '#value' => $objects,
- );
-
- $table_header = array(t('Label'), t('PID'), t('Status'));
+ $status_severities = array_keys($status_info);
+ $solution_pack_status_severity = array_search('up_to_date', $status_severities);
$table_rows = array();
-
foreach ($objects as $object) {
- $datastreams = NULL;
- if (isset($object['pid'])) {
- $pid = $object['pid'];
- $table_row = array();
- $object_status = islandora_check_object_status($object);
- switch ($object_status) {
- case 'up_to_date':
- $object_status = t('Up-to-date');
- break;
- case 'missing':
- $object_status = t('Missing');
- $needs_install = TRUE;
- break;
- case 'missing_datastream':
- $object_status = t('Missing datastream');
- $needs_update = TRUE;
- break;
- case 'out_of_date':
- $object_status = t('Out-of-date');
- $needs_update = TRUE;
- break;
- case 'could_not_connect':
- $object_status = t('Could not connect');
- $could_not_connect = TRUE;
- break;
- }
- if ($needs_install OR $could_not_connect) {
- $label = $object['label'] ? $object['label'] : '';
- }
- else {
- $label = $object['label'] ? l($object['label'], $base_url . '/islandora/object/' . $pid) : '';
- }
- $table_row[] = $label;
- $table_row[] = $pid;
- $table_row[] = $object_status;
- $table_rows[] = $table_row;
- }
- }
-
- // title
- if (!$form_state['submitted']) {
- $form['solution_pack']['solution_pack_label'] = array(
- '#markup' => filter_xss($solution_pack_name),
- '#prefix' => '
',
- '#suffix' => '
',
- );
-
- $form['solution_pack']['install_status'] = array(
- '#markup' => '' . t('Object status:') . ' ',
- '#prefix' => '',
- '#suffix' => '
',
- );
- if (!$needs_install AND !$needs_update AND !$could_not_connect) {
- $form['solution_pack']['install_status']['#markup'] .= ' ' . theme('image', array('path' => 'misc/watchdog-ok.png')) . ' ' . t('All required objects are installed and up-to-date.');
- $submit_button_text = t("Force reinstall objects");
- }
- elseif ($needs_install) {
- $form['solution_pack']['install_status']['#markup'] .= ' ' . theme('image', array('path' => 'misc/watchdog-warning.png')) . ' ' . t('Some objects are missing and must be installed. See objects list for details.');
- $submit_button_text = t("Install objects");
- }
- elseif ($needs_update) {
- $form['solution_pack']['install_status']['#markup'] .= ' ' . theme('image', array('path' => 'misc/watchdog-warning.png')) . ' ' . t('Some objects must be reinstalled. See objects list for details.');
- $submit_button_text = t("Reinstall objects");
- }
- elseif ($could_not_connect) {
- $form['solution_pack']['install_status']['#markup'] .= ' ' . theme('image', array('path' => 'misc/watchdog-error.png')) . ' ' . t('Could not connect to the repository.');
- $submit_button_text = '';
- }
-
- $form['solution_pack']['table'] = array(
- '#type' => 'item',
- '#markup' => theme('table', array('header' => $table_header, 'rows' => $table_rows)),
- );
+ $object_status = islandora_check_object_status($object);
+ $object_status_info = $status_info[$object_status['status']];
+ $object_status_severity = array_search($object_status['status'], $status_severities);
+ // The solution pack status severity will be the highest severity of the objects.
+ $solution_pack_status_severity = max($solution_pack_status_severity, $object_status_severity);
+ $exists = $object_status['status'] != 'missing';
+ $label = $exists ? l($object->label, "islandora/object/{$object->id}") : $object->label;
+ $status_msg = "{$object_status_info['image']} {$object_status['status_friendly']}";
+ $table_rows[] = array($label, $object->id, $status_msg);
}
-
- if (!$could_not_connect) {
- $form['solution_pack']['submit'] = array(
- '#value' => $submit_button_text,
- '#type' => 'submit',
- '#name' => $solution_pack_module,
- '#attributes' => array('class' => array('islandora-solution-pack-submit')),
- '#weight' => 40,
- );
- $form['solution_pack']['#submit'] = array('islandora_solution_pack_form_submit');
- }
- return $form;
+ $solution_pack_status = $status_severities[$solution_pack_status_severity];
+ $solution_pack_status_info = $status_info[$solution_pack_status];
+ return array(
+ 'solution_pack' => array(
+ '#type' => 'fieldset',
+ '#collapsible' => FALSE,
+ '#collapsed' => FALSE,
+ '#attributes' => array('class' => array('islandora-solution-pack-fieldset')),
+ 'solution_pack_module' => array(
+ '#type' => 'value',
+ '#value' => $solution_pack_module,
+ ),
+ 'solution_pack_name' => array(
+ '#type' => 'value',
+ '#value' => $solution_pack_name,
+ ),
+ 'objects' => array(
+ '#type' => 'value',
+ '#value' => $objects,
+ ),
+ 'solution_pack_label' => array(
+ '#markup' => $solution_pack_name,
+ '#prefix' => '',
+ '#suffix' => '
',
+ ),
+ 'install_status' => array(
+ '#markup' => t('Object status: !image !status', array(
+ '!image' => $solution_pack_status_info['image'],
+ '!status' => $solution_pack_status_info['solution_pack']
+ )),
+ '#prefix' => '',
+ '#suffix' => '
',
+ ),
+ 'table' => array(
+ '#type' => 'item',
+ '#markup' => theme('table', array('header' => array(t('Label'), t('PID'), t('Status')), 'rows' => $table_rows))
+ ),
+ 'submit' => array(
+ '#type' => 'submit',
+ '#name' => $solution_pack_module,
+ '#value' => $solution_pack_status_info['button'],
+ '#attributes' => array('class' => array('islandora-solution-pack-submit')),
+ )
+ )
+ );
}
/**
@@ -167,349 +153,275 @@ function islandora_solution_pack_form($form, &$form_state, $solution_pack_modul
*
* @param array $form
* The form submitted.
- * @param array_reference $form_state
+ * @param array $form_state
* The state of the form submited.
*/
-function islandora_solution_pack_form_submit($form, &$form_state) {
+function islandora_solution_pack_form_submit(array $form, array &$form_state) {
$solution_pack_module = $form_state['values']['solution_pack_module'];
- $solution_pack_name = $form_state['values']['solution_pack_name'];
$objects = $form_state['values']['objects'];
-
$batch = array(
- 'title' => t('Installing / updating solution pack objects'),
+ 'title' => t('Installing / Updating solution pack objects'),
'file' => drupal_get_path('module', 'islandora') . '/includes/solution_packs.inc',
'operations' => array(),
);
-
foreach ($objects as $object) {
- // Add this object to the batch job queue.
- $batch['operations'][] = array('islandora_batch_reingest_object', array($object));
+ $batch['operations'][] = array('islandora_solution_pack_batch_operation_reingest_object', array($object));
}
-
batch_set($batch);
-
// Hook to let solution pack objects be modified.
// Not using module_invoke so solution packs can be expanded by other modules.
+ // @todo shouldn't we send the object list along as well?
module_invoke_all('islandora_postprocess_solution_pack', $solution_pack_module);
+}
+/**
+ * Batch operation used by the solution pack forms to ingest/reingest required
+ * object(s)
+ *
+ * @param NewFedoraObject $object
+ * The object to ingest/reingest.
+ * @param array $context
+ * The context of this batch operation.
+ */
+function islandora_solution_pack_batch_operation_reingest_object(NewFedoraObject $object, array &$context) {
+ $deleted = FALSE;
+ $existing_object = islandora_object_load($object->id);
+ if ($existing_object) {
+ $deleted = islandora_delete_object($existing_object);
+ $purged = $deleted && $existing_object == NULL;
+ if (!$purged) {
+ $object_link = l($existing_object->label, "islandora/object/{$existing_object->id}");
+ drupal_set_message(t('Failed to purge existing object !object_link.', array(
+ '!object_link' => $object_link,
+ )), 'error');
+ // Failed to purge don't attempt to ingest.
+ return;
+ }
+ }
+ // Object was deleted or did not exist.
+ $pid = $object->id;
+ $label = $object->label;
+ $action = $deleted ? 'reinstalled' : 'installed';
+ $object_link = l($label, "islandora/object/{$pid}");
+ $object = islandora_add_object($object);
+ $msg = $object ? "Successfully $action !object_link." : "Failed to $action @label identified by @pid.";
+ $status = $object ? 'status' : 'error';
+ drupal_set_message(t($msg, array(
+ '@pid' => $pid,
+ '@label' => $label,
+ '!object_link' => $object_link
+ )), $status);
}
/**
- * Batch reingest object(s)
+ * This is to be called from the solution pack's hook_install()
+ * and hook_uninstall() functions. It provides a convient way to have a
+ * solution pack's required objects ingested at install time.
+ *
+ * @param string $module_name
+ * The name of the module that is calling this function in its
+ * install/unistall hooks.
+ * @param string $op
+ * The operation to perform, either install or uninstall.
*
- * @param array $object
- * @param type $context
- * @return type
+ * @todo Implement hook_modules_installed/hook_modules_uninstalled instead of
+ * calling this function directly.
+ * @todo Remove the second parameter and have two seperate functions.
*/
-function islandora_batch_reingest_object($object_model, &$context) {
+function islandora_install_solution_pack($module, $op = 'install') {
+ if ($op == 'uninstall') {
+ islandora_uninstall_solution_pack($module);
+ return;
+ }
+ module_load_include('module', 'islandora', 'islandora');
module_load_include('inc', 'islandora', 'includes/utilities');
- global $base_url;
- $connection = islandora_get_tuque_connection();
- if (!$connection) {
+ module_load_include('module', $module, $module);
+ $info_file = drupal_get_path('module', $module) . "/{$module}.info";
+ $info_array = drupal_parse_info_file($info_file);
+ $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()) {
+ $msg = '@module: Did not install any objects. Could not connect to the ';
+ $msg .= 'repository. Please check the settings on the !config_link page ';
+ $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;
}
- if (!empty($object_model) && is_array($object_model)) {
- $pid = $object_model['pid'];
- if (!islandora_is_valid_pid($pid)) {
- return NULL;
- }
-
- // purge object
- // check if object already exits
- $object_query = $connection->api->a->findObjects('query', 'pid=' . $pid);
- $reinstall = FALSE;
- if (!empty($object_query['results'])) {
- $object = islandora_object_load($pid);
- if (isset($object)) {
- islandora_delete_object($object);
- }
- $reinstall = TRUE;
+ $connection = islandora_get_tuque_connection();
+ $islandora_required_objects = $module . '_islandora_required_objects';
+ $required_objects = $islandora_required_objects($connection);
+ $objects = $required_objects[$module]['objects'];
+ $status_messages = array(
+ 'up_to_date' => 'The object already exists and is up-to-date',
+ 'missing_datastream' => 'The object already exists but is missing a datastream. Please reinstall the object on the !admin_link page',
+ 'out_of_date' => 'The object already exists but is out-of-date. Please update the object on the !admin_link page',
+ 'modified_datastream' => 'The object already exists but datastreams are modified. Please reinstall the object on the !admin_link page',
+ );
+ foreach ($objects as $object) {
+ $query = $connection->api->a->findObjects('query', 'pid=' . $object->id);
+ $already_exists = !empty($query['results']);
+ $label = $object->label;
+ $object_link = l($label, "islandora/object/{$object->id}");
+ if ($already_exists) {
+ $object_status = islandora_check_object_status($object);
+ $status_msg = $status_messages[$object_status['status']];
+ drupal_set_message(st("@module: Did not install !object_link. $status_msg.", array(
+ '@module' => $module_name,
+ '!object_link' => $object_link,
+ '!admin_link' => $admin_link,
+ )), 'warning');
}
-
- // build and ingest new object
- try {
- $object = islandora_solution_pack_add_object($object_model);
- $object_name = $object->label;
- if ($reinstall) {
- drupal_set_message(t('Successfully reinstalled @object_name.', array('@object_name' => $object_name, '@pid' => $pid)));
+ else {
+ $object = islandora_add_object($object);
+ if ($object) {
+ drupal_set_message(t('@module: Successfully installed. !object_link.', array(
+ '@module' => $module_name,
+ '!object_link' => $object_link,
+ )), 'status');
}
else {
- drupal_set_message(t('Successfully installed @object_name.', array('@object_name' => $object_name, '@pid' => $pid)));
+ drupal_set_message(t('@module: Failed to install. @label.', array(
+ '@module' => $module_name,
+ '@label' => $label,
+ )), 'warning');
}
}
- catch (Exception $e) {
- drupal_set_message(t('Installation of object @pid failed', array('@pid' => $pid)), 'error');
- }
}
}
-
/**
- * Callback function that can be called from the solution pack's hook_install() and hook_uninstall() functions.
+ * Uninstalls the given solution pack.
+ *
+ * @param string $module
+ * The solution pack to uninstall.
*
- * @TODO: add documentation
+ * @todo Implement hook_modules_uninstalled instead of calling this function
+ * directly for each solution pack.
*/
-function islandora_install_solution_pack($module_name = NULL, $op = 'install') {
- // check if a module name is given. // @TODO: check module name for existance
- if (!empty($module_name)) {
- module_load_include('module', 'islandora', 'islandora');
- module_load_include('inc', 'islandora', 'includes/utilities');
- module_load_include('module', $module_name, $module_name);
-
- // set globals
- global $base_url;
- global $user;
-
- // set variables
- $sp_admin = url($base_url . '/admin/islandora/solution_packs');
- $config_url = url('admin/islandora/configure');
-
- // get module info
- $info_file = drupal_get_path('module', $module_name) . '/' . $module_name . '.info';
- $info_array = drupal_parse_info_file($info_file);
- $module_label = $info_array['name'];
-
- // check connection
- $url = variable_get('islandora_base_url', 'http://localhost:8080/fedora');
- $info = islandora_describe_repository($url);
- if (!$info) {
- // operation
- switch ($op) {
- case 'install':
- drupal_set_message(st('@module_label: Did not install any objects. Could not connect to the repository. Please check the settings on the Islandora configuration page and install the required objects manually on the solution pack admin page.', array('@module_label' => $module_label, '@config_url' => $config_url, '@sp_url' => $sp_admin)), 'error');
- break;
-
- case 'uninstall':
- drupal_set_message(st('@module_label: Did not uninstall any objects. Could not connect to the repository. Please check the settings on the Islandora configuration page and uninstall the required objects manually if necessary.', array('@module_label' => $module_label, '@config_url' => $config_url)), 'error');
- break;
- }
- return;
- }
-
- $connection = islandora_get_tuque_connection();
- // get object models
- $enabled_solution_packs = module_invoke_all('islandora_required_objects');
- $islandora_required_objects = $module_name . '_islandora_required_objects';
- $required_objects = $islandora_required_objects();
- $objects = $required_objects[$module_name]['objects'];
-
- // loop over object models
- foreach ($objects as $object) {
- // set variables
- $pid = $object['pid'];
- $label = isset($object['label']) ? $object['label'] : st('Object');
- // check if object already exists
- $query = $connection->api->a->findObjects('query', 'pid=' . $pid);
- // object url
- $object_url = url($base_url . '/islandora/object/' . $pid);
-
- // operation: install or uninstall
- switch ($op) {
- case 'install':
- // if object exists, don't re-ingest
- if (!empty($query['results'])) {
- // check object status
- $object_status = islandora_check_object_status($object);
- // set messages
- switch ($object_status) {
- case 'up_to_date':
- drupal_set_message(st('@module_label: did not install @label. The object already exists and is up-to-date.', array('@module_label' => $module_label, '@label' => $label, '@pid' => $pid, '@object_url' => $object_url)));
- break;
- case 'missing_datastream':
- drupal_set_message(st('@module_label: did not install @label. The object already exists but is missing a datastream. Please reinstall the object on the solution pack admin page.', array('@module_label' => $module_label, '@label' => $label, '@pid' => $pid, '@objecturl' => $object_url, '@sp_admin' => $sp_admin)), 'warning');
- break;
- case 'out_of_date':
- drupal_set_message(st('@module_label: did not install @label. The object already exists but is out-of-date. Please update the object on the solution pack admin page.', array('@module_label' => $module_label, '@label' => $label, '@pid' => $pid, '@object_url' => $object_url, '@sp_admin' => $sp_admin)), 'warning');
- break;
- }
- }
- else {
- islandora_solution_pack_add_object($object);
- drupal_set_message(st('@module_label: installed @label object.', array('@module_label' => $module_label, '@label' => $label, '@pid' => $pid, '@object_url' => $object_url)));
- }
- break;
-
- case 'uninstall':
- // if object exists, set message
- if (!empty($query['results'])) {
- $object_url = url($base_url . '/islandora/object/' . $pid);
- drupal_set_message(st('@module_label: did not remove @label. It may be used by other sites.', array('@pid' => $pid, '@object_url' => $object_url, '@label' => $label, '@module_label' => $module_label)), 'warning');
- }
- break;
- }
- }
+function islandora_uninstall_solution_pack($module) {
+ module_load_include('module', 'islandora', 'islandora');
+ module_load_include('inc', 'islandora', 'includes/utilities');
+ module_load_include('module', $module, $module);
+ $config_link = l(t('Islandora configuration'), 'admin/islandora/configure');
+ $info_file = drupal_get_path('module', $module) . "/{$module}.info";
+ $info_array = drupal_parse_info_file($info_file);
+ $module_name = $info_array['name'];
+ if (!islandora_describe_repository()) {
+ $msg = '@module: Did not uninstall any objects. Could not connect to the ';
+ $msg .= 'repository. Please check the settings on the !config_link page ';
+ $msg .= 'and uninstall the required objects manually if necessary.';
+ drupal_set_message(st($msg, array(
+ '@module' => $module_name,
+ '!config_link' => $config_link
+ )), 'error');
+ return;
+ }
+ $connection = islandora_get_tuque_connection();
+ $islandora_required_objects = $module . '_islandora_required_objects';
+ $required_objects = $islandora_required_objects($connection);
+ $objects = $required_objects[$module]['objects'];
+ $existing_objects = array_filter($objects, function($o) use($connection) {
+ $param = "pid={$o->id}";
+ $query = $connection->api->a->findObjects('query', $param);
+ return !empty($query['results']);
+ }
+ );
+ 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}");
+ drupal_set_message(st($msg, array(
+ '!object_link' => $object_link,
+ '@module' => $module_name
+ )), 'warning');
}
}
-
/**
* Function to check the status of an object against an object model array.
*
- * @param array $object_model
- * an array describing an object
+ * @param NewFedoraObject $object_definition
+ * A new fedora object that defines what the object should contain.
+ *
* @return string
* Returns one of the following values:
* up_to_date, missing, missing_datastream or out_of_date
* You can perform an appropriate action based on this value.
- * Returns FALSE if the array is empty
*
* @see islandora_solution_pack_form()
* @see islandora_install_solution_pack()
- * @todo: Should this function live in islandora.module so it can be called
- * easier without having to include the solution_packs.inc file?
*/
-function islandora_check_object_status($object_model = array()) {
- if (!empty($object_model)) {
- // set variables
- $pid = $object_model['pid'];
- $object_status = 'up_to_date';
-
- // table row
- $table_row = array();
-
- // check connection
- module_load_include('inc', 'islandora', 'includes/utilities');
- $url = variable_get('islandora_base_url', 'http://localhost:8080/fedora');
- $info = islandora_describe_repository($url);
- if (!$info) {
- $object_status = 'could_not_connect';
- }
- else {
+function islandora_check_object_status(NewFedoraObject $object_definition) {
+ $existing_object = islandora_object_load($object_definition->id);
+ if (!$existing_object) {
+ return array('status' => 'missing', 'status_friendly' => t('Missing'));
+ }
- // load object
- $object = islandora_object_load($pid);
- // check if object exists
- if (!$object) {
- $object_status = 'missing';
- }
- else {
- // object defined with single datastream file
- // @TODO: should dsversion be mandatory for the check to valid?
- if (isset($object_model['dsid']) && isset($object_model['datastream_file']) && isset($object_model['dsversion'])) {
- $datastreams = array(
- array(
- 'dsid' => $object_model['dsid'],
- 'datastream_file' => $object_model['datastream_file'],
- 'dsversion' => $object_model['dsversion'],
- ),
- );
- }
- // object defined with multiple datastreams (using an array)
- elseif (!empty($object_model['datastreams'])) {
- $datastreams = $object_model['datastreams'];
- }
- if (!empty($datastreams) && is_array($datastreams)) {
- // loop over defined datastreams
- foreach ($datastreams as $ds) {
- $ds_id = $ds['dsid'];
- // check if defined datastream exists in the object
- if (!$object[$ds_id]) {
- $object_status = 'missing_datastream';
- break;
- }
- elseif (isset($ds['dsversion'])) {
- // Check if the datastream is versioned and needs updating.
- $installed_version = islandora_get_islandora_datastream_version($object, $ds['dsid']);
- $available_version = islandora_get_islandora_datastream_version(NULL, NULL, $ds['datastream_file']);
+ $existing_datastreams = array_keys(iterator_to_array($existing_object));
+ $expected_datastreams = array_keys(iterator_to_array($object_definition));
+ $datastream_diff = array_diff($expected_datastreams, $existing_datastreams);
+ if (!empty($datastream_diff)) {
+ $status_friendly = format_plural(count($datastream_diff), 'Missing Datastream: %dsids.', 'Missing Datastreams: %dsids.', array('%dsids' => implode(', ', $datastream_diff)));
+ return array('status' => 'missing_datastream', 'status_friendly' => $status_friendly, 'data' => $datastream_diff);
+ }
- if ($available_version > $installed_version) {
- $object_status = 'out_of_date';
- break;
- }
- }
- }
- }
- }
+ $is_xml_datastream = function($ds) { return $ds->mimetype == 'text/xml'; };
+ $xml_datastreams = array_filter(iterator_to_array($object_definition), $is_xml_datastream);
+ $out_of_date_datastreams = array();
+ foreach ($xml_datastreams as $ds) {
+ $installed_version = islandora_get_islandora_datastream_version($existing_object, $ds->id);
+ $available_version = islandora_get_islandora_datastream_version($object_definition, $ds->id);
+ if ($available_version > $installed_version) {
+ $out_of_date_datastreams[] = $ds->id;
}
- return $object_status;
}
- else {
- return FALSE;
+ if(count($out_of_date_datastreams)) {
+ $status_friendly = format_plural(count($out_of_date_datastreams), 'Datastream out of date: %dsids.', 'Datastreams out of date: %dsids.', array('%dsids' => implode(', ', $out_of_date_datastreams)));
+ return array('status' => 'out_of_date', 'status_friendly' => $status_friendly, 'data' => $out_of_date_datastreams);
}
-}
-
-/**
- * Converts the given definition into an object and add's it to the repository.
- *
- * @param array $object_definition
- * An associative array containing the necessary parameters to create the
- * desired object:
- * - pid: The PID with which the object will be created.
- * - label: An optional label to apply to the object.
- * - datastreams: Same as the "datastreams" array accepted by
- * islandora_prepare_new_object().
- * - cmodel: Either an array of content models as accepted by
- * islandora_preprare_new_object(), or a single content model PID to add
- * to the object.
- * - parent: Either an array of parents, or a single parent PID to which to
- * relate to; uses isMemberOfCollection by default.
- * - relationships: An array of relationships as accepted by
- * islandora_prepare_new_object().
- *
- * @return FedoraObject
- * The newly created object.
- */
-function islandora_solution_pack_add_object(array $object_definition) {
- $object = islandora_solution_pack_prepare_new_object($object_definition);
- return islandora_add_object($object);
-}
-/**
- * Prepares a new object based on the solution pack style of declaring them as arrays.
- *
- * @param array $object_definition
- * An associative array containing the necessary parameters to create the
- * desired object:
- * - pid: The PID with which the object will be created.
- * - label: An optional label to apply to the object.
- * - datastreams: Same as the "datastreams" array accepted by
- * islandora_prepare_new_object().
- * - cmodel: Either an array of content models as accepted by
- * islandora_prepare_new_object(), or a single content model PID to add
- * to the object.
- * - parent: Either an array of parents, or a single parent PID to which to
- * relate to; uses isMemberOfCollection by default.
- * - relationships: An array of relationships as accepted by
- * islandora_prepare_new_object().
- *
- * @return NewFedoraObject
- * An NewFedoraObject which has been initalized with the given properties.
- */
-function islandora_solution_pack_prepare_new_object(array $object_definition) {
- module_load_include('inc', 'islandora', 'includes/utilities');
- $namespace = $object_definition['pid'];
- $label = !empty($object_definition['label']) ? $object_definition['label'] : NULL;
- $datastreams = array();
- if (!empty($object_definition['datastreams']) AND is_array($object_definition['datastreams'])) {
- $datastreams = $object_definition['datastreams'];
- }
- $content_models = array();
- if (!empty($object_definition['cmodel'])) {
- if (is_array($object_definition['cmodel'])) {
- $content_models = $object_definition['cmodel'];
+ // This is a pretty heavy function, but I'm not sure a better way. If we have
+ // performance trouble, we should maybe remove this.
+ $modified_datastreams = array();
+ foreach ($object_definition as $ds) {
+ if($ds->mimetype == 'text/xml' || $ds->mimetype == 'application/rdf+xml') {
+ // If the datastream is XML we use the domdocument C14N cannonicalization
+ // function to test if they are equal, because the strings likely won't
+ // be equal as Fedora does some XML mangling. In order for C14N to work
+ // we need to replace the info:fedora namespace, as C14N hates it.
+ $object_definition_dom = new DOMDocument();
+ $object_definition_dom->loadXML(str_replace('info:', 'http://', $ds->content));
+ $object_actual_dom = new DOMDocument();
+ $object_actual_dom->loadXML(str_replace('info:', 'http://', $existing_object[$ds->id]->content));
+
+ // We have to use the shutup function here. C14N throws warnings about the
+ // info:fedora namespace, but they are mostly useless.
+ if($object_actual_dom->C14N() != $object_definition_dom->C14N()) {
+ $modified_datastreams[] = $ds->id;
+ }
}
else {
- $content_models[] = $object_definition['cmodel'];
- }
- }
- $relationships = array();
- if (!empty($object_definition['parent']) AND !is_array($object_definition['parent'])) {
- $relationships[] = array('relationship' => 'isMemberOfCollection', 'pid' => $object_definition['parent']);
- }
- if (!empty($object_definition['parents']) AND is_array($object_definition['parents'])) {
- foreach ($object_definition['parents'] as $parent) {
- $relationships[] = array('relationship' => 'isMemberOfCollection', 'pid' => $parent);
+ $object_definition_hash = md5($ds->content);
+ $object_actual_hash = md5($existing_object[$ds->id]->content);
+ if($object_definition_hash != $object_actual_hash) {
+ $modified_datastreams[] = $ds->id;;
+ }
}
}
- if (!empty($object_definition['relationships']) AND is_array($object_definition['relationships'])) {
- foreach ($object_definition['relationships'] as $relationship) {
- $relationships[] = array('relationship' => $relationship['relationship'], 'pid' => $relationship['pid']);
- }
+ if(count($modified_datastreams)) {
+ $status_friendly = format_plural(count($modified_datastreams), 'Modified Datastream: %dsids.', 'Modified Datastreams: %dsids.', array('%dsids' => implode(', ', $modified_datastreams)));
+ return array('status' => 'modified_datastream', 'data' => $modified_datastreams, 'status_friendly' => $status_friendly);
}
- return islandora_prepare_new_object($namespace, $label, $datastreams, $content_models, $relationships);
-}
+ // If not anything else we can assume its up to date.
+ return array('status' => 'up_to_date', 'status_friendly' => t('Up-to-date'));
+}
+
/**
* @defgroup viewer-functions
* @{
diff --git a/includes/utilities.inc b/includes/utilities.inc
index 537c5dd8..55ef7562 100644
--- a/includes/utilities.inc
+++ b/includes/utilities.inc
@@ -413,3 +413,17 @@ function islandora_prepare_new_object($namespace = NULL, $label = NULL, $datastr
}
return $object;
}
+
+/**
+ * Displays the repository is inaccessible message
+ *
+ * Use anywhere we want to ensure a consitent error message when the repository
+ * is not accessible.
+ */
+function islandora_display_repository_inaccessible_message() {
+ $text = t('Islandora configuration');
+ $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.',
+ array('!link' => $link));
+ drupal_set_message($message, 'error', FALSE);
+}
diff --git a/islandora.module b/islandora.module
index 19b933da..5e6fd7cf 100644
--- a/islandora.module
+++ b/islandora.module
@@ -313,6 +313,12 @@ function islandora_forms($form_id) {
*/
function islandora_object_access_callback($perm, $object = NULL) {
module_load_include('inc', 'islandora', 'includes/utilities');
+
+ if (!$object && !islandora_describe_repository()) {
+ islandora_display_repository_inaccessible_message();
+ return FALSE;
+ }
+
return user_access($perm) && is_object($object) && islandora_namespace_accessible($object->id);
}
@@ -629,35 +635,32 @@ function islandora_get_islandora_datastream_version($item = NULL, $dsid = NULL,
/**
* Implements hook_islandora_required_objects().
*/
-function islandora_islandora_required_objects() {
+function islandora_islandora_required_objects(IslandoraTuque $connection) {
$module_path = drupal_get_path('module', 'islandora');
+ // Root Collection
+ $root_collection = $connection->repository->constructObject('islandora:root');
+ $root_collection->owner = 'fedoraAdmin';
+ $root_collection->label = 'Top-level Collection';
+ $root_collection->models = 'islandora:collectionCModel';
+ // Collection Policy Datastream
+ $datastream = $root_collection->constructDatastream('COLLECTION_POLICY', 'X');
+ $datastream->label = 'Collection policy';
+ $datastream->mimetype = 'text/xml';
+ $datastream->setContentFromFile("$module_path/xml/islandora_collection_policy.xml", FALSE);
+ $root_collection->ingestDatastream($datastream);
+ // TN Datastream
+ $datastream = $root_collection->constructDatastream('TN', 'M');
+ $datastream->label = 'Thumbnail';
+ $datastream->mimetype = 'image/png';
+ $datastream->setContentFromFile("$module_path/images/folder.png", FALSE);
+ $root_collection->ingestDatastream($datastream);
return array(
'islandora' => array(
'title' => 'Islandora',
'objects' => array(
- array(
- 'pid' => 'islandora:root',
- 'label' => 'Top-level collection',
- 'cmodel' => 'islandora:collectionCModel',
- 'datastreams' => array(
- array(
- 'dsid' => 'COLLECTION_POLICY',
- 'label' => 'Collection policy',
- 'mimetype' => 'text/xml',
- 'control_group' => 'X',
- 'datastream_file' => "$module_path/xml/islandora_collection_policy.xml",
- ),
- array(
- 'dsid' => 'TN',
- 'label' => 'Thumbnail',
- 'mimetype' => 'image/png',
- 'control_group' => 'M',
- 'datastream_file' => "$module_path/images/folder.png",
- ),
- ),
- ),
- ),
- ),
+ $root_collection
+ )
+ )
);
}