Skip to content

Commit e546548

Browse files
committed
Add missing core directory
1 parent d97329f commit e546548

30 files changed

+2005
-0
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
3+
namespace dokuwiki\plugin\config\core;
4+
5+
/**
6+
* A naive PHP file parser
7+
*
8+
* This parses our very simple config file in PHP format. We use this instead of simply including
9+
* the file, because we want to keep expressions such as 24*60*60 as is.
10+
*
11+
* @author Chris Smith <[email protected]>
12+
*/
13+
class ConfigParser {
14+
/** @var string variable to parse from the file */
15+
protected $varname = 'conf';
16+
/** @var string the key to mark sub arrays */
17+
protected $keymarker = Configuration::KEYMARKER;
18+
19+
/**
20+
* Parse the given PHP file into an array
21+
*
22+
* When the given files does not exist, this returns an empty array
23+
*
24+
* @param string $file
25+
* @return array
26+
*/
27+
public function parse($file) {
28+
if(!file_exists($file)) return array();
29+
30+
$config = array();
31+
$contents = @php_strip_whitespace($file);
32+
$pattern = '/\$' . $this->varname . '\[[\'"]([^=]+)[\'"]\] ?= ?(.*?);(?=[^;]*(?:\$' . $this->varname . '|$))/s';
33+
$matches = array();
34+
preg_match_all($pattern, $contents, $matches, PREG_SET_ORDER);
35+
36+
for($i = 0; $i < count($matches); $i++) {
37+
$value = $matches[$i][2];
38+
39+
// merge multi-dimensional array indices using the keymarker
40+
$key = preg_replace('/.\]\[./', $this->keymarker, $matches[$i][1]);
41+
42+
// handle arrays
43+
if(preg_match('/^array ?\((.*)\)/', $value, $match)) {
44+
$arr = explode(',', $match[1]);
45+
46+
// remove quotes from quoted strings & unescape escaped data
47+
$len = count($arr);
48+
for($j = 0; $j < $len; $j++) {
49+
$arr[$j] = trim($arr[$j]);
50+
$arr[$j] = $this->readValue($arr[$j]);
51+
}
52+
53+
$value = $arr;
54+
} else {
55+
$value = $this->readValue($value);
56+
}
57+
58+
$config[$key] = $value;
59+
}
60+
61+
return $config;
62+
}
63+
64+
/**
65+
* Convert php string into value
66+
*
67+
* @param string $value
68+
* @return bool|string
69+
*/
70+
protected function readValue($value) {
71+
$removequotes_pattern = '/^(\'|")(.*)(?<!\\\\)\1$/s';
72+
$unescape_pairs = array(
73+
'\\\\' => '\\',
74+
'\\\'' => '\'',
75+
'\\"' => '"'
76+
);
77+
78+
if($value == 'true') {
79+
$value = true;
80+
} elseif($value == 'false') {
81+
$value = false;
82+
} else {
83+
// remove quotes from quoted strings & unescape escaped data
84+
$value = preg_replace($removequotes_pattern, '$2', $value);
85+
$value = strtr($value, $unescape_pairs);
86+
}
87+
return $value;
88+
}
89+
90+
}
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
<?php
2+
3+
namespace dokuwiki\plugin\config\core;
4+
5+
use dokuwiki\plugin\config\core\Setting\Setting;
6+
use dokuwiki\plugin\config\core\Setting\SettingNoClass;
7+
use dokuwiki\plugin\config\core\Setting\SettingNoDefault;
8+
use dokuwiki\plugin\config\core\Setting\SettingNoKnownClass;
9+
use dokuwiki\plugin\config\core\Setting\SettingUndefined;
10+
11+
/**
12+
* Holds all the current settings and proxies the Loader and Writer
13+
*
14+
* @author Chris Smith <[email protected]>
15+
* @author Ben Coburn <[email protected]>
16+
* @author Andreas Gohr <[email protected]>
17+
*/
18+
class Configuration {
19+
20+
const KEYMARKER = '____';
21+
22+
/** @var Setting[] metadata as array of Settings objects */
23+
protected $settings = array();
24+
/** @var Setting[] undefined and problematic settings */
25+
protected $undefined = array();
26+
27+
/** @var array all metadata */
28+
protected $metadata;
29+
/** @var array all default settings */
30+
protected $default;
31+
/** @var array all local settings */
32+
protected $local;
33+
/** @var array all protected settings */
34+
protected $protected;
35+
36+
/** @var bool have the settings been changed since loading from disk? */
37+
protected $changed = false;
38+
39+
/** @var Loader */
40+
protected $loader;
41+
/** @var Writer */
42+
protected $writer;
43+
44+
/**
45+
* ConfigSettings constructor.
46+
*/
47+
public function __construct() {
48+
$this->loader = new Loader(new ConfigParser());
49+
$this->writer = new Writer();
50+
51+
$this->metadata = $this->loader->loadMeta();
52+
$this->default = $this->loader->loadDefaults();
53+
$this->local = $this->loader->loadLocal();
54+
$this->protected = $this->loader->loadProtected();
55+
56+
$this->initSettings();
57+
}
58+
59+
/**
60+
* Get all settings
61+
*
62+
* @return Setting[]
63+
*/
64+
public function getSettings() {
65+
return $this->settings;
66+
}
67+
68+
/**
69+
* Get all unknown or problematic settings
70+
*
71+
* @return Setting[]
72+
*/
73+
public function getUndefined() {
74+
return $this->undefined;
75+
}
76+
77+
/**
78+
* Have the settings been changed since loading from disk?
79+
*
80+
* @return bool
81+
*/
82+
public function hasChanged() {
83+
return $this->changed;
84+
}
85+
86+
/**
87+
* Check if the config can be written
88+
*
89+
* @return bool
90+
*/
91+
public function isLocked() {
92+
return $this->writer->isLocked();
93+
}
94+
95+
/**
96+
* Update the settings using the data provided
97+
*
98+
* @param array $input as posted
99+
* @return bool true if all updates went through, false on errors
100+
*/
101+
public function updateSettings($input) {
102+
$ok = true;
103+
104+
foreach($this->settings as $key => $obj) {
105+
$value = isset($input[$key]) ? $input[$key] : null;
106+
if($obj->update($value)) {
107+
$this->changed = true;
108+
}
109+
if($obj->hasError()) $ok = false;
110+
}
111+
112+
return $ok;
113+
}
114+
115+
/**
116+
* Save the settings
117+
*
118+
* This save the current state as defined in this object, including the
119+
* undefined settings
120+
*
121+
* @throws \Exception
122+
*/
123+
public function save() {
124+
// only save the undefined settings that have not been handled in settings
125+
$undefined = array_diff_key($this->undefined, $this->settings);
126+
$this->writer->save(array_merge($this->settings, $undefined));
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->undefined[$key] = new SettingNoDefault($key);
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[$key] = $obj;
188+
} else {
189+
$obj = new SettingUndefined($key);
190+
$this->undefined[$key] = $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(is_string($class)) {
205+
$modern = str_replace('_', '', ucwords($class, '_'));
206+
$modern = '\\dokuwiki\\plugin\\config\\core\\Setting\\Setting' . $modern;
207+
if($modern && class_exists($modern)) return $modern;
208+
// try class as given
209+
if(class_exists($class)) return $class;
210+
// class wasn't found add to errors
211+
$this->undefined[$key] = new SettingNoKnownClass($key);
212+
} else {
213+
// no class given, add to errors
214+
$this->undefined[$key] = new SettingNoClass($key);
215+
}
216+
return '\\dokuwiki\\plugin\\config\\core\\Setting\\Setting';
217+
}
218+
219+
}

0 commit comments

Comments
 (0)