Completed
Push — master ( 2c1133...a0bd3c )
by Mike
03:11
created

XerviceLocatorProxy::getHelperFromName()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 4

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 7
c 0
b 0
f 0
ccs 6
cts 6
cp 1
rs 10
cc 4
nc 4
nop 1
crap 4
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\HelperClass\HelperCollection;
19
use Xervice\Core\Locator\Locator;
20
use Xervice\Core\ServiceClass\EmptyXervice;
21
use Xervice\Core\ServiceClass\XerviceInterface;
22
23
class XerviceLocatorProxy implements ProxyInterface
24
{
25
    private const NAMESPACE_PROXY_FORMAT = '\%1$s\\%2$s\\%2$s%3$s';
26
27
    /**
28
     * @var string
29
     */
30
    private $service;
31
32
    /**
33
     * @var \Xervice\Core\Dependency\DependencyProviderInterface
34
     */
35
    private $container;
36
37
    /**
38
     * @var \Xervice\Core\Factory\FactoryInterface
39
     */
40
    private $factory;
41
42
    /**
43
     * @var \Xervice\Core\Facade\FacadeInterface
44
     */
45
    private $facade;
46
47
    /**
48
     * @var \Xervice\Core\Client\ClientInterface
49
     */
50
    private $client;
51
52
    /**
53
     * @var \Xervice\Core\Config\ConfigInterface
54
     */
55
    private $config;
56
57
    /**
58
     * @var string
59
     */
60
    private $projectNamespace;
61
62
    /**
63
     * @var array
64
     */
65
    private $additionalNamespaces;
66
67
    /**
68
     * @var \Xervice\Core\HelperClass\HelperCollection
69
     */
70
    private $helperCollection;
71
72
    /**
73
     * @var array
74
     */
75
    private $helperList;
76
77
    /**
78
     * XerviceLocatorProxy constructor.
79
     *
80
     * @param string $service
81
     * @param string $projectNamespace
82
     * @param array $additionalNamespaces
83
     * @param \Xervice\Core\HelperClass\HelperCollection|null $helperCollection
84
     */
85 3
    public function __construct(
86
        string $service,
87
        string $projectNamespace,
88
        array $additionalNamespaces,
89
        HelperCollection $helperCollection = null
90
    ) {
91 3
        $this->service = ucfirst($service);
92 3
        $this->projectNamespace = $projectNamespace;
93 3
        $this->additionalNamespaces = $additionalNamespaces;
94 3
        $this->helperCollection = $helperCollection;
95 3
        $this->helperList = [];
96 3
    }
97
98
    /**
99
     * @param $name
100
     * @param $arguments
101
     *
102
     * @return mixed|null
103
     */
104 3
    public function __call($name, $arguments)
105
    {
106 3
        return !method_exists($this, $name) ? $this->dynamic($name) : null;
107
    }
108
109
    /**
110
     * @return \Xervice\Core\Config\ConfigInterface
111
     */
112 5
    public function config(): ConfigInterface
113
    {
114 5
        if ($this->config === null) {
115 3
            foreach ($this->getServiceNamespaces('Config') as $class) {
116 3
                if (class_exists($class)) {
117 1
                    $this->config = new $class();
118 3
                    break;
119
                }
120
            }
121
122 3
            if ($this->config === null) {
123 2
                $this->config = new EmptyConfig();
124
            }
125
        }
126 5
        return $this->config;
127
    }
128
129
    /**
130
     * @return \Xervice\Core\Factory\FactoryInterface
131
     */
132 7
    public function factory(): FactoryInterface
133
    {
134 7
        if ($this->factory === null) {
135 2
            foreach ($this->getServiceNamespaces('Factory') as $class) {
136 2
                if (class_exists($class)) {
137 1
                    $this->factory = new $class(
138 1
                        $this->container(),
139 1
                        $this->config()
140
                    );
141 2
                    break;
142
                }
143
            }
144
145 2
            if ($this->factory === null) {
146 1
                $this->factory = new EmptyFactory(
147 1
                    $this->container(),
148 1
                    $this->config()
149
                );
150
            }
151
        }
152 7
        return $this->factory;
153
    }
154
155
    /**
156
     * @return \Xervice\Core\Facade\FacadeInterface
157
     */
158 3
    public function facade(): FacadeInterface
159
    {
160 3
        if ($this->facade === null) {
161 3
            foreach ($this->getServiceNamespaces('Facade') as $class) {
162 3
                if (class_exists($class)) {
163 2
                    $this->facade = new $class(
164 2
                        $this->factory(),
165 2
                        $this->config(),
166 2
                        $this->client()
167
                    );
168 3
                    break;
169
                }
170
            }
171
172 3
            if ($this->facade === null) {
173 1
                $this->facade = new EmptyFacade(
174 1
                    $this->factory(),
175 1
                    $this->config(),
176 1
                    $this->client()
177
                );
178
            }
179
        }
180 3
        return $this->facade;
181
    }
182
183
    /**
184
     * @return \Xervice\Core\Client\ClientInterface
185
     */
186 5
    public function client(): ClientInterface
187
    {
188 5
        if ($this->client === null) {
189 3
            foreach ($this->getServiceNamespaces('Client') as $class) {
190 3
                if (class_exists($class)) {
191 2
                    $this->client = new $class(
192 2
                        $this->factory(),
193 2
                        $this->config()
194
                    );
195 3
                    break;
196
                }
197
            }
198
199 3
            if ($this->client === null) {
200 1
                $this->client = new EmptyClient(
201 1
                    $this->factory(),
202 1
                    $this->config()
203
                );
204
            }
205
        }
206 5
        return $this->client;
207
    }
208
209
    /**
210
     * @return \Xervice\Core\Dependency\DependencyProviderInterface
211
     */
212 2
    public function container(): DependencyProviderInterface
213
    {
214 2
        if ($this->container === null) {
215 2
            $this->container = new DependencyProvider($this->config());
216 2
            $this->registerDependencies();
217
        }
218 2
        return $this->container;
219
    }
220
221
    /**
222
     * @param string $type
223
     *
224
     * @return array
225
     */
226 6
    public function getServiceNamespaces(string $type): array
227
    {
228 6
        $xerviceNamespaces = [];
229
230 6
        foreach ($this->additionalNamespaces as $addNamespace) {
231
            $xerviceNamespaces[] = $this->getNamespace($type, $addNamespace);
232
        }
233
234 6
        $xerviceNamespaces[] = $this->getNamespace($type, $this->projectNamespace);
235 6
        $xerviceNamespaces[] = $this->getNamespace($type, 'Xervice');
236
237 6
        return $xerviceNamespaces;
238
    }
239
240
    /**
241
     * @return string
242
     */
243 6
    public function getServiceName(): string
244
    {
245 6
        return $this->service;
246
    }
247
248 2
    private function registerDependencies(): void
249
    {
250 2
        foreach ($this->getServiceNamespaces('DependencyProvider') as $class) {
251 2
            if (class_exists($class)) {
252 1
                $this->container->register(new $class(Locator::getInstance()));
253 2
                break;
254
            }
255
        }
256 2
    }
257
258
    /**
259
     * @param $name
260
     *
261
     * @return \Xervice\Core\ServiceClass\XerviceInterface
262
     */
263 3
    protected function dynamic($name): XerviceInterface
264
    {
265 3
        if (!isset($this->helperList[$name])) {
266 3
            $this->getDynamicClassFromName($name);
267
        }
268
269 3
        if (!isset($this->helperList[$name])) {
270 2
            $this->getHelperFromName($name);
271
        }
272
273 3
        if (!isset($this->helperList[$name])) {
274 1
            $this->getEmptyXervice($name);
275
        }
276
277 3
        return $this->helperList[$name];
278
    }
279
280
    /**
281
     * @param string $type
282
     * @param string $layer
283
     *
284
     * @return string
285
     */
286 6
    protected function getNamespace(string $type, string $layer): string
287
    {
288 6
        return sprintf(
289 6
            self::NAMESPACE_PROXY_FORMAT,
290 6
            $layer,
291 6
            $this->getServiceName(),
292 6
            $type
293
        );
294
    }
295
296
    /**
297
     * @param $name
298
     */
299 2
    protected function getHelperFromName($name): void
300
    {
301 2
        if ($this->helperCollection instanceof HelperCollection) {
0 ignored issues
show
introduced by
$this->helperCollection is always a sub-type of Xervice\Core\HelperClass\HelperCollection. If $this->helperCollection can have other possible types, add them to src/Xervice/Core/Locator...XerviceLocatorProxy.php:68.
Loading history...
302 2
            foreach ($this->helperCollection as $helper) {
303 2
                if ($helper->getMethodName() === $name) {
304 1
                    $this->helperList[$name] = $helper->getHelper($this);
305 2
                    break;
306
                }
307
            }
308
        }
309 2
    }
310
311
    /**
312
     * @param $name
313
     */
314 1
    protected function getEmptyXervice($name): void
315
    {
316 1
        $this->helperList[$name] = new EmptyXervice(
317 1
            $this->config()
318
        );
319 1
    }
320
321
    /**
322
     * @param $name
323
     */
324 3
    protected function getDynamicClassFromName($name): void
325
    {
326 3
        foreach ($this->getServiceNamespaces(ucfirst($name)) as $class) {
327 3
            if (class_exists($class)) {
328 1
                $this->helperList[$name] = new $class(
329 1
                    $this->config()
330
                );
331 3
                break;
332
            }
333
        }
334 3
    }
335
}
336