Completed
Push — feature/spotify ( 892350...f45a0e )
by Oguzhan
05:14
created

MusicInfo::getService()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

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