Completed
Push — authpdo ( 0476c5...3b7a97 )
by Andreas
04:49
created

configuration::retrieve_settings()   C

Complexity

Conditions 12
Paths 66

Size

Total Lines 49
Code Lines 32

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 49
rs 5.1474
cc 12
eloc 32
nc 66
nop 0

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] = preg_replace('/^(\'|")(.*)(?<!\\\\)\1$/s','$2',$arr[$j]);
224
                            $arr[$j] = strtr($arr[$j], array('\\\\'=>'\\','\\\''=>'\'','\\"'=>'"'));
225
                        }
226
227
                        $value = $arr;
228
                    }else{
229
                        // remove quotes from quoted strings & unescape escaped data
230
                        $value = preg_replace('/^(\'|")(.*)(?<!\\\\)\1$/s','$2',$value);
231
                        $value = strtr($value, array('\\\\'=>'\\','\\\''=>'\'','\\"'=>'"'));
232
                    }
233
234
                    $config[$key] = $value;
235
                }
236
            }
237
238
            return $config;
239
        }
240
241
        /**
242
         * Returns header of rewritten settings file
243
         *
244
         * @param string $id plugin name of which generated this output
245
         * @param string $header additional text for at top of the file
246
         * @return string text of header
247
         */
248
        protected function _out_header($id, $header) {
249
            $out = '';
250
            if ($this->_format == 'php') {
251
                $out .= '<'.'?php'."\n".
252
                      "/*\n".
253
                      " * ".$header."\n".
254
                      " * Auto-generated by ".$id." plugin\n".
255
                      " * Run for user: ".$_SERVER['REMOTE_USER']."\n".
256
                      " * Date: ".date('r')."\n".
257
                      " */\n\n";
258
            }
259
260
            return $out;
261
        }
262
263
        /**
264
         * Returns footer of rewritten settings file
265
         *
266
         * @return string text of footer
267
         */
268
        protected function _out_footer() {
269
            $out = '';
270
            if ($this->_format == 'php') {
271
                $out .= "\n// end auto-generated content\n";
272
            }
273
274
            return $out;
275
        }
276
277
        /**
278
         * Configuration is considered locked if there is no local settings filename
279
         * or the directory its in is not writable or the file exists and is not writable
280
         *
281
         * @return bool true: locked, false: writable
282
         */
283
        protected function _is_locked() {
284
            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...
285
286
            $local = $this->_local_files[0];
287
288
            if (!is_writable(dirname($local))) return true;
289
            if (file_exists($local) && !is_writable($local)) return true;
290
291
            return false;
292
        }
293
294
        /**
295
         * not used ... conf's contents are an array!
296
         * reduce any multidimensional settings to one dimension using CM_KEYMARKER
297
         *
298
         * @param $conf
299
         * @param string $prefix
300
         * @return array
301
         */
302
        protected function _flatten($conf,$prefix='') {
303
304
            $out = array();
305
306
            foreach($conf as $key => $value) {
307
                if (!is_array($value)) {
308
                    $out[$prefix.$key] = $value;
309
                    continue;
310
                }
311
312
                $tmp = $this->_flatten($value,$prefix.$key.CM_KEYMARKER);
313
                $out = array_merge($out,$tmp);
314
            }
315
316
            return $out;
317
        }
318
319
        /**
320
         * Returns array of plugin names
321
         *
322
         * @return array plugin names
323
         * @triggers PLUGIN_CONFIG_PLUGINLIST event
324
         */
325
        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...
326
            if (is_null($this->_plugin_list)) {
327
                $list = plugin_list('',$this->show_disabled_plugins);
328
329
                // remove this plugin from the list
330
                $idx = array_search('config',$list);
331
                unset($list[$idx]);
332
333
                trigger_event('PLUGIN_CONFIG_PLUGINLIST',$list);
334
                $this->_plugin_list = $list;
335
            }
336
337
            return $this->_plugin_list;
338
        }
339
340
        /**
341
         * load metadata for plugin and template settings
342
         *
343
         * @param string $tpl name of active template
344
         * @return array metadata of settings
345
         */
346
        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...
347
            $file     = '/conf/metadata.php';
348
            $class    = '/conf/settings.class.php';
349
            $metadata = array();
350
351
            foreach ($this->get_plugin_list() as $plugin) {
352
                $plugin_dir = plugin_directory($plugin);
353
                if (file_exists(DOKU_PLUGIN.$plugin_dir.$file)){
354
                    $meta = array();
355
                    @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...
356
                    @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...
357
                    if (!empty($meta)) {
358
                        $metadata['plugin'.CM_KEYMARKER.$plugin.CM_KEYMARKER.'plugin_settings_name'] = array('fieldset');
359
                    }
360
                    foreach ($meta as $key => $value){
361
                        if ($value[0]=='fieldset') { continue; } //plugins only get one fieldset
362
                        $metadata['plugin'.CM_KEYMARKER.$plugin.CM_KEYMARKER.$key] = $value;
363
                    }
364
                }
365
            }
366
367
            // the same for the active template
368
            if (file_exists(tpl_incdir().$file)){
369
                $meta = array();
370
                @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...
371
                @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...
372
                if (!empty($meta)) {
373
                    $metadata['tpl'.CM_KEYMARKER.$tpl.CM_KEYMARKER.'template_settings_name'] = array('fieldset');
374
                }
375
                foreach ($meta as $key => $value){
376
                    if ($value[0]=='fieldset') { continue; } //template only gets one fieldset
377
                    $metadata['tpl'.CM_KEYMARKER.$tpl.CM_KEYMARKER.$key] = $value;
378
                }
379
            }
380
381
            return $metadata;
382
        }
383
384
        /**
385
         * Load default settings for plugins and templates
386
         *
387
         * @param string $tpl name of active template
388
         * @return array default settings
389
         */
390
        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...
391
            $file    = '/conf/default.php';
392
            $default = array();
393
394
            foreach ($this->get_plugin_list() as $plugin) {
395
                $plugin_dir = plugin_directory($plugin);
396
                if (file_exists(DOKU_PLUGIN.$plugin_dir.$file)){
397
                    $conf = $this->_read_config(DOKU_PLUGIN.$plugin_dir.$file);
398
                    foreach ($conf as $key => $value){
399
                        $default['plugin'.CM_KEYMARKER.$plugin.CM_KEYMARKER.$key] = $value;
400
                    }
401
                }
402
            }
403
404
            // the same for the active template
405
            if (file_exists(tpl_incdir().$file)){
406
                $conf = $this->_read_config(tpl_incdir().$file);
407
                foreach ($conf as $key => $value){
408
                    $default['tpl'.CM_KEYMARKER.$tpl.CM_KEYMARKER.$key] = $value;
409
                }
410
            }
411
412
            return $default;
413
        }
414
415
    }
416
}
417
418
if (!class_exists('setting')) {
419
    /**
420
     * Class setting
421
     */
422
    class setting {
423
424
        var $_key = '';
425
        var $_default = null;
426
        var $_local = null;
427
        var $_protected = null;
428
429
        var $_pattern = '';
430
        var $_error = false;            // only used by those classes which error check
431
        var $_input = null;             // only used by those classes which error check
432
        var $_caution = null;           // used by any setting to provide an alert along with the setting
433
                                        // valid alerts, 'warning', 'danger', 'security'
434
                                        // images matching the alerts are in the plugin's images directory
435
436
        static protected $_validCautions = array('warning','danger','security');
437
438
        /**
439
         * @param string $key
440
         * @param array|null $params array with metadata of setting
441
         */
442
        public function __construct($key, $params=null) {
443
            $this->_key = $key;
444
445
            if (is_array($params)) {
446
                foreach($params as $property => $value) {
447
                    $this->$property = $value;
448
                }
449
            }
450
        }
451
452
        /**
453
         * Receives current values for the setting $key
454
         *
455
         * @param mixed $default   default setting value
456
         * @param mixed $local     local setting value
457
         * @param mixed $protected protected setting value
458
         */
459
        public function initialize($default, $local, $protected) {
460
            if (isset($default)) $this->_default = $default;
461
            if (isset($local)) $this->_local = $local;
462
            if (isset($protected)) $this->_protected = $protected;
463
        }
464
465
        /**
466
         * update changed setting with user provided value $input
467
         * - if changed value fails error check, save it to $this->_input (to allow echoing later)
468
         * - if changed value passes error check, set $this->_local to the new value
469
         *
470
         * @param  mixed   $input   the new value
471
         * @return boolean          true if changed, false otherwise (also on error)
472
         */
473
        public function update($input) {
474
            if (is_null($input)) return false;
475
            if ($this->is_protected()) return false;
476
477
            $value = is_null($this->_local) ? $this->_default : $this->_local;
478
            if ($value == $input) return false;
479
480
            if ($this->_pattern && !preg_match($this->_pattern,$input)) {
481
                $this->_error = true;
482
                $this->_input = $input;
483
                return false;
484
            }
485
486
            $this->_local = $input;
487
            return true;
488
        }
489
490
        /**
491
         * Build html for label and input of setting
492
         *
493
         * @param DokuWiki_Plugin $plugin object of config plugin
494
         * @param bool            $echo   true: show inputted value, when error occurred, otherwise the stored setting
495
         * @return string[] with content array(string $label_html, string $input_html)
496
         */
497
        public function html(&$plugin, $echo=false) {
498
            $disable = '';
499
500
            if ($this->is_protected()) {
501
                $value = $this->_protected;
502
                $disable = 'disabled="disabled"';
503
            } else {
504
                if ($echo && $this->_error) {
505
                    $value = $this->_input;
506
                } else {
507
                    $value = is_null($this->_local) ? $this->_default : $this->_local;
508
                }
509
            }
510
511
            $key = htmlspecialchars($this->_key);
512
            $value = formText($value);
513
514
            $label = '<label for="config___'.$key.'">'.$this->prompt($plugin).'</label>';
515
            $input = '<textarea rows="3" cols="40" id="config___'.$key.'" name="config['.$key.']" class="edit" '.$disable.'>'.$value.'</textarea>';
516
            return array($label,$input);
517
        }
518
519
        /**
520
         * Generate string to save setting value to file according to $fmt
521
         *
522
         * @param string $var name of variable
523
         * @param string $fmt save format
524
         * @return string
525
         */
526
        public function out($var, $fmt='php') {
527
528
            if ($this->is_protected()) return '';
529
            if (is_null($this->_local) || ($this->_default == $this->_local)) return '';
530
531
            $out = '';
532
533
            if ($fmt=='php') {
534
                $tr = array("\\" => '\\\\', "'" => '\\\'');
535
536
                $out =  '$'.$var."['".$this->_out_key()."'] = '".strtr( cleanText($this->_local), $tr)."';\n";
537
            }
538
539
            return $out;
540
        }
541
542
        /**
543
         * Returns the localized prompt
544
         *
545
         * @param DokuWiki_Plugin $plugin object of config plugin
546
         * @return string text
547
         */
548
        public function prompt(&$plugin) {
549
            $prompt = $plugin->getLang($this->_key);
550
            if (!$prompt) $prompt = htmlspecialchars(str_replace(array('____','_'),' ',$this->_key));
551
            return $prompt;
552
        }
553
554
        /**
555
         * Is setting protected
556
         *
557
         * @return bool
558
         */
559
        public function is_protected() { return !is_null($this->_protected); }
560
561
        /**
562
         * Is setting the default?
563
         *
564
         * @return bool
565
         */
566
        public function is_default() { return !$this->is_protected() && is_null($this->_local); }
567
568
        /**
569
         * Has an error?
570
         *
571
         * @return bool
572
         */
573
        public function error() { return $this->_error; }
574
575
        /**
576
         * Returns caution
577
         *
578
         * @return false|string caution string, otherwise false for invalid caution
579
         */
580
        public function caution() {
581
            if (!empty($this->_caution)) {
582
                if (!in_array($this->_caution, setting::$_validCautions)) {
583
                    trigger_error('Invalid caution string ('.$this->_caution.') in metadata for setting "'.$this->_key.'"', E_USER_WARNING);
584
                    return false;
585
                }
586
                return $this->_caution;
587
            }
588
            // compatibility with previous cautionList
589
            // TODO: check if any plugins use; remove
590
            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...
591
                $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...
592
                unset($this->_cautionList);
593
594
                return $this->caution();
595
            }
596
            return false;
597
        }
598
599
        /**
600
         * Returns setting key, eventually with referer to config: namespace at dokuwiki.org
601
         *
602
         * @param bool $pretty create nice key
603
         * @param bool $url    provide url to config: namespace
604
         * @return string key
605
         */
606
        public function _out_key($pretty=false,$url=false) {
607
            if($pretty){
608
                $out = str_replace(CM_KEYMARKER,"»",$this->_key);
609
                if ($url && !strstr($out,'»')) {//provide no urls for plugins, etc.
610
                    if ($out == 'start') //one exception
611
                        return '<a href="http://www.dokuwiki.org/config:startpage">'.$out.'</a>';
612
                    else
613
                        return '<a href="http://www.dokuwiki.org/config:'.$out.'">'.$out.'</a>';
614
                }
615
                return $out;
616
            }else{
617
                return str_replace(CM_KEYMARKER,"']['",$this->_key);
618
            }
619
        }
620
    }
621
}
622
623
624
if (!class_exists('setting_array')) {
625
    /**
626
     * Class setting_array
627
     */
628
    class setting_array extends setting {
629
630
        /**
631
         * Create an array from a string
632
         *
633
         * @param string $string
634
         * @return array
635
         */
636
        protected function _from_string($string){
637
            $array = explode(',', $string);
638
            $array = array_map('trim', $array);
639
            $array = array_filter($array);
640
            $array = array_unique($array);
641
            return $array;
642
        }
643
644
        /**
645
         * Create a string from an array
646
         *
647
         * @param array $array
648
         * @return string
649
         */
650
        protected function _from_array($array){
651
            return join(', ', (array) $array);
652
        }
653
654
        /**
655
         * update setting with user provided value $input
656
         * if value fails error check, save it
657
         *
658
         * @param string $input
659
         * @return bool true if changed, false otherwise (incl. on error)
660
         */
661
        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...
662
            if (is_null($input)) return false;
663
            if ($this->is_protected()) return false;
664
665
            $input = $this->_from_string($input);
666
667
            $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...
668
            if ($value == $input) return false;
669
670
            foreach($input as $item){
671
                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...
672
                    $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...
673
                    $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...
674
                    return false;
675
                }
676
            }
677
678
            $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...
679
            return true;
680
        }
681
682
        /**
683
         * Escaping
684
         *
685
         * @param string $string
686
         * @return string
687
         */
688
        protected function _escape($string) {
689
            $tr = array("\\" => '\\\\', "'" => '\\\'');
690
            return "'".strtr( cleanText($string), $tr)."'";
691
        }
692
693
        /**
694
         * Generate string to save setting value to file according to $fmt
695
         *
696
         * @param string $var name of variable
697
         * @param string $fmt save format
698
         * @return string
699
         */
700
        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...
701
702
            if ($this->is_protected()) return '';
703
            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...
704
705
            $out = '';
706
707
            if ($fmt=='php') {
708
                $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...
709
                $out =  '$'.$var."['".$this->_out_key()."'] = array(".join(', ',$vals).");\n";
710
            }
711
712
            return $out;
713
        }
714
715
        /**
716
         * Build html for label and input of setting
717
         *
718
         * @param DokuWiki_Plugin $plugin object of config plugin
719
         * @param bool            $echo   true: show inputted value, when error occurred, otherwise the stored setting
720
         * @return string[] with content array(string $label_html, string $input_html)
721
         */
722
        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...
723
            $disable = '';
724
725
            if ($this->is_protected()) {
726
                $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...
727
                $disable = 'disabled="disabled"';
728
            } else {
729
                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...
730
                    $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...
731
                } else {
732
                    $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...
733
                }
734
            }
735
736
            $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...
737
            $value = htmlspecialchars($this->_from_array($value));
738
739
            $label = '<label for="config___'.$key.'">'.$this->prompt($plugin).'</label>';
740
            $input = '<input id="config___'.$key.'" name="config['.$key.']" type="text" class="edit" value="'.$value.'" '.$disable.'/>';
741
            return array($label,$input);
742
        }
743
    }
744
}
745
746
if (!class_exists('setting_string')) {
747
    /**
748
     * Class setting_string
749
     */
750
    class setting_string extends setting {
751
        /**
752
         * Build html for label and input of setting
753
         *
754
         * @param DokuWiki_Plugin $plugin object of config plugin
755
         * @param bool            $echo   true: show inputted value, when error occurred, otherwise the stored setting
756
         * @return string[] with content array(string $label_html, string $input_html)
757
         */
758
        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...
759
            $disable = '';
760
761
            if ($this->is_protected()) {
762
                $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...
763
                $disable = 'disabled="disabled"';
764
            } else {
765
                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...
766
                    $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...
767
                } else {
768
                    $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...
769
                }
770
            }
771
772
            $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...
773
            $value = htmlspecialchars($value);
774
775
            $label = '<label for="config___'.$key.'">'.$this->prompt($plugin).'</label>';
776
            $input = '<input id="config___'.$key.'" name="config['.$key.']" type="text" class="edit" value="'.$value.'" '.$disable.'/>';
777
            return array($label,$input);
778
        }
779
    }
780
}
781
782
if (!class_exists('setting_password')) {
783
    /**
784
     * Class setting_password
785
     */
786
    class setting_password extends setting_string {
787
788
        var $_code = 'plain';  // mechanism to be used to obscure passwords
789
790
        /**
791
         * update changed setting with user provided value $input
792
         * - if changed value fails error check, save it to $this->_input (to allow echoing later)
793
         * - if changed value passes error check, set $this->_local to the new value
794
         *
795
         * @param  mixed   $input   the new value
796
         * @return boolean          true if changed, false otherwise (also on error)
797
         */
798
        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...
799
            if ($this->is_protected()) return false;
800
            if (!$input) return false;
801
802
            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...
803
                $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...
804
                $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...
805
                return false;
806
            }
807
808
            $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...
809
            return true;
810
        }
811
812
        /**
813
         * Build html for label and input of setting
814
         *
815
         * @param DokuWiki_Plugin $plugin object of config plugin
816
         * @param bool            $echo   true: show inputted value, when error occurred, otherwise the stored setting
817
         * @return string[] with content array(string $label_html, string $input_html)
818
         */
819
        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...
820
821
            $disable = $this->is_protected() ? 'disabled="disabled"' : '';
822
823
            $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...
824
825
            $label = '<label for="config___'.$key.'">'.$this->prompt($plugin).'</label>';
826
            $input = '<input id="config___'.$key.'" name="config['.$key.']" autocomplete="off" type="password" class="edit" value="" '.$disable.' />';
827
            return array($label,$input);
828
        }
829
    }
830
}
831
832
if (!class_exists('setting_email')) {
833
    /**
834
     * Class setting_email
835
     */
836
    class setting_email extends setting_string {
837
        var $_multiple = false;
838
        var $_placeholders = false;
839
840
        /**
841
         * update setting with user provided value $input
842
         * if value fails error check, save it
843
         *
844
         * @param mixed $input
845
         * @return boolean true if changed, false otherwise (incl. on error)
846
         */
847
        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...
848
            if (is_null($input)) return false;
849
            if ($this->is_protected()) return false;
850
851
            $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...
852
            if ($value == $input) return false;
853
            if($input === ''){
854
                $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...
855
                return true;
856
            }
857
            $mail = $input;
858
859
            if($this->_placeholders){
860
                // replace variables with pseudo values
861
                $mail = str_replace('@USER@','joe',$mail);
862
                $mail = str_replace('@NAME@','Joe Schmoe',$mail);
863
                $mail = str_replace('@MAIL@','[email protected]',$mail);
864
            }
865
866
            // multiple mail addresses?
867
            if ($this->_multiple) {
868
                $mails = array_filter(array_map('trim', explode(',', $mail)));
869
            } else {
870
                $mails = array($mail);
871
            }
872
873
            // check them all
874
            foreach ($mails as $mail) {
875
                // only check the address part
876
                if(preg_match('#(.*?)<(.*?)>#', $mail, $matches)){
877
                    $addr = $matches[2];
878
                }else{
879
                    $addr = $mail;
880
                }
881
882
                if (!mail_isvalid($addr)) {
883
                    $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...
884
                    $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...
885
                    return false;
886
                }
887
            }
888
889
            $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...
890
            return true;
891
        }
892
    }
893
}
894
895
if (!class_exists('setting_numeric')) {
896
    /**
897
     * Class setting_numeric
898
     */
899
    class setting_numeric extends setting_string {
900
        // This allows for many PHP syntax errors...
901
        // var $_pattern = '/^[-+\/*0-9 ]*$/';
902
        // much more restrictive, but should eliminate syntax errors.
903
        var $_pattern = '/^[-+]? *[0-9]+ *(?:[-+*] *[0-9]+ *)*$/';
904
        var $_min = null;
905
        var $_max = null;
906
907
        /**
908
         * update changed setting with user provided value $input
909
         * - if changed value fails error check, save it to $this->_input (to allow echoing later)
910
         * - if changed value passes error check, set $this->_local to the new value
911
         *
912
         * @param  mixed   $input   the new value
913
         * @return boolean          true if changed, false otherwise (also on error)
914
         */
915
        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...
916
            $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...
917
            $valid = parent::update($input);
918
            if ($valid && !(is_null($this->_min) && is_null($this->_max))) {
919
                $numeric_local = (int) eval('return '.$this->_local.';');
920
                if ((!is_null($this->_min) && $numeric_local < $this->_min) ||
921
                    (!is_null($this->_max) && $numeric_local > $this->_max)) {
922
                    $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...
923
                    $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...
924
                    $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...
925
                    $valid = false;
926
                }
927
            }
928
            return $valid;
929
        }
930
931
        /**
932
         * Generate string to save setting value to file according to $fmt
933
         *
934
         * @param string $var name of variable
935
         * @param string $fmt save format
936
         * @return string
937
         */
938
        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...
939
940
            if ($this->is_protected()) return '';
941
            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...
942
943
            $out = '';
944
945
            if ($fmt=='php') {
946
                $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...
947
                $out .=  '$'.$var."['".$this->_out_key()."'] = ".$local.";\n";
948
            }
949
950
            return $out;
951
        }
952
    }
953
}
954
955
if (!class_exists('setting_numericopt')) {
956
    /**
957
     * Class setting_numericopt
958
     */
959
    class setting_numericopt extends setting_numeric {
960
        // just allow an empty config
961
        var $_pattern = '/^(|[-]?[0-9]+(?:[-+*][0-9]+)*)$/';
962
    }
963
}
964
965
if (!class_exists('setting_onoff')) {
966
    /**
967
     * Class setting_onoff
968
     */
969
    class setting_onoff extends setting_numeric {
970
        /**
971
         * Build html for label and input of setting
972
         *
973
         * @param DokuWiki_Plugin $plugin object of config plugin
974
         * @param bool            $echo   true: show inputted value, when error occurred, otherwise the stored setting
975
         * @return string[] with content array(string $label_html, string $input_html)
976
         */
977
        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...
978
            $disable = '';
979
980
            if ($this->is_protected()) {
981
                $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...
982
                $disable = ' disabled="disabled"';
983
            } else {
984
                $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...
985
            }
986
987
            $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...
988
            $checked = ($value) ? ' checked="checked"' : '';
989
990
            $label = '<label for="config___'.$key.'">'.$this->prompt($plugin).'</label>';
991
            $input = '<div class="input"><input id="config___'.$key.'" name="config['.$key.']" type="checkbox" class="checkbox" value="1"'.$checked.$disable.'/></div>';
992
            return array($label,$input);
993
        }
994
995
        /**
996
         * update changed setting with user provided value $input
997
         * - if changed value fails error check, save it to $this->_input (to allow echoing later)
998
         * - if changed value passes error check, set $this->_local to the new value
999
         *
1000
         * @param  mixed   $input   the new value
1001
         * @return boolean          true if changed, false otherwise (also on error)
1002
         */
1003
        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...
1004
            if ($this->is_protected()) return false;
1005
1006
            $input = ($input) ? 1 : 0;
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
            if ($value == $input) return false;
1009
1010
            $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...
1011
            return true;
1012
        }
1013
    }
1014
}
1015
1016
if (!class_exists('setting_multichoice')) {
1017
    /**
1018
     * Class setting_multichoice
1019
     */
1020
    class setting_multichoice extends setting_string {
1021
        var $_choices = array();
1022
        var $lang; //some custom language strings are stored in setting
1023
1024
        /**
1025
         * Build html for label and input of setting
1026
         *
1027
         * @param DokuWiki_Plugin $plugin object of config plugin
1028
         * @param bool            $echo   true: show inputted value, when error occurred, otherwise the stored setting
1029
         * @return string[] with content array(string $label_html, string $input_html)
1030
         */
1031
        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...
1032
            $disable = '';
1033
            $nochoice = '';
1034
1035
            if ($this->is_protected()) {
1036
                $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...
1037
                $disable = ' disabled="disabled"';
1038
            } else {
1039
                $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...
1040
            }
1041
1042
            // ensure current value is included
1043
            if (!in_array($value, $this->_choices)) {
1044
                $this->_choices[] = $value;
1045
            }
1046
            // disable if no other choices
1047
            if (!$this->is_protected() && count($this->_choices) <= 1) {
1048
                $disable = ' disabled="disabled"';
1049
                $nochoice = $plugin->getLang('nochoice');
1050
            }
1051
1052
            $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...
1053
1054
            $label = '<label for="config___'.$key.'">'.$this->prompt($plugin).'</label>';
1055
1056
            $input = "<div class=\"input\">\n";
1057
            $input .= '<select class="edit" id="config___'.$key.'" name="config['.$key.']"'.$disable.'>'."\n";
1058
            foreach ($this->_choices as $choice) {
1059
                $selected = ($value == $choice) ? ' selected="selected"' : '';
1060
                $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...
1061
                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...
1062
                if (!$option) $option = $choice;
1063
1064
                $choice = htmlspecialchars($choice);
1065
                $option = htmlspecialchars($option);
1066
                $input .= '  <option value="'.$choice.'"'.$selected.' >'.$option.'</option>'."\n";
1067
            }
1068
            $input .= "</select> $nochoice \n";
1069
            $input .= "</div>\n";
1070
1071
            return array($label,$input);
1072
        }
1073
1074
        /**
1075
         * update changed setting with user provided value $input
1076
         * - if changed value fails error check, save it to $this->_input (to allow echoing later)
1077
         * - if changed value passes error check, set $this->_local to the new value
1078
         *
1079
         * @param  mixed   $input   the new value
1080
         * @return boolean          true if changed, false otherwise (also on error)
1081
         */
1082
        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...
1083
            if (is_null($input)) return false;
1084
            if ($this->is_protected()) return false;
1085
1086
            $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...
1087
            if ($value == $input) return false;
1088
1089
            if (!in_array($input, $this->_choices)) return false;
1090
1091
            $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...
1092
            return true;
1093
        }
1094
    }
1095
}
1096
1097
1098
if (!class_exists('setting_dirchoice')) {
1099
    /**
1100
     * Class setting_dirchoice
1101
     */
1102
    class setting_dirchoice extends setting_multichoice {
1103
1104
        var $_dir = '';
1105
1106
        /**
1107
         * Receives current values for the setting $key
1108
         *
1109
         * @param mixed $default   default setting value
1110
         * @param mixed $local     local setting value
1111
         * @param mixed $protected protected setting value
1112
         */
1113
        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...
1114
1115
            // populate $this->_choices with a list of directories
1116
            $list = array();
1117
1118
            if ($dh = @opendir($this->_dir)) {
1119
                while (false !== ($entry = readdir($dh))) {
1120
                    if ($entry == '.' || $entry == '..') continue;
1121
                    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...
1122
1123
                    $file = (is_link($this->_dir.$entry)) ? readlink($this->_dir.$entry) : $this->_dir.$entry;
1124
                    if (is_dir($file)) $list[] = $entry;
1125
                }
1126
                closedir($dh);
1127
            }
1128
            sort($list);
1129
            $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...
1130
1131
            parent::initialize($default,$local,$protected);
1132
        }
1133
    }
1134
}
1135
1136
1137
if (!class_exists('setting_hidden')) {
1138
    /**
1139
     * Class setting_hidden
1140
     */
1141
    class setting_hidden extends setting {
1142
        // Used to explicitly ignore a setting in the configuration manager.
1143
    }
1144
}
1145
1146
if (!class_exists('setting_fieldset')) {
1147
    /**
1148
     * Class setting_fieldset
1149
     */
1150
    class setting_fieldset extends setting {
1151
        // A do-nothing class used to detect the 'fieldset' type.
1152
        // Used to start a new settings "display-group".
1153
    }
1154
}
1155
1156
if (!class_exists('setting_undefined')) {
1157
    /**
1158
     * Class setting_undefined
1159
     */
1160
    class setting_undefined extends setting_hidden {
1161
        // A do-nothing class used to detect settings with no metadata entry.
1162
        // Used internaly to hide undefined settings, and generate the undefined settings list.
1163
    }
1164
}
1165
1166
if (!class_exists('setting_no_class')) {
1167
    /**
1168
     * Class setting_no_class
1169
     */
1170
    class setting_no_class extends setting_undefined {
1171
        // A do-nothing class used to detect settings with a missing setting class.
1172
        // Used internaly to hide undefined settings, and generate the undefined settings list.
1173
    }
1174
}
1175
1176
if (!class_exists('setting_no_default')) {
1177
    /**
1178
     * Class setting_no_default
1179
     */
1180
    class setting_no_default extends setting_undefined {
1181
        // A do-nothing class used to detect settings with no default value.
1182
        // Used internaly to hide undefined settings, and generate the undefined settings list.
1183
    }
1184
}
1185
1186
if (!class_exists('setting_multicheckbox')) {
1187
    /**
1188
     * Class setting_multicheckbox
1189
     */
1190
    class setting_multicheckbox extends setting_string {
1191
1192
        var $_choices = array();
1193
        var $_combine = array();
1194
1195
        /**
1196
         * update changed setting with user provided value $input
1197
         * - if changed value fails error check, save it to $this->_input (to allow echoing later)
1198
         * - if changed value passes error check, set $this->_local to the new value
1199
         *
1200
         * @param  mixed   $input   the new value
1201
         * @return boolean          true if changed, false otherwise (also on error)
1202
         */
1203
        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...
1204
            if ($this->is_protected()) return false;
1205
1206
            // split any combined values + convert from array to comma separated string
1207
            $input = ($input) ? $input : array();
1208
            $input = $this->_array2str($input);
1209
1210
            $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...
1211
            if ($value == $input) return false;
1212
1213
            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...
1214
                $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...
1215
                $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...
1216
                return false;
1217
            }
1218
1219
            $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...
1220
            return true;
1221
        }
1222
1223
        /**
1224
         * Build html for label and input of setting
1225
         *
1226
         * @param DokuWiki_Plugin $plugin object of config plugin
1227
         * @param bool            $echo   true: show input value, when error occurred, otherwise the stored setting
1228
         * @return string[] with content array(string $label_html, string $input_html)
1229
         */
1230
        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...
1231
1232
            $disable = '';
1233
1234
            if ($this->is_protected()) {
1235
                $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...
1236
                $disable = 'disabled="disabled"';
1237
            } else {
1238
                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...
1239
                    $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...
1240
                } else {
1241
                    $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...
1242
                }
1243
            }
1244
1245
            $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...
1246
1247
            // convert from comma separated list into array + combine complimentary actions
1248
            $value = $this->_str2array($value);
1249
            $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...
1250
1251
            $input = '';
1252
            foreach ($this->_choices as $choice) {
1253
                $idx = array_search($choice, $value);
1254
                $idx_default = array_search($choice,$default);
1255
1256
                $checked = ($idx !== false) ? 'checked="checked"' : '';
1257
1258
                // ideally this would be handled using a second class of "default", however IE6 does not
1259
                // correctly support CSS selectors referencing multiple class names on the same element
1260
                // (e.g. .default.selection).
1261
                $class = (($idx !== false) == (false !== $idx_default)) ? " selectiondefault" : "";
1262
1263
                $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...
1264
                                $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...
1265
1266
                $input .= '<div class="selection'.$class.'">'."\n";
1267
                $input .= '<label for="config___'.$key.'_'.$choice.'">'.$prompt."</label>\n";
1268
                $input .= '<input id="config___'.$key.'_'.$choice.'" name="config['.$key.'][]" type="checkbox" class="checkbox" value="'.$choice.'" '.$disable.' '.$checked."/>\n";
1269
                $input .= "</div>\n";
1270
1271
                // remove this action from the disabledactions array
1272
                if ($idx !== false) unset($value[$idx]);
1273
                if ($idx_default !== false) unset($default[$idx_default]);
1274
            }
1275
1276
            // handle any remaining values
1277
            $other = join(',',$value);
1278
1279
            $class = ((count($default) == count($value)) && (count($value) == count(array_intersect($value,$default)))) ?
1280
                            " selectiondefault" : "";
1281
1282
            $input .= '<div class="other'.$class.'">'."\n";
1283
            $input .= '<label for="config___'.$key.'_other">'.$plugin->getLang($key.'_other')."</label>\n";
1284
            $input .= '<input id="config___'.$key.'_other" name="config['.$key.'][other]" type="text" class="edit" value="'.htmlspecialchars($other).'" '.$disable." />\n";
1285
            $input .= "</div>\n";
1286
1287
            $label = '<label>'.$this->prompt($plugin).'</label>';
1288
            return array($label,$input);
1289
        }
1290
1291
        /**
1292
         * convert comma separated list to an array and combine any complimentary values
1293
         *
1294
         * @param string $str
1295
         * @return array
1296
         */
1297
        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...
1298
            $array = explode(',',$str);
1299
1300
            if (!empty($this->_combine)) {
1301
                foreach ($this->_combine as $key => $combinators) {
1302
                    $idx = array();
1303
                    foreach ($combinators as $val) {
1304
                        if  (($idx[] = array_search($val, $array)) === false) break;
1305
                    }
1306
1307
                    if (count($idx) && $idx[count($idx)-1] !== false) {
1308
                        foreach ($idx as $i) unset($array[$i]);
1309
                        $array[] = $key;
1310
                    }
1311
                }
1312
            }
1313
1314
            return $array;
1315
        }
1316
1317
        /**
1318
         * convert array of values + other back to a comma separated list, incl. splitting any combined values
1319
         *
1320
         * @param array $input
1321
         * @return string
1322
         */
1323
        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...
1324
1325
            // handle other
1326
            $other = trim($input['other']);
1327
            $other = !empty($other) ? explode(',',str_replace(' ','',$input['other'])) : array();
1328
            unset($input['other']);
1329
1330
            $array = array_unique(array_merge($input, $other));
1331
1332
            // deconstruct any combinations
1333
            if (!empty($this->_combine)) {
1334
                foreach ($this->_combine as $key => $combinators) {
1335
1336
                    $idx = array_search($key,$array);
1337
                    if ($idx !== false) {
1338
                        unset($array[$idx]);
1339
                        $array = array_merge($array, $combinators);
1340
                    }
1341
                }
1342
            }
1343
1344
            return join(',',array_unique($array));
1345
        }
1346
    }
1347
}
1348
1349
if (!class_exists('setting_regex')){
1350
    /**
1351
     * Class setting_regex
1352
     */
1353
    class setting_regex extends setting_string {
1354
1355
        var $_delimiter = '/';    // regex delimiter to be used in testing input
1356
        var $_pregflags = 'ui';   // regex pattern modifiers to be used in testing input
1357
1358
        /**
1359
         * update changed setting with user provided value $input
1360
         * - if changed value fails error check, save it to $this->_input (to allow echoing later)
1361
         * - if changed value passes error check, set $this->_local to the new value
1362
         *
1363
         * @param  mixed   $input   the new value
1364
         * @return boolean          true if changed, false otherwise (incl. on error)
1365
         */
1366
        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...
1367
1368
            // let parent do basic checks, value, not changed, etc.
1369
            $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...
1370
            if (!parent::update($input)) return false;
1371
            $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...
1372
1373
            // see if the regex compiles and runs (we don't check for effectiveness)
1374
            $regex = $this->_delimiter . $input . $this->_delimiter . $this->_pregflags;
1375
            $lastError = error_get_last();
1376
            @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...
1377
            if (preg_last_error() != PREG_NO_ERROR || error_get_last() != $lastError) {
1378
                $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...
1379
                $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...
1380
                return false;
1381
            }
1382
1383
            $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...
1384
            return true;
1385
        }
1386
    }
1387
}
1388