Failed Conditions
Push — psr2-config ( de33cd...0a5b05 )
by Andreas
08:47 queued 04:28
created

Configuration::isLocked()   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
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace dokuwiki\plugin\config\core;
4
use dokuwiki\plugin\config\core\Setting\Setting;
5
use dokuwiki\plugin\config\core\Setting\SettingUndefined;
6
7
/**
8
 * Holds all the current settings and proxies the Loader and Writer
9
 *
10
 * @author Chris Smith <[email protected]>
11
 * @author Ben Coburn <[email protected]>
12
 * @author Andreas Gohr <[email protected]>
13
 */
14
class Configuration {
15
16
    const KEYMARKER = '____';
17
18
    /** @var Setting[] metadata as array of Settings objects */
19
    protected $settings = array();
20
    /** @var array problematic keys */
21
    protected $errors;
22
    /** @var Setting[] undefined settings */
23
    protected $undefined = array();
24
25
    /** @var array all metadata */
26
    protected $metadata;
27
    /** @var array all default settings */
28
    protected $default;
29
    /** @var array all local settings */
30
    protected $local;
31
    /** @var array all protected settings */
32
    protected $protected;
33
34
    /** @var bool have the settings been changed since loading from disk? */
35
    protected $changed = false;
36
37
    /** @var Loader */
38
    protected $loader;
39
    /** @var Writer */
40
    protected $writer;
41
42
    /**
43
     * ConfigSettings constructor.
44
     */
45
    public function __construct() {
46
        $this->loader = new Loader(new ConfigParser());
47
        $this->writer = new Writer();
48
49
        $this->metadata = $this->loader->loadMeta();
50
        $this->default = $this->loader->loadDefaults();
51
        $this->local = $this->loader->loadLocal();
52
        $this->protected = $this->loader->loadProtected();
53
54
        $this->initSettings();
55
    }
56
57
    /**
58
     * Get all settings
59
     *
60
     * @return Setting[]
61
     */
62
    public function getSettings() {
63
        return $this->settings;
64
    }
65
66
    /**
67
     * Get all unknown settings
68
     *
69
     * @return Setting[]
70
     */
71
    public function getUndefined() {
72
        return $this->undefined;
73
    }
74
75
    /**
76
     * Get the settings that had some kind of setup problem
77
     *
78
     * @return array associative error, key is the setting, value the error
79
     */
80
    public function getErrors() {
81
        return $this->errors;
82
    }
83
84
    /**
85
     * Have the settings been changed since loading from disk?
86
     *
87
     * @return bool
88
     */
89
    public function hasChanged() {
90
        return $this->changed;
91
    }
92
93
    /**
94
     * Check if the config can be written
95
     *
96
     * @return bool
97
     */
98
    public function isLocked() {
99
        return $this->writer->isLocked();
100
    }
101
102
    /**
103
     * Update the settings using the data provided
104
     *
105
     * @param array $input as posted
106
     * @return bool true if all updates went through, false on errors
107
     */
108
    public function updateSettings($input) {
109
        $ok = true;
110
111
        foreach($this->settings as $key => $obj) {
112
            $value = isset($input[$key]) ? $input[$key] : null;
113
            if($obj->update($value)) {
114
                $this->changed = true;
115
            }
116
            if($obj->hasError()) $ok = false;
117
        }
118
119
        return $ok;
120
    }
121
122
    /**
123
     * Save the settings
124
     *
125
     * @throws \Exception
126
     */
127
    public function save() {
128
        $this->writer->save($this->settings);
129
    }
130
131
    /**
132
     * Touch the settings
133
     *
134
     * @throws \Exception
135
     */
136
    public function touch() {
137
        $this->writer->touch();
138
    }
139
140
    /**
141
     * Load the extension language strings
142
     *
143
     * @return array
144
     */
145
    public function getLangs() {
146
        return $this->loader->loadLangs();
147
    }
148
149
    /**
150
     * Initalizes the $settings and $undefined properties
151
     */
152
    protected function initSettings() {
153
        $keys = array_merge(
154
            array_keys($this->metadata),
155
            array_keys($this->default),
156
            array_keys($this->local),
157
            array_keys($this->protected)
158
        );
159
        $keys = array_unique($keys);
160
161
        foreach($keys as $key) {
162
            $obj = $this->instantiateClass($key);
163
164
            if($obj->shouldHaveDefault() && !isset($this->default[$key])) {
165
                $this->errors[$key] = 'no default';
166
            }
167
168
            $d = isset($this->default[$key]) ? $this->default[$key] : null;
169
            $l = isset($this->local[$key]) ? $this->local[$key] : null;
170
            $p = isset($this->protected[$key]) ? $this->protected[$key] : null;
171
172
            $obj->initialize($d, $l, $p);
173
        }
174
    }
175
176
    /**
177
     * Instantiates the proper class for the given config key
178
     *
179
     * The class is added to the $settings or $undefined arrays and returned
180
     *
181
     * @param string $key
182
     * @return Setting
183
     */
184
    protected function instantiateClass($key) {
185
        if(isset($this->metadata[$key])) {
186
            $param = $this->metadata[$key];
187
            $class = $this->determineClassName(array_shift($param), $key); // first param is class
188
            $obj = new $class($key, $param);
189
            $this->settings[] = $obj;
190
        } else {
191
            $obj = new SettingUndefined($key);
192
            $this->undefined[] = $obj;
193
        }
194
        return $obj;
195
    }
196
197
    /**
198
     * Return the class to load
199
     *
200
     * @param string $class the class name as given in the meta file
201
     * @param string $key the settings key
202
     * @return string
203
     */
204
    protected function determineClassName($class, $key) {
205
        // try namespaced class first
206
        if($class) {
207
            $modern = str_replace('_', '', ucwords($class, '_'));
208
            $modern = '\\dokuwiki\\plugin\\config\\core\\Setting\\Setting' . $modern;
209
            if($modern && class_exists($modern)) return $modern;
210
            // try class as given
211
            if(class_exists($class)) return $class;
212
            // class wasn't found add to errors
213
            $this->errors[$key] = 'unknown class';
214
        } else {
215
            // no class given, add to errors
216
            $this->errors[$key] = 'no class';
217
        }
218
        return '\\dokuwiki\\plugin\\config\\core\\Setting\\Setting';
219
    }
220
221
}
222