From 3d1be9b5ca8cf7baadeb2e86665c080526d805cf Mon Sep 17 00:00:00 2001 From: David Rothstein Date: Mon, 12 Oct 2015 00:54:08 -0400 Subject: Issue #2342667 by claudiu.cristea, Dave Reid, ndobromirov: Cron and batch processing of queues are not accepting callables --- CHANGELOG.txt | 3 +++ includes/batch.inc | 4 ++-- includes/common.inc | 4 ++-- modules/system/system.test | 19 ++++++++++++++++++- modules/system/tests/cron_queue_test.module | 12 ++++++++++++ 5 files changed, 37 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index c0b63c861..ce4501782 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,6 +1,9 @@ Drupal 7.40, xxxx-xx-xx (development version) ----------------------- +- The "worker callback" provided in hook_cron_queue_info() and the "finished" + callback specified during batch processing can now be any PHP callable + instead of just functions. - Prevented drupal_set_time_limit() from decreasing the time limit in the case where the PHP maximum execution time is already unlimited. - Changed the default thousand marker for numeric fields from a space ("1 000") diff --git a/includes/batch.inc b/includes/batch.inc index 061acd4c6..e89ab8dec 100644 --- a/includes/batch.inc +++ b/includes/batch.inc @@ -460,10 +460,10 @@ function _batch_finished() { if (isset($batch_set['file']) && is_file($batch_set['file'])) { include_once DRUPAL_ROOT . '/' . $batch_set['file']; } - if (function_exists($batch_set['finished'])) { + if (is_callable($batch_set['finished'])) { $queue = _batch_queue($batch_set); $operations = $queue->getAllItems(); - $batch_set['finished']($batch_set['success'], $batch_set['results'], $operations, format_interval($batch_set['elapsed'] / 1000)); + call_user_func($batch_set['finished'], $batch_set['success'], $batch_set['results'], $operations, format_interval($batch_set['elapsed'] / 1000)); } } } diff --git a/includes/common.inc b/includes/common.inc index e863f411f..5268fd830 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -5380,12 +5380,12 @@ function drupal_cron_run() { // Do not run if queue wants to skip. continue; } - $function = $info['worker callback']; + $callback = $info['worker callback']; $end = time() + (isset($info['time']) ? $info['time'] : 15); $queue = DrupalQueue::get($queue_name); while (time() < $end && ($item = $queue->claimItem())) { try { - $function($item->data); + call_user_func($callback, $item->data); $queue->deleteItem($item); } catch (Exception $e) { diff --git a/modules/system/system.test b/modules/system/system.test index 6e5f2b358..2865bbb25 100644 --- a/modules/system/system.test +++ b/modules/system/system.test @@ -923,7 +923,7 @@ class CronQueueTestCase extends DrupalWebTestCase { } function setUp() { - parent::setUp(array('common_test', 'common_test_cron_helper')); + parent::setUp(array('common_test', 'common_test_cron_helper', 'cron_queue_test')); } /** @@ -943,6 +943,23 @@ class CronQueueTestCase extends DrupalWebTestCase { $this->assertEqual($queue->numberOfItems(), 1, 'Failing item still in the queue after throwing an exception.'); } + /** + * Tests worker defined as a class method callable. + */ + function testCallable() { + $queue = DrupalQueue::get('cron_queue_test_callback'); + + // Enqueue an item for processing. + $queue->createItem(array($this->randomName() => $this->randomName())); + + // Run cron; the worker should perform the task and delete the item from the + // queue. + $this->cronRun(); + + // The queue should be empty. + $this->assertEqual($queue->numberOfItems(), 0); + } + } class AdminMetaTagTestCase extends DrupalWebTestCase { diff --git a/modules/system/tests/cron_queue_test.module b/modules/system/tests/cron_queue_test.module index e95c6b6af..0df6396a6 100644 --- a/modules/system/tests/cron_queue_test.module +++ b/modules/system/tests/cron_queue_test.module @@ -7,9 +7,21 @@ function cron_queue_test_cron_queue_info() { $queues['cron_queue_test_exception'] = array( 'worker callback' => 'cron_queue_test_exception', ); + $queues['cron_queue_test_callback'] = array( + 'worker callback' => array('CronQueueTestCallbackClass', 'foo'), + ); + return $queues; } function cron_queue_test_exception($item) { throw new Exception('That is not supposed to happen.'); } + +class CronQueueTestCallbackClass { + + static public function foo() { + // Do nothing. + } + +} -- cgit v1.2.3