diff --git a/includes/batch.inc b/includes/batch.inc index 9a4f8271fb6..1efeb64702b 100644 --- a/includes/batch.inc +++ b/includes/batch.inc @@ -16,6 +16,26 @@ * @see batch_get() */ +/** + * Loads a batch from the database. + * + * @param $id + * The ID of the batch to load. When a progressive batch is being processed, + * the relevant ID is found in $_REQUEST['id']. + * @return + * An array representing the batch, or FALSE if no batch was found. + */ +function batch_load($id) { + $batch = db_query("SELECT batch FROM {batch} WHERE bid = :bid AND token = :token", array( + ':bid' => $id, + ':token' => drupal_get_token($id), + ))->fetchField(); + if ($batch) { + return unserialize($batch); + } + return FALSE; +} + /** * State-based dispatcher for the batch processing page. * @@ -28,19 +48,15 @@ function _batch_page() { return FALSE; } - // Retrieve the current state of batch from db. - $batch = db_query("SELECT batch FROM {batch} WHERE bid = :bid AND token = :token", array( - ':bid' => $_REQUEST['id'], - ':token' => drupal_get_token($_REQUEST['id'])) - )->fetchField(); - + // Retrieve the current state of the batch. if (!$batch) { - drupal_set_message(t('No active batch.'), 'error'); - drupal_goto(); + $batch = batch_load($_REQUEST['id']); + if (!$batch) { + drupal_set_message(t('No active batch.'), 'error'); + drupal_goto(); + } } - $batch = unserialize($batch); - // Register database update for the end of processing. register_shutdown_function('_batch_shutdown'); diff --git a/modules/simpletest/tests/batch.test b/modules/simpletest/tests/batch.test index a3ace7b9e3b..897e8a803d6 100644 --- a/modules/simpletest/tests/batch.test +++ b/modules/simpletest/tests/batch.test @@ -6,6 +6,40 @@ * Unit tests for the Drupal Batch API. */ +/** + * Tests for the batch API progress page theme. + */ +class BatchAPIThemeTestCase extends DrupalWebTestCase { + public static function getInfo() { + return array( + 'name' => 'Batch API progress page theme', + 'description' => 'Tests that while a progressive batch is running, it correctly uses the theme of the page that started the batch.', + 'group' => 'Batch API', + ); + } + + function setUp() { + parent::setUp('system_test'); + // Make sure that the page which starts the batch (an administrative page) + // is using a different theme than would normally be used by the batch API. + variable_set('theme_default', 'garland'); + variable_set('admin_theme', 'seven'); + } + + /** + * Tests that the batch API progress page uses the correct theme. + */ + function testBatchAPIProgressPageTheme() { + // Visit an administrative page that runs a test batch, and check that the + // theme that was used during batch execution (which the batch callback + // function saved as a variable) matches the theme used on the + // administrative page. + $this->drupalGet('admin/system-test/batch-theme'); + $batch_theme_used = variable_get('system_test_batch_theme_used', 'garland'); + $this->assertEqual($batch_theme_used, 'seven', t('A progressive batch correctly uses the theme of the page that started the batch.')); + } +} + /** * Tests the function _batch_api_percentage() to make sure that the rounding * works properly in all cases. diff --git a/modules/simpletest/tests/system_test.module b/modules/simpletest/tests/system_test.module index be4d443f587..6703055366f 100644 --- a/modules/simpletest/tests/system_test.module +++ b/modules/simpletest/tests/system_test.module @@ -5,6 +5,11 @@ * Implement hook_menu(). */ function system_test_menu() { + $items['admin/system-test/batch-theme'] = array( + 'page callback' => 'system_test_batch_theme', + 'access callback' => TRUE, + 'type' => MENU_CALLBACK, + ); $items['system-test/sleep/%'] = array( 'page callback' => 'system_test_sleep', 'page arguments' => array(2), @@ -97,6 +102,34 @@ function system_test_menu() { return $items; } +/** + * Menu callback; start a new batch for testing the batch progress page theme. + */ +function system_test_batch_theme() { + $batch = array( + 'operations' => array( + array('system_test_batch_theme_callback', array()), + ), + ); + batch_set($batch); + // Force the batch to redirect to some page other than this one (to avoid an + // infinite loop). + batch_process('node'); +} + +/** + * Batch callback function for testing the theme used by a batch. + */ +function system_test_batch_theme_callback() { + // Because drupalGet() steps through the full progressive batch before + // returning control to the test function, we cannot test that the correct + // theme is being used on the batch processing page by viewing that page + // directly. Instead, we save the theme being used in a variable here, so + // that it can be loaded and inspected in the thread running the test. + global $theme; + variable_set('system_test_batch_theme_used', $theme); +} + function system_test_sleep($seconds) { sleep($seconds); } diff --git a/modules/system/system.admin.inc b/modules/system/system.admin.inc index aa1d2e9d12a..7e672950f84 100644 --- a/modules/system/system.admin.inc +++ b/modules/system/system.admin.inc @@ -2054,10 +2054,6 @@ function system_batch_page() { require_once DRUPAL_ROOT . '/includes/batch.inc'; $output = _batch_page(); - // Use the same theme that the page that started the batch. - $batch = &batch_get(); - $GLOBALS['custom_theme'] = $batch['theme']; - if ($output === FALSE) { drupal_access_denied(); } diff --git a/modules/system/system.module b/modules/system/system.module index 4b69e964b97..7398653ad6e 100644 --- a/modules/system/system.module +++ b/modules/system/system.module @@ -993,12 +993,29 @@ function system_menu() { $items['batch'] = array( 'page callback' => 'system_batch_page', 'access callback' => TRUE, + 'theme callback' => '_system_batch_theme', 'type' => MENU_CALLBACK, 'file' => 'system.admin.inc', ); return $items; } +/** + * Theme callback for the default batch page. + */ +function _system_batch_theme() { + // Retrieve the current state of the batch. + $batch = &batch_get(); + if (!$batch && isset($_REQUEST['id'])) { + require_once DRUPAL_ROOT . '/includes/batch.inc'; + $batch = batch_load($_REQUEST['id']); + } + // Use the same theme as the page that started the batch. + if (!empty($batch['theme'])) { + return $batch['theme']; + } +} + /** * Implementation of hook_library(). */