Test Failed
Pull Request — develop (#18)
by Kevin
02:51
created

buildConfigurationFileList()   B

Complexity

Conditions 5
Paths 7

Size

Total Lines 24
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 24
rs 8.5125
c 0
b 0
f 0
cc 5
eloc 16
nc 7
nop 2
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
    public function __construct(array $secureBases = [], array $configurationFiles = [])
16
    {
17
        foreach ($secureBases as $base) {
18
            $this->addSecureBase($base);
19
        }
20
21
        $supportedTypes = $this->getSupportedTypes($configurationFiles);
22
        $this->buildConfigurationFileList($configurationFiles, $supportedTypes);
23
24
    }
25
26
    protected function buildConfigurationFileList(array $configurationFiles, array $supportedTypes)
27
    {
28
        foreach ($configurationFiles as $file) {
29
            $fileName = basename($file);
30
            $typeFound = false;
31
            foreach ($supportedTypes as $type) {
32
                if (strpos($fileName, '.' . $type) !== false) {
33
                    $class = 'Magium\Configuration\File\Configuration\\' . ucfirst($type) . 'File';
34
                    $configurationFile = new $class($file);
35
                    $this->registerConfigurationFile($configurationFile);
36
                    $typeFound = true;
37
                }
38
            }
39
            if (!$typeFound) {
40
                throw new UnsupportedFileTypeException(
41
                    sprintf(
42
                        'File %s does not have a supported file extension: %s',
43
                        $file,
44
                        implode(',', $supportedTypes)
45
                    ))
46
                ;
47
            }
48
        }
49
    }
50
51
    protected function getSupportedTypes(array $configurationFiles)
52
    {
53
        $supportedTypes = [];
54
        if (!empty($configurationFiles)) {
55
            $checkSupportedTypes = glob(__DIR__ . '/*File.php');
56
            foreach ($checkSupportedTypes as $file) {
57
                $file = basename($file);
58
                if ($file != 'AbstractConfigurationFile.php') {
59
                    $match = null;
60
                    if (preg_match('/^([a-zA-Z]+)File.php$/', $file, $match)) {
61
                        $supportedTypes[] = strtolower($match[1]);
62
                    }
63
                }
64
            }
65
        }
66
        return $supportedTypes;
67
    }
68
69
    public function count()
70
    {
71
        return count($this->files);
72
    }
73
74
    public function registerConfigurationFile(AdapterInterface $file)
75
    {
76
        if (isset($this->files[$file->getFile()])) {
77
            throw new InvalidFileException('The file has been added already: ' . $file->getFile());
78
        }
79
        $this->files[$file->getFile()] = $file;
80
    }
81
82
    public function addSecureBase($base)
83
    {
84
        $path = realpath($base);
85
        if (!is_dir($path)) {
86
            throw new InvalidDirectoryException('Unable to determine real path for directory: ' . $base);
87
        }
88
        $this->secureBases[] = $path;
89
    }
90
91
    protected function checkFileLocation(AdapterInterface $file)
92
    {
93
        $path = realpath($file->getFile());
94
        $inSecurePath = false;
95
        foreach ($this->secureBases as $base) {
96
            if (strpos($path, $base) === 0) {
97
                $inSecurePath = true;
98
                break;
99
            }
100
        }
101
102
        if (!$inSecurePath) {
103
            throw new InvalidConfigurationLocationException($path . ' is not in one of the designated secure configuration paths.');
104
        }
105
    }
106
107
    /**
108
     * Retrieves a list of secure base directories
109
     *
110
     * @return array
111
     */
112
113
    public function getSecureBases()
114
    {
115
        return $this->secureBases;
116
    }
117
118
    public function current()
119
    {
120
        $current =  current($this->files);
121
        $this->checkFileLocation($current);
122
        return $current;
123
    }
124
125
    public function next()
126
    {
127
        $next = next($this->files);
128
        if (!is_bool($next)) {
129
            $this->checkFileLocation($next);
130
        }
131
        return $next;
132
    }
133
134
    public function key()
135
    {
136
        return key($this->files);
137
    }
138
139
    public function valid()
140
    {
141
        $key = $this->key();
142
        $var = ($key !== NULL && $key !== FALSE);
143
        return $var;
144
    }
145
146
    public function rewind()
147
    {
148
        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