Completed
Push — onoffsetting ( 6388dc )
by Gerrit
04:37
created

configuration::get_plugintpl_metadata()   D

Complexity

Conditions 10
Paths 24

Size

Total Lines 37
Code Lines 25

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 37
rs 4.8196
cc 10
eloc 25
nc 24
nop 1

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Configuration Class and generic setting classes
4
 *
5
 * @author  Chris Smith <[email protected]>
6
 * @author  Ben Coburn <[email protected]>
7
 */
8
9
10
if(!defined('CM_KEYMARKER')) define('CM_KEYMARKER','____');
11
12
if (!class_exists('configuration')) {
13
    /**
14
     * Class configuration
15
     */
16
    class configuration {
17
18
        var $_name = 'conf';           // name of the config variable found in the files (overridden by $config['varname'])
19
        var $_format = 'php';          // format of the config file, supported formats - php (overridden by $config['format'])
20
        var $_heading = '';            // heading string written at top of config file - don't include comment indicators
21
        var $_loaded = false;          // set to true after configuration files are loaded
22
        var $_metadata = array();      // holds metadata describing the settings
23
        /** @var setting[]  */
24
        var $setting = array();        // array of setting objects
25
        var $locked = false;           // configuration is considered locked if it can't be updated
26
        var $show_disabled_plugins = false;
27
28
        // configuration filenames
29
        var $_default_files  = array();
30
        var $_local_files = array();      // updated configuration is written to the first file
31
        var $_protected_files = array();
32
33
        var $_plugin_list = null;
34
35
        /**
36
         * constructor
37
         *
38
         * @param string $datafile path to config metadata file
39
         */
40
        public function __construct($datafile) {
41
            global $conf, $config_cascade;
42
43
            if (!file_exists($datafile)) {
44
                msg('No configuration metadata found at - '.htmlspecialchars($datafile),-1);
45
                return;
46
            }
47
            $meta = array();
48
            include($datafile);
49
50
            if (isset($config['varname'])) $this->_name = $config['varname'];
0 ignored issues
show
Bug introduced by
The variable $config does not exist. Did you mean $config_cascade?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
51
            if (isset($config['format'])) $this->_format = $config['format'];
52
            if (isset($config['heading'])) $this->_heading = $config['heading'];
53
54
            $this->_default_files = $config_cascade['main']['default'];
55
            $this->_local_files = $config_cascade['main']['local'];
56
            $this->_protected_files = $config_cascade['main']['protected'];
57
58
            $this->locked = $this->_is_locked();
59
            $this->_metadata = array_merge($meta, $this->get_plugintpl_metadata($conf['template']));
60
            $this->retrieve_settings();
61
        }
62
63
        /**
64
         * Retrieve and stores settings in setting[] attribute
65
         */
66
        public function retrieve_settings() {
67
            global $conf;
68
            $no_default_check = array('setting_fieldset', 'setting_undefined', 'setting_no_class');
69
70
            if (!$this->_loaded) {
71
                $default = array_merge($this->get_plugintpl_default($conf['template']), $this->_read_config_group($this->_default_files));
72
                $local = $this->_read_config_group($this->_local_files);
73
                $protected = $this->_read_config_group($this->_protected_files);
74
75
                $keys = array_merge(array_keys($this->_metadata),array_keys($default), array_keys($local), array_keys($protected));
76
                $keys = array_unique($keys);
77
78
                $param = null;
79
                foreach ($keys as $key) {
80
                    if (isset($this->_metadata[$key])) {
81
                        $class = $this->_metadata[$key][0];
82
83
                        if($class && class_exists('setting_'.$class)){
84
                            $class = 'setting_'.$class;
85
                        } else {
86
                            if($class != '') {
87
                                $this->setting[] = new setting_no_class($key,$param);
88
                            }
89
                            $class = 'setting';
90
                        }
91
92
                        $param = $this->_metadata[$key];
93
                        array_shift($param);
94
                    } else {
95
                        $class = 'setting_undefined';
96
                        $param = null;
97
                    }
98
99
                    if (!in_array($class, $no_default_check) && !isset($default[$key])) {
100
                        $this->setting[] = new setting_no_default($key,$param);
101
                    }
102
103
                    $this->setting[$key] = new $class($key,$param);
104
105
                    $d = array_key_exists($key, $default) ? $default[$key] : null;
106
                    $l = array_key_exists($key, $local) ? $local[$key] : null;
107
                    $p = array_key_exists($key, $protected) ? $protected[$key] : null;
108
109
                    $this->setting[$key]->initialize($d,$l,$p);
110
                }
111
112
                $this->_loaded = true;
113
            }
114
        }
115
116
        /**
117
         * Stores setting[] array to file
118
         *
119
         * @param string $id     Name of plugin, which saves the settings
120
         * @param string $header Text at the top of the rewritten settings file
121
         * @param bool $backup   backup current file? (remove any existing backup)
122
         * @return bool succesful?
123
         */
124
        public function save_settings($id, $header='', $backup=true) {
125
            global $conf;
126
127
            if ($this->locked) return false;
128
129
            // write back to the last file in the local config cascade
130
            $file = end($this->_local_files);
131
132
            // backup current file (remove any existing backup)
133
            if (file_exists($file) && $backup) {
134
                if (file_exists($file.'.bak')) @unlink($file.'.bak');
1 ignored issue
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
135
                if (!io_rename($file, $file.'.bak')) return false;
136
            }
137
138
            if (!$fh = @fopen($file, 'wb')) {
139
                io_rename($file.'.bak', $file);     // problem opening, restore the backup
140
                return false;
141
            }
142
143
            if (empty($header)) $header = $this->_heading;
144
145
            $out = $this->_out_header($id,$header);
146
147
            foreach ($this->setting as $setting) {
148
                $out .= $setting->out($this->_name, $this->_format);
149
            }
150
151
            $out .= $this->_out_footer();
152
153
            @fwrite($fh, $out);
1 ignored issue
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
154
            fclose($fh);
155
            if($conf['fperm']) chmod($file, $conf['fperm']);
156
            return true;
157
        }
158
159
        /**
160
         * Update last modified time stamp of the config file
161
         *
162
         * @return bool
163
         */
164
        public function touch_settings(){
165
            if ($this->locked) return false;
166
            $file = end($this->_local_files);
167
            return @touch($file);
168
        }
169
170
        /**
171
         * Read and merge given config files
172
         *
173
         * @param array $files file paths
174
         * @return array config settings
175
         */
176
        protected function _read_config_group($files) {
177
            $config = array();
178
            foreach ($files as $file) {
179
                $config = array_merge($config, $this->_read_config($file));
180
            }
181
182
            return $config;
183
        }
184
185
        /**
186
         * Return an array of config settings
187
         *
188
         * @param string $file file path
189
         * @return array config settings
190
         */
191
        function _read_config($file) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
192
193
            if (!$file) return array();
194
195
            $config = array();
196
197
            if ($this->_format == 'php') {
198
199
                if(file_exists($file)){
200
                    $contents = @php_strip_whitespace($file);
201
                }else{
202
                    $contents = '';
203
                }
204
                $pattern = '/\$'.$this->_name.'\[[\'"]([^=]+)[\'"]\] ?= ?(.*?);(?=[^;]*(?:\$'.$this->_name.'|$))/s';
205
                $matches=array();
206
                preg_match_all($pattern,$contents,$matches,PREG_SET_ORDER);
207
208
                for ($i=0; $i<count($matches); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
209
                    $value = $matches[$i][2];
210
211
                    // correct issues with the incoming data
212
                    // FIXME ... for now merge multi-dimensional array indices using ____
213
                    $key = preg_replace('/.\]\[./',CM_KEYMARKER,$matches[$i][1]);
214
215
                    // handle arrays
216
                    if(preg_match('/^array ?\((.*)\)/', $value, $match)){
217
                        $arr = explode(',', $match[1]);
218
219
                        // remove quotes from quoted strings & unescape escaped data
220
                        $len = count($arr);
221
                        for($j=0; $j<$len; $j++){
222
                            $arr[$j] = trim($arr[$j]);
223
                            $arr[$j] = $this->_readValue($arr[$j]);
224
                        }
225
226
                        $value = $arr;
227
                    }else{
228
                        $value = $this->_readValue($value);
229
                    }
230
231
                    $config[$key] = $value;
232
                }
233
            }
234
235
            return $config;
236
        }
237
238
        /**
239
         * Convert php string into value
240
         *
241
         * @param string $value
242
         * @return bool|string
243
         */
244
        protected function _readValue($value) {
245
            $removequotes_pattern = '/^(\'|")(.*)(?<!\\\\)\1$/s';
246
            $unescape_pairs = array(
247
                '\\\\' => '\\',
248
                '\\\'' => '\'',
249
                '\\"' => '"'
250
            );
251
252
            if($value == 'true') {
253
                $value = true;
254
            } elseif($value == 'false') {
255
                $value = false;
256
            } else {
257
                // remove quotes from quoted strings & unescape escaped data
258
                $value = preg_replace($removequotes_pattern,'$2',$value);
259
                $value = strtr($value, $unescape_pairs);
260
            }
261
            return $value;
262
        }
263
264
        /**
265
         * Returns header of rewritten settings file
266
         *
267
         * @param string $id plugin name of which generated this output
268
         * @param string $header additional text for at top of the file
269
         * @return string text of header
270
         */
271
        protected function _out_header($id, $header) {
272
            $out = '';
273
            if ($this->_format == 'php') {
274
                $out .= '<'.'?php'."\n".
275
                      "/*\n".
276
                      " * ".$header."\n".
277
                      " * Auto-generated by ".$id." plugin\n".
278
                      " * Run for user: ".$_SERVER['REMOTE_USER']."\n".
279
                      " * Date: ".date('r')."\n".
280
                      " */\n\n";
281
            }
282
283
            return $out;
284
        }
285
286
        /**
287
         * Returns footer of rewritten settings file
288
         *
289
         * @return string text of footer
290
         */
291
        protected function _out_footer() {
292
            $out = '';
293
            if ($this->_format == 'php') {
294
                $out .= "\n// end auto-generated content\n";
295
            }
296
297
            return $out;
298
        }
299
300
        /**
301
         * Configuration is considered locked if there is no local settings filename
302
         * or the directory its in is not writable or the file exists and is not writable
303
         *
304
         * @return bool true: locked, false: writable
305
         */
306
        protected function _is_locked() {
307
            if (!$this->_local_files) return true;
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->_local_files of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
308
309
            $local = $this->_local_files[0];
310
311
            if (!is_writable(dirname($local))) return true;
312
            if (file_exists($local) && !is_writable($local)) return true;
313
314
            return false;
315
        }
316
317
        /**
318
         * not used ... conf's contents are an array!
319
         * reduce any multidimensional settings to one dimension using CM_KEYMARKER
320
         *
321
         * @param $conf
322
         * @param string $prefix
323
         * @return array
324
         */
325
        protected function _flatten($conf,$prefix='') {
326
327
            $out = array();
328
329
            foreach($conf as $key => $value) {
330
                if (!is_array($value)) {
331
                    $out[$prefix.$key] = $value;
332
                    continue;
333
                }
334
335
                $tmp = $this->_flatten($value,$prefix.$key.CM_KEYMARKER);
336
                $out = array_merge($out,$tmp);
337
            }
338
339
            return $out;
340
        }
341
342
        /**
343
         * Returns array of plugin names
344
         *
345
         * @return array plugin names
346
         * @triggers PLUGIN_CONFIG_PLUGINLIST event
347
         */
348
        function get_plugin_list() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
349
            if (is_null($this->_plugin_list)) {
350
                $list = plugin_list('',$this->show_disabled_plugins);
351
352
                // remove this plugin from the list
353
                $idx = array_search('config',$list);
354
                unset($list[$idx]);
355
356
                trigger_event('PLUGIN_CONFIG_PLUGINLIST',$list);
357
                $this->_plugin_list = $list;
358
            }
359
360
            return $this->_plugin_list;
361
        }
362
363
        /**
364
         * load metadata for plugin and template settings
365
         *
366
         * @param string $tpl name of active template
367
         * @return array metadata of settings
368
         */
369
        function get_plugintpl_metadata($tpl){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
370
            $file     = '/conf/metadata.php';
371
            $class    = '/conf/settings.class.php';
372
            $metadata = array();
373
374
            foreach ($this->get_plugin_list() as $plugin) {
375
                $plugin_dir = plugin_directory($plugin);
376
                if (file_exists(DOKU_PLUGIN.$plugin_dir.$file)){
377
                    $meta = array();
378
                    @include(DOKU_PLUGIN.$plugin_dir.$file);
1 ignored issue
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
379
                    @include(DOKU_PLUGIN.$plugin_dir.$class);
1 ignored issue
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
380
                    if (!empty($meta)) {
381
                        $metadata['plugin'.CM_KEYMARKER.$plugin.CM_KEYMARKER.'plugin_settings_name'] = array('fieldset');
382
                    }
383
                    foreach ($meta as $key => $value){
384
                        if ($value[0]=='fieldset') { continue; } //plugins only get one fieldset
385
                        $metadata['plugin'.CM_KEYMARKER.$plugin.CM_KEYMARKER.$key] = $value;
386
                    }
387
                }
388
            }
389
390
            // the same for the active template
391
            if (file_exists(tpl_incdir().$file)){
392
                $meta = array();
393
                @include(tpl_incdir().$file);
1 ignored issue
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
394
                @include(tpl_incdir().$class);
1 ignored issue
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
395
                if (!empty($meta)) {
396
                    $metadata['tpl'.CM_KEYMARKER.$tpl.CM_KEYMARKER.'template_settings_name'] = array('fieldset');
397
                }
398
                foreach ($meta as $key => $value){
399
                    if ($value[0]=='fieldset') { continue; } //template only gets one fieldset
400
                    $metadata['tpl'.CM_KEYMARKER.$tpl.CM_KEYMARKER.$key] = $value;
401
                }
402
            }
403
404
            return $metadata;
405
        }
406
407
        /**
408
         * Load default settings for plugins and templates
409
         *
410
         * @param string $tpl name of active template
411
         * @return array default settings
412
         */
413
        function get_plugintpl_default($tpl){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
414
            $file    = '/conf/default.php';
415
            $default = array();
416
417
            foreach ($this->get_plugin_list() as $plugin) {
418
                $plugin_dir = plugin_directory($plugin);
419
                if (file_exists(DOKU_PLUGIN.$plugin_dir.$file)){
420
                    $conf = $this->_read_config(DOKU_PLUGIN.$plugin_dir.$file);
421
                    foreach ($conf as $key => $value){
422
                        $default['plugin'.CM_KEYMARKER.$plugin.CM_KEYMARKER.$key] = $value;
423
                    }
424
                }
425
            }
426
427
            // the same for the active template
428
            if (file_exists(tpl_incdir().$file)){
429
                $conf = $this->_read_config(tpl_incdir().$file);
430
                foreach ($conf as $key => $value){
431
                    $default['tpl'.CM_KEYMARKER.$tpl.CM_KEYMARKER.$key] = $value;
432
                }
433
            }
434
435
            return $default;
436
        }
437
438
    }
439
}
440
441
if (!class_exists('setting')) {
442
    /**
443
     * Class setting
444
     */
445
    class setting {
446
447
        var $_key = '';
448
        var $_default = null;
449
        var $_local = null;
450
        var $_protected = null;
451
452
        var $_pattern = '';
453
        var $_error = false;            // only used by those classes which error check
454
        var $_input = null;             // only used by those classes which error check
455
        var $_caution = null;           // used by any setting to provide an alert along with the setting
456
                                        // valid alerts, 'warning', 'danger', 'security'
457
                                        // images matching the alerts are in the plugin's images directory
458
459
        static protected $_validCautions = array('warning','danger','security');
460
461
        /**
462
         * @param string $key
463
         * @param array|null $params array with metadata of setting
464
         */
465
        public function __construct($key, $params=null) {
466
            $this->_key = $key;
467
468
            if (is_array($params)) {
469
                foreach($params as $property => $value) {
470
                    $this->$property = $value;
471
                }
472
            }
473
        }
474
475
        /**
476
         * Receives current values for the setting $key
477
         *
478
         * @param mixed $default   default setting value
479
         * @param mixed $local     local setting value
480
         * @param mixed $protected protected setting value
481
         */
482
        public function initialize($default, $local, $protected) {
483
            if (isset($default)) $this->_default = $default;
484
            if (isset($local)) $this->_local = $local;
485
            if (isset($protected)) $this->_protected = $protected;
486
        }
487
488
        /**
489
         * update changed setting with user provided value $input
490
         * - if changed value fails error check, save it to $this->_input (to allow echoing later)
491
         * - if changed value passes error check, set $this->_local to the new value
492
         *
493
         * @param  mixed   $input   the new value
494
         * @return boolean          true if changed, false otherwise (also on error)
495
         */
496
        public function update($input) {
497
            if (is_null($input)) return false;
498
            if ($this->is_protected()) return false;
499
500
            $value = is_null($this->_local) ? $this->_default : $this->_local;
501
            if ($value == $input) return false;
502
503
            if ($this->_pattern && !preg_match($this->_pattern,$input)) {
504
                $this->_error = true;
505
                $this->_input = $input;
506
                return false;
507
            }
508
509
            $this->_local = $input;
510
            return true;
511
        }
512
513
        /**
514
         * Build html for label and input of setting
515
         *
516
         * @param DokuWiki_Plugin $plugin object of config plugin
517
         * @param bool            $echo   true: show inputted value, when error occurred, otherwise the stored setting
518
         * @return string[] with content array(string $label_html, string $input_html)
519
         */
520
        public function html(&$plugin, $echo=false) {
521
            $disable = '';
522
523
            if ($this->is_protected()) {
524
                $value = $this->_protected;
525
                $disable = 'disabled="disabled"';
526
            } else {
527
                if ($echo && $this->_error) {
528
                    $value = $this->_input;
529
                } else {
530
                    $value = is_null($this->_local) ? $this->_default : $this->_local;
531
                }
532
            }
533
534
            $key = htmlspecialchars($this->_key);
535
            $value = formText($value);
536
537
            $label = '<label for="config___'.$key.'">'.$this->prompt($plugin).'</label>';
538
            $input = '<textarea rows="3" cols="40" id="config___'.$key.'" name="config['.$key.']" class="edit" '.$disable.'>'.$value.'</textarea>';
539
            return array($label,$input);
540
        }
541
542
        /**
543
         * Generate string to save setting value to file according to $fmt
544
         *
545
         * @param string $var name of variable
546
         * @param string $fmt save format
547
         * @return string
548
         */
549
        public function out($var, $fmt='php') {
550
551
            if ($this->is_protected()) return '';
552
            if (is_null($this->_local) || ($this->_default == $this->_local)) return '';
553
554
            $out = '';
555
556
            if ($fmt=='php') {
557
                $tr = array("\\" => '\\\\', "'" => '\\\'');
558
559
                $out =  '$'.$var."['".$this->_out_key()."'] = '".strtr( cleanText($this->_local), $tr)."';\n";
560
            }
561
562
            return $out;
563
        }
564
565
        /**
566
         * Returns the localized prompt
567
         *
568
         * @param DokuWiki_Plugin $plugin object of config plugin
569
         * @return string text
570
         */
571
        public function prompt(&$plugin) {
572
            $prompt = $plugin->getLang($this->_key);
573
            if (!$prompt) $prompt = htmlspecialchars(str_replace(array('____','_'),' ',$this->_key));
574
            return $prompt;
575
        }
576
577
        /**
578
         * Is setting protected
579
         *
580
         * @return bool
581
         */
582
        public function is_protected() { return !is_null($this->_protected); }
583
584
        /**
585
         * Is setting the default?
586
         *
587
         * @return bool
588
         */
589
        public function is_default() { return !$this->is_protected() && is_null($this->_local); }
590
591
        /**
592
         * Has an error?
593
         *
594
         * @return bool
595
         */
596
        public function error() { return $this->_error; }
597
598
        /**
599
         * Returns caution
600
         *
601
         * @return false|string caution string, otherwise false for invalid caution
602
         */
603
        public function caution() {
604
            if (!empty($this->_caution)) {
605
                if (!in_array($this->_caution, setting::$_validCautions)) {
606
                    trigger_error('Invalid caution string ('.$this->_caution.') in metadata for setting "'.$this->_key.'"', E_USER_WARNING);
607
                    return false;
608
                }
609
                return $this->_caution;
610
            }
611
            // compatibility with previous cautionList
612
            // TODO: check if any plugins use; remove
613
            if (!empty($this->_cautionList[$this->_key])) {
0 ignored issues
show
Bug introduced by
The property _cautionList does not seem to exist. Did you mean _caution?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
614
                $this->_caution = $this->_cautionList[$this->_key];
0 ignored issues
show
Bug introduced by
The property _cautionList does not seem to exist. Did you mean _caution?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
615
                unset($this->_cautionList);
616
617
                return $this->caution();
618
            }
619
            return false;
620
        }
621
622
        /**
623
         * Returns setting key, eventually with referer to config: namespace at dokuwiki.org
624
         *
625
         * @param bool $pretty create nice key
626
         * @param bool $url    provide url to config: namespace
627
         * @return string key
628
         */
629
        public function _out_key($pretty=false,$url=false) {
630
            if($pretty){
631
                $out = str_replace(CM_KEYMARKER,"»",$this->_key);
632
                if ($url && !strstr($out,'»')) {//provide no urls for plugins, etc.
633
                    if ($out == 'start') //one exception
634
                        return '<a href="http://www.dokuwiki.org/config:startpage">'.$out.'</a>';
635
                    else
636
                        return '<a href="http://www.dokuwiki.org/config:'.$out.'">'.$out.'</a>';
637
                }
638
                return $out;
639
            }else{
640
                return str_replace(CM_KEYMARKER,"']['",$this->_key);
641
            }
642
        }
643
    }
644
}
645
646
647
if (!class_exists('setting_array')) {
648
    /**
649
     * Class setting_array
650
     */
651
    class setting_array extends setting {
652
653
        /**
654
         * Create an array from a string
655
         *
656
         * @param string $string
657
         * @return array
658
         */
659
        protected function _from_string($string){
660
            $array = explode(',', $string);
661
            $array = array_map('trim', $array);
662
            $array = array_filter($array);
663
            $array = array_unique($array);
664
            return $array;
665
        }
666
667
        /**
668
         * Create a string from an array
669
         *
670
         * @param array $array
671
         * @return string
672
         */
673
        protected function _from_array($array){
674
            return join(', ', (array) $array);
675
        }
676
677
        /**
678
         * update setting with user provided value $input
679
         * if value fails error check, save it
680
         *
681
         * @param string $input
682
         * @return bool true if changed, false otherwise (incl. on error)
683
         */
684
        function update($input) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
685
            if (is_null($input)) return false;
686
            if ($this->is_protected()) return false;
687
688
            $input = $this->_from_string($input);
689
690
            $value = is_null($this->_local) ? $this->_default : $this->_local;
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
Bug introduced by
The property _default cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
691
            if ($value == $input) return false;
692
693
            foreach($input as $item){
694
                if ($this->_pattern && !preg_match($this->_pattern,$item)) {
0 ignored issues
show
Bug introduced by
The property _pattern cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
695
                    $this->_error = true;
0 ignored issues
show
Bug introduced by
The property _error cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
696
                    $this->_input = $input;
0 ignored issues
show
Bug introduced by
The property _input cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
697
                    return false;
698
                }
699
            }
700
701
            $this->_local = $input;
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
702
            return true;
703
        }
704
705
        /**
706
         * Escaping
707
         *
708
         * @param string $string
709
         * @return string
710
         */
711
        protected function _escape($string) {
712
            $tr = array("\\" => '\\\\', "'" => '\\\'');
713
            return "'".strtr( cleanText($string), $tr)."'";
714
        }
715
716
        /**
717
         * Generate string to save setting value to file according to $fmt
718
         *
719
         * @param string $var name of variable
720
         * @param string $fmt save format
721
         * @return string
722
         */
723
        function out($var, $fmt='php') {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
724
725
            if ($this->is_protected()) return '';
726
            if (is_null($this->_local) || ($this->_default == $this->_local)) return '';
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
Bug introduced by
The property _default cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
727
728
            $out = '';
729
730
            if ($fmt=='php') {
731
                $vals = array_map(array($this, '_escape'), $this->_local);
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
732
                $out =  '$'.$var."['".$this->_out_key()."'] = array(".join(', ',$vals).");\n";
733
            }
734
735
            return $out;
736
        }
737
738
        /**
739
         * Build html for label and input of setting
740
         *
741
         * @param DokuWiki_Plugin $plugin object of config plugin
742
         * @param bool            $echo   true: show inputted value, when error occurred, otherwise the stored setting
743
         * @return string[] with content array(string $label_html, string $input_html)
744
         */
745
        function html(&$plugin, $echo=false) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
746
            $disable = '';
747
748
            if ($this->is_protected()) {
749
                $value = $this->_protected;
0 ignored issues
show
Bug introduced by
The property _protected cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
750
                $disable = 'disabled="disabled"';
751
            } else {
752
                if ($echo && $this->_error) {
0 ignored issues
show
Bug introduced by
The property _error cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
753
                    $value = $this->_input;
0 ignored issues
show
Bug introduced by
The property _input cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
754
                } else {
755
                    $value = is_null($this->_local) ? $this->_default : $this->_local;
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
Bug introduced by
The property _default cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
756
                }
757
            }
758
759
            $key = htmlspecialchars($this->_key);
0 ignored issues
show
Bug introduced by
The property _key cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
760
            $value = htmlspecialchars($this->_from_array($value));
761
762
            $label = '<label for="config___'.$key.'">'.$this->prompt($plugin).'</label>';
763
            $input = '<input id="config___'.$key.'" name="config['.$key.']" type="text" class="edit" value="'.$value.'" '.$disable.'/>';
764
            return array($label,$input);
765
        }
766
    }
767
}
768
769
if (!class_exists('setting_string')) {
770
    /**
771
     * Class setting_string
772
     */
773
    class setting_string extends setting {
774
        /**
775
         * Build html for label and input of setting
776
         *
777
         * @param DokuWiki_Plugin $plugin object of config plugin
778
         * @param bool            $echo   true: show inputted value, when error occurred, otherwise the stored setting
779
         * @return string[] with content array(string $label_html, string $input_html)
780
         */
781
        function html(&$plugin, $echo=false) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
782
            $disable = '';
783
784
            if ($this->is_protected()) {
785
                $value = $this->_protected;
0 ignored issues
show
Bug introduced by
The property _protected cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
786
                $disable = 'disabled="disabled"';
787
            } else {
788
                if ($echo && $this->_error) {
0 ignored issues
show
Bug introduced by
The property _error cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
789
                    $value = $this->_input;
0 ignored issues
show
Bug introduced by
The property _input cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
790
                } else {
791
                    $value = is_null($this->_local) ? $this->_default : $this->_local;
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
Bug introduced by
The property _default cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
792
                }
793
            }
794
795
            $key = htmlspecialchars($this->_key);
0 ignored issues
show
Bug introduced by
The property _key cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
796
            $value = htmlspecialchars($value);
797
798
            $label = '<label for="config___'.$key.'">'.$this->prompt($plugin).'</label>';
799
            $input = '<input id="config___'.$key.'" name="config['.$key.']" type="text" class="edit" value="'.$value.'" '.$disable.'/>';
800
            return array($label,$input);
801
        }
802
    }
803
}
804
805
if (!class_exists('setting_password')) {
806
    /**
807
     * Class setting_password
808
     */
809
    class setting_password extends setting_string {
810
811
        var $_code = 'plain';  // mechanism to be used to obscure passwords
812
813
        /**
814
         * update changed setting with user provided value $input
815
         * - if changed value fails error check, save it to $this->_input (to allow echoing later)
816
         * - if changed value passes error check, set $this->_local to the new value
817
         *
818
         * @param  mixed   $input   the new value
819
         * @return boolean          true if changed, false otherwise (also on error)
820
         */
821
        function update($input) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
822
            if ($this->is_protected()) return false;
823
            if (!$input) return false;
824
825
            if ($this->_pattern && !preg_match($this->_pattern,$input)) {
0 ignored issues
show
Bug introduced by
The property _pattern cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
826
                $this->_error = true;
0 ignored issues
show
Bug introduced by
The property _error cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
827
                $this->_input = $input;
0 ignored issues
show
Bug introduced by
The property _input cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
828
                return false;
829
            }
830
831
            $this->_local = conf_encodeString($input,$this->_code);
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
832
            return true;
833
        }
834
835
        /**
836
         * Build html for label and input of setting
837
         *
838
         * @param DokuWiki_Plugin $plugin object of config plugin
839
         * @param bool            $echo   true: show inputted value, when error occurred, otherwise the stored setting
840
         * @return string[] with content array(string $label_html, string $input_html)
841
         */
842
        function html(&$plugin, $echo=false) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
843
844
            $disable = $this->is_protected() ? 'disabled="disabled"' : '';
845
846
            $key = htmlspecialchars($this->_key);
0 ignored issues
show
Bug introduced by
The property _key cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
847
848
            $label = '<label for="config___'.$key.'">'.$this->prompt($plugin).'</label>';
849
            $input = '<input id="config___'.$key.'" name="config['.$key.']" autocomplete="off" type="password" class="edit" value="" '.$disable.' />';
850
            return array($label,$input);
851
        }
852
    }
853
}
854
855
if (!class_exists('setting_email')) {
856
    /**
857
     * Class setting_email
858
     */
859
    class setting_email extends setting_string {
860
        var $_multiple = false;
861
        var $_placeholders = false;
862
863
        /**
864
         * update setting with user provided value $input
865
         * if value fails error check, save it
866
         *
867
         * @param mixed $input
868
         * @return boolean true if changed, false otherwise (incl. on error)
869
         */
870
        function update($input) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
871
            if (is_null($input)) return false;
872
            if ($this->is_protected()) return false;
873
874
            $value = is_null($this->_local) ? $this->_default : $this->_local;
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
Bug introduced by
The property _default cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
875
            if ($value == $input) return false;
876
            if($input === ''){
877
                $this->_local = $input;
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
878
                return true;
879
            }
880
            $mail = $input;
881
882
            if($this->_placeholders){
883
                // replace variables with pseudo values
884
                $mail = str_replace('@USER@','joe',$mail);
885
                $mail = str_replace('@NAME@','Joe Schmoe',$mail);
886
                $mail = str_replace('@MAIL@','[email protected]',$mail);
887
            }
888
889
            // multiple mail addresses?
890
            if ($this->_multiple) {
891
                $mails = array_filter(array_map('trim', explode(',', $mail)));
892
            } else {
893
                $mails = array($mail);
894
            }
895
896
            // check them all
897
            foreach ($mails as $mail) {
898
                // only check the address part
899
                if(preg_match('#(.*?)<(.*?)>#', $mail, $matches)){
900
                    $addr = $matches[2];
901
                }else{
902
                    $addr = $mail;
903
                }
904
905
                if (!mail_isvalid($addr)) {
906
                    $this->_error = true;
0 ignored issues
show
Bug introduced by
The property _error cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
907
                    $this->_input = $input;
0 ignored issues
show
Bug introduced by
The property _input cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
908
                    return false;
909
                }
910
            }
911
912
            $this->_local = $input;
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
913
            return true;
914
        }
915
    }
916
}
917
918
if (!class_exists('setting_numeric')) {
919
    /**
920
     * Class setting_numeric
921
     */
922
    class setting_numeric extends setting_string {
923
        // This allows for many PHP syntax errors...
924
        // var $_pattern = '/^[-+\/*0-9 ]*$/';
925
        // much more restrictive, but should eliminate syntax errors.
926
        var $_pattern = '/^[-+]? *[0-9]+ *(?:[-+*] *[0-9]+ *)*$/';
927
        var $_min = null;
928
        var $_max = null;
929
930
        /**
931
         * update changed setting with user provided value $input
932
         * - if changed value fails error check, save it to $this->_input (to allow echoing later)
933
         * - if changed value passes error check, set $this->_local to the new value
934
         *
935
         * @param  mixed   $input   the new value
936
         * @return boolean          true if changed, false otherwise (also on error)
937
         */
938
        function update($input) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
939
            $local = $this->_local;
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
940
            $valid = parent::update($input);
941
            if ($valid && !(is_null($this->_min) && is_null($this->_max))) {
942
                $numeric_local = (int) eval('return '.$this->_local.';');
943
                if ((!is_null($this->_min) && $numeric_local < $this->_min) ||
944
                    (!is_null($this->_max) && $numeric_local > $this->_max)) {
945
                    $this->_error = true;
0 ignored issues
show
Bug introduced by
The property _error cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
946
                    $this->_input = $input;
0 ignored issues
show
Bug introduced by
The property _input cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
947
                    $this->_local = $local;
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
948
                    $valid = false;
949
                }
950
            }
951
            return $valid;
952
        }
953
954
        /**
955
         * Generate string to save setting value to file according to $fmt
956
         *
957
         * @param string $var name of variable
958
         * @param string $fmt save format
959
         * @return string
960
         */
961
        function out($var, $fmt='php') {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
962
963
            if ($this->is_protected()) return '';
964
            if (is_null($this->_local) || ($this->_default == $this->_local)) return '';
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
Bug introduced by
The property _default cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
965
966
            $out = '';
967
968
            if ($fmt=='php') {
969
                $local = $this->_local === '' ? "''" : $this->_local;
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
970
                $out .=  '$'.$var."['".$this->_out_key()."'] = ".$local.";\n";
971
            }
972
973
            return $out;
974
        }
975
    }
976
}
977
978
if (!class_exists('setting_numericopt')) {
979
    /**
980
     * Class setting_numericopt
981
     */
982
    class setting_numericopt extends setting_numeric {
983
        // just allow an empty config
984
        var $_pattern = '/^(|[-]?[0-9]+(?:[-+*][0-9]+)*)$/';
985
    }
986
}
987
988
if (!class_exists('setting_onoff')) {
989
    /**
990
     * Class setting_onoff
991
     */
992
    class setting_onoff extends setting_numeric {
993
        /**
994
         * Build html for label and input of setting
995
         *
996
         * @param DokuWiki_Plugin $plugin object of config plugin
997
         * @param bool            $echo   true: show inputted value, when error occurred, otherwise the stored setting
998
         * @return string[] with content array(string $label_html, string $input_html)
999
         */
1000
        function html(&$plugin, $echo = false) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1001
            $disable = '';
1002
1003
            if ($this->is_protected()) {
1004
                $value = $this->_protected;
0 ignored issues
show
Bug introduced by
The property _protected cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1005
                $disable = ' disabled="disabled"';
1006
            } else {
1007
                $value = is_null($this->_local) ? $this->_default : $this->_local;
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
Bug introduced by
The property _default cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1008
            }
1009
1010
            $key = htmlspecialchars($this->_key);
0 ignored issues
show
Bug introduced by
The property _key cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1011
            $checked = ($value) ? ' checked="checked"' : '';
1012
1013
            $label = '<label for="config___'.$key.'">'.$this->prompt($plugin).'</label>';
1014
            $input = '<div class="input"><input id="config___'.$key.'" name="config['.$key.']" type="checkbox" class="checkbox" value="1"'.$checked.$disable.'/></div>';
1015
            return array($label,$input);
1016
        }
1017
1018
        /**
1019
         * update changed setting with user provided value $input
1020
         * - if changed value fails error check, save it to $this->_input (to allow echoing later)
1021
         * - if changed value passes error check, set $this->_local to the new value
1022
         *
1023
         * @param  mixed   $input   the new value
1024
         * @return boolean          true if changed, false otherwise (also on error)
1025
         */
1026
        function update($input) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1027
            if ($this->is_protected()) return false;
1028
1029
            $input = ($input) ? 1 : 0;
1030
            $value = is_null($this->_local) ? $this->_default : $this->_local;
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
Bug introduced by
The property _default cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1031
            if ($value == $input) return false;
1032
1033
            $this->_local = $input;
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1034
            return true;
1035
        }
1036
    }
1037
}
1038
1039
if (!class_exists('setting_multichoice')) {
1040
    /**
1041
     * Class setting_multichoice
1042
     */
1043
    class setting_multichoice extends setting_string {
1044
        var $_choices = array();
1045
        var $lang; //some custom language strings are stored in setting
1046
1047
        /**
1048
         * Build html for label and input of setting
1049
         *
1050
         * @param DokuWiki_Plugin $plugin object of config plugin
1051
         * @param bool            $echo   true: show inputted value, when error occurred, otherwise the stored setting
1052
         * @return string[] with content array(string $label_html, string $input_html)
1053
         */
1054
        function html(&$plugin, $echo = false) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1055
            $disable = '';
1056
            $nochoice = '';
1057
1058
            if ($this->is_protected()) {
1059
                $value = $this->_protected;
0 ignored issues
show
Bug introduced by
The property _protected cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1060
                $disable = ' disabled="disabled"';
1061
            } else {
1062
                $value = is_null($this->_local) ? $this->_default : $this->_local;
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
Bug introduced by
The property _default cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1063
            }
1064
1065
            // ensure current value is included
1066
            if (!in_array($value, $this->_choices)) {
1067
                $this->_choices[] = $value;
1068
            }
1069
            // disable if no other choices
1070
            if (!$this->is_protected() && count($this->_choices) <= 1) {
1071
                $disable = ' disabled="disabled"';
1072
                $nochoice = $plugin->getLang('nochoice');
1073
            }
1074
1075
            $key = htmlspecialchars($this->_key);
0 ignored issues
show
Bug introduced by
The property _key cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1076
1077
            $label = '<label for="config___'.$key.'">'.$this->prompt($plugin).'</label>';
1078
1079
            $input = "<div class=\"input\">\n";
1080
            $input .= '<select class="edit" id="config___'.$key.'" name="config['.$key.']"'.$disable.'>'."\n";
1081
            foreach ($this->_choices as $choice) {
1082
                $selected = ($value == $choice) ? ' selected="selected"' : '';
1083
                $option = $plugin->getLang($this->_key.'_o_'.$choice);
0 ignored issues
show
Bug introduced by
The property _key cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1084
                if (!$option && isset($this->lang[$this->_key.'_o_'.$choice])) $option = $this->lang[$this->_key.'_o_'.$choice];
0 ignored issues
show
Bug introduced by
The property _key cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1085
                if (!$option) $option = $choice;
1086
1087
                $choice = htmlspecialchars($choice);
1088
                $option = htmlspecialchars($option);
1089
                $input .= '  <option value="'.$choice.'"'.$selected.' >'.$option.'</option>'."\n";
1090
            }
1091
            $input .= "</select> $nochoice \n";
1092
            $input .= "</div>\n";
1093
1094
            return array($label,$input);
1095
        }
1096
1097
        /**
1098
         * update changed setting with user provided value $input
1099
         * - if changed value fails error check, save it to $this->_input (to allow echoing later)
1100
         * - if changed value passes error check, set $this->_local to the new value
1101
         *
1102
         * @param  mixed   $input   the new value
1103
         * @return boolean          true if changed, false otherwise (also on error)
1104
         */
1105
        function update($input) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1106
            if (is_null($input)) return false;
1107
            if ($this->is_protected()) return false;
1108
1109
            $value = is_null($this->_local) ? $this->_default : $this->_local;
0 ignored issues
show
Bug introduced by
The property _default cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1110
            if ($value == $input) return false;
1111
1112
            if (!in_array($input, $this->_choices)) return false;
1113
1114
            $this->_local = $input;
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1115
            return true;
1116
        }
1117
    }
1118
}
1119
1120
1121
if (!class_exists('setting_dirchoice')) {
1122
    /**
1123
     * Class setting_dirchoice
1124
     */
1125
    class setting_dirchoice extends setting_multichoice {
1126
1127
        var $_dir = '';
1128
1129
        /**
1130
         * Receives current values for the setting $key
1131
         *
1132
         * @param mixed $default   default setting value
1133
         * @param mixed $local     local setting value
1134
         * @param mixed $protected protected setting value
1135
         */
1136
        function initialize($default,$local,$protected) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1137
1138
            // populate $this->_choices with a list of directories
1139
            $list = array();
1140
1141
            if ($dh = @opendir($this->_dir)) {
1142
                while (false !== ($entry = readdir($dh))) {
1143
                    if ($entry == '.' || $entry == '..') continue;
1144
                    if ($this->_pattern && !preg_match($this->_pattern,$entry)) continue;
0 ignored issues
show
Bug introduced by
The property _pattern cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1145
1146
                    $file = (is_link($this->_dir.$entry)) ? readlink($this->_dir.$entry) : $this->_dir.$entry;
1147
                    if (is_dir($file)) $list[] = $entry;
1148
                }
1149
                closedir($dh);
1150
            }
1151
            sort($list);
1152
            $this->_choices = $list;
0 ignored issues
show
Bug introduced by
The property _choices cannot be accessed from this context as it is declared private in class setting_multichoice.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1153
1154
            parent::initialize($default,$local,$protected);
1155
        }
1156
    }
1157
}
1158
1159
1160
if (!class_exists('setting_hidden')) {
1161
    /**
1162
     * Class setting_hidden
1163
     */
1164
    class setting_hidden extends setting {
1165
        // Used to explicitly ignore a setting in the configuration manager.
1166
    }
1167
}
1168
1169
if (!class_exists('setting_fieldset')) {
1170
    /**
1171
     * Class setting_fieldset
1172
     */
1173
    class setting_fieldset extends setting {
1174
        // A do-nothing class used to detect the 'fieldset' type.
1175
        // Used to start a new settings "display-group".
1176
    }
1177
}
1178
1179
if (!class_exists('setting_undefined')) {
1180
    /**
1181
     * Class setting_undefined
1182
     */
1183
    class setting_undefined extends setting_hidden {
1184
        // A do-nothing class used to detect settings with no metadata entry.
1185
        // Used internaly to hide undefined settings, and generate the undefined settings list.
1186
    }
1187
}
1188
1189
if (!class_exists('setting_no_class')) {
1190
    /**
1191
     * Class setting_no_class
1192
     */
1193
    class setting_no_class extends setting_undefined {
1194
        // A do-nothing class used to detect settings with a missing setting class.
1195
        // Used internaly to hide undefined settings, and generate the undefined settings list.
1196
    }
1197
}
1198
1199
if (!class_exists('setting_no_default')) {
1200
    /**
1201
     * Class setting_no_default
1202
     */
1203
    class setting_no_default extends setting_undefined {
1204
        // A do-nothing class used to detect settings with no default value.
1205
        // Used internaly to hide undefined settings, and generate the undefined settings list.
1206
    }
1207
}
1208
1209
if (!class_exists('setting_multicheckbox')) {
1210
    /**
1211
     * Class setting_multicheckbox
1212
     */
1213
    class setting_multicheckbox extends setting_string {
1214
1215
        var $_choices = array();
1216
        var $_combine = array();
1217
        var $_other = 'always';
1218
1219
        /**
1220
         * update changed setting with user provided value $input
1221
         * - if changed value fails error check, save it to $this->_input (to allow echoing later)
1222
         * - if changed value passes error check, set $this->_local to the new value
1223
         *
1224
         * @param  mixed   $input   the new value
1225
         * @return boolean          true if changed, false otherwise (also on error)
1226
         */
1227
        function update($input) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1228
            if ($this->is_protected()) return false;
1229
1230
            // split any combined values + convert from array to comma separated string
1231
            $input = ($input) ? $input : array();
1232
            $input = $this->_array2str($input);
1233
1234
            $value = is_null($this->_local) ? $this->_default : $this->_local;
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
Bug introduced by
The property _default cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1235
            if ($value == $input) return false;
1236
1237
            if ($this->_pattern && !preg_match($this->_pattern,$input)) {
0 ignored issues
show
Bug introduced by
The property _pattern cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1238
                $this->_error = true;
0 ignored issues
show
Bug introduced by
The property _error cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1239
                $this->_input = $input;
0 ignored issues
show
Bug introduced by
The property _input cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1240
                return false;
1241
            }
1242
1243
            $this->_local = $input;
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1244
            return true;
1245
        }
1246
1247
        /**
1248
         * Build html for label and input of setting
1249
         *
1250
         * @param DokuWiki_Plugin $plugin object of config plugin
1251
         * @param bool            $echo   true: show input value, when error occurred, otherwise the stored setting
1252
         * @return string[] with content array(string $label_html, string $input_html)
1253
         */
1254
        function html(&$plugin, $echo=false) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1255
1256
            $disable = '';
1257
1258
            if ($this->is_protected()) {
1259
                $value = $this->_protected;
0 ignored issues
show
Bug introduced by
The property _protected cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1260
                $disable = 'disabled="disabled"';
1261
            } else {
1262
                if ($echo && $this->_error) {
0 ignored issues
show
Bug introduced by
The property _error cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1263
                    $value = $this->_input;
0 ignored issues
show
Bug introduced by
The property _input cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1264
                } else {
1265
                    $value = is_null($this->_local) ? $this->_default : $this->_local;
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
Bug introduced by
The property _default cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1266
                }
1267
            }
1268
1269
            $key = htmlspecialchars($this->_key);
0 ignored issues
show
Bug introduced by
The property _key cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1270
1271
            // convert from comma separated list into array + combine complimentary actions
1272
            $value = $this->_str2array($value);
1273
            $default = $this->_str2array($this->_default);
0 ignored issues
show
Bug introduced by
The property _default cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1274
1275
            $input = '';
1276
            foreach ($this->_choices as $choice) {
1277
                $idx = array_search($choice, $value);
1278
                $idx_default = array_search($choice,$default);
1279
1280
                $checked = ($idx !== false) ? 'checked="checked"' : '';
1281
1282
                // @todo ideally this would be handled using a second class of "default"
1283
                $class = (($idx !== false) == (false !== $idx_default)) ? " selectiondefault" : "";
1284
1285
                $prompt = ($plugin->getLang($this->_key.'_'.$choice) ?
0 ignored issues
show
Bug introduced by
The property _key cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1286
                                $plugin->getLang($this->_key.'_'.$choice) : htmlspecialchars($choice));
0 ignored issues
show
Bug introduced by
The property _key cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1287
1288
                $input .= '<div class="selection'.$class.'">'."\n";
1289
                $input .= '<label for="config___'.$key.'_'.$choice.'">'.$prompt."</label>\n";
1290
                $input .= '<input id="config___'.$key.'_'.$choice.'" name="config['.$key.'][]" type="checkbox" class="checkbox" value="'.$choice.'" '.$disable.' '.$checked."/>\n";
1291
                $input .= "</div>\n";
1292
1293
                // remove this action from the disabledactions array
1294
                if ($idx !== false) unset($value[$idx]);
1295
                if ($idx_default !== false) unset($default[$idx_default]);
1296
            }
1297
1298
            // handle any remaining values
1299
            if ($this->_other != 'never'){
1300
                $other = join(',',$value);
1301
                // test equivalent to ($this->_other == 'always' || ($other && $this->_other == 'exists')
1302
                // use != 'exists' rather than == 'always' to ensure invalid values default to 'always'
1303
                if ($this->_other != 'exists' || $other) {
1304
1305
                    $class = ((count($default) == count($value)) && (count($value) == count(array_intersect($value,$default)))) ?
1306
                                    " selectiondefault" : "";
1307
1308
                    $input .= '<div class="other'.$class.'">'."\n";
1309
                    $input .= '<label for="config___'.$key.'_other">'.$plugin->getLang($key.'_other')."</label>\n";
1310
                    $input .= '<input id="config___'.$key.'_other" name="config['.$key.'][other]" type="text" class="edit" value="'.htmlspecialchars($other).'" '.$disable." />\n";
1311
                    $input .= "</div>\n";
1312
                }
1313
            }
1314
            $label = '<label>'.$this->prompt($plugin).'</label>';
1315
            return array($label,$input);
1316
        }
1317
1318
        /**
1319
         * convert comma separated list to an array and combine any complimentary values
1320
         *
1321
         * @param string $str
1322
         * @return array
1323
         */
1324
        function _str2array($str) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1325
            $array = explode(',',$str);
1326
1327
            if (!empty($this->_combine)) {
1328
                foreach ($this->_combine as $key => $combinators) {
1329
                    $idx = array();
1330
                    foreach ($combinators as $val) {
1331
                        if  (($idx[] = array_search($val, $array)) === false) break;
1332
                    }
1333
1334
                    if (count($idx) && $idx[count($idx)-1] !== false) {
1335
                        foreach ($idx as $i) unset($array[$i]);
1336
                        $array[] = $key;
1337
                    }
1338
                }
1339
            }
1340
1341
            return $array;
1342
        }
1343
1344
        /**
1345
         * convert array of values + other back to a comma separated list, incl. splitting any combined values
1346
         *
1347
         * @param array $input
1348
         * @return string
1349
         */
1350
        function _array2str($input) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1351
1352
            // handle other
1353
            $other = trim($input['other']);
1354
            $other = !empty($other) ? explode(',',str_replace(' ','',$input['other'])) : array();
1355
            unset($input['other']);
1356
1357
            $array = array_unique(array_merge($input, $other));
1358
1359
            // deconstruct any combinations
1360
            if (!empty($this->_combine)) {
1361
                foreach ($this->_combine as $key => $combinators) {
1362
1363
                    $idx = array_search($key,$array);
1364
                    if ($idx !== false) {
1365
                        unset($array[$idx]);
1366
                        $array = array_merge($array, $combinators);
1367
                    }
1368
                }
1369
            }
1370
1371
            return join(',',array_unique($array));
1372
        }
1373
    }
1374
}
1375
1376
if (!class_exists('setting_regex')){
1377
    /**
1378
     * Class setting_regex
1379
     */
1380
    class setting_regex extends setting_string {
1381
1382
        var $_delimiter = '/';    // regex delimiter to be used in testing input
1383
        var $_pregflags = 'ui';   // regex pattern modifiers to be used in testing input
1384
1385
        /**
1386
         * update changed setting with user provided value $input
1387
         * - if changed value fails error check, save it to $this->_input (to allow echoing later)
1388
         * - if changed value passes error check, set $this->_local to the new value
1389
         *
1390
         * @param  mixed   $input   the new value
1391
         * @return boolean          true if changed, false otherwise (incl. on error)
1392
         */
1393
        function update($input) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1394
1395
            // let parent do basic checks, value, not changed, etc.
1396
            $local = $this->_local;
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1397
            if (!parent::update($input)) return false;
1398
            $this->_local = $local;
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1399
1400
            // see if the regex compiles and runs (we don't check for effectiveness)
1401
            $regex = $this->_delimiter . $input . $this->_delimiter . $this->_pregflags;
1402
            $lastError = error_get_last();
1403
            @preg_match($regex,'testdata');
1 ignored issue
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1404
            if (preg_last_error() != PREG_NO_ERROR || error_get_last() != $lastError) {
1405
                $this->_input = $input;
0 ignored issues
show
Bug introduced by
The property _input cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1406
                $this->_error = true;
0 ignored issues
show
Bug introduced by
The property _error cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1407
                return false;
1408
            }
1409
1410
            $this->_local = $input;
0 ignored issues
show
Bug introduced by
The property _local cannot be accessed from this context as it is declared private in class setting.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
1411
            return true;
1412
        }
1413
    }
1414
}
1415