batch_test.module

Same filename in other branches
  1. 9 core/modules/system/tests/modules/batch_test/batch_test.module
  2. 8.9.x core/modules/system/tests/modules/batch_test/batch_test.module
  3. 10 core/modules/system/tests/modules/batch_test/batch_test.module
  4. 11.x core/modules/system/tests/modules/batch_test/batch_test.module

Helper module for the Batch API tests.

File

modules/simpletest/tests/batch_test.module

View source
<?php


/**
 * @file
 * Helper module for the Batch API tests.
 */

/**
 * Implement hook_menu().
 */
function batch_test_menu() {
    $items = array();
    $items['batch-test'] = array(
        'title' => 'Batch test',
        'page callback' => 'drupal_get_form',
        'page arguments' => array(
            'batch_test_simple_form',
        ),
        'access callback' => TRUE,
    );
    // Simple form: one submit handler, setting a batch.
    $items['batch-test/simple'] = array(
        'title' => 'Simple',
        'type' => MENU_DEFAULT_LOCAL_TASK,
        'weight' => 0,
    );
    // Multistep form: two steps, each setting a batch.
    $items['batch-test/multistep'] = array(
        'title' => 'Multistep',
        'page callback' => 'drupal_get_form',
        'page arguments' => array(
            'batch_test_multistep_form',
        ),
        'access callback' => TRUE,
        'type' => MENU_LOCAL_TASK,
        'weight' => 1,
    );
    // Chained form: four submit handlers, several of which set a batch.
    $items['batch-test/chained'] = array(
        'title' => 'Chained',
        'page callback' => 'drupal_get_form',
        'page arguments' => array(
            'batch_test_chained_form',
        ),
        'access callback' => TRUE,
        'type' => MENU_LOCAL_TASK,
        'weight' => 2,
    );
    // Programmatic form: the page submits the 'Chained' form through
    // drupal_form_submit().
    $items['batch-test/programmatic'] = array(
        'title' => 'Programmatic',
        'page callback' => 'batch_test_programmatic',
        'access callback' => TRUE,
        'type' => MENU_LOCAL_TASK,
        'weight' => 3,
    );
    // No form: fire a batch simply by accessing a page.
    $items['batch-test/no-form'] = array(
        'title' => 'Simple page',
        'page callback' => 'batch_test_no_form',
        'access callback' => TRUE,
        'type' => MENU_LOCAL_TASK,
        'weight' => 4,
    );
    // No form: fire a batch; return > 100% complete
    $items['batch-test/large-percentage'] = array(
        'title' => 'Simple page with batch over 100% complete',
        'page callback' => 'batch_test_large_percentage',
        'access callback' => TRUE,
        'type' => MENU_LOCAL_TASK,
        'weight' => 5,
    );
    // Tests programmatic form submission within a batch operation.
    $items['batch-test/nested-programmatic'] = array(
        'title' => 'Nested programmatic',
        'page callback' => 'batch_test_nested_drupal_form_submit',
        'access callback' => TRUE,
        'type' => MENU_LOCAL_TASK,
        'weight' => 6,
    );
    // Landing page to test redirects.
    $items['batch-test/redirect'] = array(
        'title' => 'Redirect',
        'page callback' => 'batch_test_redirect_page',
        'access callback' => TRUE,
        'type' => MENU_LOCAL_TASK,
        'weight' => 7,
    );
    // This item lives under 'admin' so that the page uses the admin theme.
    $items['admin/batch-test/test-theme'] = array(
        'page callback' => 'batch_test_theme_batch',
        'access callback' => TRUE,
        'type' => MENU_CALLBACK,
    );
    return $items;
}

/**
 * Simple form.
 */
function batch_test_simple_form() {
    $form['batch'] = array(
        '#type' => 'select',
        '#title' => 'Choose batch',
        '#options' => array(
            'batch_0' => 'batch 0',
            'batch_1' => 'batch 1',
            'batch_2' => 'batch 2',
            'batch_3' => 'batch 3',
            'batch_4' => 'batch 4',
        ),
    );
    $form['submit'] = array(
        '#type' => 'submit',
        '#value' => 'Submit',
    );
    return $form;
}

/**
 * Submit handler for the simple form.
 */
function batch_test_simple_form_submit($form, &$form_state) {
    batch_test_stack(NULL, TRUE);
    $function = '_batch_test_' . $form_state['values']['batch'];
    batch_set($function());
    $form_state['redirect'] = 'batch-test/redirect';
}

/**
 * Multistep form.
 */
function batch_test_multistep_form($form, &$form_state) {
    if (empty($form_state['storage']['step'])) {
        $form_state['storage']['step'] = 1;
    }
    $form['step_display'] = array(
        '#markup' => 'step ' . $form_state['storage']['step'] . '<br/>',
    );
    $form['submit'] = array(
        '#type' => 'submit',
        '#value' => 'Submit',
    );
    return $form;
}

/**
 * Submit handler for the multistep form.
 */
function batch_test_multistep_form_submit($form, &$form_state) {
    batch_test_stack(NULL, TRUE);
    switch ($form_state['storage']['step']) {
        case 1:
            batch_set(_batch_test_batch_1());
            break;
        case 2:
            batch_set(_batch_test_batch_2());
            break;
    }
    if ($form_state['storage']['step'] < 2) {
        $form_state['storage']['step']++;
        $form_state['rebuild'] = TRUE;
    }
    // This will only be effective on the last step.
    $form_state['redirect'] = 'batch-test/redirect';
}

/**
 * Form with chained submit callbacks.
 */
function batch_test_chained_form() {
    // This value is used to test that $form_state persists through batched
    // submit handlers.
    $form['value'] = array(
        '#type' => 'textfield',
        '#title' => 'Value',
        '#default_value' => 1,
    );
    $form['submit'] = array(
        '#type' => 'submit',
        '#value' => 'Submit',
    );
    $form['#submit'] = array(
        'batch_test_chained_form_submit_1',
        'batch_test_chained_form_submit_2',
        'batch_test_chained_form_submit_3',
        'batch_test_chained_form_submit_4',
    );
    return $form;
}

/**
 * Submit handler #1 for the chained form.
 */
function batch_test_chained_form_submit_1($form, &$form_state) {
    batch_test_stack(NULL, TRUE);
    batch_test_stack('submit handler 1');
    batch_test_stack('value = ' . $form_state['values']['value']);
    $form_state['values']['value']++;
    batch_set(_batch_test_batch_1());
    // This redirect should not be taken into account.
    $form_state['redirect'] = 'should/be/discarded';
}

/**
 * Submit handler #2 for the chained form.
 */
function batch_test_chained_form_submit_2($form, &$form_state) {
    batch_test_stack('submit handler 2');
    batch_test_stack('value = ' . $form_state['values']['value']);
    $form_state['values']['value']++;
    batch_set(_batch_test_batch_2());
    // This redirect should not be taken into account.
    $form_state['redirect'] = 'should/be/discarded';
}

/**
 * Submit handler #3 for the chained form.
 */
function batch_test_chained_form_submit_3($form, &$form_state) {
    batch_test_stack('submit handler 3');
    batch_test_stack('value = ' . $form_state['values']['value']);
    $form_state['values']['value']++;
    // This redirect should not be taken into account.
    $form_state['redirect'] = 'should/be/discarded';
}

/**
 * Submit handler #4 for the chained form.
 */
function batch_test_chained_form_submit_4($form, &$form_state) {
    batch_test_stack('submit handler 4');
    batch_test_stack('value = ' . $form_state['values']['value']);
    $form_state['values']['value']++;
    batch_set(_batch_test_batch_3());
    // This is the redirect that should prevail.
    $form_state['redirect'] = 'batch-test/redirect';
}

/**
 * Menu callback: programmatically submits the 'Chained' form.
 */
function batch_test_programmatic($value = 1) {
    $form_state = array(
        'values' => array(
            'value' => $value,
        ),
    );
    drupal_form_submit('batch_test_chained_form', $form_state);
    return 'Got out of a programmatic batched form.';
}

/**
 * Menu callback: programmatically submits a form within a batch.
 */
function batch_test_nested_drupal_form_submit($value = 1) {
    // Set the batch and process it.
    $batch['operations'] = array(
        array(
            '_batch_test_nested_drupal_form_submit_callback',
            array(
                $value,
            ),
        ),
    );
    batch_set($batch);
    batch_process('batch-test/redirect');
}

/**
 * Batch operation: submits form_test_mock_form using drupal_form_submit().
 */
function _batch_test_nested_drupal_form_submit_callback($value) {
    $state['values']['test_value'] = $value;
    drupal_form_submit('batch_test_mock_form', $state);
}

/**
 * A simple form with a textfield and submit button.
 */
function batch_test_mock_form($form, $form_state) {
    $form['test_value'] = array(
        '#type' => 'textfield',
    );
    $form['submit'] = array(
        '#type' => 'submit',
        '#value' => t('Submit'),
    );
    return $form;
}

/**
 * Submit handler for the batch_test_mock form.
 */
function batch_test_mock_form_submit($form, &$form_state) {
    batch_test_stack('mock form submitted with value = ' . $form_state['values']['test_value']);
}

/**
 * Menu callback: fire a batch process without a form submission.
 */
function batch_test_no_form() {
    batch_test_stack(NULL, TRUE);
    batch_set(_batch_test_batch_1());
    batch_process('batch-test/redirect');
}

/**
 * Menu callback: fire a batch process without a form submission.
 */
function batch_test_large_percentage() {
    batch_test_stack(NULL, TRUE);
    batch_set(_batch_test_batch_5());
    batch_process('batch-test/redirect');
}

/**
 * Menu callback: successful redirection.
 */
function batch_test_redirect_page() {
    return 'Redirection successful.';
}

/**
 * Batch 0: no operation.
 */
function _batch_test_batch_0() {
    $batch = array(
        'operations' => array(),
        'finished' => '_batch_test_finished_0',
        'file' => drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc',
    );
    return $batch;
}

/**
 * Batch 1: repeats a simple operation.
 *
 * Operations: op 1 from 1 to 10.
 */
function _batch_test_batch_1() {
    // Ensure the batch takes at least two iterations.
    $total = 10;
    $sleep = 1000000 / $total * 2;
    $operations = array();
    for ($i = 1; $i <= $total; $i++) {
        $operations[] = array(
            '_batch_test_callback_1',
            array(
                $i,
                $sleep,
            ),
        );
    }
    $batch = array(
        'operations' => $operations,
        'finished' => '_batch_test_finished_1',
        'file' => drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc',
    );
    return $batch;
}

/**
 * Batch 2: single multistep operation.
 *
 * Operations: op 2 from 1 to 10.
 */
function _batch_test_batch_2() {
    // Ensure the batch takes at least two iterations.
    $total = 10;
    $sleep = 1000000 / $total * 2;
    $operations = array(
        array(
            '_batch_test_callback_2',
            array(
                1,
                $total,
                $sleep,
            ),
        ),
    );
    $batch = array(
        'operations' => $operations,
        'finished' => '_batch_test_finished_2',
        'file' => drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc',
    );
    return $batch;
}

/**
 * Batch 3: both single and multistep operations.
 *
 * Operations:
 * - op 1 from 1 to 5,
 * - op 2 from 1 to 5,
 * - op 1 from 6 to 10,
 * - op 2 from 6 to 10.
 */
function _batch_test_batch_3() {
    // Ensure the batch takes at least two iterations.
    $total = 10;
    $sleep = 1000000 / $total * 2;
    $operations = array();
    for ($i = 1; $i <= round($total / 2); $i++) {
        $operations[] = array(
            '_batch_test_callback_1',
            array(
                $i,
                $sleep,
            ),
        );
    }
    $operations[] = array(
        '_batch_test_callback_2',
        array(
            1,
            $total / 2,
            $sleep,
        ),
    );
    for ($i = round($total / 2) + 1; $i <= $total; $i++) {
        $operations[] = array(
            '_batch_test_callback_1',
            array(
                $i,
                $sleep,
            ),
        );
    }
    $operations[] = array(
        '_batch_test_callback_2',
        array(
            6,
            $total / 2,
            $sleep,
        ),
    );
    $batch = array(
        'operations' => $operations,
        'finished' => '_batch_test_finished_3',
        'file' => drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc',
    );
    return $batch;
}

/**
 * Batch 4: batch within a batch.
 *
 * Operations:
 * - op 1 from 1 to 5,
 * - set batch 2 (op 2 from 1 to 10, should run at the end)
 * - op 1 from 6 to 10,
 */
function _batch_test_batch_4() {
    // Ensure the batch takes at least two iterations.
    $total = 10;
    $sleep = 1000000 / $total * 2;
    $operations = array();
    for ($i = 1; $i <= round($total / 2); $i++) {
        $operations[] = array(
            '_batch_test_callback_1',
            array(
                $i,
                $sleep,
            ),
        );
    }
    $operations[] = array(
        '_batch_test_nested_batch_callback',
        array(),
    );
    for ($i = round($total / 2) + 1; $i <= $total; $i++) {
        $operations[] = array(
            '_batch_test_callback_1',
            array(
                $i,
                $sleep,
            ),
        );
    }
    $batch = array(
        'operations' => $operations,
        'finished' => '_batch_test_finished_4',
        'file' => drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc',
    );
    return $batch;
}

/**
 * Batch 5: repeats a simple operation.
 *
 * Operations: op 1 from 1 to 10.
 */
function _batch_test_batch_5() {
    // Ensure the batch takes at least two iterations.
    $total = 10;
    $sleep = 1000000 / $total * 2;
    $operations = array();
    for ($i = 1; $i <= $total; $i++) {
        $operations[] = array(
            '_batch_test_callback_5',
            array(
                $i,
                $sleep,
            ),
        );
    }
    $batch = array(
        'operations' => $operations,
        'finished' => '_batch_test_finished_5',
        'file' => drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc',
    );
    return $batch;
}

/**
 * Menu callback: run a batch for testing theme used on the progress page.
 */
function batch_test_theme_batch() {
    batch_test_stack(NULL, TRUE);
    $batch = array(
        'operations' => array(
            array(
                '_batch_test_theme_callback',
                array(),
            ),
        ),
    );
    batch_set($batch);
    batch_process('batch-test/redirect');
}

/**
 * Batch callback function for testing the theme used on the progress page.
 */
function _batch_test_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;
    batch_test_stack($theme);
}

/**
 * Helper function: store or retrieve traced execution data.
 */
function batch_test_stack($data = NULL, $reset = FALSE) {
    if ($reset) {
        variable_del('batch_test_stack');
    }
    if (!isset($data)) {
        return variable_get('batch_test_stack', array());
    }
    $stack = variable_get('batch_test_stack', array());
    $stack[] = $data;
    variable_set('batch_test_stack', $stack);
}

Functions

Title Deprecated Summary
batch_test_chained_form Form with chained submit callbacks.
batch_test_chained_form_submit_1 Submit handler #1 for the chained form.
batch_test_chained_form_submit_2 Submit handler #2 for the chained form.
batch_test_chained_form_submit_3 Submit handler #3 for the chained form.
batch_test_chained_form_submit_4 Submit handler #4 for the chained form.
batch_test_large_percentage Menu callback: fire a batch process without a form submission.
batch_test_menu Implement hook_menu().
batch_test_mock_form A simple form with a textfield and submit button.
batch_test_mock_form_submit Submit handler for the batch_test_mock form.
batch_test_multistep_form Multistep form.
batch_test_multistep_form_submit Submit handler for the multistep form.
batch_test_nested_drupal_form_submit Menu callback: programmatically submits a form within a batch.
batch_test_no_form Menu callback: fire a batch process without a form submission.
batch_test_programmatic Menu callback: programmatically submits the 'Chained' form.
batch_test_redirect_page Menu callback: successful redirection.
batch_test_simple_form Simple form.
batch_test_simple_form_submit Submit handler for the simple form.
batch_test_stack Helper function: store or retrieve traced execution data.
batch_test_theme_batch Menu callback: run a batch for testing theme used on the progress page.
_batch_test_batch_0 Batch 0: no operation.
_batch_test_batch_1 Batch 1: repeats a simple operation.
_batch_test_batch_2 Batch 2: single multistep operation.
_batch_test_batch_3 Batch 3: both single and multistep operations.
_batch_test_batch_4 Batch 4: batch within a batch.
_batch_test_batch_5 Batch 5: repeats a simple operation.
_batch_test_nested_drupal_form_submit_callback Batch operation: submits form_test_mock_form using drupal_form_submit().
_batch_test_theme_callback Batch callback function for testing the theme used on the progress page.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.