Passed
Branch master (837534)
by Oguzhan
04:07 queued 33s
created

MusicInfo::__construct()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 4

Importance

Changes 5
Bugs 2 Features 1
Metric Value
c 5
b 2
f 1
dl 0
loc 21
ccs 17
cts 17
cp 1
rs 9.0534
cc 4
eloc 13
nc 4
nop 1
crap 4
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 19
    public function __construct($config)
44
    {
45 19
        $this->config = $config;
46
47 19
        $this->services = new ArrayCollection();
48 19
        $this->setClient(
49 19
            new Client($config['defaults']['guzzle'])
50 19
        );
51
52 19
        if (isset($config['services'])) {
53 19
            foreach ($config['services'] as $service) {
54 19
                if (!isset($config['init_services'])) {
55 1
                    $config['init_services'] = null;
56 1
                }
57 19
                $this->loadService($service, $config['init_services']);
58 19
                $this->supportedServices[] = $service;
59 19
            }
60 19
        } else {
61 1
            throw new ServiceConfigurationException("musicinfo.services is required");
62
        }
63 19
    }
64
65
    /**
66
     * @param ClientInterface $client
67
     *
68
     * @return $this
69
     */
70 19
    public function setClient(ClientInterface $client)
71
    {
72 19
        $this->client = $client;
73
74 19
        return $this;
75
    }
76
77
    /**
78
     * @return ClientInterface
79
     */
80 19
    public function getClient()
81
    {
82 19
        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 19
    public function loadService($service, $init = false)
96
    {
97 19
        $fqcn = implode('\\', ['Pbxg33k', 'MusicInfo', 'Service', $service, 'Service']);
98 19
        if (class_exists($fqcn)) {
99
            /** @var IMusicService $client */
100 19
            $client = new $fqcn();
101 19
            $client->setConfig($this->mergeConfig($service));
102 19
            $client->setClient($this->getClient());
103 19
            if ($init === true) {
104 3
                $client->init();
105 3
            }
106 19
            $this->addService($client, $service);
107
108 19
            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 19
    public function mergeConfig($service)
122
    {
123 19
        $service = strtolower($service);
124 19
        if (isset($this->config['service_configuration'][$service])) {
125 19
            $config = array_merge(
126 19
                $this->config['defaults'],
127 19
                $this->config['service_configuration'][$service]
128 19
            );
129
130 19
            return $config;
131
        } else {
132 1
            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 3
    public function loadServices($initialize = false)
145
    {
146 3
        foreach ($this->supportedServices as $service) {
147 3
            $this->loadService($service, $initialize);
148 3
        }
149
150 3
        return $this->getServices();
151
    }
152
153
    /**
154
     * @param IMusicService $service
155
     * @param               $key
156
     *
157
     * @return $this
158
     */
159 19
    public function addService(IMusicService $service, $key)
160
    {
161 19
        $this->services[strtolower($key)] = $service;
162
163 19
        return $this;
164
    }
165
166
    /**
167
     * @return ArrayCollection
168
     */
169 3
    public function getServices()
170
    {
171 3
        return $this->services;
172
    }
173
174
    /**
175
     * @param $key
176
     *
177
     * @return BaseService|null
178
     */
179 11
    public function getService($key)
180
    {
181 11
        $key = strtolower($key);
182 11
        if (isset($this->services[$key])) {
183 10
            return $this->initializeService($this->services[$key]);
184
        } else {
185 2
            return null;
186
        }
187
    }
188
189
    /**
190
     * @param BaseService $service
191
     *
192
     * @return BaseService
193
     * @throws ServiceConfigurationException
194
     */
195 10
    public function initializeService(BaseService $service)
196
    {
197 10
        if (!$service->isInitialized()) {
198 10
            $service->init();
199 10
        }
200
201 10
        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 5
    public function doSearch($argument, $type, $servicesArg = null)
237
    {
238 5
        $services = $this->_prepareSearch($servicesArg);
239 5
        $results = new ArrayCollection();
240
241 5
        foreach ($services as $serviceKey => $service) {
242 5
            $methodName = $this->getMethodName($type);
243
244 5
            if (!method_exists($service, $methodName)) {
245
                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 5
    protected function _prepareSearch($servicesArg = null)
262
    {
263 5
        $services = new ArrayCollection();
264
265 5
        if (null === $servicesArg) {
266 1
            $services = $this->getServices();
267 5
        } elseif (is_array($servicesArg)) {
268 2
            foreach ($servicesArg as $service) {
269 2
                if (is_string($service) && $loadedService = $this->getService($service)) {
270 2
                    $services->set($service, $loadedService);
271 2
                } else {
272
                    throw new \Exception(sprintf('Service (%s) cannot be found', $service));
273
                }
274 2
            }
275 4
        } elseif (is_string($servicesArg) && $loadedService = $this->getService($servicesArg)) {
276 2
            $services->set($servicesArg, $loadedService);
277
278 2
        }
279
280 5
        return $services;
281
    }
282
}