Failed Conditions
Push — psr2-config ( 8ea568...077c27 )
by Andreas
03:33
created

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