1

I have 2 operations in a module using Batch API. Below is the code for the first one:

function get_first_data($qc, $path) {
    $testsets = some array...

    foreach ($testsets as $testset) {
    $operations[] = array('first_data_batch', array($testset));
  }

  $batch = array(
    'operations' => $operations,
    'finished' => 'first_data_batch_finished',
    'title' => t('First Data'),
    'init_message' => t('Import is starting...'),
    'progress_message' => t('Processed @current out of @total.'),
    'error_message' => t('An error has occurred')
  );

  batch_set($batch);
  batch_process('user'); // The path to redirect to when done.
}

function first_data_batch($testset, &$context) {
    // do something with $testset

    $context['message'] = "Processing...";
}

function first_data_batch_finished($success, $results, $operations) {
  if ($success) {
    drupal_set_message('First import is complete!');
  }
  else {
    $error_operation = reset($operations);
    $message = t('An error occurred while processing %error_operation with arguments: @arguments', array(
      '%error_operation' => $error_operation[0],
      '@arguments' => print_r($error_operation[1], TRUE)
    ));
    drupal_set_message($message, 'error');
  }
  drupal_set_message(l('Run again', 'my_module/batch'));
}

What I need is to have another operation that uses the output of the first one.

I think I can't set this second operation on the foreach cycle of the first one because the loop is completely different so I'm assuming I would repeate the code below for my second batch. The only issue is how to pass the output of the first one to the second one.

Another thing: in the first_data_batch function I generate part of the output that I want to feed in the second batch. The final array that I want to feed will be completed only after all the calls to this function end.

So, how can I pass this array to the second batch?

Thanks.

================================ EDIT ================================

I cleaned my code. This one is simpler but I still can't the information I need after the operation.

testcases_raw array (: testcases_raw array

My code:

function mymodule_form_submit($form, &$form_state) {
  $testcases_raw = array...
  $batch = array(
    'title' => t('Working ...'),
    'operations' => array(),
    'finished' => 'mymodule_batch_finished',
    'init_message' => t('Starting ...'),
    'progress_message' => t('Processed @current out of @total.'),
    'error_message' => t('An error occurred during processing'),
    'progressive' => FALSE
  );

  if (isset($testcases_raw['Entity'][0])) {
    foreach ($testcases_raw['Entity'] as $folder) {
      $batch['operations'][] = array('batch_testsets_multiple', array($folder));
    }
  } else {
    $batch['operations'][] = array('batch_testsets_single', array($testcases_raw));
  }
  batch_set($batch);
}

function batch_testsets_multiple($folder, &$context) {
  $a = $folder;

  $id = $a['Fields']['Field'][51]['Value'];
  $parent_id = $a['Fields']['Field'][28]['Value'];
  $name = $a['Fields']['Field'][54]['Value'];

  $testset = array('id' => $id, 'parent_id' => $parent_id, 'name' => $name);
  array_push($testsets, $testset);
  dd($testset);         
  $context['results'] = $testsets;
  $context['message'] = $testsets;
}

function batch_testsets_single($folder, &$context) {
  $testsets = $context['results'];
  $id = $folder['Entity']['Fields']['Field'][51]['Value'];
  $parent_id = $folder['Entity']['Fields']['Field'][28]['Value'];
  $name = $folder['Entity']['Fields']['Field'][54]['Value'];

  $testset = array('id' => $id, 'parent_id' => $parent_id, 'name' => $name);
  array_push($testsets, $testset);

  $context['results'] = $testsets;
  $context['message'] = $testsets;
}

function mymodule_batch_finished($success, $results, $operations) {
  if ($success) {
    $message = format_plural(count($results), 'One processed.', '@count processed');
  } else {
    $message = t('Finished with an error.');
  }
  foreach ($results as $result) {
    drupal_set_message($result);
  }
  drupal_set_message($message);
}

In this example, the batch_testsets_multiple function will run 4 times. In each of the iterations I get one new array ($testset). Below are the 4 arrays as outputed to file by dd command:

Array
(
    [id] => 132202
    [parent_id] => 38680
    [name] => _TestSet1
)

Array
(
    [id] => 132203
    [parent_id] => 38680
    [name] => _TestSet2
)

Array
(
    [id] => 132345
    [parent_id] => 38797
    [name] => _TestSet3
)

Array
(
    [id] => 132394
    [parent_id] => 38831
    [name] => _TestSet4
)

What I need at the end of the batch opearation batch_testsets_multiple is an array with the 4 arrays above so I can use that array as input for a second operation. I think this code is simplier to understand. Hope it really helps.

2 Answers 2

1

OK, after some struggle I found the solution and it's very simple (maybe I was complicating?).

Here is how my solution looks like:

function batch_testsets_multiple($folder, &$context) {
  $id = $folder['Fields']['Field'][51]['Value'];
  $parent_id = $folder['Fields']['Field'][28]['Value'];
  $name = $folder['Fields']['Field'][54]['Value'];

  $testset = array('id' => $id, 'parent_id' => $parent_id, 'name' => $name);

  // Here I save the iteration results to an array.
  // The [] ensures that all iteration results ($testset) are saved;
  $context['results']['testsets'][] = $testset;
  $context['message'] = $testsets;
}
0

You can use $context['results'] to pass data between operations.

function first_data_batch($data, &$context) {
  // Get the data from previous operation.
  $bar = $context['results']['foo'];

  // Do something with it...

  // And store the results for the next operation. 
  $context['results']['foo'] = $bar;
}
5
  • Thanks typologist. I think that stores the results to reuse in the same operation. I need to store an array to use in a second operation. My first tought was that I could access that data in the 'first_data_batch_finished' function but I think it does not work like that. Maybe I'm wrong?
    – zephirus
    Oct 27, 2015 at 9:10
  • No. The $context['results'] variable is available in all operations, so if you save your first operation's array results in it, you'll be able to use them in your next operation. Did you try the code?
    – typologist
    Oct 27, 2015 at 14:50
  • Hi typologist. Imagine I use your code like this: $bar = $context['results']['foo'] + 1; Can I see this value when the operation is finished?
    – zephirus
    Oct 29, 2015 at 1:20
  • The $context variable is referenced. It means that whatever changes you do to it will be available for the next function. If in your first operation you do this $context['results']['foo'] = 'hello'; and in your second operation you do echo $context['results']['foo']; it will print 'hello'. In simple terms, do whatever you want to your array in each operation and assign those values to the $context['results'] variable so you can use them in the following operations.
    – typologist
    Oct 29, 2015 at 5:09
  • Hi @typologist, I tried everything and I still can't get the results I want. I edit the question and added a second code that I made after some heavy refactoring. Hope it's a simple question. And thanks again!
    – zephirus
    Nov 1, 2015 at 22:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.