From 902742f10af7ef034257b41fdad98e1fefc1525d Mon Sep 17 00:00:00 2001 From: Alan Stanley Date: Thu, 14 Feb 2013 16:23:47 -0400 Subject: [PATCH 1/6] Added method to retreive basic ds_comp info --- includes/utilities.inc | 55 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/includes/utilities.inc b/includes/utilities.inc index 3679acf2..118cf961 100644 --- a/includes/utilities.inc +++ b/includes/utilities.inc @@ -577,3 +577,58 @@ function islandora_directory_exists_message($path) { function islandora_system_settings_form_default_value($name, $default_value, array &$form_state) { return isset($form_state['values'][$name]) ? $form_state['values'][$name] : variable_get($name, $default_value); } + +/** + * Returns basic information about DS-COMPOSITE-MODEL + * + * @param string $pid + * pid of content model containing DS_COMP stream + * @return array + * array of values in the following form + * + * [DC] => Array + * ( + * [mimetype] => text/xml + * ) + * + * [MODS] => Array + * ( + * [optional] => true + * [mimetype] => text/xml + * ) + * + * [RELS-EXT] => Array + * ( + * [mimetype] => application/rdf+xml + * ) + * + * [RELS-INT] => Array + * ( + * [optional] => true + * [mimetype] => application/rdf+xml + * ) + * + */ + +function islandora_get_comp_ds_mappings($pid) { + $cm_object = islandora_object_load($pid); + if (!isset($cm_object) || !isset($cm_object['DS-COMPOSITE-MODEL'])) { + return FALSE; + } + $datastream = $cm_object['DS-COMPOSITE-MODEL']; + $ds_comp_stream = $datastream->content; + $sxml = new SimpleXMLElement($ds_comp_stream); + $mappings = array(); + foreach ($sxml->dsTypeModel as $ds) { + $dsid = (string) $ds['ID']; + $optional = (string) $ds['optional']; + foreach ($ds->form as $form) { + $mime = (string) $form['MIME']; + if ($optional) { + $mappings[$dsid]['optional'] = $optional; + } + $mappings[$dsid]['mimetype'] = $mime; + } + } + return $mappings; +} \ No newline at end of file From 355367ae158fd8883f636bad009fab5d7ad3595b Mon Sep 17 00:00:00 2001 From: Nigel Banks Date: Thu, 14 Feb 2013 09:05:51 +0100 Subject: [PATCH 2/6] Issue: 1013 MARCXml module ingest hook conflicts with Newspaper/Book page ingest Clean up the ingest form code, and make it easier to interact with. --- includes/ingest.form.inc | 528 ++++++++++++++++++++++----------------- includes/ingest.menu.inc | 32 +-- 2 files changed, 308 insertions(+), 252 deletions(-) diff --git a/includes/ingest.form.inc b/includes/ingest.form.inc index 420ebc87..c285c5a1 100644 --- a/includes/ingest.form.inc +++ b/includes/ingest.form.inc @@ -12,9 +12,9 @@ * the current step. * * @param array $form - * The drupal form. + * The Drupal form. * @param array $form_state - * The drupal form state. + * The Drupal form state. * @param array $configuration * An associative array of configuration values that are used to build the * list of steps to be executed, including: @@ -31,67 +31,196 @@ * The form definition of the current step. */ function islandora_ingest_form(array $form, array &$form_state, array $configuration) { - islandora_ingest_form_init_form_state($form_state, $configuration); - $form = islandora_ingest_form_execute_step($form, $form_state); - return $form; + islandora_ingest_form_init_form_state_storage($form_state, $configuration); + return islandora_ingest_form_execute_step($form, $form_state); } /** - * Prepares/Initializes the form state for use. + * Validates the given ingest configuration. * - * Also cleans up or loads any data required. + * At the moment it only requires that models are present. + * + * @todo Add hook for manipulating/validating the configuration. + * + * @throws InvalidArgumentException * - * @param array $form_state - * The drupal form state. * @param array $configuration - * A list of key value pairs that are used to build the list of steps to be - * executed. + * The key value pairs that are used to build the multi-paged ingest process. + * + * @see islandora_ingest_form() + * + * @return bool + * TRUE if the configuration is valid, FALSE otherwise. */ -function islandora_ingest_form_init_form_state(array &$form_state, array $configuration) { - // First time initialization of storage. - islandora_ingest_form_init_form_state_storage($form_state, $configuration); +function islandora_ingest_form_validiate_configuration(array $configuration) { + if (empty($configuration['models'])) { + $message = t('Ingest configuration not vaild, no models were given'); + drupal_set_message($message, 'error'); + throw new InvalidArgumentException($message); + } } /** * Initializes the form_state storage for use in the ingest multi-page forms. * * @param array $form_state - * The drupal form state. + * The Drupal form state. * @param array $configuration * A list of key value pairs that are used to build the list of steps to be * executed. */ function islandora_ingest_form_init_form_state_storage(array &$form_state, array $configuration) { if (empty($form_state['islandora'])) { - module_load_include('inc', 'islandora', 'includes/utilities'); - // Use ID if given. - $id = isset($configuration['id']) ? $configuration['id'] : NULL; - // Use namespace if ID not given. - $namespace = isset($configuration['namespace']) && !isset($id) ? $configuration['namespace'] : $id; - $label = isset($configuration['label']) ? $configuration['label'] : 'New Object'; - $relationship_map = function($o) { - return array('relationship' => 'isMemberOfCollection', 'pid' => $o); - }; - $relationships = empty($configuration['collections']) ? array() : array_map($relationship_map, $configuration['collections']); - $object = islandora_prepare_new_object($namespace, $label, array(), array(), $relationships); + // Validate the configuration before using it. + islandora_ingest_form_validiate_configuration($configuration); + $object = islandora_ingest_form_prepare_new_object($configuration); $form_state['islandora'] = array( 'step_id' => NULL, 'objects' => array($object), - 'configuration' => $configuration, + 'shared_storage' => $configuration, 'step_storage' => array(), ); } +} + +/** + * Prepares a new object based on the given configuration. + * + * @param array $configuration + * The list of key/value pairs of configuration. + * + * @return NewFedoraObject + * The new object. + */ +function islandora_ingest_form_prepare_new_object(array $configuration) { + module_load_include('inc', 'islandora', 'includes/utilities'); + // ID is more specific than namespace so it will take precedence. + $id = isset($configuration['namespace']) ? $configuration['namespace'] : 'islandora'; + $id = isset($configuration['id']) ? $configuration['id'] : $id; + $label = isset($configuration['label']) ? $configuration['label'] : 'New Object'; + $relationship_map = function($o) { + return array('relationship' => 'isMemberOfCollection', 'pid' => $o); + }; + $relationships = empty($configuration['collections']) ? array() : array_map($relationship_map, $configuration['collections']); + return islandora_prepare_new_object($id, $label, array(), array(), $relationships); +} + +/** + * Gets the given/current step. + * + * The current step is returned if no step ID is given. If the current step is + * not defined it's assume to be the first step. + * + * @param array $form_state + * The Drupal form state. + * @param string $step_id + * The ID of the step. + * + * @return array + * The given/current step if found, NULL otherwise. + */ +function islandora_ingest_form_get_step(array &$form_state, $step_id = NULL) { + $step_id = isset($step_id) ? $step_id : islandora_ingest_form_get_current_step_id($form_state); + $steps = islandora_ingest_form_get_steps($form_state); + if (isset($step_id) && isset($steps[$step_id])) { + return $steps[$step_id]; + } + return NULL; +} - $steps = islandora_ingest_get_steps($form_state); - if ($form_state['islandora']['step_id'] === NULL || !array_key_exists( - $form_state['islandora']['step_id'], $steps)) { - reset($steps); - $form_state['islandora']['step_id'] = key($steps); +/** + * Gets the ID of the current step. + * + * If a current step is not defined, its assumed to be the first step. + * + * @param array $form_state + * The Drupal form state. + * + * @return string + * The step ID. + */ +function islandora_ingest_form_get_current_step_id(array &$form_state) { + if (empty($form_state['islandora']['step_id'])) { + $steps = islandora_ingest_form_get_steps($form_state); + return array_shift(array_keys($steps)); } + return $form_state['islandora']['step_id']; +} - // Stash the current configuration in the step. - $storage = &islandora_ingest_form_get_step_storage($form_state); - $storage['configuration'] = $form_state['islandora']['configuration']; +/** + * Gets the ID of the next step. + * + * If a current step is not defined, its assumed to be the first step. + * + * @param array $form_state + * The Drupal form state. + * + * @return string + * The next step ID if found, NULL otherwise. + */ +function islandora_ingest_form_get_next_step_id(array &$form_state) { + $step_id = islandora_ingest_form_get_current_step_id($form_state); + $step_ids = array_keys(islandora_ingest_form_get_steps($form_state)); + $index = array_search($step_id, $step_ids); + $count = count($step_ids); + if ($index !== FALSE && ++$index < $count) { + return $step_ids[$index]; + } + return NULL; +} + +/** + * Gets the ID of the previous step. + * + * If a current step is not defined, its assumed to be the first step. + * + * @param array $form_state + * The Drupal form state. + * + * @return string + * The previous step ID if found, NULL otherwise. + */ +function islandora_ingest_form_get_previous_step_id(array &$form_state) { + $step_id = islandora_ingest_form_get_current_step_id($form_state); + $step_ids = array_keys(islandora_ingest_form_get_steps($form_state)); + $index = array_search($step_id, $step_ids); + if ($index !== FALSE && --$index >= 0) { + return $step_ids[$index]; + } + return NULL; +} + +/** + * Increments the current step if possible. + * + * @param array $form_state + * The Drupal form state. + */ +function islandora_ingest_form_increment_step(array &$form_state) { + // When going to the next step rebuild the list of steps as the submit + // of the current step could have added/removed a step. + drupal_static_reset('islandora_ingest_form_get_steps'); + $next_step_id = islandora_ingest_form_get_next_step_id($form_state); + if (isset($next_step_id)) { + islandora_ingest_form_stash_info($form_state); + $form_state['islandora']['step_id'] = $next_step_id; + islandora_ingest_form_grab_info($form_state); + } +} + +/** + * Decrement the current step if possible. + * + * @param array $form_state + * The Drupal form state. + */ +function islandora_ingest_form_decrement_step(array &$form_state) { + $previous_step_id = islandora_ingest_form_get_previous_step_id($form_state); + if (isset($previous_step_id)) { + islandora_ingest_form_stash_info($form_state); + $form_state['islandora']['step_id'] = $previous_step_id; + islandora_ingest_form_grab_info($form_state); + } } /** @@ -106,40 +235,38 @@ function islandora_ingest_form_init_form_state_storage(array &$form_state, array function islandora_ingest_get_approximate_steps(array $configuration) { $fake_form_state = array( 'islandora' => array( - 'configuration' => $configuration, + 'shared_storage' => $configuration, ), ); - $steps = islandora_ingest_get_steps($fake_form_state); - drupal_static_reset('islandora_ingest_get_steps'); + $steps = islandora_ingest_form_get_steps($fake_form_state); + drupal_static_reset('islandora_ingest_form_get_steps'); return $steps; } /** * Executes the current step. * - * Builds the form definition and appends any additonal elements required for - * the step to function. + * Builds the form definition and appends on any additonal elements required + * for the step to function. * * @param array $form - * The drupal form. + * The Drupal form. * @param array $form_state - * The drupal form state. + * The Drupal form state. * * @return array * The form definition of the current step. */ function islandora_ingest_form_execute_step(array $form, array &$form_state) { // Load any required files for the current step. - islandora_ingest_form_step_form_load_include($form_state); - - $step_info = islandora_ingest_form_get_step_info($form_state); - - switch ($step_info['type']) { + islandora_ingest_form_load_include($form_state); + $step = islandora_ingest_form_get_step($form_state); + switch ($step['type']) { case 'form': $args = array($form, &$form_state); - $args = isset($step_info['args']) ? array_merge($args, $step_info['args']) : $args; - $form = call_user_func_array($step_info['form_id'], $args); - return islandora_ingest_form_stepify($form, $form_state, $step_info); + $args = isset($step['args']) ? array_merge($args, $step['args']) : $args; + $form = call_user_func_array($step['form_id'], $args); + return islandora_ingest_form_stepify($form, $form_state, $step); case 'batch': // @todo Implement if possible. @@ -152,37 +279,76 @@ function islandora_ingest_form_execute_step(array $form, array &$form_state) { * Append Prev/Next buttons submit/validation handlers etc. * * @param array $form - * The drupal form. + * The Drupal form. * @param array $form_state - * The drupal form state. - * @param array $step_info - * The info for building the current form step. + * The Drupal form state. * * @return array * The stepified drupal form definition for the given step. */ -function islandora_ingest_form_stepify(array $form, array &$form_state, array $step_info) { - $step = islandora_ingest_form_get_step_number($form_state); - - $first_step = $step > 0; - $last_step = $step == (islandora_ingest_form_get_step_count($form_state) - 1); - $form['prev'] = $first_step ? islandora_ingest_form_previous_button() : NULL; - $form['next'] = $last_step ? islandora_ingest_form_ingest_button($step_info) : islandora_ingest_form_next_button($step_info); +function islandora_ingest_form_stepify(array $form, array &$form_state) { + $first_step = islandora_ingest_form_on_first_step($form_state); + $last_step = islandora_ingest_form_on_last_step($form_state); + $form['prev'] = $first_step ? NULL : islandora_ingest_form_previous_button($form_state); + $form['next'] = $last_step ? islandora_ingest_form_ingest_button($form_state) : islandora_ingest_form_next_button($form_state); return $form; } +/** + * Checks if we are on the first step. + * + * @param array $form_state + * The Drupal form state. + * + * @return bool + * TRUE if we are currently on the first step, FALSE otherwise. + */ +function islandora_ingest_form_on_first_step(array &$form_state) { + $step_id = islandora_ingest_form_get_current_step_id($form_state); + $step_ids = array_keys(islandora_ingest_form_get_steps($form_state)); + return array_search($step_id, $step_ids) == 0; +} + +/** + * Checks if we are on the last step. + * + * @param array $form_state + * The Drupal form state. + * + * @return bool + * TRUE if we are currently on the last step, FALSE otherwise. + */ +function islandora_ingest_form_on_last_step(array &$form_state) { + $step_id = islandora_ingest_form_get_current_step_id($form_state); + $step_ids = array_keys(islandora_ingest_form_get_steps($form_state)); + $count = count($step_ids); + return array_search($step_id, $step_ids) == --$count; +} + /** * Defines the previous button for the ingest form. * + * Adds submit handlers for the form step if they exist. + * + * @param array $form_state + * The Drupal form state. + * * @return array * The previous button for the ingest form. */ -function islandora_ingest_form_previous_button() { +function islandora_ingest_form_previous_button(array &$form_state) { + // Before we move back to the previous step we should tell the previous step + // to undo whatever its submit handler did. + $prev_step_id = islandora_ingest_form_get_previous_step_id($form_state); + $prev_step = islandora_ingest_form_get_step($form_state, $prev_step_id); + $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'); return array( '#type' => 'submit', '#value' => t('Previous'), '#name' => 'prev', - '#submit' => array('islandora_ingest_form_previous_submit'), + '#submit' => $submit, // #limit_validation_errors, is why when the previous button is pressed no // values persisted in the form_state, but its also what allows us to go // back when validation errors occur. To have a better solution going @@ -194,23 +360,6 @@ function islandora_ingest_form_previous_button() { ); } -/** - * Get the current step. - * - * @param array $form_state - * The Drupal form state. - * @param string $step_id - * The ID of the step to get. - */ -function islandora_ingest_form_get_step_number(array $form_state, $step_id = NULL) { - if ($step_id === NULL) { - $step_id = islandora_ingest_form_get_step_id($form_state); - } - - $steps = array_flip(array_keys(islandora_ingest_form_get_steps($form_state))); - return $steps[$step_id]; -} - /** * The submit handler for the ingest form previous button. * @@ -219,16 +368,12 @@ function islandora_ingest_form_get_step_number(array $form_state, $step_id = NUL * Restores the form values for the previous step. * * @param array $form - * The drupal form. + * The Drupal form. * @param array $form_state - * The drupal form state. + * The Drupal form state. */ function islandora_ingest_form_previous_submit(array $form, array &$form_state) { - $step = islandora_ingest_form_get_step_number($form_state); - islandora_ingest_form_stash_info($form_state); - $step = max(array($step - 1, 0)); - $form_state['islandora']['step_id'] = islandora_ingest_form_get_step_id($form_state, $step); - islandora_ingest_form_grab_info($form_state); + islandora_ingest_form_decrement_step($form_state); $form_state['rebuild'] = TRUE; } @@ -237,11 +382,15 @@ function islandora_ingest_form_previous_submit(array $form, array &$form_state) * * Adds submit/validate handlers for the form step if they exist. * + * @param array $form_state + * The Drupal form state. + * * @return array * The next button for the ingest form. */ -function islandora_ingest_form_next_button(array $step_info) { - $form_id = $step_info['form_id']; +function islandora_ingest_form_next_button(array &$form_state) { + $step = islandora_ingest_form_get_step($form_state); + $form_id = $step['form_id']; $validate_callback = $form_id . '_validate'; $validate = function_exists($validate_callback) ? array($validate_callback) : NULL; $submit_callback = $form_id . '_submit'; @@ -263,22 +412,20 @@ function islandora_ingest_form_next_button(array $step_info) { * Restores the form values for the next step if present. * * @param array $form - * The drupal form. + * The Drupal form. * @param array $form_state - * The drupal form state. + * The Drupal form state. */ function islandora_ingest_form_next_submit(array $form, array &$form_state) { - $step = islandora_ingest_form_get_step_number($form_state); - drupal_static_reset('islandora_ingest_form_get_steps'); - islandora_ingest_form_stash_info($form_state); - $step = min(array($step + 1, islandora_ingest_form_get_step_count($form_state) - 1)); - $form_state['islandora']['step_id'] = islandora_ingest_form_get_step_id($form_state, $step); - islandora_ingest_form_grab_info($form_state); + islandora_ingest_form_increment_step($form_state); $form_state['rebuild'] = TRUE; } /** * Push current info into the current step's storage. + * + * @param array $form_state + * The Drupal form state. */ function islandora_ingest_form_stash_info(array &$form_state) { $storage = &islandora_ingest_form_get_step_storage($form_state); @@ -288,13 +435,13 @@ function islandora_ingest_form_stash_info(array &$form_state) { /** * Pops the info for the given step from storage into the form_state. + * + * @param array $form_state + * The Drupal form state. */ function islandora_ingest_form_grab_info(array &$form_state) { $storage = islandora_ingest_form_get_step_storage($form_state); $form_state['values'] = isset($storage['values']) ? $storage['values'] : array(); - if (isset($storage['configuration'])) { - $form_state['islandora']['configuration'] = $storage['configuration']; - } } /** @@ -302,11 +449,15 @@ function islandora_ingest_form_grab_info(array &$form_state) { * * This button is only shown on the last page of the multi-page ingest form. * + * @param array $form_state + * The Drupal form state. + * * @return array * The ingest button for the ingest form. */ -function islandora_ingest_form_ingest_button(array $step_info) { - $form_id = $step_info['form_id']; +function islandora_ingest_form_ingest_button(array &$form_state) { + $step = islandora_ingest_form_get_step($form_state); + $form_id = $step['form_id']; $validate_callback = $form_id . '_validate'; $validate = function_exists($validate_callback) ? array($validate_callback) : NULL; $submit_callback = $form_id . '_submit'; @@ -326,9 +477,9 @@ function islandora_ingest_form_ingest_button(array $step_info) { * Attempts to ingest every object built by the previous steps. * * @param array $form - * The drupal form. + * The Drupal form. * @param array $form_state - * The drupal form state. + * The Drupal form state. */ function islandora_ingest_form_submit(array $form, array &$form_state) { foreach ($form_state['islandora']['objects'] as $object) { @@ -345,159 +496,94 @@ function islandora_ingest_form_submit(array $form, array &$form_state) { } } -/** - * Gets the configuration used to create the multi-page ingest form. - * - * @param array $form_state - * The drupal form state. - * - * @return array - * The configuration used to generate the multi-page ingest forms. - */ -function &islandora_ingest_form_get_configuration(array &$form_state) { - return $form_state['islandora']['configuration']; -} - /** * Gets a reference to the stored NewFedoraObject's. * * @param array $form_state - * The drupal form state. + * The Drupal form state. * * @return array * A reference to the stored NewFedoraObjects to be ingested when the final * step submits. */ -function &islandora_ingest_form_get_objects(array $form_state) { +function &islandora_ingest_form_get_objects(array &$form_state) { return $form_state['islandora']['objects']; } /** * Gets a single object from the stored NewFedoraObject's. * - * @note - In our current use case we are only dealing with a single object + * @note In our current use case we are only dealing with a single object * ingest, this makes it convenient to access it. Ideally the steps * implementations will be abstracted to be indifferent to what object it's * currently working on. This will act as a placeholder for such * functionality. * * @param array $form_state - * The drupal form state. + * The Drupal form state. * * @return NewFedoraObject * Returns the 'current' object in the array of NewFedoraObjects, generally * this is only used when there is one object in the list of objects. */ -function islandora_ingest_form_get_object(array $form_state) { +function islandora_ingest_form_get_object(array &$form_state) { $objects = &islandora_ingest_form_get_objects($form_state); return current($objects); } -/** - * Get a reference to the current step index. - * - * @param array $form_state - * The drupal form state. - * - * @return string - * The current step index. - */ -function islandora_ingest_form_get_step_id(array &$form_state, $step_number = NULL) { - if ($step_number === NULL) { - return $form_state['islandora']['step_id']; - } - else { - $steps = array_keys(islandora_ingest_form_get_steps($form_state)); - return $steps[$step_number]; - } -} - -/** - * Get the step info of the given step or the current step if none is given. - * - * @param array $form_state - * The drupal form state. - * @param int $step - * The index of the step to get. - * - * @return int - * The step info of the requested step if found, NULL otherwise. - */ -function islandora_ingest_form_get_step_info(array &$form_state, $step = NULL) { - $step = isset($step) ? $step : islandora_ingest_form_get_step_id($form_state); - $steps = islandora_ingest_form_get_steps($form_state); - if (!empty($steps[$step])) { - return $steps[$step]; - } - // @todo deal with unknown case. - return NULL; -} - /** * Get general storage for the given/current step. * * @param array $form_state - * The drupal form state. - * @param string $step_id + * The Drupal form state. + * @param array $step_id * The ID of the step. + * + * @return array + * The given/current step storage if found, NULL otherwise. */ function &islandora_ingest_form_get_step_storage(array &$form_state, $step_id = NULL) { - if ($step_id === NULL) { - $step_id = islandora_ingest_form_get_step_id($form_state); - } - - if (!isset($form_state['islandora']['step_storage'][$step_id])) { - $form_state['islandora']['step_storage'][$step_id] = array(); + $step_id = isset($step_id) ? $step_id : islandora_ingest_form_get_current_step_id($form_state); + if (isset($step_id)) { + if (!isset($form_state['islandora']['step_storage'][$step_id])) { + $form_state['islandora']['step_storage'][$step_id] = array(); + } + return $form_state['islandora']['step_storage'][$step_id]; } - - return $form_state['islandora']['step_storage'][$step_id]; + return NULL; } /** - * Get a reference to the steps stored in the form state. + * Gets the configuration used to create the multi-page ingest form. * * @param array $form_state - * The drupal form state. + * The Drupal form state. * * @return array - * All the steps to be used in the ingest process. + * The configuration used to generate the multi-page ingest forms. */ -function islandora_ingest_form_get_steps(array &$form_state) { - return islandora_ingest_get_steps($form_state); +function &islandora_ingest_form_get_shared_storage(array &$form_state) { + return $form_state['islandora']['shared_storage']; } /** * Call form_load_include, for the current step if it defines a required file. * * @param array $form_state - * The drupal form state. + * The Drupal form state. */ -function islandora_ingest_form_step_form_load_include(array &$form_state) { +function islandora_ingest_form_load_include(array &$form_state) { form_load_include($form_state, 'inc', 'islandora', 'includes/ingest.form'); - $step_info = islandora_ingest_form_get_step_info($form_state); + $step = islandora_ingest_form_get_step($form_state); // Load include files. - if (isset($step_info['file']) && isset($step_info['module'])) { + if (isset($step['file']) && isset($step['module'])) { $matches = array(); - preg_match('/^(.*)\.(.*)$/', $step_info['file'], $matches); + preg_match('/^(.*)\.(.*)$/', $step['file'], $matches); list($file, $name, $type) = $matches; - form_load_include($form_state, $type, $step_info['module'], $name); + form_load_include($form_state, $type, $step['module'], $name); } } -/** - * Get the number of steps. - * - * @param array $form_state - * The drupal form state. - * - * @return int - * The number of steps. - */ -function islandora_ingest_form_get_step_count(array $form_state) { - $steps = islandora_ingest_form_get_steps($form_state); - return count($steps); -} - /** * Buildes the initial list of ingest steps. * @@ -512,40 +598,26 @@ function islandora_ingest_form_get_step_count(array $form_state) { * The list of sorted ingest steps as defined by all implementers * of ISLANDORA_INGEST_STEP_HOOK. */ -function &islandora_ingest_get_steps(array &$form_state) { +function islandora_ingest_form_get_steps(array &$form_state) { module_load_include('inc', 'islandora', 'includes/utilities'); $steps = &drupal_static(__FUNCTION__); - - if (!isset($steps)) { - $steps = array(); - $configuration = islandora_ingest_form_get_configuration($form_state); - $models = array(); - if (isset($configuration['selected_models'])) { - $models = $configuration['selected_models']; - } - elseif (isset($configuration['models'])) { - $models = $configuration['models']; - } - - foreach (islandora_build_hook_list(ISLANDORA_INGEST_STEP_HOOK, $models) as $hook) { - // Need to pass by ref... But don't really want an alter. - foreach (module_implements($hook) as $module) { - $function = $module . '_' . $hook; - $module_steps = (array) $function($form_state); - $steps = array_merge($steps, $module_steps); - } - } - - // Remove NULL values. - $steps = array_filter($steps); - uasort($steps, 'drupal_sort_weight'); - foreach (islandora_build_hook_list(ISLANDORA_INGEST_STEP_HOOK, $models) as $hook) { - $form_state_copy = $form_state; - drupal_alter($hook, $steps, $form_state_copy); + if (isset($steps)) { + return $steps; + } + $steps = array(); + $shared_storage = &islandora_ingest_form_get_shared_storage($form_state); + foreach (islandora_build_hook_list(ISLANDORA_INGEST_STEP_HOOK, $shared_storage['models']) as $hook) { + // Required for pass by reference. + foreach (module_implements($hook) as $module) { + $function = $module . '_' . $hook; + $module_steps = (array) $function($form_state); + $steps = array_merge($steps, $module_steps); } - - uasort($steps, 'drupal_sort_weight'); } - + $steps = array_filter($steps); + foreach (islandora_build_hook_list(ISLANDORA_INGEST_STEP_HOOK, $shared_storage['models']) as $hook) { + drupal_alter($hook, $steps, $form_state); + } + uasort($steps, 'drupal_sort_weight'); return $steps; } diff --git a/includes/ingest.menu.inc b/includes/ingest.menu.inc index ca4f6156..a6f79891 100644 --- a/includes/ingest.menu.inc +++ b/includes/ingest.menu.inc @@ -12,19 +12,20 @@ * HTML representing the mult-page ingest form. */ function islandora_ingest_callback() { - $configuration = islandora_ingest_get_configuration(); - if ($configuration === FALSE) { - drupal_set_message(t('Invalid ingest configuration.'), 'error'); + module_load_include('inc', 'islandora', 'includes/ingest.form'); + try { + $configuration = islandora_ingest_get_configuration(); + return drupal_get_form('islandora_ingest_form', $configuration); + } + catch(Exception $e) { $redirect = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''; // Redirect back to referer or top level collection. drupal_goto($redirect); } - module_load_include('inc', 'islandora', 'includes/ingest.form'); - return drupal_get_form('islandora_ingest_form', $configuration); } /** - * Fetches/validates the ingest configuration from the $_GET parameters. + * Fetches the ingest configuration from the $_GET parameters. * * Generic parameters as accepted by all ingest processes, other modules may * add to this list. @@ -44,22 +45,5 @@ function islandora_ingest_get_configuration() { foreach ($convert_to_array_keys as $key) { $configuration[$key] = explode(',', $configuration[$key]); } - // @todo add hook for manipulating/validating the configuration. - return islandora_valid_ingest_configuration($configuration) ? $configuration : FALSE; -} - -/** - * Validates the given ingest configuration. - * - * At the moment it requires that models and collections are present. - * - * @param array $configuration - * The key value pairs that are used to build the multi-paged ingest process. - * - * @return bool - * TRUE if the configuration is valid, FALSE otherwise. - */ -function islandora_valid_ingest_configuration(array $configuration) { - // @todo Add more robust validation, add watchdog logs, etc. - return isset($configuration['models']) && isset($configuration['collections']); + return $configuration; } From bbf813848e621de1de33b803832f3d356093555a Mon Sep 17 00:00:00 2001 From: Alan Stanley Date: Tue, 19 Feb 2013 16:32:53 -0400 Subject: [PATCH 3/6] fixed forced reingest --- includes/solution_packs.inc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/includes/solution_packs.inc b/includes/solution_packs.inc index 02952233..e1cf8478 100644 --- a/includes/solution_packs.inc +++ b/includes/solution_packs.inc @@ -186,12 +186,10 @@ function islandora_solution_pack_form_submit(array $form, array &$form_state) { * 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) { + if (!$deleted) { $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, From d6d6155a61427567b778d0a199109f0558c3eaaa Mon Sep 17 00:00:00 2001 From: Jordan Dukart Date: Wed, 20 Feb 2013 14:52:44 -0400 Subject: [PATCH 4/6] Flush the caches before we output so we don't overrun PHP memory limit. --- includes/datastream.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/includes/datastream.inc b/includes/datastream.inc index 9bc94f2d..b817b70d 100644 --- a/includes/datastream.inc +++ b/includes/datastream.inc @@ -43,6 +43,7 @@ function islandora_view_datastream(FedoraDatastream $datastream, $download = FAL } drupal_page_is_cacheable(FALSE); // Try not to load the file into PHP memory! + ob_end_flush(); $datastream->getContent('php://output'); exit(); } From c7aca6feae86c5bdeca96beb0b1633e8df6c1099 Mon Sep 17 00:00:00 2001 From: Phil Soga Date: Mon, 25 Feb 2013 13:12:52 -0400 Subject: [PATCH 5/6] modify manage permissions D7 --- islandora.info | 1 + islandora.module | 33 +++++------ tests/islandora_manage_permissions.test | 78 +++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 20 deletions(-) create mode 100644 tests/islandora_manage_permissions.test diff --git a/islandora.info b/islandora.info index 9763819b..e44ec721 100644 --- a/islandora.info +++ b/islandora.info @@ -14,4 +14,5 @@ files[] = includes/object.entity_controller.inc files[] = tests/web_test_case.inc files[] = tests/authtokens.test files[] = tests/hooks.test +files[] = tests/islandora_manage_permissions.test php = 5.3 diff --git a/islandora.module b/islandora.module index b700807e..10cc1cb4 100644 --- a/islandora.module +++ b/islandora.module @@ -28,7 +28,6 @@ define('DS_COMP_STREAM', 'DS-COMPOSITE-MODEL'); // Permissions. define('FEDORA_VIEW_OBJECTS', 'view fedora repository objects'); -define('FEDORA_MANAGE_DATASTREAMS', 'view fedora repository datastreams'); define('FEDORA_METADATA_EDIT', 'edit fedora metadata'); define('FEDORA_ADD_DS', 'add fedora datastreams'); define('FEDORA_INGEST', 'ingest fedora objects'); @@ -38,6 +37,8 @@ define('FEDORA_MANAGE_PROPERTIES', 'manage object properties'); // Hooks. define('ISLANDORA_VIEW_HOOK', 'islandora_view_object'); define('ISLANDORA_EDIT_HOOK', 'islandora_edit_object'); +define('ISLANDORA_OVERVIEW_HOOK', 'islandora_overview_object'); 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'); + // @todo Add Documentation. define('ISLANDORA_OBJECT_INGESTED_HOOK', 'islandora_object_ingested'); define('ISLANDORA_OBJECT_MODIFIED_HOOK', 'islandora_object_modified'); @@ -105,18 +106,17 @@ function islandora_menu() { ); $items['islandora/object/%islandora_object/manage'] = array( 'title' => 'Manage', - 'page callback' => 'islandora_edit_object', + 'page callback' => 'islandora_manage_overview_object', 'page arguments' => array(2), 'type' => MENU_LOCAL_TASK, 'access callback' => 'islandora_object_manage_access_callback', - 'access arguments' => array( - array(FEDORA_MANAGE_DATASTREAMS, FEDORA_MANAGE_PROPERTIES, FEDORA_ADD_DS), 2), - ); - $items['islandora/object/%islandora_object/manage/datastreams'] = array( - 'title' => 'Datastreams', - 'type' => MENU_DEFAULT_LOCAL_TASK, - 'weight' => -10, + 'access arguments' => array(array(FEDORA_MANAGE_PROPERTIES, FEDORA_METADATA_EDIT, FEDORA_ADD_DS, FEDORA_PURGE), 2), ); + + $items['islandora/object/%islandora_object/manage/overview'] = array( 'title' => 'Overview', 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -20, ); + + $items['islandora/object/%islandora_object/manage/datastreams'] = array( 'title' => 'Datastreams', 'type' => MENU_LOCAL_TASK, 'page callback' => 'islandora_edit_object', 'page arguments' => array(2), 'access callback' => 'islandora_object_manage_access_callback', 'access arguments' => array(array(FEDORA_METADATA_EDIT, FEDORA_ADD_DS, FEDORA_PURGE), 2), 'weight' => -10, ); + $items['islandora/object/%islandora_object/manage/properties'] = array( 'title' => 'Properties', 'page callback' => 'drupal_get_form', @@ -256,10 +256,6 @@ function islandora_permission() { 'title' => t('View repository objects'), 'description' => t('View objects in the repository. Note: Fedora XACML security policies may override this permission.'), ), - FEDORA_MANAGE_DATASTREAMS => array( - 'title' => t('Manage repository object datastreams'), - 'description' => t('Manage datastreams of objects in the repository. Note: Fedora XACML security policies may override this permission.'), - ), FEDORA_ADD_DS => array( 'title' => t('Add datastreams to repository objects'), 'description' => t('Add datastreams to objects in the repository. Note: Fedora XACML security policies may override this position.'), @@ -405,13 +401,7 @@ function islandora_object_manage_access_callback($perms, $object = NULL) { } /** - * Renders the given objects manage page. - * - * Its possible to modify the output of this function if 'ISLANDORA_EDIT_HOOK' - * is implemented in other modules. - * - * If no modules implement 'ISLANDORA_EDIT_HOOK' then this function returns the - * default manage view. + * Renders the given objects manage overview page. * * @param FedoraObject $object * The object to manage. @@ -419,6 +409,9 @@ function islandora_object_manage_access_callback($perms, $object = NULL) { * @return string * The HTML repersentation of the manage object page. */ + +function islandora_manage_overview_object(FedoraObject $object) { module_load_include('inc', 'islandora', 'includes/utilities'); $output = array(); //return $output; foreach (islandora_build_hook_list(ISLANDORA_OVERVIEW_HOOK, $object->models) as $hook) { $temp = module_invoke_all($hook, $object); if (!empty($temp)) { $output = array_merge_recursive($output, $temp); } } if (empty($output)) { // Add in the default, if we did not get any results. $output = islandora_default_islandora_manage_overview_object($object); } arsort($output); drupal_alter(ISLANDORA_OVERVIEW_HOOK, $object, $output); return implode('', $output); } /** * Renders the default manage object page for the given object. * * @param FedoraObject $object * The object used to render the manage object page. * * @return array * The default rendering of the object manage page, indexed at * 'Default Edit output'. */ function islandora_default_islandora_manage_overview_object(FedoraObject $object) { $output = theme('islandora_default_overview', array('islandora_object' => $object)); return array('Default overview output' => $output); } /** * Renders the given objects manage page. * * Its possible to modify the output of this function if 'ISLANDORA_EDIT_HOOK' * is implemented in other modules. * * If no modules implement 'ISLANDORA_EDIT_HOOK' then this function returns the * default manage view. * * @param FedoraObject $object * The object to manage. * * @return string * The HTML repersentation of the manage object page. */ + function islandora_edit_object(FedoraObject $object) { module_load_include('inc', 'islandora', 'includes/breadcrumb'); module_load_include('inc', 'islandora', 'includes/utilities'); diff --git a/tests/islandora_manage_permissions.test b/tests/islandora_manage_permissions.test new file mode 100644 index 00000000..76f43a6d --- /dev/null +++ b/tests/islandora_manage_permissions.test @@ -0,0 +1,78 @@ + 'Islandora Manage Permissions', + 'description' => 'Ensure the manage tab is shown based on the corrent permissions.', + 'group' => 'Islandora', + ); + } + + public function setUp() { + parent::setUp(array('islandora')); + } + + public function testManagePermissions() { + + + // permission FEDORA_VIEW_OBJECTS + // create a user with permission + $user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS)); + // log the user in + $this->drupalLogin($user); + $this->clickLink(t('Islandora Repository')); + $this->assertNoLink('Manage', 'Manage tab is not on current page.'); + + + // permission FEDORA_VIEW_OBJECTS, FEDORA_MANAGE_PROPERTIES + $user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS, FEDORA_MANAGE_PROPERTIES)); + // log the user in + $this->drupalLogin($user); + $this->clickLink(t('Islandora Repository')); + $this->assertLink('Manage', 0, 'Manage tab is on current page.'); + $this->clickLink(t('Manage')); + $this->assertLink('Properties', 0, 'Properties tab is on current page.'); + $this->assertNoLink('Datastreams', 'Datastreams tab is not on current page.'); + $this->assertNoLink('Collection','Collection tab is not on current page.'); + + + // permission FEDORA_VIEW_OBJECTS, FEDORA_ADD_DS + $user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS, FEDORA_ADD_DS)); + // log the user in + $this->drupalLogin($user); + $this->clickLink(t('Islandora Repository')); + $this->assertLink('Manage', 0, 'Manage tab is on current page.'); + $this->clickLink(t('Manage')); + $this->assertLink('Datastreams', 0, 'Datastreams tab is on current page.'); + $this->assertNoLink('Properties', 'Properties tab is not on current page.'); + $this->assertNoLink('Collection','Collection tab is not on current page.'); + + + // permission FEDORA_VIEW_OBJECTS, FEDORA_METADATA_EDIT + $user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS, FEDORA_METADATA_EDIT)); + // log the user in + $this->drupalLogin($user); + $this->clickLink(t('Islandora Repository')); + $this->assertLink('Manage', 0, 'Manage tab is on current page.'); + $this->clickLink(t('Manage')); + $this->assertLink('Datastreams', 0, 'Datastreams tab is on current page.'); + $this->assertNoLink('Properties', 'Properties tab is not on current page.'); + $this->assertNoLink('Collection','Collection tab is not on current page.'); + + + // permission FEDORA_VIEW_OBJECTS, FEDORA_PURGE + $user = $this->drupalCreateUser(array(FEDORA_VIEW_OBJECTS, FEDORA_PURGE)); + // log the user in + $this->drupalLogin($user); + $this->clickLink(t('Islandora Repository')); + $this->assertLink('Manage', 0, 'Manage tab is on current page.'); + $this->clickLink(t('Manage')); + $this->assertLink('Datastreams', 0, 'Datastreams tab is on current page.'); + $this->assertNoLink('Properties', 'Properties tab is not on current page.'); + $this->assertNoLink('Collection','Collection tab is not on current page.'); + + } + + } \ No newline at end of file From 47718e57ca6efa11ba2447380601c38a10274ca9 Mon Sep 17 00:00:00 2001 From: Nigel Banks Date: Tue, 26 Feb 2013 10:29:44 +0100 Subject: [PATCH 6/6] Code Review * Removed Windows line endings (^M). * Applied Coding Standards. --- islandora.module | 92 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 82 insertions(+), 10 deletions(-) diff --git a/islandora.module b/islandora.module index 10cc1cb4..d5287286 100644 --- a/islandora.module +++ b/islandora.module @@ -37,7 +37,11 @@ define('FEDORA_MANAGE_PROPERTIES', 'manage object properties'); // Hooks. define('ISLANDORA_VIEW_HOOK', 'islandora_view_object'); define('ISLANDORA_EDIT_HOOK', 'islandora_edit_object'); -define('ISLANDORA_OVERVIEW_HOOK', 'islandora_overview_object'); 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_OVERVIEW_HOOK', 'islandora_overview_object'); +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'); // @todo Add Documentation. define('ISLANDORA_OBJECT_INGESTED_HOOK', 'islandora_object_ingested'); @@ -110,13 +114,36 @@ function islandora_menu() { 'page arguments' => array(2), 'type' => MENU_LOCAL_TASK, 'access callback' => 'islandora_object_manage_access_callback', - 'access arguments' => array(array(FEDORA_MANAGE_PROPERTIES, FEDORA_METADATA_EDIT, FEDORA_ADD_DS, FEDORA_PURGE), 2), + 'access arguments' => array( + array( + FEDORA_MANAGE_PROPERTIES, + FEDORA_METADATA_EDIT, + FEDORA_ADD_DS, + FEDORA_PURGE, + ), 2), ); - - $items['islandora/object/%islandora_object/manage/overview'] = array( 'title' => 'Overview', 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -20, ); - - $items['islandora/object/%islandora_object/manage/datastreams'] = array( 'title' => 'Datastreams', 'type' => MENU_LOCAL_TASK, 'page callback' => 'islandora_edit_object', 'page arguments' => array(2), 'access callback' => 'islandora_object_manage_access_callback', 'access arguments' => array(array(FEDORA_METADATA_EDIT, FEDORA_ADD_DS, FEDORA_PURGE), 2), 'weight' => -10, ); - + + $items['islandora/object/%islandora_object/manage/overview'] = array( + 'title' => 'Overview', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -20, + ); + + $items['islandora/object/%islandora_object/manage/datastreams'] = array( + 'title' => 'Datastreams', + 'type' => MENU_LOCAL_TASK, + 'page callback' => 'islandora_edit_object', + 'page arguments' => array(2), + 'access callback' => 'islandora_object_manage_access_callback', + 'access arguments' => array( + array( + FEDORA_METADATA_EDIT, + FEDORA_ADD_DS, + FEDORA_PURGE, + ), 2), + 'weight' => -10, + ); + $items['islandora/object/%islandora_object/manage/properties'] = array( 'title' => 'Properties', 'page callback' => 'drupal_get_form', @@ -409,9 +436,54 @@ function islandora_object_manage_access_callback($perms, $object = NULL) { * @return string * The HTML repersentation of the manage object page. */ - -function islandora_manage_overview_object(FedoraObject $object) { module_load_include('inc', 'islandora', 'includes/utilities'); $output = array(); //return $output; foreach (islandora_build_hook_list(ISLANDORA_OVERVIEW_HOOK, $object->models) as $hook) { $temp = module_invoke_all($hook, $object); if (!empty($temp)) { $output = array_merge_recursive($output, $temp); } } if (empty($output)) { // Add in the default, if we did not get any results. $output = islandora_default_islandora_manage_overview_object($object); } arsort($output); drupal_alter(ISLANDORA_OVERVIEW_HOOK, $object, $output); return implode('', $output); } /** * Renders the default manage object page for the given object. * * @param FedoraObject $object * The object used to render the manage object page. * * @return array * The default rendering of the object manage page, indexed at * 'Default Edit output'. */ function islandora_default_islandora_manage_overview_object(FedoraObject $object) { $output = theme('islandora_default_overview', array('islandora_object' => $object)); return array('Default overview output' => $output); } /** * Renders the given objects manage page. * * Its possible to modify the output of this function if 'ISLANDORA_EDIT_HOOK' * is implemented in other modules. * * If no modules implement 'ISLANDORA_EDIT_HOOK' then this function returns the * default manage view. * * @param FedoraObject $object * The object to manage. * * @return string * The HTML repersentation of the manage object page. */ - +function islandora_manage_overview_object(FedoraObject $object) { + module_load_include('inc', 'islandora', 'includes/utilities'); + $output = array(); + foreach (islandora_build_hook_list(ISLANDORA_OVERVIEW_HOOK, $object->models) as $hook) { + $temp = module_invoke_all($hook, $object); + if (!empty($temp)) { + $output = array_merge_recursive($output, $temp); + } + } + if (empty($output)) { + // Add in the default, if we did not get any results. + $output = islandora_default_islandora_manage_overview_object($object); + } + arsort($output); + drupal_alter(ISLANDORA_OVERVIEW_HOOK, $object, $output); + return implode('', $output); +} + +/** + * Renders the default manage object page for the given object. + * + * @param FedoraObject $object + * The object used to render the manage object page. + * + * @return array + * The default rendering of the object manage page, indexed at + * 'Default Edit output'. + */ +function islandora_default_islandora_manage_overview_object(FedoraObject $object) { + $output = theme('islandora_default_overview', array('islandora_object' => $object)); + return array('Default overview output' => $output); +} + +/** + * Renders the given objects manage page. + * + * Its possible to modify the output of this function if 'ISLANDORA_EDIT_HOOK' + * is implemented in other modules. + * + * If no modules implement 'ISLANDORA_EDIT_HOOK' then this function returns the + * default manage view. + * + * @param FedoraObject $object + * The object to manage. + * + * @return string + * The HTML repersentation of the manage object page. + */ function islandora_edit_object(FedoraObject $object) { module_load_include('inc', 'islandora', 'includes/breadcrumb'); module_load_include('inc', 'islandora', 'includes/utilities');