ConfigurationFileRepository   A
last analyzed

Complexity

Total Complexity 39

Size/Duplication

Total Lines 182
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 87.23%

Importance

Changes 0
Metric Value
wmc 39
lcom 1
cbo 4
dl 0
loc 182
ccs 82
cts 94
cp 0.8723
rs 9.28
c 0
b 0
f 0

19 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 1 1
A getInstance() 0 14 4
A reset() 0 4 1
A buildConfigurationFileList() 0 24 5
A getSupportedTypes() 0 19 6
A count() 0 4 1
A registerConfigurationFile() 0 7 2
A addSecureBase() 0 10 3
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
    protected $supportedTypes = [];
15
16
    protected static $me;
17
18
    protected function __construct() {}
19
20 25
    public static function getInstance(array $secureBases = [], array $configurationFiles = [])
21
    {
22 25
        if (!self::$me instanceof self) {
23 24
            self::$me = new self();
24
        }
25 25
        foreach ($secureBases as $base) {
26 6
            self::$me->addSecureBase($base);
27
        }
28 24
        if ($configurationFiles) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $configurationFiles of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

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