Projet

Général

Profil

Paste
Télécharger (13,3 ko) Statistiques
| Branche: | Révision:

root / drupal7 / modules / simpletest / tests / batch_test.module @ db2d93dd

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
}