Completed
Pull Request — master (#37)
by Tom
02:18
created

ApplicationConfig::fromFiles()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 27
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 1 Features 0
Metric Value
c 4
b 1
f 0
dl 0
loc 27
rs 8.8571
cc 2
eloc 15
nc 2
nop 2

3 Methods

Rating   Name   Duplication   Size   Complexity  
A ApplicationConfig::merge() 0 4 1
A ApplicationConfig::setSeparator() 0 4 1
A ApplicationConfig::getIterator() 0 4 1
1
<?php
2
3
namespace TomPHP\ConfigServiceProvider;
4
5
use ArrayAccess;
6
use IteratorAggregate;
7
use TomPHP\ConfigServiceProvider\Exception\EntryDoesNotExistException;
8
use TomPHP\ConfigServiceProvider\Exception\ReadOnlyException;
9
10
final class ApplicationConfig implements ArrayAccess, IteratorAggregate
11
{
12
    /**
13
     * @var array
14
     */
15
    private $config;
16
17
    /**
18
     * @var string
19
     */
20
    private $separator;
21
22
    /**
23
     * @param array  $config
24
     * @param string $separator
25
     */
26
    public function __construct(array $config, $separator = '.')
27
    {
28
        \Assert\that($separator)->string()->notEmpty();
29
30
        $this->config    = $config;
31
        $this->separator = $separator;
32
    }
33
34
    public function merge(array $config)
35
    {
36
        $this->config = array_replace_recursive($this->config, $config);
37
    }
38
39
    /**
40
     * @param string $separator
41
     *
42
     * @return void
43
     */
44
    public function setSeparator($separator)
45
    {
46
        $this->separator = $separator;
47
    }
48
49
    public function getIterator()
50
    {
51
        return new ApplicationConfigIterator($this);
52
    }
53
54
    /**
55
     * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<integer|string>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
56
     */
57
    public function getKeys()
58
    {
59
        return array_keys(iterator_to_array(new ApplicationConfigIterator($this)));
60
    }
61
62
    public function offsetExists($offset)
63
    {
64
        try {
65
            $this->traverseConfig($this->getPath($offset));
66
        } catch (EntryDoesNotExistException $e) {
67
            return false;
68
        }
69
70
        return true;
71
    }
72
73
    public function offsetGet($offset)
74
    {
75
        return $this->traverseConfig($this->getPath($offset));
76
    }
77
78
    public function offsetSet($offset, $value)
79
    {
80
        throw ReadOnlyException::fromClassName(__CLASS__);
81
    }
82
83
    public function offsetUnset($offset)
84
    {
85
        throw ReadOnlyException::fromClassName(__CLASS__);
86
    }
87
88
    /**
89
     * @return array
90
     */
91
    public function asArray()
92
    {
93
        return $this->config;
94
    }
95
96
    /**
97
     * @return string
98
     */
99
    public function getSeparator()
100
    {
101
        return $this->separator;
102
    }
103
104
    private function getPath($offset)
105
    {
106
        return explode($this->separator, $offset);
107
    }
108
109
    private function traverseConfig(array $path)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
110
    {
111
        $pointer = &$this->config;
112
113
        foreach ($path as $node) {
114
            if (!is_array($pointer) || !array_key_exists($node, $pointer)) {
115
                throw EntryDoesNotExistException::fromKey(implode($this->separator, $path));
116
            }
117
118
            $pointer = &$pointer[$node];
119
        }
120
121
        return $pointer;
122
    }
123
}
124