Completed
Push — psr2-config ( d6fc72...e901cf )
by Andreas
04:42
created

Setting::cleanValue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
namespace dokuwiki\plugin\config\core\Setting;
4
5
use dokuwiki\plugin\config\core\Configuration;
6
7
/**
8
 * Class Setting
9
 */
10
class Setting {
11
    /** @var string unique identifier of this setting */
12
    protected $key = '';
13
14
    /** @var mixed the default value of this setting */
15
    protected $default = null;
16
    /** @var mixed the local value of this setting */
17
    protected $local = null;
18
    /** @var mixed the protected value of this setting */
19
    protected $protected = null;
20
21
    /** @var array valid alerts, images matching the alerts are in the plugin's images directory */
22
    static protected $validCautions = array('warning', 'danger', 'security');
23
24
    protected $pattern = '';
25
    protected $error = false;            // only used by those classes which error check
26
    protected $input = null;             // only used by those classes which error check
27
    protected $caution = null;           // used by any setting to provide an alert along with the setting
28
29
    /**
30
     * Constructor.
31
     *
32
     * The given parameters will be set up as class properties
33
     *
34
     * @see initialize() to set the actual value of the setting
35
     *
36
     * @param string $key
37
     * @param array|null $params array with metadata of setting
38
     */
39
    public function __construct($key, $params = null) {
40
        $this->key = $key;
41
42
        if(is_array($params)) {
43
            foreach($params as $property => $value) {
44
                $property = trim($property, '_'); // we don't use underscores anymore
45
                $this->$property = $value;
46
            }
47
        }
48
    }
49
50
    /**
51
     * Set the current values for the setting $key
52
     *
53
     * This is used to initialize the setting with the data read form the config files.
54
     *
55
     * @see update() to set a new value
56
     * @param mixed $default default setting value
57
     * @param mixed $local local setting value
58
     * @param mixed $protected protected setting value
59
     */
60
    public function initialize($default = null, $local = null, $protected = null) {
61
        $this->default = $this->cleanValue($default);
62
        $this->local = $this->cleanValue($local);
63
        $this->protected = $this->cleanValue($protected);
64
    }
65
66
    /**
67
     * update changed setting with user provided value $input
68
     * - if changed value fails error check, save it to $this->_input (to allow echoing later)
69
     * - if changed value passes error check, set $this->_local to the new value
70
     *
71
     * @param  mixed $input the new value
72
     * @return boolean          true if changed, false otherwise (also on error)
73
     */
74
    public function update($input) {
75
        if(is_null($input)) return false;
76
        if($this->isProtected()) return false;
77
        $input = $this->cleanValue($input);
78
79
        $value = is_null($this->local) ? $this->default : $this->local;
80
        if($value == $input) return false;
81
82
        if($this->pattern && !preg_match($this->pattern, $input)) {
83
            $this->error = true;
84
            $this->input = $input;
85
            return false;
86
        }
87
88
        $this->local = $input;
89
        return true;
90
    }
91
92
    /**
93
     * Clean a value read from a config before using it internally
94
     *
95
     * Default implementation returns $value as is. Subclasses can override.
96
     * Note: null should always be returned as null!
97
     *
98
     * This is applied in initialize() and update()
99
     *
100
     * @param mixed $value
101
     * @return mixed
102
     */
103
    protected function cleanValue($value) {
104
        return $value;
105
    }
106
107
    /**
108
     * Should this type of config have a default?
109
     *
110
     * @return bool
111
     */
112
    public function shouldHaveDefault() {
113
        return true;
114
    }
115
116
    /**
117
     * Get this setting's unique key
118
     *
119
     * @return string
120
     */
121
    public function getKey() {
122
        return $this->key;
123
    }
124
125
    /**
126
     * Get the key of this setting marked up human readable
127
     *
128
     * @param bool $url link to dokuwiki.org manual?
129
     * @return string
130
     */
131
    public function getPrettyKey($url = true) {
132
        $out = str_replace(Configuration::KEYMARKER, "»", $this->key);
133
        if($url && !strstr($out, '»')) {//provide no urls for plugins, etc.
134
            if($out == 'start') {
135
                // exception, because this config name is clashing with our actual start page
136
                return '<a href="http://www.dokuwiki.org/config:startpage">' . $out . '</a>';
137
            } else {
138
                return '<a href="http://www.dokuwiki.org/config:' . $out . '">' . $out . '</a>';
139
            }
140
        }
141
        return $out;
142
    }
143
144
    /**
145
     * Returns setting key as an array key separator
146
     *
147
     * This is used to create form output
148
     *
149
     * @return string key
150
     */
151
    public function getArrayKey() {
152
        return str_replace(Configuration::KEYMARKER, "']['", $this->key);
153
    }
154
155
    /**
156
     * What type of configuration is this
157
     *
158
     * Returns one of
159
     *
160
     * 'plugin' for plugin configuration
161
     * 'template' for template configuration
162
     * 'dokuwiki' for core configuration
163
     *
164
     * @return string
165
     */
166
    public function getType() {
167
        if(substr($this->getKey(), 0, 10) == 'plugin' . Configuration::KEYMARKER) {
168
            return 'plugin';
169
        } else if(substr($this->getKey(), 0, 7) == 'tpl' . Configuration::KEYMARKER) {
170
            return 'template';
171
        } else {
172
            return 'dokuwiki';
173
        }
174
    }
175
176
    /**
177
     * Build html for label and input of setting
178
     *
179
     * @param \admin_plugin_config $plugin object of config plugin
180
     * @param bool $echo true: show inputted value, when error occurred, otherwise the stored setting
181
     * @return string[] with content array(string $label_html, string $input_html)
182
     */
183
    public function html(\admin_plugin_config $plugin, $echo = false) {
184
        $disable = '';
185
186
        if($this->isProtected()) {
187
            $value = $this->protected;
188
            $disable = 'disabled="disabled"';
189
        } else {
190
            if($echo && $this->error) {
191
                $value = $this->input;
192
            } else {
193
                $value = is_null($this->local) ? $this->default : $this->local;
194
            }
195
        }
196
197
        $key = htmlspecialchars($this->key);
198
        $value = formText($value);
199
200
        $label = '<label for="config___' . $key . '">' . $this->prompt($plugin) . '</label>';
201
        $input = '<textarea rows="3" cols="40" id="config___' . $key .
202
            '" name="config[' . $key . ']" class="edit" ' . $disable . '>' . $value . '</textarea>';
203
        return array($label, $input);
204
    }
205
206
    /**
207
     * Should the current local value be saved?
208
     *
209
     * @see out() to run when this returns true
210
     * @return bool
211
     */
212
    public function shouldBeSaved() {
213
        if($this->isProtected()) return false;
214
        if($this->local === null) return false;
215
        if($this->default == $this->local) return false;
216
        return true;
217
    }
218
219
    /**
220
     * Generate string to save local setting value to file according to $fmt
221
     *
222
     * @see shouldBeSaved() to check if this should be called
223
     * @param string $var name of variable
224
     * @param string $fmt save format
225
     * @return string
226
     */
227
    public function out($var, $fmt = 'php') {
228
        if($fmt != 'php') return '';
229
230
        $tr = array("\\" => '\\\\', "'" => '\\\''); // escape the value
231
        $out = '$' . $var . "['" . $this->getArrayKey() . "'] = '" . strtr(cleanText($this->local), $tr) . "';\n";
232
233
        return $out;
234
    }
235
236
    /**
237
     * Returns the localized prompt
238
     *
239
     * @param \admin_plugin_config $plugin object of config plugin
240
     * @return string text
241
     */
242
    public function prompt(\admin_plugin_config $plugin) {
243
        $prompt = $plugin->getLang($this->key);
244
        if(!$prompt) $prompt = htmlspecialchars(str_replace(array('____', '_'), ' ', $this->key));
245
        return $prompt;
246
    }
247
248
    /**
249
     * Is setting protected
250
     *
251
     * @return bool
252
     */
253
    public function isProtected() {
254
        return !is_null($this->protected);
255
    }
256
257
    /**
258
     * Is setting the default?
259
     *
260
     * @return bool
261
     */
262
    public function isDefault() {
263
        return !$this->isProtected() && is_null($this->local);
264
    }
265
266
    /**
267
     * Has an error?
268
     *
269
     * @return bool
270
     */
271
    public function hasError() {
272
        return $this->error;
273
    }
274
275
    /**
276
     * Returns caution
277
     *
278
     * @return false|string caution string, otherwise false for invalid caution
279
     */
280
    public function caution() {
281
        if(!empty($this->caution)) {
282
            if(!in_array($this->caution, Setting::$validCautions)) {
283
                throw new \RuntimeException(
284
                    'Invalid caution string (' . $this->caution . ') in metadata for setting "' . $this->key . '"'
285
                );
286
            }
287
            return $this->caution;
288
        }
289
        // compatibility with previous cautionList
290
        // TODO: check if any plugins use; remove
291
        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...
292
            $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...
293
            unset($this->cautionList);
294
295
            return $this->caution();
296
        }
297
        return false;
298
    }
299
300
}
301