Index: includes/project_edit_issues.inc =================================================================== RCS file: /cvs/drupal/contributions/modules/project_issue/includes/project_edit_issues.inc,v retrieving revision 1.2 diff -u -r1.2 project_edit_issues.inc --- includes/project_edit_issues.inc 5 May 2009 19:15:58 -0000 1.2 +++ includes/project_edit_issues.inc 27 Jul 2009 06:43:32 -0000 @@ -226,6 +226,10 @@ * @see project_issue_project_edit_issues */ function project_issue_project_edit_form_submit($form, &$form_state) { + // Load the original project node and components. + $original_node = node_load($form_state['values']['nid']); + $original_components = array_values($original_node->project_issue['components']); + $components = array(); if (!empty($form_state['values']['component_add']['name'])) { $components[trim($form_state['values']['component_add']['name'])] = $form_state['values']['component_add']['weight']; @@ -236,13 +240,33 @@ } } asort($components); + + // Determine which components were renamed upon submit. + $index = 0; + foreach(array_keys($components) as $new_component) { + if ($original_components[$index] != $new_component) { + $renamed_components[$original_components[$index]] = $new_component; + } + $index++; + } + $components = serialize(array_keys($components)); $default_component = !empty($form_state['values']['default_component']) ? $form_state['values']['default_component'] : ''; + + // If the default component is amongst the renamed components, save the new + // component name instead of the old one. + if ($default_component && isset($renamed_components[$default_component])) { + $default_component = $renamed_components[$default_component]; + } + $mail_copy_filter = serialize($form_state['values']['mail_copy_filter']); $mail_copy_filter_state = serialize($form_state['values']['mail_copy_filter_state']); db_query("UPDATE {project_issue_projects} SET issues = %d, components = '%s',default_component = '%s', mail_digest = '%s', mail_reminder = %d, mail_copy = '%s', mail_copy_filter = '%s', mail_copy_filter_state = '%s', help = '%s' WHERE nid = %d", $form_state['values']['issues'], $components, $default_component, $form_state['values']['mail_digest'], $form_state['values']['mail_reminder'], $form_state['values']['mail_copy'], $mail_copy_filter, $mail_copy_filter_state, $form_state['values']['help'], $form_state['values']['nid']); db_query("UPDATE {node} SET changed = %d WHERE nid = %d", time(), $form_state['values']['nid']); + + project_issue_component_rename_start_batch($original_node, $renamed_components); + drupal_set_message(t('Issue settings have been saved.')); } @@ -287,4 +311,38 @@ db_query("UPDATE {node} SET changed = %d WHERE nid = %d", time(), $project->nid); } +/* + * Set up and launch batch processing via the Batch API. + * + * @param $project + * @param $old_name + * @param $new_name + */ +function project_issue_component_rename_start_batch($project, $renamed_components) { + require_once(drupal_get_path('module', 'project_issue') . '/includes/batch.inc'); + + // Set up the batch operation which will update the component for each + // issues & comments. + $batch = array( + 'finished' => 'project_issue_batch_rename_component_finished', + 'title' => t('Updating issues & follow-ups.'), + 'error_message' => t('An error occured while updating issues.'), + 'file' => drupal_get_path('module', 'project_issue') . "/includes/batch.inc" + ); + + foreach ($renamed_components as $old_name => $new_name) { + $batch['operations'][] = array('project_issue_batch_rename_component_current_values', array($project, $old_name, $new_name)); + $batch['operations'][] = array('project_issue_batch_rename_component_original_values', array($project, $old_name, $new_name)); + } + + batch_set($batch); +} + +function project_issue_batch_rename_component_finished($success, $results, $operations) { + if ($success) { + $pid = $results['pid']; + drupal_set_message(t('Successfully processed !processed issues. ', array('!processed' => $results['processed'], '!issue_updated' => $results['issues_updated'], '!comments_updated' => $results['comments_updated'], '!orig_updated' => $results['orig_updated']))); + drupal_goto("node/$pid/edit/issues"); + } +} Index: includes/batch.inc =================================================================== RCS file: includes/batch.inc diff -N includes/batch.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ includes/batch.inc 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,63 @@ +project_issue['components']; + $components[array_search($old_name, $components, TRUE)] = $new_name; + db_query("UPDATE {project_issue_projects} SET components = '%s' WHERE nid = %d", serialize($components), $project->nid); + + // Update the *current* component for all the issues in one go. + db_query("UPDATE {project_issues} SET component = '%s' WHERE pid = %d AND component = '%s'", $new_name, $project->nid, $old_name); + $context['results']['issues_updated'] = db_affected_rows(); + + // Update all the comments in one go + db_query("UPDATE {project_issue_comments} SET component = '%s' WHERE pid = %d AND component = '%s'", $new_name, $project->nid, $old_name); + $context['results']['comments_updated'] = db_affected_rows(); + + $context['finished'] = 1; +} + +function project_issue_batch_rename_component_original_values($project, $old_name, $new_name, &$context) { + // Get the list of issues to update + if (!isset($context['sandbox']['issues'])) { + // We need to get every single issue from the database, since issues might have originally + // belonged to the project for which we're changing the component + $result = db_query('SELECT DISTINCT nid FROM {project_issues}'); + while($nid = db_fetch_array($result)) { + $context['sandbox']['issues'][] = $nid['nid']; + } + + $context['finished'] = 0; + $context['sandbox']['max'] = count($context['sandbox']['issues']); + $context['sandbox']['progress'] = 0; + $conetxt['message'] = 'Updated @current out of @total issues.'; + $context['results']['orig_updated'] = 0; + $context['results']['processed'] = 0; + $context['results']['pid'] = $project->nid; + + // Make sure there is at least one issue to update, otherwise set finished = 1 and + // stop processing immediately. + if (!$context['sandbox']['max']) { + $context['finished'] = 1; + return; + } + } + + if ($context['sandbox']['issues']) { + $nid = array_pop($context['sandbox']['issues']); + // The original component for an issue is stored in a serialized array, so we have to + // load each of the issues, change the value, and save back to the database. + $original_values = unserialize(db_result(db_query('SELECT original_issue_data FROM {project_issues} WHERE nid = %d', $nid))); + if ($original_values->pid == $project->nid) { + if ($original_values->component == $old_name) { + $original_values->component = $new_name; + db_query("UPDATE {project_issues} SET original_issue_data = '%s' WHERE nid = %d", serialize($original_values), $nid); + $context['results']['orig_updated']++; + } + } + } + $context['sandbox']['progress']++; + $context['results']['processed']++; + + // Update the completion level. + $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max']; +}