Skip to content

Commit f7895c7

Browse files
committed
Add abstract config
1 parent f9e23e3 commit f7895c7

4 files changed

Lines changed: 433 additions & 0 deletions

File tree

src/AbstractConfig.php

Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
<?php
2+
3+
namespace ConfigWriter;
4+
5+
use RecursiveIteratorIterator;
6+
use RecursiveArrayIterator;
7+
use ArrayAccess;
8+
9+
/**
10+
* Abstract configuration class.
11+
*
12+
* @since 2.0.0
13+
*
14+
* @author Filip Š <projects@filips.si>
15+
*
16+
* @license MIT
17+
*
18+
* @package ConfigWriter
19+
*/
20+
abstract class AbstractConfig implements ConfigInterface, ArrayAccess
21+
{
22+
/**
23+
* Stores the configuration data.
24+
*
25+
* @var array;
26+
*/
27+
public $data = [];
28+
29+
/**
30+
* Stores the configuration comment.
31+
*
32+
* @var mixed|null
33+
*/
34+
public $comment = null;
35+
36+
/**
37+
* Constructs the configuration.
38+
*
39+
* @param array $data Configuration data (optional)
40+
* @param string $comment Configuration comment (optional)
41+
*/
42+
public function __construct($data = [], $comment = null)
43+
{
44+
$ritit = new RecursiveIteratorIterator(
45+
new RecursiveArrayIterator(
46+
$data,
47+
RecursiveArrayIterator::CHILD_ARRAYS_ONLY
48+
)
49+
);
50+
51+
foreach ($ritit as $leafValue) {
52+
$keys = [];
53+
54+
foreach (range(0, $ritit->getDepth()) as $depth) {
55+
$keys[] = $ritit->getSubIterator($depth)->key();
56+
}
57+
58+
$this->set(join('.', $keys), $leafValue);
59+
}
60+
61+
$this->data = self::stringToRecord($this->data);
62+
$this->comment = $comment;
63+
}
64+
65+
/**
66+
* Changes string to config record.
67+
*
68+
* @param array $arr Array with configuration
69+
*
70+
* @return array Converted array with configuration
71+
*/
72+
public static function stringToRecord($arr)
73+
{
74+
$result = [];
75+
76+
foreach ($arr as $key => $value) {
77+
if ($value instanceof Record) {
78+
if (is_array($value->value)) {
79+
$result[$key] = new Record(
80+
self::stringToRecord($value->value),
81+
$value->comment
82+
);
83+
} else {
84+
$result[$key] = new Record(
85+
$value->value,
86+
$value->comment
87+
);
88+
}
89+
} elseif ($value instanceof static) {
90+
$result[$key] = $value;
91+
} else {
92+
if (is_array($value)) {
93+
$result[$key] = new Record(
94+
self::stringToRecord($value)
95+
);
96+
} else {
97+
$result[$key] = new Record(
98+
$value
99+
);
100+
}
101+
}
102+
}
103+
104+
return $result;
105+
}
106+
107+
/**
108+
* Changes config record to string.
109+
*
110+
* @param array $arr Array with configuration
111+
*
112+
* @return array Converted array with configuration
113+
*/
114+
public static function recordToString($arr)
115+
{
116+
$result = [];
117+
118+
foreach ($arr as $key => $value) {
119+
if ($value instanceof Record) {
120+
if (is_array($value->value)) {
121+
$result[$key] = self::recordToString($value->value);
122+
} else {
123+
$result[$key] = $value->value;
124+
}
125+
} elseif ($value instanceof static) {
126+
$result = array_merge($result, self::recordToString($value->data));
127+
} else {
128+
if (is_array($value)) {
129+
$result[$key] = self::recordToString($value);
130+
} else {
131+
$result[$key] = $value;
132+
}
133+
}
134+
}
135+
136+
return $result;
137+
}
138+
139+
/**
140+
* Function for setting configuration values, using
141+
* either simple or nested keys.
142+
*
143+
* @param string $key Record's key
144+
* @param mixed $value Record's value
145+
*
146+
* @return mixed Added record
147+
*/
148+
protected function set($key, $value)
149+
{
150+
$segs = explode('.', $key);
151+
$root = &$this->data;
152+
$cacheKey = '';
153+
154+
// Look for the key, creating nested keys if needed
155+
while ($part = array_shift($segs)) {
156+
if ($cacheKey !== '') {
157+
$cacheKey .= '.';
158+
}
159+
$cacheKey .= $part;
160+
161+
if (!isset($root[$part]) && count($segs)) {
162+
$root[$part] = [];
163+
}
164+
$root = &$root[$part];
165+
}
166+
167+
// Assign value at target node
168+
$root = $value;
169+
170+
return $value;
171+
}
172+
173+
/**
174+
* ConfigInterface methods.
175+
*/
176+
177+
/**
178+
* {@inheritDoc}
179+
*/
180+
public function addRecord($key, $value = null, $comment = null)
181+
{
182+
$record = $this->set(
183+
$key,
184+
new Record($value, $comment)
185+
);
186+
187+
$this->data = self::stringToRecord($this->data);
188+
189+
return $record;
190+
}
191+
192+
/**
193+
* {@inheritDoc}
194+
*/
195+
public function addSection($key, $data = [], $comment = null)
196+
{
197+
$section = $this->set(
198+
$key,
199+
new static(
200+
$data,
201+
$comment
202+
)
203+
);
204+
205+
$this->data = self::stringToRecord($this->data);
206+
207+
return $section;
208+
}
209+
210+
/**
211+
* ArrayAccess methods.
212+
*/
213+
214+
/**
215+
* Gets a value using the offset as a key.
216+
*
217+
* @param string $offset
218+
*
219+
* @return mixed
220+
*/
221+
public function &offsetGet($offset)
222+
{
223+
return $this->data[$offset];
224+
}
225+
226+
/**
227+
* Checks if a key exists.
228+
*
229+
* @param string $offset
230+
*
231+
* @return bool
232+
*/
233+
public function offsetExists($offset)
234+
{
235+
return isset($this->data[$offset]);
236+
}
237+
238+
/**
239+
* Sets a value using the offset as a key.
240+
*
241+
* @param string $offset
242+
* @param mixed $value
243+
*
244+
* @return void
245+
*/
246+
public function offsetSet($offset, $value)
247+
{
248+
if ($value instanceof Record || $value instanceof ConfigInterface) {
249+
$this->set($offset, $value);
250+
} else {
251+
$this->addRecord($offset, $value);
252+
}
253+
}
254+
255+
/**
256+
* Deletes a key and its value
257+
*
258+
* @param string $offset
259+
*
260+
* @return void
261+
*/
262+
public function offsetUnset($offset)
263+
{
264+
$this->set($offset, null);
265+
}
266+
}

src/Config.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace ConfigWriter;
4+
5+
/**
6+
* Configuration class.
7+
*
8+
* @since 2.0.0
9+
*
10+
* @author Filip Š <projects@filips.si>
11+
*
12+
* @license MIT
13+
*
14+
* @package ConfigWriter
15+
*/
16+
class Config extends AbstractConfig
17+
{
18+
/**
19+
* Writes configuration to string.
20+
*
21+
* TODO: Documentation
22+
*/
23+
public function toString($format)
24+
{
25+
// TODO: Return configuration as a string.
26+
}
27+
28+
/**
29+
* Writes configuration to file.
30+
*
31+
* TODO: Documentation
32+
*/
33+
public function toFile($filename, $format)
34+
{
35+
// TODO: Write configuration to file using method `toString()`.
36+
}
37+
}

src/ConfigInterface.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
namespace ConfigWriter;
4+
5+
/**
6+
* Configuration interface.
7+
*
8+
* @since 2.0.0
9+
*
10+
* @author Filip Š <projects@filips.si>
11+
*
12+
* @license MIT
13+
*
14+
* @package ConfigWriter
15+
*/
16+
interface ConfigInterface
17+
{
18+
/**
19+
* Adds configuration record.
20+
*
21+
* @param string $key Record's key
22+
* @param mixed|null $value Record's value (optional)
23+
* @param mixed|null $comment Record's comment (optional)
24+
*
25+
* @return Record Added record
26+
*/
27+
public function addRecord($key, $value = null, $comment = null);
28+
29+
/**
30+
* Adds configuration section.
31+
*
32+
* @param string $key Section's key
33+
* @param array $data Section's data (optional)
34+
* @param mixed|null $comment Section's comment (optional)
35+
*
36+
* @return ConfigInterface Added section
37+
*/
38+
public function addSection($key, $data = [], $comment = null);
39+
}

0 commit comments

Comments
 (0)