MusicInfo   A
last analyzed

Complexity

Total Complexity 33

Size/Duplication

Total Lines 272
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 33
lcom 1
cbo 6
dl 0
loc 272
ccs 95
cts 95
cp 1
rs 9.76
c 0
b 0
f 0

14 Methods

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