Completed
Push — psr2-config ( 077c27...5675a0 )
by Andreas
06:18 queued 03:15
created

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