Browse Source

Modified solution_packs.inc to return datastreams

The table printed by solution_packs.inc used to not mention
which datastreams were modified. We do that now.

We also test the MD5 of the datastream to make sure that it is
actually the same.
pull/221/head
jonathangreen 12 years ago
parent
commit
d0de6d6b90
  1. 85
      includes/solution_packs.inc
  2. 6
      includes/utilities.inc
  3. 6
      islandora.module

85
includes/solution_packs.inc

@ -15,10 +15,12 @@
*/ */
function islandora_solution_packs_admin() { function islandora_solution_packs_admin() {
module_load_include('inc', 'islandora', 'includes/utilities'); module_load_include('inc', 'islandora', 'includes/utilities');
if (($connection = islandora_get_tuque_connection()) === NULL) { if (!islandora_describe_repository()) {
islandora_display_repository_inaccessible_message(); islandora_display_repository_inaccessible_message();
return; return '';
} }
$connection = islandora_get_tuque_connection();
drupal_add_css(drupal_get_path('module', 'islandora') . '/css/islandora.admin.css'); drupal_add_css(drupal_get_path('module', 'islandora') . '/css/islandora.admin.css');
$output = ''; $output = '';
$enabled_solution_packs = module_invoke_all('islandora_required_objects', $connection); $enabled_solution_packs = module_invoke_all('islandora_required_objects', $connection);
@ -60,25 +62,26 @@ function islandora_solution_pack_form(array $form, array &$form_state, $solutio
$warning_image = theme_image(array('path' => 'misc/watchdog-warning.png', 'attributes' => array())); $warning_image = theme_image(array('path' => 'misc/watchdog-warning.png', 'attributes' => array()));
$status_info = array( $status_info = array(
'up_to_date' => array( 'up_to_date' => array(
'object' => t('Up-to-date'),
'solution_pack' => t('All required objects are installed and up-to-date.'), 'solution_pack' => t('All required objects are installed and up-to-date.'),
'image' => $ok_image, 'image' => $ok_image,
'button' => t("Force reinstall objects"), '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( 'out_of_date' => array(
'object' => t('Out-of-date'),
'solution_pack' => t('Some objects must be reinstalled. See objects list for details.'), 'solution_pack' => t('Some objects must be reinstalled. See objects list for details.'),
'image' => $warning_image, 'image' => $warning_image,
'button' => t("Reinstall objects") 'button' => t("Reinstall objects")
), ),
'missing_datastream' => array( 'missing_datastream' => array(
'object' => t('Missing Datastream'),
'solution_pack' => t('Some objects must be reinstalled. See objects list for details.'), 'solution_pack' => t('Some objects must be reinstalled. See objects list for details.'),
'image' => $warning_image, 'image' => $warning_image,
'button' => t("Reinstall objects") 'button' => t("Reinstall objects")
), ),
'missing' => array( 'missing' => array(
'object' => t('Missing'),
'solution_pack' => t( 'Some objects are missing and must be installed. See objects list for details.'), 'solution_pack' => t( 'Some objects are missing and must be installed. See objects list for details.'),
'image' => $warning_image, 'image' => $warning_image,
'button' => t("Install objects") 'button' => t("Install objects")
@ -89,13 +92,13 @@ function islandora_solution_pack_form(array $form, array &$form_state, $solutio
$table_rows = array(); $table_rows = array();
foreach ($objects as $object) { foreach ($objects as $object) {
$object_status = islandora_check_object_status($object); $object_status = islandora_check_object_status($object);
$object_status_info = $status_info[$object_status]; $object_status_info = $status_info[$object_status['status']];
$object_status_severity = array_search($object_status, $status_severities); $object_status_severity = array_search($object_status['status'], $status_severities);
// The solution pack status severity will be the highest severity of the objects. // 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); $solution_pack_status_severity = max($solution_pack_status_severity, $object_status_severity);
$exists = $object_status != 'missing'; $exists = $object_status['status'] != 'missing';
$label = $exists ? l($object->label, "islandora/object/{$object->id}") : $object->label; $label = $exists ? l($object->label, "islandora/object/{$object->id}") : $object->label;
$status_msg = "{$object_status_info['image']}&nbsp{$object_status_info['object']}"; $status_msg = "{$object_status_info['image']}&nbsp{$object_status['status_friendly']}";
$table_rows[] = array($label, $object->id, $status_msg); $table_rows[] = array($label, $object->id, $status_msg);
} }
$solution_pack_status = $status_severities[$solution_pack_status_severity]; $solution_pack_status = $status_severities[$solution_pack_status_severity];
@ -155,7 +158,6 @@ function islandora_solution_pack_form(array $form, array &$form_state, $solutio
*/ */
function islandora_solution_pack_form_submit(array $form, array &$form_state) { function islandora_solution_pack_form_submit(array $form, array &$form_state) {
$solution_pack_module = $form_state['values']['solution_pack_module']; $solution_pack_module = $form_state['values']['solution_pack_module'];
$solution_pack_name = $form_state['values']['solution_pack_name'];
$objects = $form_state['values']['objects']; $objects = $form_state['values']['objects'];
$batch = array( $batch = array(
'title' => t('Installing / Updating solution pack objects'), 'title' => t('Installing / Updating solution pack objects'),
@ -186,7 +188,7 @@ function islandora_solution_pack_batch_operation_reingest_object(NewFedoraObject
$existing_object = islandora_object_load($object->id); $existing_object = islandora_object_load($object->id);
if ($existing_object) { if ($existing_object) {
$deleted = islandora_delete_object($existing_object); $deleted = islandora_delete_object($existing_object);
$purged = $deleted && $exsiting_object == NULL; $purged = $deleted && $existing_object == NULL;
if (!$purged) { if (!$purged) {
$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(t('Failed to purge existing object !object_link.', array(
@ -257,7 +259,8 @@ function islandora_install_solution_pack($module, $op = 'install') {
$status_messages = array( $status_messages = array(
'up_to_date' => 'The object already exists and is up-to-date', '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', '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' '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) { foreach ($objects as $object) {
$query = $connection->api->a->findObjects('query', 'pid=' . $object->id); $query = $connection->api->a->findObjects('query', 'pid=' . $object->id);
@ -266,7 +269,7 @@ 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_msg = $status_messages[$object_status['status']];
drupal_set_message(st("@module: Did not install !object_link. $status_msg.", array( drupal_set_message(st("@module: Did not install !object_link. $status_msg.", array(
'@module' => $module_name, '@module' => $module_name,
'!object_link' => $object_link, '!object_link' => $object_link,
@ -304,7 +307,6 @@ function islandora_uninstall_solution_pack($module) {
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);
$admin_link = l(t('Solution Pack admin'), 'admin/islandora/solution_packs');
$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);
@ -352,31 +354,72 @@ function islandora_uninstall_solution_pack($module) {
* *
* @see islandora_solution_pack_form() * @see islandora_solution_pack_form()
* @see islandora_install_solution_pack() * @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(NewFedoraObject $object_definition) { function islandora_check_object_status(NewFedoraObject $object_definition) {
$existing_object = islandora_object_load($object_definition->id); $existing_object = islandora_object_load($object_definition->id);
if (!$existing_object) { if (!$existing_object) {
return 'missing'; return array('status' => 'missing', 'status_friendly' => t('Missing'));
} }
$existing_datastreams = array_keys(iterator_to_array($existing_object)); $existing_datastreams = array_keys(iterator_to_array($existing_object));
$expected_datastreams = array_keys(iterator_to_array($object_definition)); $expected_datastreams = array_keys(iterator_to_array($object_definition));
$datastream_diff = array_diff($expected_datastreams, $existing_datastreams); $datastream_diff = array_diff($expected_datastreams, $existing_datastreams);
if (!empty($datastream_diff)) { if (!empty($datastream_diff)) {
return 'missing_datastream'; $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);
} }
$is_xml_datastream = function($ds) { return $ds->mimetype == 'text/xml'; }; $is_xml_datastream = function($ds) { return $ds->mimetype == 'text/xml'; };
$xml_datastreams = array_filter(iterator_to_array($object_definition), $is_xml_datastream); $xml_datastreams = array_filter(iterator_to_array($object_definition), $is_xml_datastream);
$out_of_date_datastreams = array();
foreach ($xml_datastreams as $ds) { foreach ($xml_datastreams as $ds) {
$installed_version = islandora_get_islandora_datastream_version($existing_object, $ds->id); $installed_version = islandora_get_islandora_datastream_version($existing_object, $ds->id);
$available_version = islandora_get_islandora_datastream_version($object_definition, $ds->id); $available_version = islandora_get_islandora_datastream_version($object_definition, $ds->id);
if ($available_version > $installed_version) { if ($available_version > $installed_version) {
return 'out_of_date'; $out_of_date_datastreams[] = $ds->id;
} }
} }
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);
}
// 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 {
$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(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);
}
// If not anything else we can assume its up to date. // If not anything else we can assume its up to date.
return 'up_to_date'; return array('status' => 'up_to_date', 'status_friendly' => t('Up-to-date'));
} }
/** /**

6
includes/utilities.inc

@ -423,7 +423,7 @@ function islandora_prepare_new_object($namespace = NULL, $label = NULL, $datastr
function islandora_display_repository_inaccessible_message() { 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'); drupal_set_message($message, 'error', FALSE);
} }

6
islandora.module

@ -314,6 +314,12 @@ function islandora_forms($form_id) {
*/ */
function islandora_object_access_callback($perm, $object = NULL) { function islandora_object_access_callback($perm, $object = NULL) {
module_load_include('inc', 'islandora', 'includes/utilities'); 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); return user_access($perm) && is_object($object) && islandora_namespace_accessible($object->id);
} }

Loading…
Cancel
Save