*** project_issue/includes/admin.settings.inc	Sat Apr 04 02:30:22 2009
--- project_issue/includes/admin.settings.inc	Fri Jun 19 22:11:02 2009
***************
*** 74,79 ****
--- 74,95 ----
      '#element_validate' => array('project_issue_validate_default_components'),
    );
  
+   $form['project_issue_add_new_component'] = array(
+     '#type' => 'textfield',
+     '#title' => t('Add a new component to existing projects'),
+     '#default_value' => '',
+     '#required' => FALSE,
+     '#description' => t("Enter a new component, to be added to existing projects."),
+   );
+   $form['project_issue_add_new_component_conditional'] = array(
+     '#type' => 'textfield',
+     '#title' => t('But only if they have this other component'),
+     '#default_value' => '',
+     '#required' => FALSE,
+     '#description' => t("Optionally, enter an current component name to only add the new one to projects with that component."),
+   );
+   $form['#submit'][] = 'project_issue_add_new_component';
+ 
    if (module_exists('mailhandler')) {
      // TODO: move this stuff to mailhandler.module ?
      $items = array(t('<none>'));
***************
*** 131,136 ****
--- 147,238 ----
      // Regardless, now that we've trimmed everything, save those values.
      $form_state['values']['project_issue_default_components'] = implode("\n", $new);
    }
+ }
+ 
+ function project_issue_add_new_component($form, &$form_state) {
+   $newcomponent = check_plain(trim($form_state['values']['project_issue_add_new_component']));
+   $conditional = check_plain(trim($form_state['values']['project_issue_add_new_component_conditional']));
+   if ($newcomponent){
+     $title = t('Adding new component @component to existing projects @conditional', array('@component' => $newcomponent, 
+ 	'@conditional' => $conditional ? "with ".$conditional : '' ));
+     $batch = array(
+       'operations' => array(
+             array('project_issue_batch_component_add', array($newcomponent, $conditional))
+       ),
+       'finished' => 'project_issue_batch_component_add_finished',
+       'title' => $title,
+       'init_message' => $title,
+       'progress_message' => t('Updating components...'),
+       'error_message' => t('Error in adding new component to existing projects.'),
+       'file' => drupal_get_path('module', 'project_issue').'/includes/admin.settings.inc'
+     );
+     batch_set($batch);
+   }
+ }
+ 
+ function project_issue_batch_component_add($newcomponent, $conditional, &$context) {
+   if (!isset($context['sandbox']['projects'])) {
+     // We need to get projects from the database which match the conditional, if any.
+     // If there is no conditional, we're adding the component to all existing projects (unless it has it already)
+     if ($conditional){
+     	$result = db_query("SELECT nid FROM {project_issue_projects} WHERE components LIKE '%s'", '%'. $conditional .'%');
+     } else {
+     	$result = db_query('SELECT nid FROM {project_issue_projects}');
+     }
+     while($nid = db_fetch_array($result)) {
+       $context['sandbox']['projects'][] = $nid['nid'];
+     }
+     $context['finished']                  = 0;
+     $context['sandbox']['max']            = count($context['sandbox']['projects']);
+     $context['sandbox']['progress']       = 0;
+     $context['message']                   = t('Adding new component...');
+     $context['results']['updated']		= 0;
+     $context['results']['processed']      = 0;
+     // Make sure there is at least one project to update, otherwise set finished = 1 and
+     // stop processing immediately.
+     if (!$context['sandbox']['max']) {
+       $context['finished'] = 1;
+       return;
+     }
+   }
+ 
+   if ($context['sandbox']['projects']) {
+     $nid = array_pop($context['sandbox']['projects']);
+ 	$node = node_load($nid);
+     // The component list for a project is stored in a serialized array, so we have to
+     // load the array, add the value at the end (if it doesn't have it already), and save back to the database.
+     $components = unserialize(db_result(db_query('SELECT components FROM {project_issue_projects} WHERE nid = %d', $nid)));
+     if (!in_array($newcomponent, $components)) {
+ 	 $components[] = $newcomponent;
+         db_query("UPDATE {project_issue_projects} SET components = '%s' WHERE nid = %d", serialize($components), $nid);
+ 		//drupal_set_message($node->title. ' updated with ' . $newcomponent);
+         $context['results']['updated']++;
+     }
+   }
+   $context['sandbox']['progress']++;
+   $context['results']['processed']++;
+   $context['message']= t('Now processing Project: @node', array('@node' => $node->title));
+ 
+   // Update the completion level.
+   $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
+ }
+ 
+ 
+ /**
+ * Batch 'finished' callback
+ */
+ function project_issue_batch_component_add_finished($success, $results, $operations) {
+   if ($success) {
+     $message = t('@updated projects updated out of @processed processed.', array('@updated' => $results['updated'], '@processed' =>
+ 	$results['processed'])); 
+   }
+   else {
+     // An error occurred.
+     // $operations contains the operations that remained unprocessed.
+     $error_operation = reset($operations);
+     $message = t('An error occurred while processing with arguments:'). print_r($error_operation[0], TRUE);
+   }
+   drupal_set_message($message);
  }
  
  /**
