Failed Conditions
Push — psr2-config ( eb1b59...98a151 )
by Andreas
03:25
created

Setting::shouldBeSaved()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 6
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 5
nc 4
nop 0
dl 0
loc 6
rs 9.2
c 0
b 0
f 0
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 = $default;
62
        $this->local = $local;
63
        $this->protected = $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
78
        $value = is_null($this->local) ? $this->default : $this->local;
79
        if($value == $input) return false;
80
81
        if($this->pattern && !preg_match($this->pattern, $input)) {
82
            $this->error = true;
83
            $this->input = $input;
84
            return false;
85
        }
86
87
        $this->local = $input;
88
        return true;
89
    }
90
91
    /**
92
     * Should this type of config have a default?
93
     *
94
     * @return bool
95
     */
96
    public function shouldHaveDefault() {
97
        return true;
98
    }
99
100
    /**
101
     * Get this setting's unique key
102
     *
103
     * @return string
104
     */
105
    public function getKey() {
106
        return $this->key;
107
    }
108
109
    /**
110
     * Get the key of this setting marked up human readable
111
     *
112
     * @param bool $url link to dokuwiki.org manual?
113
     * @return string
114
     */
115
    public function getPrettyKey($url = true) {
116
        $out = str_replace(Configuration::KEYMARKER, "»", $this->key);
117
        if($url && !strstr($out, '»')) {//provide no urls for plugins, etc.
118
            if($out == 'start') {
119
                // exception, because this config name is clashing with our actual start page
120
                return '<a href="http://www.dokuwiki.org/config:startpage">' . $out . '</a>';
121
            } else {
122
                return '<a href="http://www.dokuwiki.org/config:' . $out . '">' . $out . '</a>';
123
            }
124
        }
125
        return $out;
126
    }
127
128
    /**
129
     * Returns setting key as an array key separator
130
     *
131
     * This is used to create form output
132
     *
133
     * @return string key
134
     */
135
    public function getArrayKey() {
136
        return str_replace(Configuration::KEYMARKER, "']['", $this->key);
137
    }
138
139
    /**
140
     * What type of configuration is this
141
     *
142
     * Returns one of
143
     *
144
     * 'plugin' for plugin configuration
145
     * 'template' for template configuration
146
     * 'conf' for core configuration
147
     *
148
     * @return string
149
     */
150
    public function getType() {
151
        if(substr($this->getKey(), 0, 10) == 'plugin' . Configuration::KEYMARKER) {
152
            return 'plugin';
153
        } else if(substr($this->getKey(), 0, 7) == 'tpl' . Configuration::KEYMARKER) {
154
            return 'template';
155
        } else {
156
            return 'conf';
157
        }
158
    }
159
160
    /**
161
     * Build html for label and input of setting
162
     *
163
     * @param \admin_plugin_config $plugin object of config plugin
164
     * @param bool $echo true: show inputted value, when error occurred, otherwise the stored setting
165
     * @return string[] with content array(string $label_html, string $input_html)
166
     */
167
    public function html(\admin_plugin_config $plugin, $echo = false) {
168
        $disable = '';
169
170
        if($this->isProtected()) {
171
            $value = $this->protected;
172
            $disable = 'disabled="disabled"';
173
        } else {
174
            if($echo && $this->error) {
175
                $value = $this->input;
176
            } else {
177
                $value = is_null($this->local) ? $this->default : $this->local;
178
            }
179
        }
180
181
        $key = htmlspecialchars($this->key);
182
        $value = formText($value);
183
184
        $label = '<label for="config___' . $key . '">' . $this->prompt($plugin) . '</label>';
185
        $input = '<textarea rows="3" cols="40" id="config___' . $key .
186
            '" name="config[' . $key . ']" class="edit" ' . $disable . '>' . $value . '</textarea>';
187
        return array($label, $input);
188
    }
189
190
    /**
191
     * Should the current local value be saved?
192
     *
193
     * @see out() to run when this returns true
194
     * @return bool
195
     */
196
    public function shouldBeSaved() {
197
        if($this->isProtected()) return false;
198
        if($this->local === null) return false;
199
        if($this->default == $this->local) return false;
200
        return true;
201
    }
202
203
    /**
204
     * Generate string to save local setting value to file according to $fmt
205
     *
206
     * @see shouldBeSaved() to check if this should be called
207
     * @param string $var name of variable
208
     * @param string $fmt save format
209
     * @return string
210
     */
211
    public function out($var, $fmt = 'php') {
212
        if($fmt != 'php') return '';
213
214
        $tr = array("\\" => '\\\\', "'" => '\\\''); // escape the value
215
        $out = '$' . $var . "['" . $this->getArrayKey() . "'] = '" . strtr(cleanText($this->local), $tr) . "';\n";
216
217
        return $out;
218
    }
219
220
    /**
221
     * Returns the localized prompt
222
     *
223
     * @param \admin_plugin_config $plugin object of config plugin
224
     * @return string text
225
     */
226
    public function prompt(\admin_plugin_config $plugin) {
227
        $prompt = $plugin->getLang($this->key);
228
        if(!$prompt) $prompt = htmlspecialchars(str_replace(array('____', '_'), ' ', $this->key));
229
        return $prompt;
230
    }
231
232
    /**
233
     * Is setting protected
234
     *
235
     * @return bool
236
     */
237
    public function isProtected() {
238
        return !is_null($this->protected);
239
    }
240
241
    /**
242
     * Is setting the default?
243
     *
244
     * @return bool
245
     */
246
    public function isDefault() {
247
        return !$this->isProtected() && is_null($this->local);
248
    }
249
250
    /**
251
     * Has an error?
252
     *
253
     * @return bool
254
     */
255
    public function hasError() {
256
        return $this->error;
257
    }
258
259
    /**
260
     * Returns caution
261
     *
262
     * @return false|string caution string, otherwise false for invalid caution
263
     */
264
    public function caution() {
265
        if(!empty($this->caution)) {
266
            if(!in_array($this->caution, Setting::$validCautions)) {
267
                throw new \RuntimeException(
268
                    'Invalid caution string (' . $this->caution . ') in metadata for setting "' . $this->key . '"'
269
                );
270
            }
271
            return $this->caution;
272
        }
273
        // compatibility with previous cautionList
274
        // TODO: check if any plugins use; remove
275
        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...
276
            $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...
277
            unset($this->cautionList);
278
279
            return $this->caution();
280
        }
281
        return false;
282
    }
283
284
}
285