Completed
Pull Request — master (#28)
by Tom
06:02 queued 03:01
created

ConfigServiceProvider::addPrefix()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 9
rs 9.6666
cc 1
eloc 5
nc 1
nop 1
1
<?php
2
3
namespace TomPHP\ConfigServiceProvider;
4
5
use League\Container\ServiceProvider\AbstractServiceProvider;
6
use League\Container\ServiceProvider\BootableServiceProviderInterface;
7
use TomPHP\ConfigServiceProvider\Exception\NoMatchingFilesException;
8
9
final class ConfigServiceProvider extends AbstractServiceProvider implements
10
    BootableServiceProviderInterface
11
{
12
    const DEFAULT_PREFIX         = 'config';
13
    const DEFAULT_SEPARATOR      = '.';
14
    const DEFAULT_INFLECTORS_KEY = 'inflectors';
15
    const DEFAULT_DI_KEY         = 'di';
16
17
    const SETTING_PREFIX    = 'prefix';
18
    const SETTING_SEPARATOR = 'separator';
19
20
    /**
21
     * @var array
22
     */
23
    private $config;
24
25
    /**
26
     * @var ConfigurableServiceProvider[]
27
     */
28
    private $subProviders;
29
30
    /**
31
     * @api
32
     *
33
     * @param array $config
34
     * @param array $settings
35
     *
36
     * @return ConfigServiceProvider
37
     */
38
    public static function fromConfig(array $config, array $settings = [])
39
    {
40
        return new self(
41
            $config,
42
            self::getSettingOrDefault(self::SETTING_PREFIX, $settings, self::DEFAULT_PREFIX),
43
            self::getSettingOrDefault(self::SETTING_SEPARATOR, $settings, self::DEFAULT_SEPARATOR),
44
            [
45
                self::DEFAULT_INFLECTORS_KEY => new InflectorConfigServiceProvider([]),
46
                self::DEFAULT_DI_KEY         => new DIConfigServiceProvider([]),
47
            ]
48
        );
49
    }
50
51
    /**
52
     * @api
53
     *
54
     * @param string[] $patterns
55
     * @param array    $settings
56
     *
57
     * @return ConfigServiceProvider
58
     */
59
    public static function fromFiles(array $patterns, array $settings = [])
60
    {
61
        $locator = new FileLocator();
62
        $files   = $locator->locate($patterns);
63
64
        if (empty($files)) {
65
            throw new NoMatchingFilesException(
66
                'No files found matching patterns: ' . implode(', ', $patterns)
67
            );
68
        }
69
70
        $factory = new ReaderFactory([
71
            '.json' => 'TomPHP\ConfigServiceProvider\JSONFileReader',
72
            '.php'  => 'TomPHP\ConfigServiceProvider\PHPFileReader',
73
        ]);
74
75
        $configs = array_map(
76
            function ($filename) use ($factory) {
77
                $reader = $factory->create($filename);
78
                return $reader->read($filename);
79
            },
80
            $files
81
        );
82
83
        $config = call_user_func_array('array_replace_recursive', $configs);
84
85
        return self::fromConfig($config, $settings);
86
    }
87
88
    /**
89
     * @api
90
     *
91
     * @param array                         $config
92
     * @param string                        $prefix
93
     * @param string                        $separator
94
     * @param ConfigurableServiceProvider[] $subProviders
95
     */
96
    public function __construct(
97
        array $config,
98
        $prefix = self::DEFAULT_PREFIX,
99
        $separator = self::DEFAULT_SEPARATOR,
100
        array $subProviders = []
101
    ) {
102
        $this->config = [];
103
104
        $iterator = new ConfigIterator(new Config($config, $separator), $separator);
0 ignored issues
show
Unused Code introduced by
The call to ConfigIterator::__construct() has too many arguments starting with $separator.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
105
        $prefix = $prefix ? $prefix . $separator : '';
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
106
107
        foreach ($iterator as $key => $value) {
108
            $this->config[$prefix . $key] = $value;
109
        }
110
111
        $this->subProviders = $subProviders;
112
113
        $this->provides = array_keys($this->config);
114
115
        foreach ($this->subProviders as $key => $provider) {
116
            $this->configureSubProvider($key, $config, $provider);
117
        }
118
    }
119
120
    public function register()
121
    {
122
        foreach ($this->config as $key => $value) {
123
            $this->getContainer()->add($key, function () use ($value) {
124
                return $value;
125
            });
126
        }
127
128
        foreach ($this->subProviders as $provider) {
129
            $provider->setContainer($this->getContainer());
130
            $provider->register();
131
        }
132
    }
133
134
    public function boot()
135
    {
136
        foreach ($this->subProviders as $provider) {
137
            if (!$provider instanceof BootableServiceProviderInterface) {
138
                continue;
139
            }
140
141
            $provider->setContainer($this->getContainer());
142
            $provider->boot();
143
        }
144
    }
145
146
    /**
147
     * @param string $key
148
     * @param array $config
149
     * @param ConfigurableServiceProvider $provider
150
     */
151
    private function configureSubProvider($key, array $config, ConfigurableServiceProvider $provider)
152
    {
153
        if (!array_key_exists($key, $config)) {
154
            return;
155
        }
156
157
        $provider->configure($config[$key]);
158
159
        $this->provides = array_merge($this->provides, $provider->provides());
160
    }
161
162
    /**
163
     * @param string $name
164
     * @param array  $settings
165
     * @param mixed  $default
166
     *
167
     * @return mixed
168
     */
169
    private static function getSettingOrDefault($name, array $settings, $default)
170
    {
171
        return isset($settings[$name]) ? $settings[$name] : $default;
172
    }
173
}
174