Passed
Branch feature/spotify (f0f03e)
by Oguzhan
04:06
created

MusicInfo::initializeService()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
ccs 5
cts 5
cp 1
rs 9.4285
cc 2
eloc 4
nc 2
nop 1
crap 2
1
<?php
2
namespace Pbxg33k\MusicInfo;
3
4
use Pbxg33k\MusicInfo\Exception\ServiceConfigurationException;
5
use GuzzleHttp\Client;
6
use GuzzleHttp\ClientInterface;
7
use Doctrine\Common\Collections\ArrayCollection;
8
use Pbxg33k\MusicInfo\Model\IMusicService;
9
use Pbxg33k\MusicInfo\Service\BaseService;
10
use Pbxg33k\Traits\PropertyTrait;
11
use Symfony\Component\Config\FileLocator;
12
13
class MusicInfo
14
{
15
    use PropertyTrait;
16
    /**
17
     * @var ClientInterface
18
     */
19
    protected $client;
20
21
    /**
22
     * @var ArrayCollection
23
     */
24
    protected $services;
25
26
    /**
27
     * @var array
28
     */
29
    protected $config;
30
31
    /**
32
     * Supported Services
33
     * @var array
34
     */
35
    protected $supportedServices = [];
36
37
    /**
38
     * MusicInfo constructor.
39
     * @param $config
40
     * @throws ServiceConfigurationException if musicinfo.service is missing
41
     */
42 10
    public function __construct($config)
43
    {
44 10
        $this->config = $config;
45
46 10
        $this->services = new ArrayCollection();
47 10
        $this->setClient(
48 10
            new Client($config['defaults']['guzzle'])
49 10
        );
50
51 10
        if(isset($config['services'])) {
52 10
            foreach($config['services'] as $service) {
53 10
                if(!isset($config['init_services'])) {
54 1
                    $config['init_services'] = null;
55 1
                }
56 10
                $this->loadService($service, $config['init_services']);
57 10
                $this->supportedServices[] = $service;
58 10
            }
59 10
        } else {
60 1
            throw new ServiceConfigurationException("musicinfo.services is required");
61
        }
62 10
    }
63
64
    /**
65
     * @param ClientInterface $client
66
     *
67
     * @return $this
68
     */
69 10
    public function setClient(ClientInterface $client)
70
    {
71 10
        $this->client = $client;
72
73 10
        return $this;
74
    }
75
76
    /**
77
     * @return ClientInterface
78
     */
79 10
    public function getClient()
80
    {
81 10
        return $this->client;
82
    }
83
84
    /**
85
     * Load service
86
     *
87
     * @param $service
88
     * @param $init
89
     *
90
     * @return IMusicService
91
     *
92
     * @throws \Exception
93
     */
94 10
    public function loadService($service, $init = false)
95
    {
96 10
        $fqcn = implode('\\',['Pbxg33k', 'MusicInfo', 'Service', $service, 'Service']);
97 10
        if(class_exists($fqcn)) {
98
            /** @var IMusicService $client */
99 10
            $client = new $fqcn();
100 10
            $client->setConfig($this->mergeConfig($service));
101 10
            $client->setClient($this->getClient());
102 10
            if($init == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
103 1
                $client->init();
104 1
            }
105 10
            $this->addService($client, $service);
106 10
            return $service;
107
        } else {
108 1
            throw new \Exception('Service class does not exist: '.$service.' ('.$fqcn.')');
109
        }
110
    }
111
112
    /**
113
     * Merge shared config with service specific configuration
114
     *
115
     * @param $service
116
     * @return array
117
     */
118 10
    public function mergeConfig($service)
119
    {
120 10
        $service = strtolower($service);
121 10
        if(isset($this->config['service_configuration'][$service])) {
122 10
            $config = array_merge(
123 10
                $this->config['defaults'],
124 10
                $this->config['service_configuration'][$service]
125 10
            );
126 10
            return $config;
127
        } else {
128
            return $this->config['defaults'];
129
        }
130
    }
131
132
    /**
133
     * Load all services
134
     *
135
     * @param bool $initialize
136
     *
137
     * @return ArrayCollection
138
     * @throws \Exception
139
     */
140 1
    public function loadServices($initialize = false)
141
    {
142 1
        foreach($this->supportedServices as $service) {
143 1
            $this->loadService($service, $initialize);
144 1
        }
145
146 1
        return $this->getServices();
147
    }
148
149
    /**
150
     * @param IMusicService $service
151
     *
152
     * @return $this
153
     */
154 10
    public function addService(IMusicService $service, $key)
155
    {
156 10
        $this->services[strtolower($key)] = $service;
157 10
        return $this;
158
    }
159
160
    /**
161
     * @return ArrayCollection
162
     */
163 1
    public function getServices()
164
    {
165 1
        return $this->services;
166
    }
167
168
    /**
169
     * @param $key
170
     * @return IMusicService|null
171
     */
172 4
    public function getService($key)
173
    {
174 4
        $key = strtolower($key);
175 4
        if(isset($this->services[$key])) {
176 3
            return $this->initializeService($this->services[$key]);
177
        } else {
178 2
            return null;
179
        }
180
    }
181
182
    /**
183
     * @param BaseService $service
184
     *
185
     * @return BaseService
186
     * @throws ServiceConfigurationException
187
     */
188 3
    public function initializeService(BaseService $service)
189
    {
190 3
        if(!$service->isInitialized()) {
191 3
            $service->init();
192 3
        }
193
        
194 3
        return $service;
195
    }
196
197
    /**
198
     * @param string $key
199
     *
200
     * @return $this
201
     */
202 1
    public function removeService($key)
203
    {
204 1
        if(isset($this->services[$key])) {
205 1
            unset($this->services[$key]);
206 1
        }
207
208 1
        return $this;
209
    }
210
211
    /**
212
     * @return IMusicService
213
     */
214
    public function getPreferredService()
215
    {
216
        return $this->getService($this->config['preferred_order'][0]);
217
    }
218
219
    /**
220
     * Perform Multiservice search
221
     *
222
     * @param      $argument
223
     * @param      $type
224
     * @param null $servicesArg
225
     *
226
     * @return array
227
     * @throws \Exception
228
     */
229
    public function doSearch($argument, $type, $servicesArg = null)
230
    {
231
        $services = [];
232
        if(null === $servicesArg) {
233
            $services = $this->getServices();
234
        } elseif(is_array($servicesArg)) {
235
            foreach($servicesArg as $service) {
236
                if(is_string($service) && $loadedService = $this->getService($service)) {
237
                    $services[$service] = $loadedService;
238
                } else {
239
                    throw new \Exception(sprintf('Service (%s) cannot be found', $service));
240
                }
241
            }
242
        } elseif(is_string($servicesArg) && $loadedService = $this->getService($servicesArg)) {
243
            $services[$servicesArg] = $loadedService;
244
        }
245
246
        $results = [];
247
248
        foreach($services as $serviceKey => $service) {
249
            $methodName = $this->getMethodName($type);
250
251
            if(!method_exists($service, $methodName)) {
252
                throw new \Exception(sprintf('Method (%s) not found in %s', $methodName, get_class($service)));
253
            }
254
255
            $results[$serviceKey] = $service->{$methodName}()->getByName($argument);
256
        }
257
258
        return $results;
259
    }
260
}