Passed
Branch develop (a933a7)
by Oguzhan
02:58
created

MusicInfo::getClient()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
namespace Pbxg33k\MusicInfo;
3
4
use Doctrine\Common\Collections\ArrayCollection;
5
use GuzzleHttp\Client;
6
use GuzzleHttp\ClientInterface;
7
use Pbxg33k\MusicInfo\Exception\ServiceConfigurationException;
8
use Pbxg33k\MusicInfo\Model\IMusicService;
9
use Pbxg33k\MusicInfo\Service\BaseService;
10
use Pbxg33k\Traits\PropertyTrait;
11
12
class MusicInfo
13
{
14
    use PropertyTrait;
15
    /**
16
     * @var ClientInterface
17
     */
18
    protected $client;
19
20
    /**
21
     * @var ArrayCollection
22
     */
23
    protected $services;
24
25
    /**
26
     * @var array
27
     */
28
    protected $config;
29
30
    /**
31
     * Supported Services
32
     * @var array
33
     */
34
    protected $supportedServices = [];
35
36
    /**
37
     * MusicInfo constructor.
38
     *
39
     * @param $config
40
     *
41
     * @throws ServiceConfigurationException if musicinfo.service is missing
42
     */
43 27
    public function __construct($config)
44
    {
45 27
        $this->config = $config;
46
47 27
        $this->services = new ArrayCollection();
48 27
        $this->setClient(
49 27
            new Client($config['defaults']['guzzle'])
50 27
        );
51
52 27
        if (isset($config['services'])) {
53 27
            foreach ($config['services'] as $service) {
54 27
                if (!isset($config['init_services'])) {
55 1
                    $config['init_services'] = null;
56 1
                }
57 27
                $this->loadService($service, $config['init_services']);
58 27
                $this->supportedServices[] = $service;
59 27
            }
60 27
        } else {
61 1
            throw new ServiceConfigurationException("musicinfo.services is required");
62
        }
63 27
    }
64
65
    /**
66
     * @param ClientInterface $client
67
     *
68
     * @return $this
69
     */
70 27
    public function setClient(ClientInterface $client)
71
    {
72 27
        $this->client = $client;
73
74 27
        return $this;
75
    }
76
77
    /**
78
     * @return ClientInterface
79
     */
80 27
    public function getClient()
81
    {
82 27
        return $this->client;
83
    }
84
85
    /**
86
     * Load service
87
     *
88
     * @param $service
89
     * @param $init
90
     *
91
     * @return IMusicService
92
     *
93
     * @throws \Exception
94
     */
95 27
    public function loadService($service, $init = false)
96
    {
97 27
        $fqcn = implode('\\', ['Pbxg33k', 'MusicInfo', 'Service', $service, 'Service']);
98 27
        if (class_exists($fqcn)) {
99
            /** @var IMusicService $client */
100 27
            $client = new $fqcn();
101 27
            $client->setConfig($this->mergeConfig($service));
102 27
            $client->setClient($this->getClient());
103 27
            if ($init === true) {
104 4
                $client->init();
105 4
            }
106 27
            $this->addService($client, $service);
107
108 27
            return $service;
109
        } else {
110 1
            throw new \Exception('Service class does not exist: ' . $service . ' (' . $fqcn . ')');
111
        }
112
    }
113
114
    /**
115
     * Merge shared config with service specific configuration
116
     *
117
     * @param $service
118
     *
119
     * @return array
120
     */
121 27
    public function mergeConfig($service)
122
    {
123 27
        $service = strtolower($service);
124 27
        if (isset($this->config['service_configuration'][$service])) {
125 27
            $config = array_merge(
126 27
                $this->config['defaults'],
127 27
                $this->config['service_configuration'][$service]
128 27
            );
129
130 27
            return $config;
131
        } else {
132 7
            return $this->config['defaults'];
133
        }
134
    }
135
136
    /**
137
     * Load all services
138
     *
139
     * @param bool $initialize
140
     *
141
     * @return ArrayCollection
142
     * @throws \Exception
143
     */
144 4
    public function loadServices($initialize = false)
145
    {
146 4
        foreach ($this->supportedServices as $service) {
147 4
            $this->loadService($service, $initialize);
148 4
        }
149
150 4
        return $this->getServices();
151
    }
152
153
    /**
154
     * @param IMusicService $service
155
     * @param               $key
156
     *
157
     * @return $this
158
     */
159 27
    public function addService(IMusicService $service, $key)
160
    {
161 27
        $this->services[strtolower($key)] = $service;
162
163 27
        return $this;
164
    }
165
166
    /**
167
     * @return ArrayCollection
168
     */
169 4
    public function getServices()
170
    {
171 4
        return $this->services;
172
    }
173
174
    /**
175
     * @param $key
176
     *
177
     * @return BaseService|null
178
     */
179 13
    public function getService($key)
180
    {
181 13
        $key = strtolower($key);
182 13
        if (isset($this->services[$key])) {
183 11
            return $this->initializeService($this->services[$key]);
184
        } else {
185 3
            return null;
186
        }
187
    }
188
189
    /**
190
     * @param BaseService $service
191
     *
192
     * @return BaseService
193
     * @throws ServiceConfigurationException
194
     */
195 11
    public function initializeService(BaseService $service)
196
    {
197 11
        if (!$service->isInitialized()) {
198 11
            $service->init();
199 11
        }
200
201 11
        return $service;
202
    }
203
204
    /**
205
     * @param string $key
206
     *
207
     * @return $this
208
     */
209 1
    public function removeService($key)
210
    {
211 1
        if (isset($this->services[$key])) {
212 1
            unset($this->services[$key]);
213 1
        }
214
215 1
        return $this;
216
    }
217
218
    /**
219
     * @return BaseService|null
220
     */
221 1
    public function getPreferredService()
222
    {
223 1
        return $this->getService($this->config['preferred_order'][0]);
224
    }
225
226
    /**
227
     * Perform Multi-service search
228
     *
229
     * @param      $argument
230
     * @param      $type
231
     * @param null $servicesArg
232
     *
233
     * @return ArrayCollection
234
     * @throws \Exception
235
     */
236 7
    public function doSearch($argument, $type, $servicesArg = null)
237
    {
238 7
        $services = $this->_prepareSearch($servicesArg);
239 6
        $results = new ArrayCollection();
240
241 6
        foreach ($services as $serviceKey => $service) {
242 6
            $methodName = $this->getMethodName($type);
243
244 6
            if (!method_exists($service, $methodName)) {
245 1
                throw new \Exception(sprintf('Method (%s) not found in %s', $methodName, get_class($service)));
246
            }
247 5
            $results->set($serviceKey, $service->{$methodName}()->getByName($argument));
248 5
        }
249
250 5
        return $results;
251
    }
252
253
    /**
254
     * Return an arraycollection with (loaded) services
255
     *
256
     * @param mixed $servicesArg
257
     *
258
     * @return ArrayCollection
259
     * @throws \Exception
260
     */
261 7
    protected function _prepareSearch($servicesArg = null)
262
    {
263 7
        $services = new ArrayCollection();
264
265 7
        if (null === $servicesArg) {
266 1
            $services = $this->getServices();
267 7
        } elseif (is_array($servicesArg)) {
268 4
            foreach ($servicesArg as $service) {
269 4
                if (is_string($service) && $loadedService = $this->getService($service)) {
270 3
                    $services->set($service, $loadedService);
271 3
                } else {
272 1
                    throw new \Exception(sprintf('Service (%s) cannot be found', $service));
273
                }
274 3
            }
275 5
        } elseif (is_string($servicesArg) && $loadedService = $this->getService($servicesArg)) {
276 2
            $services->set($servicesArg, $loadedService);
277
278 2
        }
279
280 6
        return $services;
281
    }
282
}