Browse Source

Update to ingest_steps to add the callback type and logic associated with that.

pull/317/head
Jordan Dukart 12 years ago
parent
commit
5deab4f3e3
  1. 187
      includes/ingest.form.inc
  2. 33
      islandora.api.php

187
includes/ingest.form.inc

@ -188,6 +188,8 @@ function islandora_ingest_form_get_next_step_id(array &$form_state) {
*/ */
function islandora_ingest_form_get_previous_step_id(array &$form_state) { function islandora_ingest_form_get_previous_step_id(array &$form_state) {
$step_id = islandora_ingest_form_get_current_step_id($form_state); $step_id = islandora_ingest_form_get_current_step_id($form_state);
$step = islandora_ingest_form_get_step($form_state, $step_id);
$step_ids = array_keys(islandora_ingest_form_get_steps($form_state)); $step_ids = array_keys(islandora_ingest_form_get_steps($form_state));
$index = array_search($step_id, $step_ids); $index = array_search($step_id, $step_ids);
if ($index !== FALSE && --$index >= 0) { if ($index !== FALSE && --$index >= 0) {
@ -270,10 +272,10 @@ function islandora_ingest_get_approximate_steps(array $configuration) {
* @return array * @return array
* The form definition of the current step. * The form definition of the current step.
*/ */
function islandora_ingest_form_execute_step(array $form, array &$form_state) { function islandora_ingest_form_execute_step(array $form, array &$form_state, $step_id = NULL) {
// Load any required files for the current step. // Load any required files for the current step.
islandora_ingest_form_load_include($form_state); islandora_ingest_form_load_include($form_state);
$step = islandora_ingest_form_get_step($form_state); $step = isset($step_id) ? islandora_ingest_form_get_step($form_state) : islandora_ingest_form_get_step($form_state, $step_id);
switch ($step['type']) { switch ($step['type']) {
case 'form': case 'form':
$args = array($form, &$form_state); $args = array($form, &$form_state);
@ -284,10 +286,36 @@ function islandora_ingest_form_execute_step(array $form, array &$form_state) {
case 'batch': case 'batch':
// @todo Implement if possible. // @todo Implement if possible.
break; break;
case 'callback':
call_user_func_array($step['do_function']['function'], $step['do_function']['args']);
$next_step = islandora_ingest_form_get_next_step_id($form_state);
if ($next_step) {
islandora_ingest_form_increment_step($form_state);
return islandora_ingest_form_execute_step($form, $form_state, $next_step);
}
} }
return array(); return array();
} }
/**
* Handles occurances where a callback is executed to grab the next form type.
*
* @param array $form_state
* The Drupal form state.
* @param array $step
* Describes the current step.
*
* @return array
* The stepified Drupal form definition for the given step.
*/
function islandora_ingest_callback_stepify(array &$form_state, $step) {
$next_step = islandora_ingest_form_get_step($form_state, $step);
$form = call_user_func_array($next_step['form_id'], $args);
islandora_ingest_form_increment_step($form_state);
return islandora_ingest_form_stepify($form, $form_state, $next_step);
}
/** /**
* Append Prev/Next buttons submit/validation handlers etc. * Append Prev/Next buttons submit/validation handlers etc.
* *
@ -297,7 +325,7 @@ function islandora_ingest_form_execute_step(array $form, array &$form_state) {
* The Drupal form state. * The Drupal form state.
* *
* @return array * @return array
* The stepified drupal form definition for the given step. * The stepified Drupal form definition for the given step.
*/ */
function islandora_ingest_form_stepify(array $form, array &$form_state, $step) { function islandora_ingest_form_stepify(array $form, array &$form_state, $step) {
$first_step = islandora_ingest_form_on_first_step($form_state); $first_step = islandora_ingest_form_on_first_step($form_state);
@ -307,7 +335,6 @@ function islandora_ingest_form_stepify(array $form, array &$form_state, $step) {
// Allow for a hook_form_FORM_ID_alter(). // Allow for a hook_form_FORM_ID_alter().
drupal_alter(array('form_' . $step['form_id'], 'form'), $form, $form_state, $step['form_id']); drupal_alter(array('form_' . $step['form_id'], 'form'), $form, $form_state, $step['form_id']);
return $form; return $form;
} }
@ -336,10 +363,28 @@ function islandora_ingest_form_on_first_step(array &$form_state) {
* TRUE if we are currently on the last step, FALSE otherwise. * TRUE if we are currently on the last step, FALSE otherwise.
*/ */
function islandora_ingest_form_on_last_step(array &$form_state) { function islandora_ingest_form_on_last_step(array &$form_state) {
$step_id = islandora_ingest_form_get_current_step_id($form_state); $next_id = islandora_ingest_form_get_next_step_id($form_state);
$step_ids = array_keys(islandora_ingest_form_get_steps($form_state)); if (!$next_id) {
$count = count($step_ids); return TRUE;
return array_search($step_id, $step_ids) == --$count; }
else {
$step_ids = array_keys(islandora_ingest_form_get_steps($form_state));
$next_step_num = array_search($next_id, $step_ids);
$callback_chain = TRUE;
while ($next_step_num < count($step_ids)) {
$next_step = islandora_ingest_form_get_step($form_state, $step_ids[$next_step_num]);
// Still is a form somewhere down our chain.
if ($next_step['type'] === 'form') {
$callback_chain = FALSE;
break;
}
else {
$next_step_num++;
}
}
return $callback_chain;
}
} }
/** /**
@ -358,9 +403,35 @@ function islandora_ingest_form_previous_button(array &$form_state) {
// to undo whatever its submit handler did. // to undo whatever its submit handler did.
$prev_step_id = islandora_ingest_form_get_previous_step_id($form_state); $prev_step_id = islandora_ingest_form_get_previous_step_id($form_state);
$prev_step = islandora_ingest_form_get_step($form_state, $prev_step_id); $prev_step = islandora_ingest_form_get_step($form_state, $prev_step_id);
$form_id = $prev_step['form_id'];
$submit_callback = $form_id . '_undo_submit'; if ($prev_step['type'] === 'form') {
$submit = function_exists($submit_callback) ? array($submit_callback, 'islandora_ingest_form_previous_submit') : array('islandora_ingest_form_undo_submit'); $form_id = $prev_step['form_id'];
$submit_callback = $form_id . '_undo_submit';
$submit = function_exists($submit_callback) ? array($submit_callback, 'islandora_ingest_form_previous_submit') : array('islandora_ingest_form_undo_submit');
}
elseif ($prev_step['type'] === 'callback') {
// Need to check if we have one or more callbacks at the start of our steps.
$steps = islandora_ingest_form_get_steps($form_state);
$keys = array_keys($steps);
$form = FALSE;
$current_step = array_search($prev_step_id, $keys);
while ($current_step >= 0 && !$form) {
$step = islandora_ingest_form_get_step($form_state, $keys[$current_step]);
if ($step['type'] === 'form') {
$form = TRUE;
break;
}
$current_step--;
}
// Only render a previous button if there a form somewhere behind us in our
// history chain.
if ($form) {
$submit = array('islandora_ingest_form_callback_previous');
}
else {
return;
}
}
return array( return array(
'#type' => 'submit', '#type' => 'submit',
'#value' => t('Previous'), '#value' => t('Previous'),
@ -377,6 +448,38 @@ function islandora_ingest_form_previous_button(array &$form_state) {
); );
} }
/**
* Handles the execution of "undoing" callbacks until a form type is reached.
*
* @param array $form
* The Drupal form.
* @param array $form_state
* The Drupal form state.
*/
function islandora_ingest_form_callback_previous(array $form, array &$form_state) {
// Arbitrarily move at least 1 back.
islandora_ingest_form_decrement_step($form_state);
$step_id = islandora_ingest_form_get_current_step_id($form_state);
$steps = islandora_ingest_form_get_steps($form_state);
$keys = array_keys($steps);
$current_step = array_search($step_id, $keys);
$form = FALSE;
while ($current_step >= 0 && !$form) {
$step = islandora_ingest_form_get_step($form_state, $keys[$current_step]);
islandora_ingest_form_decrement_step($form_state);
if ($step['type'] === 'callback') {
call_user_func_array($step['undo_function']['function'], $step['undo_function']['args']);
}
else {
$form = TRUE;
}
$current_step--;
}
$form_state['rebuild'] = TRUE;
}
/** /**
* The submit handler for the ingest form previous button. * The submit handler for the ingest form previous button.
* *
@ -446,8 +549,10 @@ function islandora_ingest_form_next_submit(array $form, array &$form_state) {
*/ */
function islandora_ingest_form_stash_info(array &$form_state) { function islandora_ingest_form_stash_info(array &$form_state) {
$storage = &islandora_ingest_form_get_step_storage($form_state); $storage = &islandora_ingest_form_get_step_storage($form_state);
$storage['values'] = $form_state['values']; if ($storage) {
unset($form_state['values']); $storage['values'] = $form_state['values'];
unset($form_state['values']);
}
} }
/** /**
@ -479,6 +584,15 @@ function islandora_ingest_form_ingest_button(array &$form_state) {
$validate = function_exists($validate_callback) ? array($validate_callback) : NULL; $validate = function_exists($validate_callback) ? array($validate_callback) : NULL;
$submit_callback = $form_id . '_submit'; $submit_callback = $form_id . '_submit';
$submit = function_exists($submit_callback) ? array($submit_callback, 'islandora_ingest_form_submit') : array('islandora_ingest_form_submit'); $submit = function_exists($submit_callback) ? array($submit_callback, 'islandora_ingest_form_submit') : array('islandora_ingest_form_submit');
// Because of callback shananigans we have to check if there are a chain of
// n callbacks that are weighted after the current step.
$next_id = islandora_ingest_form_get_next_step_id($form_state);
if ($next_id) {
$submit[] = 'islandora_ingest_form_callback_ingest';
}
return array( return array(
'#type' => 'submit', '#type' => 'submit',
'#name' => 'ingest', '#name' => 'ingest',
@ -513,6 +627,28 @@ function islandora_ingest_form_submit(array $form, array &$form_state) {
} }
} }
/**
* Execute any callbacks that are weighted at end of the ingest steps on ingest.
*
* @param array $form
* The Drupal form.
* @param array $form_state
* The Drupal form state.
*/
function islandora_ingest_form_callback_ingest(array $form, array &$form_state) {
$next_id = islandora_ingest_form_get_next_step_id($form_state);
$steps = islandora_ingest_form_get_steps($form_state);
$keys = array_keys($steps);
$current_step = array_search($next_id, $keys);
// Execute our n chain of callbacks.
while ($current_step < count($steps)) {
$step = islandora_ingest_form_get_step($form_state, $keys[$current_step]);
call_user_func_array($step['do_function']['function'], $step['do_function']['args']);
$current_step++;
}
}
/** /**
* Gets a reference to the stored NewFedoraObject's. * Gets a reference to the stored NewFedoraObject's.
* *
@ -635,6 +771,31 @@ function islandora_ingest_form_get_steps(array &$form_state) {
foreach (islandora_build_hook_list(ISLANDORA_INGEST_STEP_HOOK, $shared_storage['models']) as $hook) { foreach (islandora_build_hook_list(ISLANDORA_INGEST_STEP_HOOK, $shared_storage['models']) as $hook) {
drupal_alter($hook, $steps, $form_state); drupal_alter($hook, $steps, $form_state);
} }
// Check to see if the callback functions are implemented (existed). Remove
// any implementations from the steps that are incorrectly defined.
foreach ($steps as $key => $step) {
$watchdog = FALSE;
if ($step['type'] === 'callback') {
if (!isset($step['do_function']) || !isset($step['undo_function'])) {
$watchdog = TRUE;
}
elseif (!isset($step['do_function']['function']) || !isset($step['undo_function']['function'])) {
$watchdog = TRUE;
}
if ($watchdog) {
watchdog('islandora', 'The @module module is incorrectly implementing the
callback functionality of islandora_ingest_steps. The step @step has
not been included in the list of steps.', array(
'@module' => $step['module'],
'@step' => $key,
), WATCHDOG_ERROR);
dd('errorsaursu');
unset($steps[$key]);
}
}
}
uasort($steps, 'drupal_sort_weight'); uasort($steps, 'drupal_sort_weight');
return $steps; return $steps;
} }

33
islandora.api.php

@ -386,15 +386,26 @@ function hook_islandora_undeletable_datastreams(array $models) {
* @return array * @return array
* An associative array of associative arrays which define each step in the * An associative array of associative arrays which define each step in the
* ingest process. Each step should consist of a unique name mapped to an * ingest process. Each step should consist of a unique name mapped to an
* array of properties (keys) including: * array of properties (keys) which take different paramaters based upon type:
* - type: The type of step. Currently, only "form" is implemented. * - type: Type of step. Only "form" and "callback" are implemented so far.
* - weight: The "weight" of this step--heavier(/"larger") values sink to the * Required "form" type specific parameters:
* end of the process while smaller(/"lighter") values are executed first.
* - form_id: The form building function to call to get the form structure * - form_id: The form building function to call to get the form structure
* for this step. * for this step.
* - args: An array of arguments to pass to the form building function. * - args: An array of arguments to pass to the form building function.
* And may optionally include both: * Required "callback" type specific parameters:
* - do_function: An associate array including:
* - 'function': The callback function to be called.
* - 'args': An array of arguments to pass to the callback function.
* - undo_function: An associate array including:
* - 'function': The callback function to be called to reverse the
* executed action in the ingest steps.
* - 'args': An array of arguments to pass to the callback function.
* Shared parameters between both types:
* - weight: The "weight" of this step--heavier(/"larger") values sink to the
* end of the process while smaller(/"lighter") values are executed first.
* Both types may optionally include:
* - module: A module from which we want to load an include. * - module: A module from which we want to load an include.
* "Form type" may optionally include:
* - file: A file to include (relative to the module's path, including the * - file: A file to include (relative to the module's path, including the
* file's extension). * file's extension).
*/ */
@ -406,6 +417,18 @@ function hook_islandora_ingest_steps(array $form_state) {
'form_id' => 'my_cool_form', 'form_id' => 'my_cool_form',
'args' => array('arg_one', 'numero deux'), 'args' => array('arg_one', 'numero deux'),
), ),
'my_cool_step_callback' => array(
'type' => 'callback',
'weight' => 2,
'do_function' => array(
'function' => 'my_cool_execute_function',
'args' => array('arg_one', 'numero deux'),
),
'undo_function' => array(
'function' => 'my_cool_undo_function',
'args' => array('arg_one', 'numero deux'),
),
),
); );
} }
/** /**

Loading…
Cancel
Save