Test Failed
Push — master ( 690a7e...426d8f )
by Andy
02:20
created

Resolver::getEnvParameterKey()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 3
nc 2
nop 1
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Palmtree\Container;
4
5
use Palmtree\Container\Exception\ParameterNotFoundException;
6
use Palmtree\Container\Exception\ServiceNotFoundException;
7
use Palmtree\Container\Exception\ServiceNotPublicException;
8
9
class Resolver
10
{
11
    /** Regex for single parameters e.g '%my.parameter%' */
12
    private const PATTERN_PARAMETER = '/^%([^%\s]+)%$/';
13
    /** Regex for multiple parameters in a string */
14
    private const PATTERN_MULTI_PARAMETER = '/%%|%([^%\s]+)%/';
15
    /** @var Container */
16
    private $container;
17
    /** @var array */
18
    private $containerServices;
19
    /** @var array */
20
    private $envCache = [];
21
22 25
    public function __construct(Container $container, array &$containerServices)
23
    {
24 25
        $this->container         = $container;
25 25
        $this->containerServices = &$containerServices;
26 25
    }
27
28 25
    public function resolveArgs(array $args): array
29
    {
30 25
        foreach ($args as $key => &$arg) {
31 23
            if (\is_array($arg)) {
32 22
                $arg = $this->resolveArgs($arg);
33
            } else {
34 23
                $arg = $this->resolveArg($arg);
35
            }
36
        }
37
38 25
        return $args;
39
    }
40
41
    /**
42
     * @param mixed $arg
43
     *
44
     * @return mixed
45
     *
46
     * @throws ServiceNotFoundException
47
     * @throws ParameterNotFoundException
48
     */
49 24
    public function resolveArg($arg)
50
    {
51 24
        if (!\is_string($arg)) {
52 21
            return $arg;
53
        }
54
55 24
        if ($arg[0] === '@') {
56 21
            return $this->inject(substr($arg, 1));
57
        }
58
59 24
        return $this->resolveParameter($arg);
60
    }
61
62
    /**
63
     * @param string $key
64
     *
65
     * @return mixed
66
     *
67
     * @throws ServiceNotFoundException
68
     */
69 21
    private function inject(string $key)
70
    {
71
        try {
72 21
            $this->container->get($key);
73 21
        } catch (ServiceNotPublicException $e) {
74
            // Ensures the service is created. Private services are allowed to be injected.
75
        }
76
77 21
        return $this->containerServices[$key];
78
    }
79
80
    /**
81
     * @param string $arg
82
     *
83
     * @return mixed
84
     *
85
     * @throws ParameterNotFoundException
86
     */
87 24
    private function resolveParameter($arg)
88
    {
89
        // Resolve a single parameter value e.g %my_param%
90
        // Used for non-string values (boolean, integer etc)
91 24
        if (preg_match(self::PATTERN_PARAMETER, $arg, $matches)) {
92 21
            $envKey = $this->getEnvParameterKey($matches[1]);
93
94 21
            if ($envKey !== null) {
95 21
                return $this->getEnv($envKey);
96
            }
97
98 21
            return $this->container->getParameter($matches[1]);
99
        }
100
101
        // Resolve multiple parameters in a string e.g /%parent_dir%/somewhere/%child_dir%
102
        return preg_replace_callback(self::PATTERN_MULTI_PARAMETER, function ($matches) {
103
            // Skip %% to allow escaping percent signs
104 21
            if (!isset($matches[1])) {
105 21
                return '%';
106
            }
107
108 21
            if ($envKey = $this->getEnvParameterKey($matches[1])) {
109 21
                return $this->getEnv($envKey);
110
            }
111
112 21
            return $this->container->getParameter($matches[1]);
113 24
        }, $arg);
114
    }
115
116 21
    private function getEnvParameterKey(string $value): ?string
117
    {
118 21
        if (strpos($value, 'env(') === 0 && substr($value, -1) === ')' && $value !== 'env()') {
119 21
            return substr($value, 4, -1);
120
        }
121
122 21
        return null;
123
    }
124
125
    /**
126
     * @param string $key
127
     *
128
     * @return string|bool
129
     */
130 21
    private function getEnv(string $key)
131
    {
132 21
        if (isset($this->envCache[$key]) || array_key_exists($key, $this->envCache)) {
133 21
            return $this->envCache[$key];
134
        }
135
136 21
        if (!$envVar = getenv($key)) {
137
            try {
138 20
                $envVar = $this->resolveArg($this->container->getParameter("env($key)"));
139
            } catch (ParameterNotFoundException $exception) {
140
                // do nothing
141
            }
142
        }
143
144 21
        $this->envCache[$key] = $envVar;
145
146 21
        return $this->envCache[$key];
147
    }
148
}
149