Browse Source

Merge pull request #386 from ajstanley/7.x

7.x
pull/400/merge
Morgan Dawe 11 years ago
parent
commit
680d643063
  1. 14
      css/islandora.theme.css
  2. 340
      includes/manage_deleted_objects.inc
  3. 79
      includes/object_properties.form.inc
  4. 8
      includes/utilities.inc
  5. 15
      islandora.api.php
  6. 67
      islandora.module

14
css/islandora.theme.css

@ -11,16 +11,16 @@
dl.islandora-object-tn {
float: left;
width: 20.8333%;
padding: 0 10px 0 0;
margin: 1.5em 0;
padding: 0 10px 0 0;
width: 20.8333%;
}
dl.islandora-object-fields {
border-top: 0px solid #ddd;
float: right;
width:79.1666%;
border-top:0px solid #ddd;
margin: 1.5em 0;
width: 79.1666%;
}
.islandora-object-fields dt {
@ -28,13 +28,13 @@ dl.islandora-object-fields {
}
.islandora-object-fields dt.first {
border-top:0;
border-top: 0;
}
.islandora-object-fields dt,
.islandora-object-fields dd {
padding:6px 2% 4px;
border-top:1px solid #ddd;
border-top: 1px solid #ddd;
padding: 6px 2% 4px;
}
.islandora-object-fields dt.first,

340
includes/manage_deleted_objects.inc

@ -0,0 +1,340 @@
<?php
/**
* @file
* Handles the management of deleted objects.
*/
/**
* The deletion management prep form.
*
* @param array $form
* The Drupal form definition.
* @param array $form_state
* The Drupal form state.
*
* @return array
* The Drupal form definition.
*/
function islandora_deleted_objects_prep_form($form, $form_state, $serialized_chosen = NULL) {
module_load_include('inc', 'islandora', 'includes/utilities');
$chosen_contentmodels = array();
if ($serialized_chosen) {
$chosen_contentmodels = unserialize($serialized_chosen);
}
$contentmodels_with_deleted_members = islandora_get_contentmodels_with_deleted_members();
$elegible_contentmodels = array_keys($contentmodels_with_deleted_members);
if (empty($contentmodels_with_deleted_members)) {
$form['message'] = array(
'#type' => 'markup',
'#markup' => t("There are no deleted objects in this repository."),
);
return $form;
}
$form['message'] = array(
'#type' => 'markup',
'#markup' => t("Select content models of deleted objects."),
);
$form['mapped_contentmodels'] = array(
'#type' => 'hidden',
'#value' => $contentmodels_with_deleted_members,
);
$table_element = islandora_content_model_select_table_form_element(NULL);
foreach ($table_element['#options'] as $option) {
if (!in_array($option['pid'], $elegible_contentmodels)) {
unset($table_element['#options'][$option['pid']]);
}
if (array_key_exists($option['pid'], $chosen_contentmodels)) {
$table_element['#default_value'][$option['pid']] = TRUE;
}
}
$form['contentmodels'] = $table_element;
$form['next'] = array(
'#type' => 'submit',
'#value' => t('Next'),
);
return $form;
}
/**
* Submit handler for deletion management prep form.
*
* @param array $form
* The form.
* @param array $form_state
* The form state.
*/
function islandora_deleted_objects_prep_form_submit($form, $form_state) {
$content_models = $form_state['values']['contentmodels'];
$chosen = function($element) {
return $element;
};
$serialized_contentmodels = serialize(array_filter($content_models, $chosen));
drupal_goto("admin/islandora/restore/manage/$serialized_contentmodels");
}
/**
* The deletion management prep form.
*
* @param array $form
* The Drupal form definition.
* @param array $form_state
* The Drupal form state.
*
* @return array
* The Drupal form definition.
*/
function islandora_deleted_objects_manage_form($form, $form_state, $serialized_chosen = NULL) {
$form['previous'] = array(
'#type' => 'submit',
'#value' => t('Previous'),
'#attributes' => array('source' => 'previous'),
);
$chosen_contentmodels = unserialize($serialized_chosen);
$content_models_with_deleted = islandora_get_contentmodels_with_deleted_members();
foreach ($chosen_contentmodels as $contentmodel) {
if (!array_key_exists($contentmodel, $content_models_with_deleted)) {
unset($chosen_contentmodels[$contentmodel]);
}
}
if (empty($chosen_contentmodels)) {
$form['message'] = array(
'#type' => 'markup',
'#markup' => t("There are no deleted objects with the selected content models in this repository."),
);
return $form;
}
if (is_array($chosen_contentmodels)) {
foreach ($chosen_contentmodels as $key => $value) {
if (in_array($key, $content_models_with_deleted)) {
$chosen_contentmodels[$key] = $content_models_with_deleted[$key];
}
}
}
$tuque = islandora_get_tuque_connection();
$repository = $tuque->repository;
// Query brings back fedora-system:FedoraObject-3.0, doubling the results.
$total = $repository->ri->countQuery(islandora_get_deleted_query($chosen_contentmodels), 'sparql') / 2;
$limit = 25;
if ($total < 28) {
$limit = $total;
}
$current_page = pager_default_initialize($total, $limit);
$query_limit = $limit * 2;
$offset = $current_page * $query_limit;
$options = islandora_get_deleted_objects($chosen_contentmodels, $query_limit, $offset);
foreach ($options as &$option) {
$option['content_model'] = $content_models_with_deleted[$option['content_model']];
}
$form['serialized_chosen'] = array(
'#type' => 'hidden',
'#value' => $serialized_chosen,
);
$form['pager'] = array(
'#type' => 'markup',
'#markup' => theme('pager', array('quantity', count($options))),
);
$form['propogate'] = array(
'#title' => t('Apply changes to related objects?'),
'#default_value' => TRUE,
'#description' => t("Objects associated with selected objects will also be purged/restored. ie page objects associated with a book object."),
'#type' => 'checkbox',
);
$form['chosen'] = array(
'#type' => 'hidden',
'#value' => $chosen_contentmodels,
);
$form['objects_to_process'] = array(
'#type' => 'tableselect',
'#header' => array(
'title' => t('Name'),
'pid' => t('PID'),
'content_model' => t('Content Model'),
),
'#multiple' => TRUE,
'#options' => $options,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Restore selected objects'),
'#attributes' => array('source' => 'restore'),
);
if (user_access(ISLANDORA_PURGE)) {
$form['purge'] = array(
'#type' => 'submit',
'#value' => t('Irrevocably purge selected objects'),
'#attributes' => array('source' => 'purge'),
);
}
return $form;
}
/**
* Submit handler for deletion management form.
*
* @param array $form
* The form.
* @param array $form_state
* The form state.
*/
function islandora_deleted_objects_manage_form_submit($form, $form_state) {
module_load_include('inc', 'islandora', 'includes/utilities');
$serialized_chosen = isset($form_state['values']['serialized_chosen']) ? $form_state['values']['serialized_chosen'] : NULL;
if (isset($form_state['clicked_button']['#attributes']['source']) && $form_state['clicked_button']['#attributes']['source'] == 'previous') {
drupal_goto("admin/islandora/restore/prep/$serialized_chosen");
}
if ($form_state['clicked_button']['#attributes']['source'] == 'restore') {
$descriptor = "Restoring";
$action = 'islandora_restore_object_by_pid';
}
if ($form_state['clicked_button']['#attributes']['source'] == 'purge') {
$descriptor = "Purging";
$action = 'islandora_purge_object_by_pid';
}
$objects_to_process = array_filter($form_state['values']['objects_to_process']);
$pids_to_restore = $objects_to_process;
if ($form_state['values']['propogate']) {
foreach ($objects_to_process as $pid) {
$fedora_object = islandora_object_load($pid);
$temp = islandora_invoke_hook_list(ISLANDORA_UPDATE_RELATED_OBJECTS_PROPERTIES_HOOK, $fedora_object->models, array($fedora_object));
if (!empty($temp)) {
$pids_to_restore = array_merge_recursive($pids_to_restore, $temp);
}
}
}
$batch = array(
'title' => t('@descriptor selected objects', array('@descriptor' => $descriptor)),
'file' => drupal_get_path('module', 'islandora') . '/includes/manage_deleted_objects.inc',
'operations' => array(),
);
foreach ($pids_to_restore as $pid) {
$batch['operations'][] = array(
$action,
array($pid),
);
}
batch_set($batch);
batch_process("admin/islandora/restore/manage/$serialized_chosen");
}
/**
* Gets PIDS of all deleted objects.
*
* @return array
* PIDS of deleted objects
*/
function islandora_get_deleted_objects($content_models, $limit, $offset) {
$tuque = islandora_get_tuque_connection();
$repository = $tuque->repository;
$query = islandora_get_deleted_query($content_models, $offset);
$objects = $repository->ri->sparqlQuery($query, $limit);
$deleted_objects = array();
foreach ($objects as $object) {
if ($object['object']['value'] != "fedora-system:FedoraObject-3.0") {
$pid = $object['subject']['value'];
$cm_pid = $object['object']['value'];
$title = $object['label']['value'];
$deleted_objects[$pid] = array(
'title' => $title, 'pid' => $pid,
'content_model' => $content_models[$cm_pid],
);
}
}
return $deleted_objects;
}
/**
* Gets PIDS of all content models associated with deleted objects.
*
* @return array
* array of content model pids
*/
function islandora_get_contentmodels_with_deleted_members() {
$tuque = new IslandoraTuque();
$repository = $tuque->repository;
$query = "PREFIX fm: <info:fedora/fedora-system:def/model#>
SELECT DISTINCT ?object ?label FROM <#ri>
WHERE {
{?subject fm:state fm:Deleted;
fm:hasModel ?object;
}
OPTIONAL{
?object fm:label ?label
}
}";
$objects = $repository->ri->sparqlQuery($query, -1);
$content_models = array();
foreach ($objects as $object) {
if ($object['object']['value'] != "fedora-system:FedoraObject-3.0") {
$content_models[$object['object']['value']] = $object['label']['value'];
}
}
return $content_models;
}
/**
* Restores deleted object.
*
* @param String $pid
* PID of object to be restored
*/
function islandora_restore_object_by_pid($pid) {
$fedora_object = islandora_object_load($pid);
$fedora_object->state = 'A';
}
/**
* Purges deleted object.
*
* @param String $pid
* PID of object to be restored
*/
function islandora_purge_object_by_pid($pid) {
$fedora_object = islandora_object_load($pid);
$fedora_object->repository->purgeObject($pid);
}
/**
* Get query to find all deleted objects by content type.
*
* @param array $content_models
* Content models to restrict search
* @param int $offset
* offset to be added to search
*
* @return String
* Sparql query
*/
function islandora_get_deleted_query($content_models, $offset = 0) {
$candidates = array_keys($content_models);
$first_contentmodel = array_shift($candidates);
$prefix = "PREFIX fm: <" . FEDORA_MODEL_URI . "> ";
$select = "SELECT DISTINCT ?subject ?label ?object FROM <#ri> WHERE { ";
$where_clause = "{?subject fm:hasModel <info:fedora/$first_contentmodel>;
fm:state fm:Deleted;
fm:hasModel ?object;
}";
$suffix = "} ORDER BY ?subject OFFSET $offset";
$unions = '';
foreach ($candidates as $contentmodel) {
$unions .= "UNION {?subject fm:hasModel <info:fedora/$contentmodel>;
fm:state fm:Deleted;
fm:hasModel ?object;
}
";
}
$optional = "OPTIONAL{?subject fm:label ?label}";
return "$prefix $select $where_clause $unions $optional $suffix";
}

79
includes/object_properties.form.inc

@ -21,6 +21,11 @@
function islandora_object_properties_form(array $form, array &$form_state, AbstractObject $object) {
drupal_set_title($object->label);
$form_state['object'] = $object;
$temp = islandora_invoke_hook_list(ISLANDORA_UPDATE_RELATED_OBJECTS_PROPERTIES_HOOK, $object->models, array($object));
$related_objects_pids = array();
if (!empty($temp)) {
$related_objects_pids = array_merge_recursive($related_objects_pids, $temp);
}
return array(
'pid' => array(
'#type' => 'hidden',
@ -54,6 +59,18 @@ function islandora_object_properties_form(array $form, array &$form_state, Abstr
'#type' => 'select',
'#options' => array('A' => 'Active', 'I' => 'Inactive', 'D' => 'Deleted'),
),
'propogate' => array(
'#title' => t('Apply changes to related objects?'),
'#default_value' => TRUE,
'#description' => t("Changes to owner and state will applied to associated objects. ie page objects associated with a book object."),
'#type' => 'checkbox',
'#access' => count($related_objects_pids),
),
'related_pids' => array(
'#value' => $related_objects_pids,
'#type' => 'hidden',
'#access' => count($related_objects_pids),
),
'submit' => array(
'#type' => 'submit',
'#value' => 'Update Properties',
@ -81,32 +98,54 @@ function islandora_object_properties_form_submit(array $form, array &$form_state
$owner = $form_state['values']['object_owner'];
$state = $form_state['values']['object_state'];
$label = $form_state['values']['object_label'];
$propogate = $form_state['values']['propogate'];
$update_owners = FALSE;
$update_states = FALSE;
if (isset($owner) && $owner != $object->owner) {
try {
$object->owner = $owner;
$update_owners = TRUE;
drupal_set_message(t('Successfully updated owner %s', array('%s' => $owner)));
}
catch (Exception $e) {
form_set_error('object_owner', t('Error updating owner %s', array('%s' => $e->getMessage())));
}
}
if (isset($label) && $label != $object->label) {
try {
$object->label = $label;
drupal_set_message(t('Successfully updated label %s', array('%s' => check_plain($label))));
}
catch (Exception $e) {
form_set_error(t('Error updating label %s', array('%s' => $e->getMessage())));
}
}
if (isset($state) && $state != $object->state) {
try {
$object->state = $state;
$update_states = TRUE;
drupal_set_message(t('Successfully updated state %s', array('%s' => $state)));
}
catch (Exception $e) {
form_set_error('object_state', t('Error updating state %s', array('%s' => $e->getMessage())));
}
}
if (isset($label) && $label != $object->label) {
try {
$object->label = $label;
drupal_set_message(t('Successfully updated label %s', array('%s' => check_plain($label))));
}
catch (Exception $e) {
form_set_error(t('Error updating label %s', array('%s' => $e->getMessage())));
if ($propogate && ($update_states || $update_owners)) {
$related_objects_pids = $form_state['values']['related_pids'];
$batch = array(
'title' => t('Updating related objects'),
'file' => drupal_get_path('module', 'islandora') . '/includes/object_properties.form.inc',
'operations' => array(),
);
foreach ($related_objects_pids as $pid) {
$batch['operations'][] = array(
'islandora_update_object_properties',
array($pid, $update_states, $state, $update_owners, $owner),
);
}
batch_set($batch);
}
}
@ -121,3 +160,29 @@ function islandora_object_properties_form_submit(array $form, array &$form_state
function islandora_object_properties_form_delete(array $form, array &$form_state) {
drupal_goto("islandora/object/{$form_state['values']['pid']}/delete");
}
/**
* Updates object state.
*
* @param String $pid
* PID of object to be updated
* @param Boolean $update_states
* If TRUE, update object state
* @param String $state
* Desired object state
* @param Boolean $update_owners
* If TRUE, update Owner
* @param String $owner
* New Owner
*/
function islandora_update_object_properties($pid, $update_states, $state, $update_owners, $owner) {
$fedora_object = islandora_object_load($pid);
if ($fedora_object) {
if ($update_states) {
$fedora_object->state = $state;
}
if ($update_owners) {
$fedora_object->owner = $owner;
}
}
}

8
includes/utilities.inc

@ -889,9 +889,7 @@ function islandora_as_renderable_array(&$markup_array) {
if (!is_array($value)) {
// Not a renderable array, just a string. Let's convert it to a
// renderable '#markup' element.
$value = array(
'#markup' => $value,
);
$value = array('#markup' => $value);
}
elseif (!isset($value['#type']) && !isset($value['#markup'])) {
// A simple array--possibly the result of a recursive merge? Let's
@ -902,9 +900,7 @@ function islandora_as_renderable_array(&$markup_array) {
// If it is an array at this level, we can assume that it is a
// renderable array. If it is not an array, convert to a renderable
// '#markup' element.
$inner = array(
'#markup' => $inner,
);
$inner = array('#markup' => $inner);
}
}
unset($inner);

15
islandora.api.php

@ -649,6 +649,21 @@ function hook_CMODEL_PID_islandora_derivative() {
}
/**
* Retrieves PIDS of related objects for property updating.
*
* @param AbstractObject $object
* AbstractObject representing deleted object
*/
function hook_islandora_update_related_objects_properties(AbstractObject $object) {
$related_objects = get_all_children_siblings_and_friends($object);
$pids_to_return = array();
foreach($related_objects as $related_object) {
$pids_to_return[] = $related_object->id;
}
return $pids_to_return;
}
/**
* Alters breadcrumbs used on Solr search results and within Islandora views.
*

67
islandora.module

@ -34,8 +34,10 @@ define('ISLANDORA_INGEST', 'ingest fedora objects');
define('ISLANDORA_PURGE', 'delete fedora objects and datastreams');
define('ISLANDORA_MANAGE_PROPERTIES', 'manage object properties');
define('ISLANDORA_VIEW_DATASTREAM_HISTORY', 'view old datastream versions');
define('ISLANDORA_MANAGE_DELETED_OBJECTS', 'manage deleted objects');
define('ISLANDORA_REVERT_DATASTREAM', 'revert to old datastream');
// Hooks.
define('ISLANDORA_VIEW_HOOK', 'islandora_view_object');
define('ISLANDORA_PRINT_HOOK', 'islandora_view_print_object');
@ -45,6 +47,7 @@ define('ISLANDORA_PRE_INGEST_HOOK', 'islandora_ingest_pre_ingest');
define('ISLANDORA_POST_INGEST_HOOK', 'islandora_ingest_post_ingest');
define('ISLANDORA_PRE_PURGE_OBJECT_HOOK', 'islandora_pre_purge_object');
define('ISLANDORA_POST_PURGE_OBJECT_HOOK', 'islandora_post_purge_object');
define('ISLANDORA_UPDATE_RELATED_OBJECTS_PROPERTIES_HOOK', 'islandora_update_related_objects_properties');
// @todo Add Documentation.
define('ISLANDORA_OBJECT_INGESTED_HOOK', 'islandora_object_ingested');
@ -320,6 +323,26 @@ function islandora_menu() {
'access arguments' => array('administer site configuration'),
'type' => MENU_CALLBACK,
);
$items['admin/islandora/restore/prep'] = array(
'description' => 'Restore or permanantly remove objects with Deleted status',
'title' => 'Manage Deleted Objects',
'file' => 'includes/manage_deleted_objects.inc',
'page callback' => 'drupal_get_form',
'page arguments' => array('islandora_deleted_objects_prep_form'),
'type' => MENU_NORMAL_ITEM,
'access arguments' => array(ISLANDORA_MANAGE_DELETED_OBJECTS),
);
$items['admin/islandora/restore/manage'] = array(
'description' => 'Restore or permanantly remove objects with Deleted status',
'title' => 'Manage Deleted Objects',
'file' => 'includes/manage_deleted_objects.inc',
'page callback' => 'drupal_get_form',
'page arguments' => array('islandora_deleted_objects_manage_form'),
'type' => MENU_SUGGESTED_ITEM,
'access arguments' => array(ISLANDORA_MANAGE_DELETED_OBJECTS),
);
return $items;
}
@ -487,9 +510,7 @@ function islandora_print_object(AbstractObject $object) {
function islandora_forms($form_id) {
$forms = array();
if (strpos($form_id, 'islandora_solution_pack_form_') !== FALSE) {
$forms[$form_id] = array(
'callback' => 'islandora_solution_pack_form',
);
$forms[$form_id] = array('callback' => 'islandora_solution_pack_form');
}
return $forms;
}
@ -758,11 +779,7 @@ function islandora_manage_overview_object(AbstractObject $object) {
*/
function islandora_default_islandora_manage_overview_object(AbstractObject $object) {
$output = theme('islandora_default_overview', array('islandora_object' => $object));
return array(
'Default overview output' => array(
'#markup' => $output,
),
);
return array('Default overview output' => array('#markup' => $output));
}
/**
@ -815,11 +832,7 @@ function islandora_edit_object(AbstractObject $object) {
*/
function islandora_default_islandora_edit_object(AbstractObject $object) {
$output = theme('islandora_default_edit', array('islandora_object' => $object));
return array(
'Default Edit output' => array(
'#markup' => $output,
),
);
return array('Default Edit output' => array('#markup' => $output));
}
/**
@ -860,10 +873,7 @@ function islandora_view_object(AbstractObject $object) {
), array(
'type' => 'setting'));
drupal_add_js(array(
'islandora' => array(
'print_link' => 'islandora/object/' . $object->id . '/print_object')),
array('type' => 'setting'));
drupal_add_js(array('islandora' => array('print_link' => 'islandora/object/' . $object->id . '/print')), array('type' => 'setting'));
drupal_add_js($path . '/js/add_print.js');
drupal_set_title($object->label);
@ -947,6 +957,7 @@ function islandora_drupal_title(AbstractObject $object) {
return $object->label;
}
/**
* Renders the default view object page for the given object.
*
@ -958,11 +969,7 @@ function islandora_drupal_title(AbstractObject $object) {
*/
function islandora_default_islandora_view_object($object) {
$output = theme('islandora_default', array('islandora_object' => $object));
return array(
'Default output' => array(
'#markup' => $output,
),
);
return array('Default output' => array('#markup' => $output));
}
/**
@ -1000,11 +1007,7 @@ function islandora_default_islandora_printer_object($object, $alter) {
'dc_array' => $variables,
'islandora_content' => $alter));
return array(
'Default output' => array(
'#markup' => $output,
),
);
return array('Default output' => array('#markup' => $output));
}
/**
@ -1223,9 +1226,7 @@ function islandora_islandora_required_objects(IslandoraTuque $connection) {
return array(
'islandora' => array(
'title' => 'Islandora',
'objects' => array(
$root_collection,
),
'objects' => array($root_collection),
),
);
}
@ -1401,6 +1402,7 @@ function islandora_entity_property_info() {
return $info;
}
/**
* Menu callback downloads the given clip.
*/
@ -1547,13 +1549,10 @@ function islandora_islandora_basic_collection_get_query_filters() {
if ($enforced) {
$namespace_array = islandora_get_allowed_namespaces();
$namespace_sparql = implode('|', $namespace_array);
return format_string('regex(str(?object), "info:fedora/(!namespaces):")', array(
'!namespaces' => $namespace_sparql,
));
return format_string('regex(str(?object), "info:fedora/(!namespaces):")', array('!namespaces' => $namespace_sparql));
}
}
/**
* Implements hook_islandora_object_ingested().
*

Loading…
Cancel
Save