Passed
Pull Request — develop (#18)
by Kevin
03:58 queued 41s
created

ConfigurationFileRepository::current()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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