Projet

Général

Profil

Paste
Télécharger (22,7 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / variable / variable.module @ ba09eb79

1
<?php
2
/**
3
 * @file
4
 * Variable API module
5
 */
6

    
7
/**
8
 * Implementation of hook_boot()
9
 *
10
 * Though we don't do anything here, we ensure the module is loaded at boot stage
11
 * for other modules (like variable_realm) to be able to use the API
12
 */
13
function variable_boot() {
14
}
15

    
16
/**
17
* @defgroup variable_api Variable API
18
* @{
19
* Get meta-information about variables and extended get/set methods
20
*
21
* Use these functions if you want to take full advantage of Variable API
22
*/
23

    
24
/**
25
 * Check access to variable
26
 *
27
 * All variables are restricted for editing so unless we've got some explicit access
28
 * variables cannot be edited as default.
29
 *
30
 * @param $variable
31
 *   Variable name or info array
32
 */
33
function variable_access($variable, $account = NULL) {
34
  $account = $account ? $account : $GLOBALS['user'];
35
  if (user_access('administer site configuration', $account)) {
36
    return TRUE;
37
  }
38
  elseif ($variable = _variable_variable($variable)) {
39
    // Check parent variable if this is a child variable and doesn't have explicit access.
40
    if (!isset($variable['access']) && !empty($variable['parent'])) {
41
      return variable_access($variable['parent']);
42
    }
43
    // We need either a variable or group explicit access.
44
    $group = isset($variable['group']) ? variable_get_group($variable['group']) : array();
45
    if (!isset($group['access']) && !isset($variable['access']) ||
46
      isset($group['access']) && !user_access($group['access'], $account) ||
47
      isset($variable['access']) && !user_access($variable['access'], $account) )
48
    {
49
      return FALSE;
50
    }
51
    else {
52
      return TRUE;
53
    }
54
  }
55
  else {
56
    // We don't have information for such variable
57
    return FALSE;
58
  }
59
}
60

    
61

    
62
/**
63
 * Get list of variables expanding multiple ones
64
 *
65
 * @param $names
66
 *   List of variable names or full variable arrays
67
 *
68
 * @return array()
69
 *   List variable names with spawned multiple variables
70
 */
71
function variable_children($names) {
72
  $names = is_array($names) ? $names : array($names);
73
  $list = array();
74
  foreach ($names as $name) {
75
    // We need to build the variable, it may be multiple
76
    $variable = variable_build($name);
77
    if (!empty($variable['children'])) {
78
      $list = array_merge($list, array_keys($variable['children']));
79
    }
80
    else {
81
      $list[] = $variable['name'];
82
    }
83
  }
84
  return $list;
85
}
86

    
87
/**
88
 * Map children variables to parent variables
89
 */
90
function variable_parent($name) {
91
  $map = &drupal_static(__FUNCTION__);
92
  if (!isset($map)) {
93
    foreach (array_keys(variable_get_info()) as $key) {
94
      if ($children = variable_children($key)) {
95
        foreach ($children as $child) {
96
          $map[$child] = $key;
97
        }
98
      }
99
    }
100
  }
101
  return isset($map[$name]) ? $map[$name] : NULL;
102
}
103

    
104
/**
105
 * Format printable value
106
 *
107
 * @param $variable
108
 */
109
function variable_format_value($variable, $options = array()) {
110
  $variable = variable_build($variable, $options);
111
  $variable['value'] = variable_get_value($variable, $options);
112
  if (isset($variable['value'])) {
113
    return !empty($variable['format callback']) ? variable_callback($variable['format callback'], $variable, $options) : variable_format_unknown($variable, $options);
114
  }
115
  else {
116
    return isset($variable['empty']) ? $variable['empty'] : t('Empty');
117
  }
118
}
119

    
120
/**
121
 * Format unknown variable
122
 */
123
function variable_format_unknown($variable, $options = array()) {
124
  return '<pre>' . check_plain(print_r($variable['value'], TRUE)) . '</pre>';
125
}
126

    
127
/**
128
 * Get variable child element from multiple variable
129
 *
130
 * @param $parent
131
 *   Parent variable
132
 * @param $key
133
 *   Key of the children variable (not the full name, just the piece of string that makes the difference)
134
 */
135
function variable_get_child($parent, $key, $options = array()) {
136
  $variable = variable_build($parent, $options);
137
  $name = preg_replace('/\[\w+\]/', $key, $variable['name']);
138
  $child = $variable['children'][$name];
139
  // Replace title and description
140
  foreach (array('title', 'description') as $property) {
141
    if (isset($variable[$property])) {
142
      $child[$property] = $variable[$property];
143
    }
144
  }
145
  return $child;
146
}
147

    
148
/**
149
 * Get variable information
150
 *
151
 * Variable information is collected from modules and cached by language
152
 *
153
 * @param $name
154
 *   Optional variable name. Will return all if no name.
155
 * @param $options array
156
 *   Options for variable values
157
 *   - 'langcode', Language code
158
 */
159
function variable_get_info($name = NULL, $options = array()) {
160
  $options = _variable_options($options);
161
  if (!$name) {
162
    return _variable_info('variable', NULL, $options);
163
  }
164
  elseif ($info = _variable_info('variable', $name, $options)) {
165
    return $info;
166
  }
167
  elseif ($parent = variable_parent($name)) {
168
    $info = variable_build(variable_get_info($parent));
169
    $child = $info['children'][$name];
170
    // Copy over some values from parent to child to add some context to it.
171
    $child['title'] = $info['title'] . ' [' . $child['title'] . ']';
172
    if (isset($info['description'])) {
173
      $child['description'] = $info['description'];
174
    }
175
    return $child;
176
  }
177
  else {
178
    return NULL;
179
  }
180
}
181

    
182
/**
183
 * Get variable group information.
184
 *
185
 * @param $group
186
 *   Group name. Will return all if not name.
187
 */
188
function variable_get_group($group = NULL) {
189
  return _variable_info('group', $group);
190
}
191

    
192
/**
193
 * Get variable type information.
194
 *
195
 * @param $type
196
 *   Type name. Will return all if no name.
197
 */
198
function variable_get_type($type = NULL) {
199
  $info = _variable_info('type', $type);
200
  if ($type && !empty($info['type'])) {
201
    // Add subtipe properties, recursive
202
    $info += variable_get_type($info['type']);
203
  }
204
  return $info;
205
}
206

    
207
/**
208
 * Get variable option information.
209
 */
210
function variable_get_option($type = NULL) {
211
  return _variable_info('option', $type);
212
}
213

    
214
/**
215
 * Get value for simple scalar variable
216
 *
217
 * @param $variable
218
 *   Variable name or array data
219
 * @param $options
220
 *   Options array, it may have the following elements
221
 *   - language => Language object
222
 *   - default => Default value if not set
223
 *   - realm => Realm object if working inside a variable realm
224
 */
225
function variable_get_value($variable, $options = array()) {
226
  $variable = _variable_variable($variable, $options);
227
  if (isset($variable['value'])) {
228
    return $variable['value'];
229
  }
230
  elseif (!empty($variable['value callback'])) {
231
    variable_include($variable);
232
    return variable_callback($variable['value callback'], $variable, _variable_options($options));
233
  }
234
  else {
235
    if (!empty($options['realm'])) {
236
      $value = $options['realm']->variable_get($variable['name'], NULL);
237
    }
238
    else {
239
      $value = variable_get($variable['name'], NULL);
240
    }
241
    if (isset($value)) {
242
      return $value;
243
    }
244
    else {
245
      return isset($options['default']) ? $options['default'] : variable_get_default($variable, $options);
246
    }
247
  }
248
}
249

    
250
/**
251
 * Set variable value
252
 *
253
 * This basically sets the variable but also invokes hook_variable_update
254
 */
255
function variable_set_value($name, $value, $options = array()) {
256
  $old_value = variable_get_value($name, NULL, $options);
257
  if (!empty($options['realm'])) {
258
    $options['realm']->variable_set($name, $value);
259
  }
260
  else {
261
    variable_set($name, $value);
262
  }
263
  module_invoke_all('variable_update', $name, $value, $old_value, $options);
264
}
265

    
266
/**
267
 * Get variable default
268
 *
269
 * @param $variable
270
 *   Variable name or variable information
271
 */
272
function variable_get_default($variable, $options = array()) {
273
  $variable = _variable_variable($variable, $options);
274
  if (isset($variable['default callback'])) {
275
    variable_include($variable);
276
    return call_user_func($variable['default callback'], $variable, _variable_options($options));
277
  }
278
  elseif (isset($variable['default'])) {
279
    return $variable['default'];
280
  }
281
  else {
282
    return NULL;
283
  }
284
}
285

    
286

    
287
/**
288
 * Delete variable (included children variables)
289
 */
290
function variable_delete($variable, $options = array()) {
291
  $variable = _variable_variable($variable, $options);
292
  variable_include();
293
  // We need to build the variable, it may be multiple
294
  $variable = variable_build($variable, $options);
295
  if (!empty($variable['children'])) {
296
    $callback = !empty($options['realm']) ? array($options['realm'], 'variable_del') : 'variable_del';
297
    array_map($callback, array_keys($variable['children']));
298
  }
299
  elseif (!empty($options['realm'])) {
300
    $options['realm']->variable_del($variable['name']);
301
  }
302
  else {
303
    variable_del($variable['name']);
304
  }
305
  // Invoke the hook only once even if its multiple
306
  module_invoke_all('variable_delete', $variable, $options);
307
}
308

    
309
/**
310
 * Provide list of variable titles
311
 *
312
 * @param $names
313
 *   List of variable names or full variable arrays
314
 * @return array()
315
 *   List of name => title
316
 */
317
function variable_list($names) {
318
  $list = array();
319
  foreach ($names as $name) {
320
    if ($variable = _variable_variable($name)) {
321
      $list[$variable['name']] = $variable['title'];
322
    }
323
  }
324
  return $list;
325
}
326

    
327
/**
328
 * Get human readable name for variable.
329
 */
330
function variable_name($variable) {
331
  $variable = _variable_variable($variable);
332
  return $variable['title'];
333
}
334

    
335
/**
336
 * Get human readable names for variable list.
337
 */
338
function variable_list_name($list) {
339
  $names = array_map('variable_name', $list);
340
  return implode(', ', $names);
341
}
342

    
343
/**
344
* @} End of "defgroup variable_api".
345
*/
346

    
347
/**
348
 * Build full variable data
349
 */
350
function variable_build($variable, $options = array()) {
351
  variable_include();
352
  $variable = _variable_variable($variable, $options);
353
  return variable_build_variable($variable, $options);
354
}
355

    
356
/**
357
 * Clear cache
358
 */
359
function variable_cache_clear() {
360
  cache_clear_all('*', 'cache_variable', TRUE);
361
}
362

    
363
/**
364
 * Implementation of hook_flush_caches()
365
 */
366
function variable_flush_caches() {
367
  return array('cache_variable');
368
}
369

    
370
/**
371
 * Implements hook_element_info()
372
 */
373
function variable_element_info() {
374
  // A fieldset with variable list
375
  $types['variable_fieldset'] = array(
376
    '#collapsible' => FALSE,
377
    '#collapsed' => FALSE,
378
    '#value' => NULL,
379
    '#process' => array('variable_element_process_fieldset', 'form_process_fieldset', 'ajax_process_form'),
380
    '#pre_render' => array('form_pre_render_fieldset'),
381
    '#theme_wrappers' => array('fieldset'),
382
    '#variable_list' => array(),
383
  );
384
  return $types;
385
}
386

    
387
/**
388
 * Process variable fieldset
389
 */
390
function variable_element_process_fieldset($element) {
391
  $element += variable_edit_subform($element['#variable_list']);
392
  return $element;
393
}
394

    
395
/**
396
 * Implements hook_hook_info().
397
 */
398
function variable_hook_info() {
399
  $hooks['variable_info'] = array(
400
    'group' => 'variable',
401
  );
402
  $hooks['variable_group_info'] = array(
403
    'group' => 'variable',
404
  );
405
  $hooks['variable_type_info'] = array(
406
    'group' => 'variable',
407
  );
408
  $hooks['variable_settings_form_alter'] = array(
409
    'group' => 'variable',
410
  );
411
  return $hooks;
412
}
413

    
414
/**
415
 * Form for variable list
416
 *
417
 * @param $list
418
 *   Variable name or list of variable names.
419
 * @param $options
420
 *   Optional array with variable options.
421
 */
422
function variable_edit_form($form, &$form_state, $list, $options = array()) {
423
  $list = is_array($list) ? $list : array($list);
424
  $form = variable_base_form($form, $form_state, $list, $options);
425
  $form += variable_edit_subform($list, $options);
426
  return variable_settings_form($form, $options);
427
}
428

    
429
/**
430
 * Build base form for variable list without fields.
431
 *
432
 * @param $list
433
 *   List of variable names.
434
 * @param $options
435
 *   Optional array with variable options.
436
 */
437
function variable_base_form($form, &$form_state, $list, $options = array()) {
438
  form_load_include($form_state, 'form.inc', 'variable');
439
  // Pass on the values on the form for further reference.
440
  $form['#variable_edit_form'] = $list;
441
  $form['#variable_options'] = $options;
442
  // Run submit callback for variables in form.
443
  $form['#submit'][] = 'variable_form_submit_callback';
444
  return $form;
445
}
446

    
447
/**
448
 * Form elements for variable list.
449
 *
450
 * @param $list
451
 *   Variable name or array of variable names..
452
 * @param $options
453
 *   Regular variable options (language, realm, etc) and optional 'form parents' array.
454
 */
455
function variable_edit_subform($list, $options = array()) {
456
  module_load_include('form.inc', 'variable');
457
  $list = is_array($list) ? $list : array($list);
458
  $form = array();
459
  foreach ($list as $name) {
460
    if ($variable = variable_get_info($name, $options)) {
461
      $form[$name] = variable_form_element($variable, $options);
462
    }
463
  }
464
  return $form;
465
}
466

    
467
/**
468
 * Include extended API and files related to specific variable
469
 *
470
 * @param $variable
471
 *   Variable array
472
 */
473
function variable_include($variable = NULL) {
474
  static $included;
475
  if (!isset($included)) {
476
    // As a first step, include main variable API
477
    module_load_include('inc', 'variable');
478
    $included = array();
479
  }
480
  if ($variable && !isset($included[$variable['name']])) {
481
    // Include module.variable.inc files related to the variable and the variable type.
482
    variable_module_include($variable['module']);
483
    variable_type_include($variable['type']);
484
    $included[$variable['name']] = TRUE;
485
  }
486
}
487

    
488
/**
489
 * Include variable type files
490
 */
491
function variable_type_include($type) {
492
  variable_include();
493
  $info = variable_get_type($type);
494
  variable_module_include($info['module']);
495
  // Include subtype if any
496
  if (!empty($info['type'])) {
497
    variable_type_include($info['type']);
498
  }
499
}
500

    
501
/**
502
 * Form for module variables
503
 */
504
function variable_module_form($form, $form_state, $module) {
505
  variable_include();
506
  // Pass on the values on the form for further reference.
507
  $form['#variable_module_form'] = $module;
508
  return variable_edit_form($form, $form_state, array_keys(variable_list_module($module)));
509
}
510

    
511
/**
512
 * Form for group variables
513
 */
514
function variable_group_form($form, $form_state, $group) {
515
  variable_include();
516
  // Pass on the values on the form for further reference.
517
  $form['#variable_group_form'] = $group;
518
  return variable_edit_form($form, $form_state, array_keys(variable_list_group($group)));
519
}
520

    
521
/**
522
 * Implements hook_modules_disabled().
523
 */
524
function variable_modules_disabled($modules) {
525
  variable_include();
526
  array_map('variable_module_disable', $modules);
527
  variable_cache_clear();
528
}
529

    
530
/**
531
 * Implements hook_modules_enabled().
532
 */
533
function variable_modules_enabled($modules) {
534
  variable_include();
535
  array_map('variable_module_enable', $modules);
536
  variable_cache_clear();
537
}
538

    
539
/**
540
 * Implements hook_modules_uninstalled().
541
 */
542
function variable_modules_uninstalled($modules) {
543
  variable_include();
544
  array_map('variable_module_uninstall', $modules);
545
  variable_cache_clear();
546
}
547

    
548
/**
549
 * Implements hook_theme()
550
 */
551
function variable_theme($existing, $type, $theme, $path) {
552
  return array(
553
    'variable_table_select' => array(
554
      'render element' => 'element',
555
      'file' => 'variable.form.inc',
556
    ),
557
  );
558
}
559

    
560
/**
561
 * Get variable info static data, try the cache, or invoke the hook to collect it.
562
 *
563
 * @param $type
564
 *   Name of the info to collect
565
 *   - 'variable', Variable information, hook_variable_info()
566
 *   - 'group', Group information, hook_variable_group_info()
567
 *   - 'type', Type information, hook_variable_type_info()
568
 * @param $options
569
 *   Options to retrieve or build the data.
570
 *   The only used option to collect the data is 'langcode', though a full array of options may be used for the hooks
571
 */
572
function &variable_static($type, $options = array()) {
573
  static $data;
574
  $name = 'variable_' . $type;
575
  $langcode = isset($options['langcode']) ? $options['langcode'] : 'default';
576

    
577
  if (!isset($data[$type])) {
578
    $data[$type] = &drupal_static($name);
579
  }
580
  if (!isset($data[$type][$langcode])) {
581
    $cache_id = $type . ':' . $langcode;
582
    if ($cache = cache_get($cache_id, 'cache_variable')) {
583
      $data[$type][$langcode] = $cache->data;
584
    }
585
    else {
586
      variable_include();
587
      $data[$type][$langcode] = variable_build_info($type, $options);
588
      cache_set($cache_id, $data[$type][$langcode], 'cache_variable');
589
    }
590
  }
591
  // Return a reference inside the big array
592
  return $data[$type][$langcode];
593
}
594

    
595

    
596
/**
597
 * Get data from a variable module info array.
598
 */
599
function _variable_info($type, $name = NULL, $options = array()) {
600
  $info = &variable_static($type, $options);
601
  if ($name) {
602
    return isset($info[$name]) ? $info[$name] : array();
603
  }
604
  else {
605
    return $info;
606
  }
607
}
608

    
609
/**
610
 * Get global language object.
611
 *
612
 * Initialize the language system if needed as we absolutely need a language here
613
 */
614
function _variable_language() {
615
  global $language;
616
  if (!isset($language)) {
617
    drupal_bootstrap(DRUPAL_BOOTSTRAP_LANGUAGE);
618
  }
619
  return $language;
620
}
621

    
622
/**
623
 * Normalize variable options
624
 *
625
 * Will fill the following values if not present in the parameters
626
 * - langcode, Language code
627
 * - language, Language object
628
 */
629
function _variable_options($options = array()) {
630
  if (!empty($options['language'])) {
631
    $options['langcode'] = $options['language']->language;
632
  }
633
  elseif (!empty($options['langcode']) && ($list = language_list()) && isset($list[$options['langcode']])) {
634
    $options['language'] = $list[$options['langcode']];
635
  }
636
  else {
637
    $language = _variable_language();
638
    $options['language'] = $language;
639
    $options['langcode'] = $language->language;
640
  }
641
  return $options;
642
}
643

    
644
/**
645
 * Normalize variable data
646
 *
647
 * @param $variable
648
 *   Variable name or variable info array
649
 * @return array
650
 *   Variable information
651
 */
652
function _variable_variable($variable, $options = array()) {
653
  if (is_array($variable)) {
654
    return $variable;
655
  }
656
  elseif ($info = variable_get_info($variable, $options)) {
657
    return $info;
658
  }
659
  else {
660
    // We don't have meta-information about this variable.
661
    return _variable_unknown($variable);
662
  }
663
}
664

    
665
/**
666
 * Unknown variable
667
 */
668
function _variable_unknown($name) {
669
  return array(
670
    'name' => $name,
671
    'title' => t('Unknown variable @name', array('@name' => $name)),
672
    'type' => 'unknown',
673
    'group' => 'default',
674
    'module' => 'variable',
675
    // Space for public service advertisement :-)
676
    'description' => t('We have no meta information for this variable. Please, ask module developers to declare their variables. See <a href="http://drupal.org/project/variable">Variable module</a>.'),
677
  );
678
}
679

    
680
/**
681
 * Implements hook_form_alter().
682
 *
683
 * Triggers hook_variable_realm_settings_form_alter() giving other modules a chance
684
 * to act on settings forms after other contrib modules have added their variables.
685
 */
686
function variable_form_alter(&$form, &$form_state, $form_id) {
687
  if (isset($form['#submit']) && is_array($form['#submit']) && in_array('system_settings_form_submit', $form['#submit'])) {
688
    // Replace submit callback and use our own function.
689
    $form['#submit'] = str_replace('system_settings_form_submit', 'variable_settings_form_submit', $form['#submit']);
690
    $alter = TRUE;
691
  }
692
  elseif (isset($form['#variable_edit_form'])) {
693
    // This is a variable form, just invoke the hook but don't change submit callback.
694
    $alter = TRUE;
695
  }
696
  if (!empty($alter)) {
697
    foreach (module_implements('variable_settings_form_alter') as $module) {
698
      $function = $module . '_variable_settings_form_alter';
699
      $function($form, $form_state, $form_id);
700
    }
701
  }
702
}
703

    
704
/**
705
 * Implement validate callback.
706
 *
707
 * This needs to be in the module as it may be needed by form ajax callbacks.
708
 */
709
function variable_form_element_validate($element, &$form_state, $form) {
710
  $options = isset($form['#variable_options']) ? $form['#variable_options'] : array();
711
  $variable = $element['#variable'];
712
  variable_include($variable);
713
  $variable['value'] = isset($element['#value']) ? $element['#value'] : NULL;
714

    
715
  $error = $variable['validate callback']($variable, $options, $element, $form, $form_state);
716

    
717
  if ($error) {
718
    form_error($element, $error);
719
  }
720
}
721

    
722
/**
723
 * Implements hook_module_implements_alter().
724
 *
725
 * Move variable_form_alter() to the end of the list to give modules manipulating
726
 * variables/realms a chance to act on settings forms.
727
 *
728
 * @param $implementations
729
 *   All implementations of the given hook.
730
 * @param $hook
731
 *   Name of the hook.
732
 */
733
function variable_module_implements_alter(&$implementations, $hook) {
734
  if ($hook == 'form_alter') {
735
    $group = $implementations['variable'];
736
    unset($implementations['variable']);
737
    $implementations['variable'] = $group;
738
  }
739
}
740

    
741
/**
742
 * Group variable list by variable info property.
743
 *
744
 * @param $list
745
 *   Array of variable names or full built variables.
746
 * @param $field
747
 *   Field to group by. If empty, they will be added to the '<none>' array.
748
 *
749
 * @result
750
 *   Array of arrays indexed by that field value.
751
 */
752
function variable_group_variables($list, $field = 'group') {
753
  $groups = array();
754
  foreach ($list as $variable) {
755
    $build = _variable_variable($variable);
756
    $value = isset($build[$field]) ? $build[$field] : '<none>';
757
    $groups[$value][$build['name']] = $variable;
758
  }
759
  return $groups;
760
}
761

    
762
/**
763
 * Add default buttons to a form and set its prefix.
764
 *
765
 * @param $form
766
 *   An associative array containing the structure of the form.
767
 * @param $options
768
 *   Aditional options to pass on, like variable realm.
769
 *
770
 * @return
771
 *   The form structure.
772
 *
773
 * @see system_settings_form_submit()
774
 * @ingroup forms
775
 */
776
function variable_settings_form($form, $options = array()) {
777
  $form['#variable_options'] = $options;
778
  $form['actions']['#type'] = 'actions';
779
  $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save configuration'));
780

    
781
  if (!empty($_POST) && form_get_errors()) {
782
    drupal_set_message(t('The settings have not been saved because of the errors.'), 'error');
783
  }
784
  $form['#submit'][] = 'variable_settings_form_submit';
785
  // By default, render the form using theme_system_settings_form().
786
  if (!isset($form['#theme'])) {
787
    $form['#theme'] = 'system_settings_form';
788
  }
789
  return $form;
790
}
791

    
792
/**
793
 * Execute the system_settings_form.
794
 *
795
 * If you want node type configure style handling of your checkboxes,
796
 * add an array_filter value to your form.
797
 */
798
function variable_settings_form_submit($form, &$form_state) {
799
  // Exclude unnecessary elements.
800
  form_state_values_clean($form_state);
801
  // This may contain some realm options.
802
  $options = isset($form['#variable_options']) ? $form['#variable_options'] : array();
803

    
804
  // Now run regular settings submission but using variable_set_value()
805
  foreach ($form_state['values'] as $key => $value) {
806
    if (is_array($value) && isset($form_state['values']['array_filter'])) {
807
      $value = array_keys(array_filter($value));
808
    }
809
    // Using this function will invoke variable_update hook.
810
    variable_set_value($key, $value, $options);
811
  }
812

    
813
  drupal_set_message(t('The configuration options have been saved.'));
814
}
815

    
816
/**
817
 * Invoke hook on all modules, adding 'module' property
818
 */
819
function variable_invoke_all() {
820
  $args = func_get_args();
821
  $hook = $args[0];
822
  unset($args[0]);
823
  $return = array();
824
  foreach (module_implements($hook) as $module) {
825
    $function = $module . '_' . $hook;
826
    if (function_exists($function)) {
827
      $result = call_user_func_array($function, $args);
828
      if (isset($result) && is_array($result)) {
829
        foreach ($result as $key => $value) {
830
          $return[$key] = $value + array('module' => $module);
831
        }
832
      }
833
    }
834
  }
835
  return $return;
836
}