Completed
Push — master ( 674f49...b68ebb )
by Mikael
03:02
created

Configuration   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 173
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 18
lcom 1
cbo 1
dl 0
loc 173
ccs 43
cts 43
cp 1
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A setMapping() 0 5 1
A setBaseDirectories() 0 15 5
B load() 0 43 10
A loadFromDir() 0 12 2
1
<?php
2
3
namespace Anax\Configure;
4
5
/**
6
 * Load configuration for a specified item, look in several places for the
7
 * configuration files or directories. Return the configuration as the value
8
 * received from the configuration file.
9
 */
10
class Configuration
11
{
12
    /**
13
     * @var array $dirs where to look for configuration items.
14
     */
15
    protected $dirs = [];
16
17
18
19
    /**
20
     * @var array $mapping mapping items to specific configuration file, mainly
21
     *                     useful for testing various configuration files.
22
     */
23
    protected $mapping = [];
24
25
26
27
    /**
28
     * Set a specific configuration file to load for a particluar item.
29
     *
30
     * @param string $item the item to map.
31
     * @param string $file file to load configuration from.
32
     *
33
     * @return self to allow chaining.
34
     */
35 1
    public function setMapping(string $item, string $file) : object
36
    {
37 1
        $this->mapping[$item] = $file;
38 1
        return $this;
39
    }
40
41
42
43
    /**
44
     * Set the directories where to look for configuration
45
     * items (files, directories) to load.
46
     *
47
     * @throws Exception when the path to any of the directories are incorrect.
48
     *
49
     * @param array $dirs with the path to the config directories to search in.
50
     *
51
     * @return self to allow chaining.
52
     */
53 8
    public function setBaseDirectories(array $dirs): object
54
    {
55 8
        if (empty($dirs)) {
56 1
            throw new Exception("The array for configuration directories can not be empty.");
57
        }
58
59 7
        foreach ($dirs as $dir) {
60 7
            if (!(is_readable($dir) && is_dir($dir))) {
61 7
                throw new Exception("The configuration dir '$dir' is not a valid path.");
62
            }
63
        }
64
65 6
        $this->dirs = $dirs;
66 6
        return $this;
67
    }
68
69
70
71
    /**
72
     * Read configuration from file or directory, if a file, look though all
73
     * base dirs and use the first configuration that is found. A configuration
74
     * item can be combined from a file and a directory, when available in the
75
     * same base directory.
76
     *
77
     * The resulting configuration is always an array, its structure contains
78
     * values from each individual configuration file, like this.
79
     *
80
     * $config = [
81
     *      "file" => filename for file.php,
82
     *      "config" => result returned from file.php,
83
     *      "items" => [
84
     *          [
85
     *              "file" => filename for dir/file1.php,
86
     *              "config" => result returned from dir/file1.php,
87
     *          ],
88
     *          [
89
     *              "file" => filename for dir/file2.php,
90
     *              "config" => result returned from dir/file2.php,
91
     *          ],
92
     *      ].
93
     * ]
94
     *
95
     * The configuration files in the directory are loaded per alphabetical
96
     * order.
97
     *
98
     * @param string $item is a name representing the module and is used to
99
     *                     combine the path to search for.
100
     *
101
     * @throws Exception when configuration item can not be found.
102
     * @throws Exception when $dirs are empty.
103
     *
104
     * @return array with returned value from the loaded configuration.
105
     */
106 6
    public function load(string $item) : array
107
    {
108 6
        if (empty($this->dirs)) {
109 1
            throw new Exception("The array for configuration directories can not be empty.");
110
        }
111
112 5
        $found = false;
113 5
        $config = [];
114 5
        $mapping = $this->mapping[$item] ?? null;
115 5
        if ($mapping) {
116 1
            $config["file"] = $mapping;
117 1
            $config["config"] = require $mapping;
118 1
            return $config;
119
        }
120
121 4
        foreach ($this->dirs as $dir) {
122 4
            $path = "$dir/$item";
123 4
            $file = "$path.php";
124
125
            // The configuration is found in a file
126 4
            if (is_readable($file) && is_file($file)) {
127 2
                $found = true;
128 2
                $config["file"] = $file;
129 2
                $config["config"] = require $file;
130
            }
131
132
            // The configuration is found in a directory
133 4
            if (is_readable($path) && is_dir($path)) {
134 2
                $found = true;
135 2
                $config["items"] = $this->loadFromDir($path);
136
            }
137
138 4
            if ($found) {
139 4
                break;
140
            }
141
        }
142
143 4
        if (!$found) {
144 1
            throw new Exception("Configure item '$item' can not be found.");
145
        }
146
147 3
        return $config;
148
    }
149
150
151
152
    /**
153
     * Read configuration a directory, loop through all files and add
154
     * them into the $config array as:
155
     * [
156
     *      [
157
     *          "file" => filename for dir/file1.php,
158
     *          "config" => result returned from dir/file1.php,
159
     *      ],
160
     *      [
161
     *          "file" => filename for dir/file2.php,
162
     *          "config" => result returned from dir/file2.php,
163
     *      ],
164
     * ].
165
     *
166
     * @param string $path is the path to the directory containing config files.
167
     *
168
     * @return array with configuration for each file.
169
     */
170 2
    public function loadFromDir(string $path): array
171
    {
172 2
        $config = [];
173 2
        foreach (glob("$path/*.php") as $file) {
174 2
            $config[] = [
175 2
                "file" => $file,
176 2
                "config" => require $file,
177
            ];
178
        }
179
180 2
        return $config;
181
    }
182
}
183