Completed
Push — master ( ad7fd3...b10ab8 )
by Théo
03:40
created

BaseParametersResolver::resolveValue()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 16
Code Lines 8

Duplication

Lines 16
Ratio 100 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 16
loc 16
rs 8.8571
cc 5
eloc 8
nc 4
nop 2
1
<?php
2
3
/*
4
 * This file is part of the LaravelYaml package.
5
 *
6
 * (c) Théo FIDRY <[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 Fidry\LaravelYaml\DependencyInjection\Resolver;
13
14
use Fidry\LaravelYaml\Exception\DependencyInjection\Resolver\ParameterCircularReferenceException;
15
use Fidry\LaravelYaml\Exception\Exception;
16
use Fidry\LaravelYaml\Exception\ParameterNotFoundException;
17
use Illuminate\Contracts\Config\Repository as ConfigRepository;
18
19
/**
20
 * @author Théo FIDRY <[email protected]>
21
 */
22
final class BaseParametersResolver implements ParametersResolverInterface
23
{
24
    /**
25
     * @var string
26
     */
27
    private $defaultValue;
28
29
    /**
30
     * @var ConfigRepository
31
     */
32
    private $config;
33
34
    /**
35
     * @var array|null
36
     */
37
    private $parameters;
38
39
    /**
40
     * @var array
41
     */
42
    private $resolved = [];
43
44
    public function __construct(ConfigRepository $config)
45
    {
46
        $this->config = $config;
47
        $this->defaultValue = spl_object_hash(new \stdClass());
48
    }
49
50
    /**
51
     * {@inheritdoc}
52
     *
53
     * @param array $parameters
54
     *
55
     * @return array
56
     *
57
     * @throws ParameterCircularReferenceException
58
     * @throws ParameterNotFoundException
59
     * @throws Exception
60
     */
61
    public function resolve(array $parameters)
62
    {
63
        $this->parameters = $parameters;
64
        foreach ($this->parameters as $key => $value) {
65
            $value = $this->resolveValue($value, [$key => true]);
66
            $this->resolved[$key] = $value;
67
        }
68
69
        return $this->resolved;
70
    }
71
72
    /**
73
     * @param mixed $value
74
     * @param array $resolving
75
     *
76
     * @return mixed
77
     * @throws ParameterCircularReferenceException
78
     * @throws ParameterNotFoundException
79
     */
80 View Code Duplication
    private function resolveValue($value, $resolving = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
81
    {
82
        if (is_bool($value) || is_numeric($value)) {
83
            return $value;
84
        }
85
86
        if (is_array($value)) {
87
            return $this->resolveArray($value, $resolving);
88
        }
89
90
        if (is_string($value)) {
91
            return $this->resolveString($value, $resolving);
92
        }
93
94
        return $value;
95
    }
96
97 View Code Duplication
    private function resolveArray(array $arrayValue, array $resolving)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
98
    {
99
        $resolvedValue = [];
100
        foreach ($arrayValue as $key => $value) {
101
            $resolvedValue[$key] = $this->resolveValue($value, $resolving);
102
        }
103
104
        return $resolvedValue;
105
    }
106
107
    /**
108
     * @param $value
109
     * @param $resolving
110
     *
111
     * @return array|mixed
112
     * @throws ParameterCircularReferenceException
113
     * @throws ParameterNotFoundException
114
     */
115
    private function resolveString($value, array $resolving)
116
    {
117
        if (0 === preg_match('/^%([^%\s]+)%$/', $value, $match)) {
118
            if (false === array_key_exists($value, $resolving)) {
119
                return $value;
120
            }
121
122
            $key = $value;
123
        } else {
124
            $key = $match[1];
125
        }
126
127
        if (array_key_exists($key, $this->parameters)) {
128
            return $this->resolveParameter($key, $resolving);
129
        }
130
131
        if ($this->config->has($key)) {
132
            return $this->config->get($key);
133
        }
134
135
        return $this->resolveEnvironmentValue($key);
136
    }
137
138
    /**
139
     * @param string $key
140
     * @param array  $resolving
141
     *
142
     * @return array|mixed
143
     * @throws ParameterCircularReferenceException
144
     * @throws ParameterNotFoundException
145
     */
146
    private function resolveParameter($key, array $resolving)
147
    {
148
        if (array_key_exists($key, $this->resolved)) {
149
            return $this->resolved[$key];
150
        }
151
152
        if (array_key_exists($key, $resolving)) {
153
            throw new ParameterCircularReferenceException(
154
                sprintf(
155
                    'Circular reference detected for the parameter "%s" while resolving [%s]',
156
                    $key,
157
                    implode(', ', array_keys($resolving))
158
                )
159
            );
160
        }
161
        $resolving[$key] = true;
162
        $this->resolved[$key] = $this->resolveValue($this->parameters[$key], $resolving);
163
164
        return $this->resolved[$key];
165
    }
166
167
    /**
168
     * @param string $key
169
     *
170
     * @return string|int|bool|null
171
     * @throws ParameterNotFoundException
172
     */
173 View Code Duplication
    private function resolveEnvironmentValue($key)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
174
    {
175
        $environmentKey = strtoupper(str_replace('.', '_', $key));
176
        $value = env($environmentKey, $this->defaultValue);
177
        if ($this->defaultValue !== $value) {
178
            return $value;
179
        }
180
181
        throw new ParameterNotFoundException(sprintf('No parameter "%s" found', $key));
182
    }
183
}
184