Passed
Branch develop (0ae1ad)
by Kevin
02:45
created

ConfigurationFileRepository   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 164
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 84.88%

Importance

Changes 0
Metric Value
wmc 33
lcom 1
cbo 5
dl 0
loc 164
ccs 73
cts 86
cp 0.8488
rs 9.3999
c 0
b 0
f 0

17 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 2
B buildConfigurationFileList() 0 24 5
B getSupportedTypes() 0 17 5
A count() 0 4 1
A registerConfigurationFile() 0 7 2
A addSecureBase() 0 8 2
A checkFileLocation() 0 15 4
A getSecureBases() 0 4 1
A current() 0 6 1
A next() 0 8 2
A key() 0 4 1
A valid() 0 6 2
A rewind() 0 4 1
A offsetExists() 0 4 1
A offsetGet() 0 6 1
A offsetSet() 0 4 1
A offsetUnset() 0 4 1
1
<?php
2
3
namespace Magium\Configuration\File\Configuration;
4
5
use Magium\Configuration\Config\InvalidConfigurationLocationException;
6
use Magium\Configuration\Config\InvalidDirectoryException;
7
use Magium\Configuration\File\AdapterInterface;
8
use Magium\Configuration\File\InvalidFileException;
9
10
class ConfigurationFileRepository implements \ArrayAccess, \Iterator, \Countable
11
{
12
    protected $files = [];
13
    protected $secureBases = [];
14
15 20
    public function __construct(array $secureBases = [], array $configurationFiles = [])
16
    {
17 20
        foreach ($secureBases as $base) {
18 5
            $this->addSecureBase($base);
19
        }
20
21 19
        $supportedTypes = $this->getSupportedTypes($configurationFiles);
22 19
        $this->buildConfigurationFileList($configurationFiles, $supportedTypes);
23
24 17
    }
25
26 19
    protected function buildConfigurationFileList(array $configurationFiles, array $supportedTypes)
27
    {
28 19
        foreach ($configurationFiles as $file) {
29 3
            $fileName = basename($file);
30 3
            $typeFound = false;
31 3
            foreach ($supportedTypes as $type) {
32 3
                if (strpos($fileName, '.' . $type) !== false) {
33 2
                    $class = 'Magium\Configuration\File\Configuration\\' . ucfirst($type) . 'File';
34 2
                    $configurationFile = new $class($file);
35 1
                    $this->registerConfigurationFile($configurationFile);
36 3
                    $typeFound = true;
37
                }
38
            }
39 2
            if (!$typeFound) {
40 1
                throw new UnsupportedFileTypeException(
41
                    sprintf(
42 1
                        'File %s does not have a supported file extension: %s',
43
                        $file,
44 2
                        implode(',', $supportedTypes)
45
                    ))
46
                ;
47
            }
48
        }
49 17
    }
50
51 19
    protected function getSupportedTypes(array $configurationFiles)
52
    {
53 19
        $supportedTypes = [];
54 19
        if (!empty($configurationFiles)) {
55 3
            $checkSupportedTypes = glob(__DIR__ . '/*File.php');
56 3
            foreach ($checkSupportedTypes as $file) {
57 3
                $file = basename($file);
58 3
                if ($file != 'AbstractConfigurationFile.php') {
59 3
                    $match = null;
60 3
                    if (preg_match('/^([a-zA-Z]+)File.php$/', $file, $match)) {
61 3
                        $supportedTypes[] = strtolower($match[1]);
62
                    }
63
                }
64
            }
65
        }
66 19
        return $supportedTypes;
67
    }
68
69 4
    public function count()
70
    {
71 4
        return count($this->files);
72
    }
73
74 3
    public function registerConfigurationFile(AdapterInterface $file)
75
    {
76 3
        if (isset($this->files[$file->getFile()])) {
77
            throw new InvalidFileException('The file has been added already: ' . $file->getFile());
78
        }
79 3
        $this->files[$file->getFile()] = $file;
80 3
    }
81
82 6
    public function addSecureBase($base)
83
    {
84 6
        $path = realpath($base);
85 6
        if (!is_dir($path)) {
86 1
            throw new InvalidDirectoryException('Unable to determine real path for directory: ' . $base);
87
        }
88 5
        $this->secureBases[] = $path;
89 5
    }
90
91 3
    protected function checkFileLocation(AdapterInterface $file)
92
    {
93 3
        $path = realpath($file->getFile());
94 3
        $inSecurePath = false;
95 3
        foreach ($this->secureBases as $base) {
96 2
            if (strpos($path, $base) === 0) {
97 2
                $inSecurePath = true;
98 2
                break;
99
            }
100
        }
101
102 3
        if (!$inSecurePath) {
103 1
            throw new InvalidConfigurationLocationException($path . ' is not in one of the designated secure configuration paths.');
104
        }
105 2
    }
106
107
    /**
108
     * Retrieves a list of secure base directories
109
     *
110
     * @return array
111
     */
112
113 1
    public function getSecureBases()
114
    {
115 1
        return $this->secureBases;
116
    }
117
118 3
    public function current()
119
    {
120 3
        $current =  current($this->files);
121 3
        $this->checkFileLocation($current);
122 2
        return $current;
123
    }
124
125 2
    public function next()
126
    {
127 2
        $next = next($this->files);
128 2
        if (!is_bool($next)) {
129 1
            $this->checkFileLocation($next);
130
        }
131 2
        return $next;
132
    }
133
134 3
    public function key()
135
    {
136 3
        return key($this->files);
137
    }
138
139 3
    public function valid()
140
    {
141 3
        $key = $this->key();
142 3
        $var = ($key !== NULL && $key !== FALSE);
143 3
        return $var;
144
    }
145
146 3
    public function rewind()
147
    {
148 3
        return reset($this->files);
149
    }
150
151
    public function offsetExists($offset)
152
    {
153
        return isset($this->files[$offset]);
154
    }
155
156
    public function offsetGet($offset)
157
    {
158
        $get = $this->files[$offset];
159
        $this->checkFileLocation($get);
160
        return $get;
161
    }
162
163
    public function offsetSet($offset, $value)
164
    {
165
        $this->registerConfigurationFile($value);
166
    }
167
168
    public function offsetUnset($offset)
169
    {
170
        unset($this->files[$offset]);
171
    }
172
173
}
174