Projet

Général

Profil

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

root / drupal7 / sites / all / modules / captcha / captcha.admin.inc @ 6ae446a4

1
<?php
2

    
3
/**
4
 * @file
5
 * Functionality and helper functions for CAPTCHA administration.
6
 */
7

    
8
/**
9
 * Return an array with the available CAPTCHA types, for use as options array for a select form elements.
10
 *
11
 * @param bool $add_special_options
12
 *   if true: also add a 'none' and 'default' option
13
 *
14
 * @return array
15
 *   Mapping "$module/$type" to
16
 *   "$type (from module $module)" with $module the module name implementing the CAPTCHA
17
 *   and $type the name of the CAPTCHA type.
18
 */
19
function _captcha_available_challenge_types($add_special_options = TRUE) {
20
  $captcha_types = array();
21
  if ($add_special_options) {
22
    $captcha_types['none'] = t('- No challenge -');
23
    $captcha_types['default'] = t('Default challenge type');
24
  }
25
  // We do our own version of Drupal's module_invoke_all() here because
26
  // we want to build an array with custom keys and values.
27
  foreach (module_implements('captcha') as $module) {
28
    $result = call_user_func_array($module . '_captcha', array('list'));
29
    if (is_array($result)) {
30
      foreach ($result as $type) {
31
        $captcha_types["$module/$type"] = t('@type (from module @module)', array('@type' => $type, '@module' => $module));
32
      }
33
    }
34
  }
35
  return $captcha_types;
36
}
37

    
38
/**
39
 * Form builder function for the general CAPTCHA configuration.
40
 */
41
function captcha_admin_settings() {
42
  module_load_include('inc', 'captcha');
43

    
44
  // Use JavaScript for some added usability on admin form.
45
  drupal_add_js(drupal_get_path('module', 'captcha') . '/captcha.js');
46

    
47
  // Configuration of which forms to protect, with what challenge.
48
  $form['captcha_form_protection'] = array(
49
    '#type' => 'fieldset',
50
    '#title' => t('Form protection'),
51
    '#description' => t("Select the challenge type you want for each of the listed forms (identified by their so called <em>form_id</em>'s). You can easily add arbitrary forms with the textfield at the bottom of the table or with the help of the option <em>Add CAPTCHA administration links to forms</em> below."),
52
  );
53
  $form['captcha_form_protection']['captcha_default_challenge'] = array(
54
    '#type' => 'select',
55
    '#title' => t('Default challenge type'),
56
    '#description' => t('Select the default challenge type for CAPTCHAs. This can be overriden for each form if desired.'),
57
    '#options' => _captcha_available_challenge_types(FALSE),
58
    '#default_value' => variable_get('captcha_default_challenge', 'captcha/Math'),
59
  );
60
  // List known form_ids.
61
  $form['captcha_form_protection']['captcha_form_id_overview'] = array(
62
    '#theme' => 'captcha_admin_settings_captcha_points',
63
    '#tree' => TRUE,
64
  );
65
  $form['captcha_form_protection']['captcha_form_id_overview']['captcha_captcha_points'] = array();
66
  $captcha_type_options = _captcha_available_challenge_types();
67
  $captcha_points = captcha_get_captcha_points();
68
  foreach ($captcha_points as $captcha_point) {
69
    $elem = array();
70
    $elem['form_id'] = array(
71
      '#markup' => $captcha_point->form_id,
72
    );
73
    // Select widget for CAPTCHA type.
74
    if (isset($captcha_point->module) && $captcha_point->module) {
75
      $captcha_type = $captcha_point->module . '/' . $captcha_point->captcha_type;
76
    }
77
    elseif (isset($captcha_point->captcha_type) && ($captcha_point->captcha_type == 'default')) {
78
      $captcha_type = 'default';
79
    }
80
    else {
81
      $captcha_type = 'none';
82
    }
83
    $elem['captcha_type'] = array(
84
      '#type' => 'select',
85
      '#default_value' => $captcha_type,
86
      '#options' => $captcha_type_options,
87
    );
88
    $ops = array();
89
    if (module_exists('ctools') && $captcha_point->export_type & EXPORT_IN_CODE) {
90
      if ($captcha_point->export_type & EXPORT_IN_DATABASE) {
91
        $ops[] = l(t('revert'), "admin/config/people/captcha/captcha/captcha_point/{$captcha_point->form_id}/delete");
92
      }
93
      // TODO Disable exported points.
94
    }
95
    else {
96
      $ops[] = l(t('delete'), "admin/config/people/captcha/captcha/captcha_point/{$captcha_point->form_id}/delete");
97
    }
98
    $elem['operations'] = array('#markup' => implode(", ", $ops));
99

    
100
    $form['captcha_form_protection']['captcha_form_id_overview']['captcha_captcha_points'][$captcha_point->form_id] = $elem;
101
  }
102

    
103
  // Form items for new form_id.
104
  $form['captcha_form_protection']['captcha_form_id_overview']['captcha_new_captcha_point'] = array();
105
  // Textfield for form_id.
106
  $form['captcha_form_protection']['captcha_form_id_overview']['captcha_new_captcha_point']['form_id'] = array(
107
    '#type' => 'textfield',
108
    '#size' => 16,
109
  );
110
  // Select widget for CAPTCHA type.
111
  $form['captcha_form_protection']['captcha_form_id_overview']['captcha_new_captcha_point']['captcha_type'] = array(
112
    '#type' => 'select',
113
    '#default_value' => 'none',
114
    '#options' => $captcha_type_options,
115
  );
116

    
117
  // Checkbox to add default CAPTCHA to all non listed forms as well.
118
  $form['captcha_form_protection']['captcha_default_challenge_on_nonlisted_forms'] = array(
119
    '#type' => 'checkbox',
120
    '#title' => t('Default challenge on non-listed forms.'),
121
    '#default_value' => variable_get('captcha_default_challenge_on_nonlisted_forms', FALSE),
122
    '#description' => t('Normally, no challenge is added to forms that are not listed above. Enabling this option will add the default challenge instead.'),
123
  );
124

    
125
  // Field for the CAPTCHA administration mode.
126
  $form['captcha_form_protection']['captcha_administration_mode'] = array(
127
    '#type' => 'checkbox',
128
    '#title' => t('Add CAPTCHA administration links to forms'),
129
    '#default_value' => variable_get('captcha_administration_mode', FALSE),
130
    '#description' => t('This option makes it easy to manage CAPTCHA settings on forms. When enabled, users with the <em>administer CAPTCHA settings</em> permission will see a fieldset with CAPTCHA administration links on all forms, except on administrative pages.'),
131
  );
132
  // Field for the CAPTCHAs on admin pages.
133
  $form['captcha_form_protection']['captcha_allow_on_admin_pages'] = array(
134
    '#type' => 'checkbox',
135
    '#title' => t('Allow CAPTCHAs and CAPTCHA administration links on administrative pages'),
136
    '#default_value' => variable_get('captcha_allow_on_admin_pages', FALSE),
137
    '#description' => t("This option makes it possible to add CAPTCHAs to forms on administrative pages. CAPTCHAs are disabled by default on administrative pages (which shouldn't be accessible to untrusted users normally) to avoid the related overhead. In some situations, e.g. in the case of demo sites, it can be usefull to allow CAPTCHAs on administrative pages."),
138
  );
139

    
140
  // Button for clearing the CAPTCHA placement cache.
141
  // Based on Drupal core's "Clear all caches" (performance settings page).
142
  $form['captcha_form_protection']['captcha_placement_caching'] = array(
143
    '#type' => 'item',
144
    '#title' => t('CAPTCHA placement caching'),
145
    '#description' => t('For efficiency, the positions of the CAPTCHA elements in each of the configured forms are cached. Most of the time, the structure of a form does not change and it would be a waste to recalculate the positions every time. Occasionally however, the form structure can change (e.g. during site building) and clearing the CAPTCHA placement cache can be required to fix the CAPTCHA placement.'),
146
  );
147
  $form['captcha_form_protection']['captcha_placement_caching']['captcha_placement_cache_clear'] = array(
148
    '#type' => 'submit',
149
    '#value' => t('Clear the CAPTCHA placement cache'),
150
    '#submit' => array('captcha_clear_captcha_placement_cache_submit'),
151
  );
152

    
153
  // Configuration option for adding a CAPTCHA description.
154
  $form['captcha_add_captcha_description'] = array(
155
    '#type' => 'checkbox',
156
    '#title' => t('Add a description to the CAPTCHA'),
157
    '#description' => t('Add a configurable description to explain the purpose of the CAPTCHA to the visitor.'),
158
    '#default_value' => variable_get('captcha_add_captcha_description', TRUE),
159
  );
160
  // Textfield(s) for the CAPTCHA description.
161
  if (module_exists('locale')) {
162
    $langs = locale_language_list();
163
    $form['captcha_descriptions'] = array(
164
      '#type' => 'fieldset',
165
      '#title' => t('CAPTCHA description'),
166
      '#description' => t('Configurable description of the CAPTCHA. An empty entry will reset the description to default.'),
167
      '#attributes' => array('id' => 'edit-captcha-description-wrapper'),
168
    );
169
    foreach ($langs as $lang_code => $lang_name) {
170
      $form['captcha_descriptions']["captcha_description_$lang_code"] = array(
171
        '#type' => 'textfield',
172
        '#title' => t('For language %lang_name (code %lang_code)', array('%lang_name' => $lang_name, '%lang_code' => $lang_code)),
173
        '#default_value' => _captcha_get_description($lang_code),
174
        '#maxlength' => 256,
175
      );
176
    }
177
  }
178
  else {
179
    $form['captcha_description'] = array(
180
      '#type' => 'textfield',
181
      '#title' => t('Challenge description'),
182
      '#description' => t('Configurable description of the CAPTCHA. An empty entry will reset the description to default.'),
183
      '#default_value' => _captcha_get_description(),
184
      '#maxlength' => 256,
185
      '#attributes' => array('id' => 'edit-captcha-description-wrapper'),
186
    );
187
  }
188

    
189
  // Option for case sensitive/insensitive validation of the responses.
190
  $form['captcha_default_validation'] = array(
191
    '#type' => 'radios',
192
    '#title' => t('Default CAPTCHA validation'),
193
    '#description' => t('Define how the response should be processed by default. Note that the modules that provide the actual challenges can override or ignore this.'),
194
    '#options' => array(
195
      CAPTCHA_DEFAULT_VALIDATION_CASE_SENSITIVE => t('Case sensitive validation: the response has to exactly match the solution.'),
196
      CAPTCHA_DEFAULT_VALIDATION_CASE_INSENSITIVE => t('Case insensitive validation: lowercase/uppercase errors are ignored.'),
197
    ),
198
    '#default_value' => variable_get('captcha_default_validation', CAPTCHA_DEFAULT_VALIDATION_CASE_INSENSITIVE),
199
  );
200

    
201
  // Field for CAPTCHA persistence.
202
  // TODO for D7: Rethink/simplify the explanation and UI strings.
203
  $form['captcha_persistence'] = array(
204
    '#type' => 'radios',
205
    '#title' => t('Persistence'),
206
    '#default_value' => variable_get('captcha_persistence', CAPTCHA_PERSISTENCE_SKIP_ONCE_SUCCESSFUL_PER_FORM_INSTANCE),
207
    '#options' => array(
208
      CAPTCHA_PERSISTENCE_SHOW_ALWAYS => t('Always add a challenge.'),
209
      CAPTCHA_PERSISTENCE_SKIP_ONCE_SUCCESSFUL_PER_FORM_INSTANCE => t('Omit challenges in a multi-step/preview workflow once the user successfully responds to a challenge.'),
210
      CAPTCHA_PERSISTENCE_SKIP_ONCE_SUCCESSFUL_PER_FORM_TYPE => t('Omit challenges on a form type once the user successfully responds to a challenge on a form of that type.'),
211
      CAPTCHA_PERSISTENCE_SKIP_ONCE_SUCCESSFUL => t('Omit challenges on all forms once the user successfully responds to any challenge on the site.'),
212
    ),
213
    '#description' => t('Define if challenges should be omitted during the rest of a session once the user successfully responds to a challenge.'),
214
  );
215

    
216
  // Enable wrong response counter.
217
  $form['captcha_enable_stats'] = array(
218
    '#type' => 'checkbox',
219
    '#title' => t('Enable statistics'),
220
    '#description' => t('Keep CAPTCHA related counters in the <a href="!statusreport">status report</a>. Note that this comes with a performance penalty as updating the counters results in clearing the variable cache.', array('!statusreport' => url('admin/reports/status'))),
221
    '#default_value' => variable_get('captcha_enable_stats', FALSE),
222
  );
223

    
224
  // Option for logging wrong responses.
225
  $form['captcha_log_wrong_responses'] = array(
226
    '#type' => 'checkbox',
227
    '#title' => t('Log wrong responses'),
228
    '#description' => t('Report information about wrong responses to the <a href="!dblog">log</a>.', array('!dblog' => url('admin/reports/dblog'))),
229
    '#default_value' => variable_get('captcha_log_wrong_responses', FALSE),
230
  );
231

    
232
  // Submit button.
233
  $form['actions'] = array('#type' => 'actions');
234
  $form['actions']['submit'] = array(
235
    '#type' => 'submit',
236
    '#value' => t('Save configuration'),
237
  );
238

    
239
  return $form;
240
}
241

    
242
/**
243
 * Custom theme function for a table of (form_id -> CAPTCHA type) settings.
244
 */
245
function theme_captcha_admin_settings_captcha_points($variables) {
246
  $form = $variables['form'];
247
  $header = array('form_id', t('Challenge type'), t('Operations'));
248
  $rows = array();
249
  // Existing CAPTCHA points.
250
  foreach (element_children($form['captcha_captcha_points']) as $key) {
251
    $row = array();
252
    $row[] = drupal_render($form['captcha_captcha_points'][$key]['form_id']);
253
    $row[] = drupal_render($form['captcha_captcha_points'][$key]['captcha_type']);
254
    $row[] = drupal_render($form['captcha_captcha_points'][$key]['operations']);
255
    $rows[] = $row;
256
  }
257
  // For new CAPTCHA point.
258
  $row = array();
259
  $row[] = drupal_render($form['captcha_new_captcha_point']['form_id']);
260
  $row[] = drupal_render($form['captcha_new_captcha_point']['captcha_type']);
261
  $row[] = '';
262
  $rows[] = $row;
263

    
264
  $output = theme('table', array('header' => $header, 'rows' => $rows));
265
  return $output;
266
}
267

    
268
/**
269
 * Validation handler for captcha_admin_settings form.
270
 */
271
function captcha_admin_settings_validate($form, $form_state) {
272
  $form_id = $form_state['values']['captcha_form_id_overview']['captcha_new_captcha_point']['form_id'];
273
  if (!preg_match('/^[a-z0-9_]*$/', $form_id)) {
274
    form_set_error('captcha_form_id_overview][captcha_new_captcha_point][form_id', t('Illegal form_id'));
275
  }
276
}
277

    
278
/**
279
 * Submission function for captcha_admin_settings form.
280
 */
281
function captcha_admin_settings_submit($form, &$form_state) {
282

    
283
  variable_set('captcha_administration_mode', $form_state['values']['captcha_administration_mode']);
284
  variable_set('captcha_allow_on_admin_pages', $form_state['values']['captcha_allow_on_admin_pages']);
285

    
286
  variable_set('captcha_default_challenge', $form_state['values']['captcha_default_challenge']);
287
  variable_set('captcha_default_challenge_on_nonlisted_forms', $form_state['values']['captcha_default_challenge_on_nonlisted_forms']);
288

    
289
  // Process CAPTCHA points.
290
  if (isset($form_state['values']['captcha_form_id_overview']['captcha_captcha_points'])) {
291
    // Load existing data.
292
    $captcha_points = captcha_get_captcha_points();
293
    foreach ($form_state['values']['captcha_form_id_overview']['captcha_captcha_points'] as $captcha_point_form_id => $data) {
294
      // If this is an in-code captcha point and its settings are unchanged,
295
      // don't save to the database.
296
      if (module_exists('ctools') && isset($captcha_points[$captcha_point_form_id])) {
297
        // Parse module and captcha_type from submitted values.
298
        if (is_string($data['captcha_type']) && substr_count($data['captcha_type'], '/') == 1) {
299
          list($module, $captcha_type) = explode('/', $data['captcha_type']);
300
        }
301
        else {
302
          $module = '';
303
          $captcha_type = $data['captcha_type'];
304
        }
305

    
306
        $point = $captcha_points[$captcha_point_form_id];
307
        if ($point->export_type & EXPORT_IN_CODE && !($point->export_type & EXPORT_IN_DATABASE) && $point->module == $module && $point->captcha_type == $captcha_type) {
308
          continue;
309
        }
310
      }
311
      captcha_set_form_id_setting($captcha_point_form_id, $data['captcha_type']);
312
    }
313
  }
314

    
315
  // Add new CAPTCHA point?
316
  $captcha_point_form_id = $form_state['values']['captcha_form_id_overview']['captcha_new_captcha_point']['form_id'];
317
  if (!empty($captcha_point_form_id)) {
318
    $captcha_type = $form_state['values']['captcha_form_id_overview']['captcha_new_captcha_point']['captcha_type'];
319
    captcha_set_form_id_setting($captcha_point_form_id, $captcha_type);
320
    drupal_set_message(t('Added CAPTCHA point.'), 'status');
321
  }
322

    
323
  // CAPTCHA description stuff.
324
  variable_set('captcha_add_captcha_description', $form_state['values']['captcha_add_captcha_description']);
325
  // Save (or reset) the CAPTCHA descriptions.
326
  if (module_exists('locale')) {
327
    $langs = locale_language_list();
328
    foreach ($langs as $lang_code => $lang_name) {
329
      $description = $form_state['values']["captcha_description_$lang_code"];
330
      if ($description) {
331
        variable_set("captcha_description_$lang_code", $description);
332
      }
333
      else {
334
        variable_del("captcha_description_$lang_code");
335
        drupal_set_message(t('Reset of CAPTCHA description for language %language.', array('%language' => $lang_name)), 'status');
336
      }
337
    }
338
  }
339
  else {
340
    $description = $form_state['values']['captcha_description'];
341
    if ($description) {
342
      variable_set('captcha_description', $description);
343
    }
344
    else {
345
      variable_del('captcha_description');
346
      drupal_set_message(t('Reset of CAPTCHA description.'), 'status');
347
    }
348
  }
349

    
350
  variable_set('captcha_default_validation', $form_state['values']['captcha_default_validation']);
351
  variable_set('captcha_persistence', $form_state['values']['captcha_persistence']);
352
  variable_set('captcha_enable_stats', $form_state['values']['captcha_enable_stats']);
353
  variable_set('captcha_log_wrong_responses', $form_state['values']['captcha_log_wrong_responses']);
354

    
355
  drupal_set_message(t('The CAPTCHA settings have been saved.'), 'status');
356
}
357

    
358
/**
359
 * Submit callback; clear CAPTCHA placement cache.
360
 */
361
function captcha_clear_captcha_placement_cache_submit($form, &$form_state) {
362
  variable_del('captcha_placement_map_cache');
363
  drupal_set_message(t('Cleared the CAPTCHA placement cache.'));
364
}
365

    
366
/**
367
 * Central handler for CAPTCHA point administration (adding, disabling, deleting).
368
 */
369
function captcha_point_admin($captcha_point_form_id = NULL, $op = NULL) {
370
  module_load_include('inc', 'captcha');
371

    
372
  // If $captcha_point_form_id and action $op given: do the action.
373
  if ($captcha_point_form_id) {
374
    switch ($op) {
375
      case 'disable':
376
        return drupal_get_form('captcha_point_disable_confirm', $captcha_point_form_id, FALSE);
377

    
378
      case 'delete':
379
        return drupal_get_form('captcha_point_disable_confirm', $captcha_point_form_id, TRUE);
380
    }
381
    // Return edit form for CAPTCHA point.
382
    return drupal_get_form('captcha_point_admin_form', $captcha_point_form_id);
383
  }
384
  // Return add form for CAPTCHA point.
385
  return drupal_get_form('captcha_point_admin_form');
386
}
387

    
388
/**
389
 * Admin form.
390
 */
391
function captcha_point_admin_form($form, $form_state, $captcha_point_form_id = NULL) {
392
  $form = array();
393
  $default_captcha_type = 'none';
394
  if (isset($captcha_point_form_id)) {
395
    // Use given CAPTCHA point form_id.
396
    $form['captcha_point_form_id'] = array(
397
      '#type' => 'textfield',
398
      '#title' => t('Form ID'),
399
      '#description' => t('The Drupal form_id of the form to add the CAPTCHA to.'),
400
      '#value' => check_plain($captcha_point_form_id),
401
      '#disabled' => TRUE,
402
    );
403
    $captcha_point = captcha_get_form_id_setting($captcha_point_form_id);
404
    if ($captcha_point) {
405
      $default_captcha_type = "{$captcha_point->module}/{$captcha_point->captcha_type}";
406
    }
407
  }
408
  else {
409
    // Textfield for CAPTCHA point form_id.
410
    $form['captcha_point_form_id'] = array(
411
      '#type' => 'textfield',
412
      '#title' => t('Form ID'),
413
      '#description' => t('The Drupal form_id of the form to add the CAPTCHA to.'),
414
    );
415
  }
416
  // Select widget for CAPTCHA type.
417
  $form['captcha_type'] = array(
418
    '#type' => 'select',
419
    '#title' => t('Challenge type'),
420
    '#description' => t('The CAPTCHA type to use for this form.'),
421
    '#default_value' => $default_captcha_type,
422
    '#options' => _captcha_available_challenge_types(),
423
  );
424
  // Redirect to general CAPTCHA settings page after submission.
425
  $form['#redirect'] = 'admin/config/people/captcha';
426
  // Submit button.
427
  $form['actions'] = array('#type' => 'actions');
428
  $form['actions']['submit'] = array(
429
    '#type' => 'submit',
430
    '#value' => t('Save'),
431
  );
432
  return $form;
433
}
434

    
435
/**
436
 * Validation function for captcha_point_admin_form.
437
 */
438
function captcha_point_admin_form_validate($form, $form_state) {
439
  if (!preg_match('/^[a-z0-9_]+$/', $form_state['values']['captcha_point_form_id'])) {
440
    form_set_error('captcha_point_form_id', t('Illegal form_id'));
441
  }
442
}
443

    
444
/**
445
 * Submit function for captcha_point_admin_form.
446
 */
447
function captcha_point_admin_form_submit($form, $form_state) {
448
  $captcha_point_form_id = $form_state['values']['captcha_point_form_id'];
449
  $captcha_type = $form_state['values']['captcha_type'];
450
  captcha_set_form_id_setting($captcha_point_form_id, $captcha_type);
451
  drupal_set_message(t('Saved CAPTCHA point settings.'), 'status');
452
}
453

    
454
/**
455
 * Confirm dialog for disabling/deleting a CAPTCHA point.
456
 */
457
function captcha_point_disable_confirm($form, &$form_state, $captcha_point_form_id, $delete) {
458
  $form = array();
459
  $form['captcha_point_form_id'] = array(
460
    '#type' => 'value',
461
    '#value' => $captcha_point_form_id,
462
  );
463
  $form['captcha_point_delete'] = array(
464
    '#type' => 'value',
465
    '#value' => $delete,
466
  );
467
  if ($delete) {
468
    $message = t('Are you sure you want to delete the CAPTCHA for form_id %form_id?', array('%form_id' => $captcha_point_form_id));
469
    $yes = t('Delete');
470
  }
471
  else {
472
    $message = t('Are you sure you want to disable the CAPTCHA for form_id %form_id?', array('%form_id' => $captcha_point_form_id));
473
    $yes = t('Disable');
474
  }
475
  return confirm_form($form, $message, 'admin/config/people/captcha/captcha', '', $yes);
476
}
477

    
478
/**
479
 * Submission handler of CAPTCHA point disabling/deleting confirm_form.
480
 */
481
function captcha_point_disable_confirm_submit($form, &$form_state) {
482
  $captcha_point_form_id = $form_state['values']['captcha_point_form_id'];
483
  $delete = $form_state['values']['captcha_point_delete'];
484
  if ($delete) {
485
    captcha_set_form_id_setting($captcha_point_form_id, NULL);
486
    drupal_set_message(t('Deleted CAPTCHA for form %form_id.', array('%form_id' => $captcha_point_form_id)));
487
  }
488
  else {
489
    captcha_set_form_id_setting($captcha_point_form_id, 'none');
490
    drupal_set_message(t('Disabled CAPTCHA for form %form_id.', array('%form_id' => $captcha_point_form_id)));
491
  }
492
  $form_state['redirect'] = 'admin/config/people/captcha/captcha';
493
}
494

    
495
/**
496
 * Helper function for generating an example challenge.
497
 */
498
function _captcha_generate_example_challenge($module, $type) {
499
  return array(
500
    '#type' => 'captcha',
501
    '#captcha_type' => $module . '/' . $type,
502
    '#captcha_admin_mode' => TRUE,
503
  );
504
}
505

    
506
/**
507
 * Funtion for generating a page with CAPTCHA examples.
508
 *
509
 * If the arguments $module and $challenge are not set, generate a list with
510
 * examples of the available CAPTCHA types.
511
 * If $module and $challenge are set, generate 10 examples of the concerning
512
 * CAPTCHA.
513
 */
514
function captcha_examples($form, $form_state, $module, $challenge) {
515
  module_load_include('inc', 'captcha');
516

    
517
  $form = array();
518
  if ($module && $challenge) {
519
    // Generate 10 example challenges.
520
    for ($i = 0; $i < 10; $i++) {
521
      $form["challenge_{$i}"] = _captcha_generate_example_challenge($module, $challenge);
522
    }
523
  }
524
  else {
525
    // Generate a list with examples of the available CAPTCHA types.
526
    $form['info'] = array(
527
      '#markup' => t('This page gives an overview of all available challenge types, generated with their current settings.'),
528
    );
529
    foreach (module_implements('captcha') as $mkey => $module) {
530
      $challenges = call_user_func_array($module . '_captcha', array('list'));
531
      if ($challenges) {
532
        foreach ($challenges as $ckey => $challenge) {
533
          $form["captcha_{$mkey}_{$ckey}"] = array(
534
            '#type' => 'fieldset',
535
            '#title' => t('Challenge %challenge by module %module', array('%challenge' => $challenge, '%module' => $module)),
536
            'challenge' => _captcha_generate_example_challenge($module, $challenge),
537
            'more_examples' => array(
538
              '#markup' => l(t('10 more examples of this challenge.'), "admin/config/people/captcha/captcha/examples/$module/$challenge"),
539
            ),
540
          );
541
        }
542
      }
543
    }
544
  }
545
  return $form;
546
}