Completed
Push — master ( a817db...2c1133 )
by Mike
02:49
created

XerviceLocatorProxy::getServiceName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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