ConfigServiceProvider::readConfig()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 12
Bugs 0 Features 5
Metric Value
c 12
b 0
f 5
dl 0
loc 18
rs 9.2
cc 4
eloc 10
nc 4
nop 0
1
<?php
2
3
/*
4
 * This file is part of ConfigServiceProvider.
5
 *
6
 * (c) Igor Wiedler <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Igorw\Silex;
13
14
use Silex\Application;
15
use Silex\ServiceProviderInterface;
16
17
class ConfigServiceProvider implements ServiceProviderInterface
18
{
19
    private $filename;
20
    private $replacements = array();
21
    private $driver;
22
    private $prefix = null;
23
24
    public function __construct($filename, array $replacements = array(), ConfigDriver $driver = null, $prefix = null)
25
    {
26
        $this->filename = $filename;
27
        $this->prefix = $prefix;
28
29
        if ($replacements) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $replacements 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...
30
            foreach ($replacements as $key => $value) {
31
                $this->replacements['%'.$key.'%'] = $value;
32
            }
33
        }
34
35
        $this->driver = $driver ?: new ChainConfigDriver(array(
36
            new PhpConfigDriver(),
37
            new YamlConfigDriver(),
38
            new JsonConfigDriver(),
39
            new TomlConfigDriver(),
40
        ));
41
    }
42
43
    public function register(Application $app)
44
    {
45
        $config = $this->readConfig();
46
47
        foreach ($config as $name => $value)
48
            if ('%' === substr($name, 0, 1))
49
                $this->replacements[$name] = (string) $value;
50
51
        $this->merge($app, $config);
52
    }
53
54
    public function boot(Application $app)
55
    {
56
    }
57
58
    private function merge(Application $app, array $config)
59
    {
60
        if ($this->prefix) {
61
            $config = array($this->prefix => $config);
62
        }
63
64 View Code Duplication
        foreach ($config as $name => $value) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
65
            if (isset($app[$name]) && is_array($value)) {
66
                $app[$name] = $this->mergeRecursively($app[$name], $value);
67
            } else {
68
                $app[$name] = $this->doReplacements($value);
69
            }
70
        }
71
    }
72
73
    private function mergeRecursively(array $currentValue, array $newValue)
74
    {
75 View Code Duplication
        foreach ($newValue as $name => $value) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
76
            if (is_array($value) && isset($currentValue[$name])) {
77
                $currentValue[$name] = $this->mergeRecursively($currentValue[$name], $value);
78
            } else {
79
                $currentValue[$name] = $this->doReplacements($value);
80
            }
81
        }
82
83
        return $currentValue;
84
    }
85
86
    private function doReplacements($value)
87
    {
88
        if (!$this->replacements) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->replacements 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...
89
            return $value;
90
        }
91
92
        if (is_array($value)) {
93
            foreach ($value as $k => $v) {
94
                $value[$k] = $this->doReplacements($v);
95
            }
96
97
            return $value;
98
        }
99
100
        if (is_string($value)) {
101
            return strtr($value, $this->replacements);
102
        }
103
104
        return $value;
105
    }
106
107
    private function readConfig()
108
    {
109
        if (!$this->filename) {
110
            throw new \RuntimeException('A valid configuration file must be passed before reading the config.');
111
        }
112
113
        if (!file_exists($this->filename)) {
114
            throw new \InvalidArgumentException(
115
                sprintf("The config file '%s' does not exist.", $this->filename));
116
        }
117
118
        if ($this->driver->supports($this->filename)) {
119
            return $this->driver->load($this->filename);
120
        }
121
122
        throw new \InvalidArgumentException(
123
                sprintf("The config file '%s' appears to have an invalid format.", $this->filename));
124
    }
125
}
126