Skip to content

Commit

Permalink
Merge pull request #232 from qadan/7.x-embargo-roles
Browse files Browse the repository at this point in the history
embargo roles whitelist
  • Loading branch information
nigelgbanks committed May 24, 2016
2 parents c78aced + 35a2baf commit 25a8b1a
Show file tree
Hide file tree
Showing 7 changed files with 252 additions and 20 deletions.
4 changes: 3 additions & 1 deletion modules/islandora_scholar_embargo/includes/admin.form.inc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ function islandora_embargo_admin(array $form, array &$form_state) {
$options = islandora_get_content_models();
$selected = variable_get('islandora_embargo_content_models', array('ir:citationCModel', 'ir:thesisCModel'));
foreach ($selected as $cmodel) {
$options = array($cmodel => $options[$cmodel]) + $options;
if (isset($options[$cmodel])) {
$options = array($cmodel => $options[$cmodel]) + $options;
}
}
foreach ($options as $key => $value) {
$rows[$key] = array(
Expand Down
73 changes: 73 additions & 0 deletions modules/islandora_scholar_embargo/includes/batch.inc
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,76 @@ function islandora_scholar_embargo_lift_batch_finished($success, $results, $oper
drupal_set_message(format_plural($results['skip_count'], '@count object skipped as the content model is not configured to allow embargoes.', '@count objects skipped as their content models are not configured to allow embargoes.'));
}
}

/**
* Batch definition for re-applying embargoes to embargoed objects.
*
* @return array
* The batch definition.
*/
function islandora_scholar_embargo_reapply_embargoes_batch() {
return array(
'title' => t('Re-Apply Embargos to Embargoed Objects'),
'error_message' => t('An error has occurred and the embargoes may not have all been re-applied.'),
'init_message' => t('Preparing to re-apply embargoes to embargoed objects.'),
'progress_message' => t('Time elapsed: @elapsed <br/>Estimated time remaining: @estimate.'),
'file' => drupal_get_path('module', 'islandora_scholar_embargo') . '/includes/batch.inc',
'operations' => array(
array('islandora_scholar_embargo_reapply_embargoes_batch_operation', array()),
),
);
}

/**
* Batch operation for re-applying embargoes to embargoed objects.
*
* @param array $context
* The batch context.
*/
function islandora_scholar_embargo_reapply_embargoes_batch_operation(&$context) {
module_load_include('inc', 'islandora_scholar_embargo', 'includes/embargo');
$sandbox =& $context['sandbox'];
if (empty($sandbox)) {
$sandbox['completed'] = 0;
$sandbox['slice'] = array();
}

// It's possible for this number to change during the batch (e.g., if an
// embargo expires or a datastream is modified), so re-grabbing is safest to
// prevent items from being skipped.
$sandbox['total'] = islandora_scholar_embargo_get_all_embargoed(TRUE);
if (!$sandbox['total']) {
$context['message'] = t('No items to embargo found, or embargoed items set was reduced to zero at some point during the batch.');
return;
}
else {
// Iterate through a set.
$set = islandora_scholar_embargo_get_embargoed_items_subset($sandbox['slice']);
if (!empty($set)) {
foreach ($set as $embargoed_item) {
$id_parts = explode('/', $embargoed_item['obj']['value']);
$pid = array_shift($id_parts);
$dsid = array_shift($id_parts);
$dsids = is_null($dsid) ? $dsid : array($dsid);
islandora_scholar_embargo_lift_embargo($pid, $dsids);
islandora_scholar_embargo_set_embargo($pid, $dsids, $embargoed_item['expiry']['value']);
$sandbox['completed']++;
$sandbox['slice']['offset_date'] = $embargoed_item['date']['value'];
$sandbox['slice']['offset_pid'] = $pid;
$context['message'] = t('@count/@total: Re-applied embargo to @item of @pid.', array(
'@count' => $sandbox['completed'],
'@total' => $sandbox['total'],
'@item' => is_null($dsid) ? t('entire object') : $dsid,
'@pid' => $pid,
));
}
// If the set was empty, $context['finished'] will be 1 anyway.
$context['finished'] == $sandbox['completed'] / $sandbox['total'];
}
if ($context['finished'] >= 1) {
drupal_set_message(t('Re-applied embargoes to @total objects.', array(
'@total' => $sandbox['completed'],
)));
}
}
}
74 changes: 62 additions & 12 deletions modules/islandora_scholar_embargo/includes/embargo.inc
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function islandora_scholar_embargo_form(array $form, array &$form_state, Abstrac
// Table seems somewhat of overkill for now, but as the embargo offering
// grows more robust this sort of formatting for the UI will make sense.
$rows = array();
$current_embargos = array();
$current_embargoes = array();
$date = '';
foreach ($embargo_results as $result) {
if ($result['obj']['value'] == $item->id) {
Expand All @@ -52,12 +52,12 @@ function islandora_scholar_embargo_form(array $form, array &$form_state, Abstrac
$type,
$date,
);
$current_embargos[] = array(
$current_embargoes[] = array(
'type' => $type,
'date' => $date,
);
}
$form_state['islandora_embargo'] = $current_embargos;
$form_state['islandora_embargo'] = $current_embargoes;
$embargoed = TRUE;
if (empty($embargo_results)) {
$embargoed = FALSE;
Expand Down Expand Up @@ -150,7 +150,7 @@ function islandora_scholar_embargo_form(array $form, array &$form_state, Abstrac
'#title' => check_plain($embargoed ? t('Update Options') : t('Embargo Options')),
'#options' => array(
'change_embargo_date' => $embargoed ? t('Change the embargo date') : t('Set the embargo date'),
'indefinite_embargo' => t('Embargo indefinitely (Indefinite embargos must be lifted manually).'),
'indefinite_embargo' => t('Embargo indefinitely (Indefinite embargoes must be lifted manually).'),
),
'#default_value' => ($date === 'Indefinite') ? 'indefinite_embargo' : 'change_embargo_date',
'#states' => array(
Expand Down Expand Up @@ -265,7 +265,7 @@ function islandora_scholar_embargo_form_validate(array $form, array &$form_state
$parsed = strtotime($parsed_date);
if ($embargoed) {
// This will need to be updated in the future to handle multiple
// embargos on a single object.
// embargoes on a single object.
foreach ($form_state['islandora_embargo'] as $embargo_vals) {
$embargo_date = $embargo_vals['date'];
break;
Expand All @@ -279,7 +279,7 @@ function islandora_scholar_embargo_form_validate(array $form, array &$form_state
}
}
elseif ($form_state['values']['update_date_options'] === 'indefinite_embargo') {
// This will need to be updated in the future to handle multiple embargos
// This will need to be updated in the future to handle multiple embargoes
// on a single object.
$embargo_date = '';
foreach ($form_state['islandora_embargo'] as $embargo_vals) {
Expand Down Expand Up @@ -390,7 +390,7 @@ function islandora_scholar_embargo_form_submit(array $form, array &$form_state)
}
}
// Currently we just overwrite what's already in place. In the future, for
// multiple embargos on a single object, this will have to be adjusted.
// multiple embargoes on a single object, this will have to be adjusted.

// If we're recursing do those objects in a batch.
if (isset($form_state['values']['recurse']) && $form_state['values']['recurse'] && $form_state['values']['recurse_options'] != 'newchildren') {
Expand Down Expand Up @@ -445,24 +445,74 @@ EOQ;
}

/**
* Retrieve all embargoed items from an object.
* Retrieve all embargoed items.
*
* @param bool $count
* Whether or not to just return the total count.
*
* @return array
* An array containing the list of embargoed items on an object
* An array containing the list of embargoed items.
*/
function islandora_scholar_embargo_get_all_embargoed() {
function islandora_scholar_embargo_get_all_embargoed($count = FALSE) {
$current_embargo = <<<EOQ
PREFIX is: <info:islandora/islandora-system:def/scholar#>
SELECT ?obj ?date
FROM <#ri>
WHERE {
?obj is:embargo-until ?date
}
EOQ;
if ($count) {
$current_embargo .= <<<EOQ
ORDER BY ?obj
EOQ;
}
$connection = islandora_get_tuque_connection();
$embargo_results = $connection->repository->ri->sparqlQuery($current_embargo, 'unlimited', '0');
return $embargo_results;
$ri = $connection->repository->ri;
return $count ? $ri->countQuery($current_embargo, 'sparql') : $ri->sparqlQuery($current_embargo, 'unlimited', '0');
}

/**
* Gets a subset of all embargoed items.
*
* @param array $slice_params
* An associative array containing:
* 'offset_date': an ISO8601 datetime to filter items before
* 'offset_pid': a PID to filter on when a date match is found.
* @param int $limit
* The number of items to return in the subset.
*
* @return array
* A SPARQL query results array containing a subset of embargoed items,
* including 'obj' as the object ID, 'expiry' as the expiry date, and 'date'
* as the item's created or last modified date.
*/
function islandora_scholar_embargo_get_embargoed_items_subset($slice_params = array(), $limit = 10) {
// Build the query.
$current_embargo = <<<EOQ
PREFIX is: <info:islandora/islandora-system:def/scholar#>
PREFIX xs: <xml-schema:>
SELECT DISTINCT ?obj ?expiry ?date
FROM <#ri>
WHERE {
?obj is:embargo-until ?expiry ;
{ ?obj <fedora-model:createdDate> ?date } UNION
{ ?obj <fedora-view:lastModifiedDate> ?date ;
<fedora-view:disseminationType> ?dsid
}
EOQ;
// Offset if asked.
if ($slice_params) {
$current_embargo .= "FILTER(?date > '{$slice_params['offset_date']}'^^xs:dateTime || (?date = '{$slice_params['offset_date']}'^^xs:dateTime && xs:string(?obj) > xs:string('info:fedora/{$slice_params['offset_date']}')))";
}
$current_embargo .= <<<EOQ
}
ORDER BY ASC(?date) ASC(?obj)
EOQ;

// Use the query.
$connection = islandora_get_tuque_connection();
return $connection->repository->ri->sparqlQuery($current_embargo, $limit);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

/**
* @file
* Admin form for setting embargo view/manage roles.
*/

/**
* Embargo roles admin management form.
*
* @param array $form
* The Drupal form.
* @param array $form_state
* The Drupal form state.
*
* @return array
* The form definition.
*/
function islandora_scholar_embargo_manage_roles_admin_form($form, $form_state) {
module_load_include('inc', 'islandora_scholar_embargo', 'includes/embargo');
return array(
'roles_wrapper' => array(
'#type' => 'fieldset',
'#title' => t('Roles'),
'#collapsible' => FALSE,
'islandora_scholar_embargo_whitelisted_roles' => array(
'#type' => 'checkboxes',
'#description' => t('Check off all the roles that should have access to embargoed items. <strong>NOTE:</strong> since embargo XACML role entries are whitelists, embargoed objects in a Fedora repository shared between Drupal sites will be visible to the same role in both sites. Consider using site-unique roles when dealing with shared repositories.'),
'#options' => user_roles(TRUE, ISLANDORA_SCHOLAR_EMBARGO_CAN_EMBARGO_ANY),
'#default_value' => array_keys(variable_get('islandora_scholar_embargo_whitelisted_roles', array())),
),
),
'note' => array(
'#markup' => t('Saving and applying will initiate a batch to modify the XACML policies of all embargoed objects. Bear in mind that this can take a long time to execute depending on the number of items to be embargoed, and that it may be more prudent to run the Drush command <code>islandora_scholar_embargo_apply_roles_to_embargoed_objects</code> instead. Number of embargoed objects at time of page load: <strong>@number</strong>', array(
'@number' => number_format(islandora_scholar_embargo_get_all_embargoed(TRUE)),
)),
),
'submit_buttons' => array(
'#type' => 'actions',
'save' => array(
'#type' => 'submit',
'#value' => t('Save Without Applying'),
'#name' => 'save',
),
'save_and_apply' => array(
'#type' => 'submit',
'#value' => t('Save And Apply'),
'#name' => 'save_and_apply',
),
),
);
}

/**
* Submit handler for the roles management form.
*
* @param array $form
* The submitted roles admin form.
* @param array $form_state
* The state of the submitted form.
*/
function islandora_scholar_embargo_manage_roles_admin_form_submit($form, &$form_state) {
// Attach role names to role IDs to make it more useful as a variable.
$whitelist = array();
foreach (array_filter($form_state['values']['islandora_scholar_embargo_whitelisted_roles']) as $rid => $checked) {
$whitelist[$rid] = $form['roles_wrapper']['islandora_scholar_embargo_whitelisted_roles']['#options'][$rid];
}
variable_set('islandora_scholar_embargo_whitelisted_roles', $whitelist);

// Kick off the batch if we were asked.
if ($form_state['triggering_element']['#name'] == 'save_and_apply') {
module_load_include('inc', 'islandora_scholar_embargo', 'includes/batch');
batch_set(islandora_scholar_embargo_reapply_embargoes_batch());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ function islandora_scholar_embargo_drush_command() {
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_LOGIN,
'callback' => 'islandora_scholar_embargo_lift_embargoes_update',
),
'islandora_scholar_embargo_reapply_embargoes' => array(
'description' => dt('Applies the list of roles that can administer embargoes to all embargoed objects in the repository.'),
'examples' => array('drush -v -u 1 islandora_scholar_embargo_reapply_embargoes'),
'aliases' => array('ise-reapply'),
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_LOGIN,
'callback' => 'islandora_scholar_embargo_reapply_embargoes',
),
);
}

Expand All @@ -44,6 +51,15 @@ function islandora_scholar_embargo_lift_embargoes_update() {
drush_backend_batch_process();
}

/**
* Runs the batch to apply whitelisted roles to embargoed objects.
*/
function islandora_scholar_embargo_reapply_embargoes() {
module_load_include('inc', 'islandora_scholar_embargo', 'includes/batch');
batch_set(islandora_scholar_embargo_reapply_embargoes_batch());
drush_backend_batch_process();
}

/**
* Batch operation for lifting embargoes for the update.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
function islandora_scholar_embargo_uninstall() {
$variables = array(
'islandora_embargo_content_models',
'islandora_scholar_embargo_whitelisted_roles',
);
array_walk($variables, 'variable_del');
}
Expand Down
Loading

0 comments on commit 25a8b1a

Please sign in to comment.