Passed
Push — master ( 0bd3f5...0b454c )
by Mike
05:30
created

XerviceLocatorProxy::container()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 7
ccs 5
cts 5
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
crap 2
1
<?php
2
declare(strict_types=1);
3
4
5
namespace Xervice\Core\Locator\Proxy;
6
7
8
use Xervice\Core\Client\ClientInterface;
9
use Xervice\Core\Client\EmptyClient;
10
use Xervice\Core\Config\ConfigInterface;
11
use Xervice\Core\Config\EmptyConfig;
12
use Xervice\Core\Dependency\DependencyProvider;
13
use Xervice\Core\Dependency\DependencyProviderInterface;
14
use Xervice\Core\Facade\EmptyFacade;
15
use Xervice\Core\Facade\FacadeInterface;
16
use Xervice\Core\Factory\EmptyFactory;
17
use Xervice\Core\Factory\FactoryInterface;
18
use Xervice\Core\Locator\Locator;
19
20
class XerviceLocatorProxy implements ProxyInterface
21
{
22
    private const NAMESPACE_PROXY_FORMAT = '\%1$s\\%2$s\\%2$s%3$s';
23
24
    /**
25
     * @var string
26
     */
27
    private $service;
28
29
    /**
30
     * @var \Xervice\Core\Dependency\DependencyProviderInterface
31
     */
32
    private $container;
33
34
    /**
35
     * @var \Xervice\Core\Factory\FactoryInterface
36
     */
37
    private $factory;
38
39
    /**
40
     * @var \Xervice\Core\Facade\FacadeInterface
41
     */
42
    private $facade;
43
44
    /**
45
     * @var \Xervice\Core\Client\ClientInterface
46
     */
47
    private $client;
48
49
    /**
50
     * @var \Xervice\Core\Config\ConfigInterface
51
     */
52
    private $config;
53
54
    /**
55
     * @var string
56
     */
57
    private $projectNamespace;
58
59
    /**
60
     * @var array
61
     */
62
    private $additionalNamespaces;
63
64
    /**
65
     * XerviceLocatorProxy constructor.
66
     *
67
     * @param string $service
68
     * @param string $projectNamespace
69
     * @param array $additionalNamespaces
70
     */
71 4
    public function __construct(string $service, string $projectNamespace, array $additionalNamespaces)
72
    {
73 4
        $this->service = ucfirst($service);
74 4
        $this->projectNamespace = $projectNamespace;
75 4
        $this->additionalNamespaces = $additionalNamespaces;
76 4
    }
77
78
    /**
79
     * @return \Xervice\Core\Config\ConfigInterface
80
     */
81 4
    public function config(): ConfigInterface
82
    {
83 4
        if ($this->config === null) {
84 4
            foreach ($this->getServiceNamespaces('Config') as $class) {
85 4
                if (class_exists($class)) {
86 3
                    $this->config = new $class();
87 4
                    break;
88
                }
89
            }
90
91 4
            if ($this->config === null) {
92 1
                $this->config = new EmptyConfig();
93
            }
94
        }
95 4
        return $this->config;
96
    }
97
98
    /**
99
     * @return \Xervice\Core\Factory\FactoryInterface
100
     */
101 6
    public function factory(): FactoryInterface
102
    {
103 6
        if ($this->factory === null) {
104 4
            foreach ($this->getServiceNamespaces('Factory') as $class) {
105 4
                if (class_exists($class)) {
106 3
                    $this->factory = new $class(
107 3
                        $this->container(),
108 3
                        $this->config()
109
                    );
110 4
                    break;
111
                }
112
            }
113
114 4
            if ($this->factory === null) {
115 1
                $this->factory = new EmptyFactory(
116 1
                    $this->container(),
117 1
                    $this->config()
118
                );
119
            }
120
        }
121 6
        return $this->factory;
122
    }
123
124
    /**
125
     * @return \Xervice\Core\Facade\FacadeInterface
126
     */
127 6
    public function facade(): FacadeInterface
128
    {
129 6
        if ($this->facade === null) {
130 4
            foreach ($this->getServiceNamespaces('Facade') as $class) {
131 4
                if (class_exists($class)) {
132 3
                    $this->facade = new $class(
133 3
                        $this->factory(),
134 3
                        $this->config(),
135 3
                        $this->client()
136
                    );
137 4
                    break;
138
                }
139
            }
140
141 4
            if ($this->facade === null) {
142 1
                $this->facade = new EmptyFacade(
143 1
                    $this->factory(),
144 1
                    $this->config(),
145 1
                    $this->client()
146
                );
147
            }
148
        }
149 6
        return $this->facade;
150
    }
151
152
    /**
153
     * @return \Xervice\Core\Client\ClientInterface
154
     */
155 6
    public function client(): ClientInterface
156
    {
157 6
        if ($this->client === null) {
158 4
            foreach ($this->getServiceNamespaces('Client') as $class) {
159 4
                if (class_exists($class)) {
160 2
                    $this->client = new $class(
161 2
                        $this->factory(),
162 2
                        $this->config()
163
                    );
164 4
                    break;
165
                }
166
            }
167
168 4
            if ($this->client === null) {
169 2
                $this->client = new EmptyClient(
170 2
                    $this->factory(),
171 2
                    $this->config()
172
                );
173
            }
174
        }
175 6
        return $this->client;
176
    }
177
178
    /**
179
     * @return \Xervice\Core\Dependency\DependencyProviderInterface
180
     */
181 6
    public function container(): DependencyProviderInterface
182
    {
183 6
        if ($this->container === null) {
184 4
            $this->container = new DependencyProvider($this->config());
185 4
            $this->registerDependencies();
186
        }
187 6
        return $this->container;
188
    }
189
190 4
    private function registerDependencies(): void
191
    {
192 4
        foreach ($this->getServiceNamespaces('DependencyProvider') as $class) {
193 4
            if (class_exists($class)) {
194 1
                $this->container->register(new $class(Locator::getInstance()));
195 4
                break;
196
            }
197
        }
198 4
    }
199
200
    /**
201
     * @param string $type
202
     * @param string $layer
203
     *
204
     * @return string
205
     */
206 4
    private function getNamespace(string $type, string $layer): string
207
    {
208 4
        return sprintf(
209 4
            self::NAMESPACE_PROXY_FORMAT,
210 4
            $layer,
211 4
            $this->service,
212 4
            $type
213
        );
214
    }
215
216
    /**
217
     * @param string $type
218
     *
219
     * @return array
220
     */
221 4
    private function getServiceNamespaces(string $type): array
222
    {
223 4
        $xerviceNamespaces = [];
224
225 4
        foreach ($this->additionalNamespaces as $addNamespace) {
226
            $xerviceNamespaces[] = $this->getNamespace($type, $addNamespace);
227
        }
228
229 4
        $xerviceNamespaces[] = $this->getNamespace($type, $this->projectNamespace);
230 4
        $xerviceNamespaces[] = $this->getNamespace($type, 'Xervice');
231
232 4
        return $xerviceNamespaces;
233
    }
234
}
235