cms/drupal/modules/simpletest/tests/batch_test.module
changeset 541 e756a8c72c3d
equal deleted inserted replaced
540:07239de796bb 541:e756a8c72c3d
       
     1 <?php
       
     2 
       
     3 /**
       
     4  * @file
       
     5  * Helper module for the Batch API tests.
       
     6  */
       
     7 
       
     8 /**
       
     9  * Implement hook_menu().
       
    10  */
       
    11 function batch_test_menu() {
       
    12   $items = array();
       
    13 
       
    14   $items['batch-test'] = array(
       
    15     'title' => 'Batch test',
       
    16     'page callback' => 'drupal_get_form',
       
    17     'page arguments' => array('batch_test_simple_form'),
       
    18     'access callback' => TRUE,
       
    19   );
       
    20   // Simple form: one submit handler, setting a batch.
       
    21   $items['batch-test/simple'] = array(
       
    22     'title' => 'Simple',
       
    23     'type' => MENU_DEFAULT_LOCAL_TASK,
       
    24     'weight' => 0,
       
    25   );
       
    26   // Multistep form: two steps, each setting a batch.
       
    27   $items['batch-test/multistep'] = array(
       
    28     'title' => 'Multistep',
       
    29     'page callback' => 'drupal_get_form',
       
    30     'page arguments' => array('batch_test_multistep_form'),
       
    31     'access callback' => TRUE,
       
    32     'type' => MENU_LOCAL_TASK,
       
    33     'weight' => 1,
       
    34   );
       
    35   // Chained form: four submit handlers, several of which set a batch.
       
    36   $items['batch-test/chained'] = array(
       
    37     'title' => 'Chained',
       
    38     'page callback' => 'drupal_get_form',
       
    39     'page arguments' => array('batch_test_chained_form'),
       
    40     'access callback' => TRUE,
       
    41     'type' => MENU_LOCAL_TASK,
       
    42     'weight' => 2,
       
    43   );
       
    44   // Programmatic form: the page submits the 'Chained' form through
       
    45   // drupal_form_submit().
       
    46   $items['batch-test/programmatic'] = array(
       
    47     'title' => 'Programmatic',
       
    48     'page callback' => 'batch_test_programmatic',
       
    49     'access callback' => TRUE,
       
    50     'type' => MENU_LOCAL_TASK,
       
    51     'weight' => 3,
       
    52   );
       
    53   // No form: fire a batch simply by accessing a page.
       
    54   $items['batch-test/no-form'] = array(
       
    55     'title' => 'Simple page',
       
    56     'page callback' => 'batch_test_no_form',
       
    57     'access callback' => TRUE,
       
    58     'type' => MENU_LOCAL_TASK,
       
    59     'weight' => 4,
       
    60   );
       
    61   // No form: fire a batch; return > 100% complete
       
    62   $items['batch-test/large-percentage'] = array(
       
    63     'title' => 'Simple page with batch over 100% complete',
       
    64     'page callback' => 'batch_test_large_percentage',
       
    65     'access callback' => TRUE,
       
    66     'type' => MENU_LOCAL_TASK,
       
    67     'weight' => 5,
       
    68   );
       
    69   // Tests programmatic form submission within a batch operation.
       
    70   $items['batch-test/nested-programmatic'] = array(
       
    71     'title' => 'Nested programmatic',
       
    72     'page callback' => 'batch_test_nested_drupal_form_submit',
       
    73     'access callback' => TRUE,
       
    74     'type' => MENU_LOCAL_TASK,
       
    75     'weight' => 6,
       
    76   );
       
    77   // Landing page to test redirects.
       
    78   $items['batch-test/redirect'] = array(
       
    79     'title' => 'Redirect',
       
    80     'page callback' => 'batch_test_redirect_page',
       
    81     'access callback' => TRUE,
       
    82     'type' => MENU_LOCAL_TASK,
       
    83     'weight' => 7,
       
    84   );
       
    85   // This item lives under 'admin' so that the page uses the admin theme.
       
    86   $items['admin/batch-test/test-theme'] = array(
       
    87     'page callback' => 'batch_test_theme_batch',
       
    88     'access callback' => TRUE,
       
    89     'type' => MENU_CALLBACK,
       
    90   );
       
    91 
       
    92   return $items;
       
    93 }
       
    94 
       
    95 /**
       
    96  * Simple form.
       
    97  */
       
    98 function batch_test_simple_form() {
       
    99   $form['batch'] = array(
       
   100     '#type' => 'select',
       
   101     '#title' => 'Choose batch',
       
   102     '#options' => array(
       
   103       'batch_0' => 'batch 0',
       
   104       'batch_1' => 'batch 1',
       
   105       'batch_2' => 'batch 2',
       
   106       'batch_3' => 'batch 3',
       
   107       'batch_4' => 'batch 4',
       
   108     ),
       
   109   );
       
   110   $form['submit'] = array(
       
   111     '#type' => 'submit',
       
   112     '#value' => 'Submit',
       
   113   );
       
   114 
       
   115   return $form;
       
   116 }
       
   117 
       
   118 /**
       
   119  * Submit handler for the simple form.
       
   120  */
       
   121 function batch_test_simple_form_submit($form, &$form_state) {
       
   122   batch_test_stack(NULL, TRUE);
       
   123 
       
   124   $function = '_batch_test_' . $form_state['values']['batch'];
       
   125   batch_set($function());
       
   126 
       
   127   $form_state['redirect'] = 'batch-test/redirect';
       
   128 }
       
   129 
       
   130 
       
   131 /**
       
   132  * Multistep form.
       
   133  */
       
   134 function batch_test_multistep_form($form, &$form_state) {
       
   135   if (empty($form_state['storage']['step'])) {
       
   136     $form_state['storage']['step'] = 1;
       
   137   }
       
   138 
       
   139   $form['step_display'] = array(
       
   140     '#markup' => 'step ' . $form_state['storage']['step'] . '<br/>',
       
   141   );
       
   142   $form['submit'] = array(
       
   143     '#type' => 'submit',
       
   144     '#value' => 'Submit',
       
   145   );
       
   146 
       
   147   return $form;
       
   148 }
       
   149 
       
   150 /**
       
   151  * Submit handler for the multistep form.
       
   152  */
       
   153 function batch_test_multistep_form_submit($form, &$form_state) {
       
   154   batch_test_stack(NULL, TRUE);
       
   155 
       
   156   switch ($form_state['storage']['step']) {
       
   157     case 1:
       
   158       batch_set(_batch_test_batch_1());
       
   159       break;
       
   160     case 2:
       
   161       batch_set(_batch_test_batch_2());
       
   162       break;
       
   163   }
       
   164 
       
   165   if ($form_state['storage']['step'] < 2) {
       
   166     $form_state['storage']['step']++;
       
   167     $form_state['rebuild'] = TRUE;
       
   168   }
       
   169 
       
   170   // This will only be effective on the last step.
       
   171   $form_state['redirect'] = 'batch-test/redirect';
       
   172 }
       
   173 
       
   174 /**
       
   175  * Form with chained submit callbacks.
       
   176  */
       
   177 function batch_test_chained_form() {
       
   178   // This value is used to test that $form_state persists through batched
       
   179   // submit handlers.
       
   180   $form['value'] = array(
       
   181     '#type' => 'textfield',
       
   182     '#title' => 'Value',
       
   183     '#default_value' => 1,
       
   184   );
       
   185   $form['submit'] = array(
       
   186     '#type' => 'submit',
       
   187     '#value' => 'Submit',
       
   188   );
       
   189   $form['#submit'] = array(
       
   190     'batch_test_chained_form_submit_1',
       
   191     'batch_test_chained_form_submit_2',
       
   192     'batch_test_chained_form_submit_3',
       
   193     'batch_test_chained_form_submit_4',
       
   194   );
       
   195 
       
   196   return $form;
       
   197 }
       
   198 
       
   199 /**
       
   200  * Submit handler #1 for the chained form.
       
   201  */
       
   202 function batch_test_chained_form_submit_1($form, &$form_state) {
       
   203   batch_test_stack(NULL, TRUE);
       
   204 
       
   205   batch_test_stack('submit handler 1');
       
   206   batch_test_stack('value = ' . $form_state['values']['value']);
       
   207 
       
   208   $form_state['values']['value']++;
       
   209   batch_set(_batch_test_batch_1());
       
   210 
       
   211   // This redirect should not be taken into account.
       
   212   $form_state['redirect'] = 'should/be/discarded';
       
   213 }
       
   214 
       
   215 /**
       
   216  * Submit handler #2 for the chained form.
       
   217  */
       
   218 function batch_test_chained_form_submit_2($form, &$form_state) {
       
   219   batch_test_stack('submit handler 2');
       
   220   batch_test_stack('value = ' . $form_state['values']['value']);
       
   221 
       
   222   $form_state['values']['value']++;
       
   223   batch_set(_batch_test_batch_2());
       
   224 
       
   225   // This redirect should not be taken into account.
       
   226   $form_state['redirect'] = 'should/be/discarded';
       
   227 }
       
   228 
       
   229 /**
       
   230  * Submit handler #3 for the chained form.
       
   231  */
       
   232 function batch_test_chained_form_submit_3($form, &$form_state) {
       
   233   batch_test_stack('submit handler 3');
       
   234   batch_test_stack('value = ' . $form_state['values']['value']);
       
   235 
       
   236   $form_state['values']['value']++;
       
   237 
       
   238   // This redirect should not be taken into account.
       
   239   $form_state['redirect'] = 'should/be/discarded';
       
   240 }
       
   241 
       
   242 /**
       
   243  * Submit handler #4 for the chained form.
       
   244  */
       
   245 function batch_test_chained_form_submit_4($form, &$form_state) {
       
   246   batch_test_stack('submit handler 4');
       
   247   batch_test_stack('value = ' . $form_state['values']['value']);
       
   248 
       
   249   $form_state['values']['value']++;
       
   250   batch_set(_batch_test_batch_3());
       
   251 
       
   252   // This is the redirect that should prevail.
       
   253   $form_state['redirect'] = 'batch-test/redirect';
       
   254 }
       
   255 
       
   256 /**
       
   257  * Menu callback: programmatically submits the 'Chained' form.
       
   258  */
       
   259 function batch_test_programmatic($value = 1) {
       
   260   $form_state = array(
       
   261     'values' => array('value' => $value)
       
   262   );
       
   263   drupal_form_submit('batch_test_chained_form', $form_state);
       
   264   return 'Got out of a programmatic batched form.';
       
   265 }
       
   266 
       
   267 /**
       
   268  * Menu callback: programmatically submits a form within a batch.
       
   269  */
       
   270 function batch_test_nested_drupal_form_submit($value = 1) {
       
   271   // Set the batch and process it.
       
   272   $batch['operations'] = array(
       
   273     array('_batch_test_nested_drupal_form_submit_callback', array($value)),
       
   274   );
       
   275   batch_set($batch);
       
   276   batch_process('batch-test/redirect');
       
   277 }
       
   278 
       
   279 /**
       
   280  * Batch operation: submits form_test_mock_form using drupal_form_submit().
       
   281  */
       
   282 function _batch_test_nested_drupal_form_submit_callback($value) {
       
   283   $state['values']['test_value'] = $value;
       
   284   drupal_form_submit('batch_test_mock_form', $state);
       
   285 }
       
   286 
       
   287 /**
       
   288  * A simple form with a textfield and submit button.
       
   289  */
       
   290 function batch_test_mock_form($form, $form_state) {
       
   291   $form['test_value'] = array(
       
   292     '#type' => 'textfield',
       
   293   );
       
   294   $form['submit'] = array(
       
   295     '#type' => 'submit',
       
   296     '#value' => t('Submit'),
       
   297   );
       
   298 
       
   299   return $form;
       
   300 }
       
   301 
       
   302 /**
       
   303  * Submit handler for the batch_test_mock form.
       
   304  */
       
   305 function batch_test_mock_form_submit($form, &$form_state) {
       
   306   batch_test_stack('mock form submitted with value = ' . $form_state['values']['test_value']);
       
   307 }
       
   308 
       
   309 /**
       
   310  * Menu callback: fire a batch process without a form submission.
       
   311  */
       
   312 function batch_test_no_form() {
       
   313   batch_test_stack(NULL, TRUE);
       
   314 
       
   315   batch_set(_batch_test_batch_1());
       
   316   batch_process('batch-test/redirect');
       
   317 }
       
   318 
       
   319 /**
       
   320  * Menu callback: fire a batch process without a form submission.
       
   321  */
       
   322 function batch_test_large_percentage() {
       
   323   batch_test_stack(NULL, TRUE);
       
   324 
       
   325   batch_set(_batch_test_batch_5());
       
   326   batch_process('batch-test/redirect');
       
   327 }
       
   328 
       
   329 /**
       
   330  * Menu callback: successful redirection.
       
   331  */
       
   332 function batch_test_redirect_page() {
       
   333   return 'Redirection successful.';
       
   334 }
       
   335 
       
   336 /**
       
   337  * Batch 0: no operation.
       
   338  */
       
   339 function _batch_test_batch_0() {
       
   340   $batch = array(
       
   341     'operations' => array(),
       
   342     'finished' => '_batch_test_finished_0',
       
   343     'file' => drupal_get_path('module', 'batch_test'). '/batch_test.callbacks.inc',
       
   344   );
       
   345   return $batch;
       
   346 }
       
   347 
       
   348 /**
       
   349  * Batch 1: repeats a simple operation.
       
   350  *
       
   351  * Operations: op 1 from 1 to 10.
       
   352  */
       
   353 function _batch_test_batch_1() {
       
   354   // Ensure the batch takes at least two iterations.
       
   355   $total = 10;
       
   356   $sleep = (1000000 / $total) * 2;
       
   357 
       
   358   $operations = array();
       
   359   for ($i = 1; $i <= $total; $i++) {
       
   360     $operations[] = array('_batch_test_callback_1', array($i, $sleep));
       
   361   }
       
   362   $batch = array(
       
   363     'operations' => $operations,
       
   364     'finished' => '_batch_test_finished_1',
       
   365     'file' => drupal_get_path('module', 'batch_test'). '/batch_test.callbacks.inc',
       
   366   );
       
   367   return $batch;
       
   368 }
       
   369 
       
   370 /**
       
   371  * Batch 2: single multistep operation.
       
   372  *
       
   373  * Operations: op 2 from 1 to 10.
       
   374  */
       
   375 function _batch_test_batch_2() {
       
   376   // Ensure the batch takes at least two iterations.
       
   377   $total = 10;
       
   378   $sleep = (1000000 / $total) * 2;
       
   379 
       
   380   $operations = array(
       
   381     array('_batch_test_callback_2', array(1, $total, $sleep)),
       
   382   );
       
   383   $batch = array(
       
   384     'operations' => $operations,
       
   385     'finished' => '_batch_test_finished_2',
       
   386     'file' => drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc',
       
   387   );
       
   388   return $batch;
       
   389 }
       
   390 
       
   391 /**
       
   392  * Batch 3: both single and multistep operations.
       
   393  *
       
   394  * Operations:
       
   395  * - op 1 from 1 to 5,
       
   396  * - op 2 from 1 to 5,
       
   397  * - op 1 from 6 to 10,
       
   398  * - op 2 from 6 to 10.
       
   399  */
       
   400 function _batch_test_batch_3() {
       
   401   // Ensure the batch takes at least two iterations.
       
   402   $total = 10;
       
   403   $sleep = (1000000 / $total) * 2;
       
   404 
       
   405   $operations = array();
       
   406   for ($i = 1; $i <= round($total / 2); $i++) {
       
   407     $operations[] = array('_batch_test_callback_1', array($i, $sleep));
       
   408   }
       
   409   $operations[] = array('_batch_test_callback_2', array(1, $total / 2, $sleep));
       
   410   for ($i = round($total / 2) + 1; $i <= $total; $i++) {
       
   411     $operations[] = array('_batch_test_callback_1', array($i, $sleep));
       
   412   }
       
   413   $operations[] = array('_batch_test_callback_2', array(6, $total / 2, $sleep));
       
   414   $batch = array(
       
   415     'operations' => $operations,
       
   416     'finished' => '_batch_test_finished_3',
       
   417     'file' => drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc',
       
   418   );
       
   419   return $batch;
       
   420 }
       
   421 
       
   422 /**
       
   423  * Batch 4: batch within a batch.
       
   424  *
       
   425  * Operations:
       
   426  * - op 1 from 1 to 5,
       
   427  * - set batch 2 (op 2 from 1 to 10, should run at the end)
       
   428  * - op 1 from 6 to 10,
       
   429  */
       
   430 function _batch_test_batch_4() {
       
   431   // Ensure the batch takes at least two iterations.
       
   432   $total = 10;
       
   433   $sleep = (1000000 / $total) * 2;
       
   434 
       
   435   $operations = array();
       
   436   for ($i = 1; $i <= round($total / 2); $i++) {
       
   437     $operations[] = array('_batch_test_callback_1', array($i, $sleep));
       
   438   }
       
   439   $operations[] = array('_batch_test_nested_batch_callback', array());
       
   440   for ($i = round($total / 2) + 1; $i <= $total; $i++) {
       
   441     $operations[] = array('_batch_test_callback_1', array($i, $sleep));
       
   442   }
       
   443   $batch = array(
       
   444     'operations' => $operations,
       
   445     'finished' => '_batch_test_finished_4',
       
   446     'file' => drupal_get_path('module', 'batch_test') . '/batch_test.callbacks.inc',
       
   447   );
       
   448   return $batch;
       
   449 }
       
   450 
       
   451 /**
       
   452  * Batch 5: repeats a simple operation.
       
   453  *
       
   454  * Operations: op 1 from 1 to 10.
       
   455  */
       
   456 function _batch_test_batch_5() {
       
   457   // Ensure the batch takes at least two iterations.
       
   458   $total = 10;
       
   459   $sleep = (1000000 / $total) * 2;
       
   460 
       
   461   $operations = array();
       
   462   for ($i = 1; $i <= $total; $i++) {
       
   463     $operations[] = array('_batch_test_callback_5', array($i, $sleep));
       
   464   }
       
   465   $batch = array(
       
   466     'operations' => $operations,
       
   467     'finished' => '_batch_test_finished_5',
       
   468     'file' => drupal_get_path('module', 'batch_test'). '/batch_test.callbacks.inc',
       
   469   );
       
   470   return $batch;
       
   471 }
       
   472 
       
   473 /**
       
   474  * Menu callback: run a batch for testing theme used on the progress page.
       
   475  */
       
   476 function batch_test_theme_batch() {
       
   477   batch_test_stack(NULL, TRUE);
       
   478   $batch = array(
       
   479     'operations' => array(
       
   480       array('_batch_test_theme_callback', array()),
       
   481     ),
       
   482   );
       
   483   batch_set($batch);
       
   484   batch_process('batch-test/redirect');
       
   485 }
       
   486 
       
   487 /**
       
   488  * Batch callback function for testing the theme used on the progress page.
       
   489  */
       
   490 function _batch_test_theme_callback() {
       
   491   // Because drupalGet() steps through the full progressive batch before
       
   492   // returning control to the test function, we cannot test that the correct
       
   493   // theme is being used on the batch processing page by viewing that page
       
   494   // directly. Instead, we save the theme being used in a variable here, so
       
   495   // that it can be loaded and inspected in the thread running the test.
       
   496   global $theme;
       
   497   batch_test_stack($theme);
       
   498 }
       
   499 
       
   500 /**
       
   501  * Helper function: store or retrieve traced execution data.
       
   502  */
       
   503 function batch_test_stack($data = NULL, $reset = FALSE) {
       
   504   if ($reset) {
       
   505     variable_del('batch_test_stack');
       
   506   }
       
   507   if (!isset($data)) {
       
   508     return variable_get('batch_test_stack', array());
       
   509   }
       
   510   $stack = variable_get('batch_test_stack', array());
       
   511   $stack[] = $data;
       
   512   variable_set('batch_test_stack', $stack);
       
   513 }