Looking through the Drupal documentation, a person is led to believe that automating a Batch script is tantamount to moving Mount Fuji 10 feet to the left with a wooden spoon. The general consensus seems to be that all Batch scripts should be converted to use the Queue API. Sometimes this is an acceptable solution, but when you’re running a very large script that makes extensive use of the Batch $context variable, it becomes a daunting task.
The big issue (or at least the issue I ran into) with Batch and cron, is that the Batch API was really written to be used in conjunction with the browser, so there are calls made to update the progress bar that just don’t jive when running in cron.
The solution that worked for me was a bit of a hack, but only a small one. If we look over the batch_process() documentation, there’s a telling bit of information: “Unless the batch has been marked with ‘progressive’ = FALSE, the function issues a drupal_goto and thus ends page execution.” That sounded positive, and from what I could tell it bypasses the progress bar and executes the batch in one pass.
Now the problem is that even though we are given this information, there’s no parameter to change this variable. It looks like an oversight by the developers. Instead of hacking the core though, what we can do is create a reference to batch_get and turn off the progressive option.
// create a reference to batch_get()
// this is called directly in the core batch_process() function
$batch =& batch_get();
// Using the reference, we turn progressive off
// which prevents the redirect to the standard Batch API progress bar
$batch['progressive'] = FALSE;
// Because we are not using the form to trigger the batch, we run batch_process('')
batch_process('');
So let’s take a look at how this would work:
hook_cron(){
hook_my_function();
}
hook_my_function(){
batch_set(array(
'title' => My Title',
'operations' => array(
array(‘hook_another_function_to_run’, array($info))
),
'progress_message' => 'Processing...',
));
$batch =& batch_get();
$batch['progressive'] = FALSE;
batch_process('');
}
Now there may be some issues with this implementation that I am unaware of, but I am running a rather large Batch script and have yet to come across any issues.
Hope this helps someone!