Completed
Push — master ( 79bbce...abd19f )
by Antonio Carlos
07:57 queued 05:51
created

Hydrator::checkHydrationElements()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2.0625

Importance

Changes 0
Metric Value
cc 2
eloc 9
nc 1
nop 1
dl 0
loc 15
ccs 6
cts 8
cp 0.75
crap 2.0625
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace PragmaRX\Countries\Package\Services;
4
5
use IlluminateAgnostic\Str\Support\Str;
6
use PragmaRX\Coollection\Package\Coollection;
7
8
class Hydrator
9
{
10
    /**
11
     * All hydrators.
12
     *
13
     * @var
14
     */
15
    const HYDRATORS = [
16
        'borders',
17
        'cities',
18
        'collection',
19
        'countries',
20
        'country',
21
        'currencies',
22
        'flag',
23
        'geometry',
24
        'natural_earth_data',
25
        'states',
26
        'taxes',
27
        'timezones',
28
        'timezones_times',
29
        'topology',
30
    ];
31
32
    /**
33
     * Countries repository.
34
     *
35
     * @var Repository
36
     */
37
    protected $repository;
38
39
    /**
40
     * Config.
41
     *
42
     * @var Config
43
     */
44
    protected $config;
45
46
    /**
47
     * Hydrator constructor.
48
     *
49
     * @param object $config
50
     */
51 34
    public function __construct($config)
52
    {
53 34
        $this->config = $config;
54 34
    }
55
56
    /**
57
     * Can hydrate?
58
     *
59
     * @param $element
60
     * @param $enabled
61
     * @param $countryCode
62
     * @return bool
63
     */
64 31
    protected function canHydrate($element, $enabled, $countryCode)
65
    {
66 31
        return ($enabled || $this->config->get('hydrate.elements.'.$element)) &&
67 31
                ! isset($this->repository->countries[$countryCode]['hydrated'][$element]);
68
    }
69
70
    /**
71
     * @param $countryCode
72
     */
73 31
    protected function createHydrated($countryCode)
74
    {
75 31
        if (! isset($this->repository->countries[$countryCode]['hydrated'])) {
76 31
            $this->repository->countries[$countryCode]['hydrated'] = [];
77
        }
78
79 31
        return $this->repository->countries[$countryCode]['hydrated'];
80
    }
81
82 6
    protected function fixCurrencies($country)
83
    {
84 6
        if (! isset($country['currencies']) && isset($country['currency'])) {
85 1
            $country['currencies'] = $country['currency'];
86
        }
87
88 6
        return $country;
89
    }
90
91
    /**
92
     * Hydrate elements of a collection of countries.
93
     *
94
     * @param $countries
95
     * @param $elements
96
     * @return mixed
97
     */
98 32
    private function hydrateCountries($countries, $elements = null)
99
    {
100 32
        return countriesCollect(
101 32
            $countries->map(function ($country) use ($elements) {
102 31
                return $this->hydrateCountry($country, $elements);
103 32
            })
104
        );
105
    }
106
107
    /**
108
     * Hydrate elements of a country.
109
     *
110
     * @param $country
111
     * @param $elements
112
     * @return mixed
113
     */
114 31
    private function hydrateCountry($country, $elements)
115
    {
116 31
        $countryCode = $country['cca3'];
117
118 31
        $this->addCountry($countryCode, $country);
119
120 31
        foreach ($elements as $element => $enabled) {
121 31
            $this->hydrateCountryElement($countryCode, $element, $enabled);
122
        }
123
124 31
        return $this->getCountry($countryCode);
125
    }
126
127
    /**
128
     * Check if an element is a country.
129
     *
130
     * @param $element
131
     * @return bool
132
     */
133 32
    private function isCountry($element)
134
    {
135 32
        return ($element instanceof Coollection || is_array($element)) && isset($element['cca3']);
0 ignored issues
show
Bug introduced by
The class PragmaRX\Coollection\Package\Coollection does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
136
    }
137
138
    /**
139
     * Check it's a currencies array or code.
140
     *
141
     * @param $data
142
     * @return bool
143
     */
144 6
    private function isCurrenciesArray($data)
145
    {
146 6
        return is_array($data) && isset($data['ISO4217Code']);
147
    }
148
149
    /**
150
     * Load the cities file and merge overloads.
151
     *
152
     * @param $country
153
     * @return mixed
154
     */
155 2
    private function loadCities($country)
156
    {
157 2
        return $this->repository->getHelper()->loadJson($country['cca3'], 'cities/default')
158 2
                ->overwrite($this->repository->getHelper()->loadJson($country['cca3'], 'cities/overload'));
159
    }
160
161
    /**
162
     * Load the states file and merge overloads.
163
     *
164
     * @param $country
165
     * @return mixed
166
     */
167 7
    private function loadStates($country)
168
    {
169 7
        return $this->repository->getHelper()->loadJson($country['cca3'], 'states/default')
170 7
                ->overwrite($this->repository->getHelper()->loadJson($country['cca3'], 'states/overload'));
171
    }
172
173
    /**
174
     * Load the taxes file and merge overloads.
175
     *
176
     * @param $country
177
     * @return mixed
178
     */
179 2
    private function loadTaxes($country)
180
    {
181 2
        return $this->repository->getHelper()->loadJson($country['cca3'], 'taxes/default')
182 2
                                ->overwrite($this->repository->getHelper()->loadJson($country['cca3'], 'taxes/overload'));
183
    }
184
185
    /**
186
     * Check if an element needs hydrated.
187
     *
188
     * @param $countryCode
189
     * @param $element
190
     * @param bool $enabled
191
     * @return bool
192
     */
193 31
    protected function needsHydration($countryCode, $element, $enabled = false)
194
    {
195 31
        if (! $this->canHydrate($element, $enabled, $countryCode)) {
196 29
            return false;
197
        }
198
199 31
        return $this->updateHydrated($countryCode, $element);
200
    }
201
202
    /**
203
     * Hydrate cities.
204
     *
205
     * @param $country
206
     * @return mixed
207
     */
208 2
    public function hydrateCities($country)
209
    {
210 2
        $country['cities'] = $this->loadCities($country);
211
212 2
        return $country;
213
    }
214
215
    /**
216
     * Hydrate states.
217
     *
218
     * @param $country
219
     * @return mixed
220
     */
221 7
    public function hydrateStates($country)
222
    {
223 7
        $country['states'] = $this->loadStates($country);
224
225 7
        return $country;
226
    }
227
228
    /**
229
     * Hydrate taxes.
230
     *
231
     * @param $country
232
     * @return Coollection
233
     */
234 2
    public function hydrateTaxes($country)
235
    {
236 2
        $country['taxes'] = $this->loadTaxes($country);
237
238 2
        return $country;
239
    }
240
241
    /**
242
     * Hydrate topoloy.
243
     *
244
     * @param $country
245
     * @return mixed
246
     */
247 1
    public function hydrateTopology($country)
248
    {
249 1
        $country['topology'] = $this->repository->getTopology($country['cca3']);
250
251 1
        return $country;
252
    }
253
254
    /**
255
     * Hydrate geometry.
256
     *
257
     * @param $country
258
     * @return mixed
259
     */
260 1
    public function hydrateGeometry($country)
261
    {
262 1
        $country['geometry'] = $this->repository->getGeometry($country['cca3']);
263
264 1
        return $country;
265
    }
266
267
    /**
268
     * Get hydration elements.
269
     *
270
     * @param $elements
271
     * @return array|string|mixed
272
     */
273 32
    protected function getHydrationElements($elements)
274
    {
275 32
        $elements = ($elements ?: $this->config->get('hydrate.elements'));
276
277 32
        if (is_string($elements) || is_numeric($elements)) {
278 19
            return [$elements => true];
279
        }
280
281 32
        return $this->checkHydrationElements($elements);
282
    }
283
284
    /**
285
     * Hydrate flag.
286
     *
287
     * @param $country
288
     * @return mixed
289
     */
290 31
    public function hydrateFlag($country)
291
    {
292 31
        $country = countriesCollect($country)->overwrite(
293 31
            ['flag' => $this->repository->makeAllFlags($country)]
294
        );
295
296 31
        return $country;
297
    }
298
299
    /**
300
     * Hydrate borders.
301
     *
302
     * @param $country
303
     * @return mixed
304
     */
305 4
    public function hydrateBorders($country)
306
    {
307 4
        $country['borders'] = isset($country['borders'])
308 4
            ? $country['borders'] = countriesCollect($country['borders'])->map(function ($border) {
309 3
                return $this->repository->call('where', ['cca3', $border])->first();
310 4
            })
311 1
            : countriesCollect();
312
313 4
        return $country;
314
    }
315
316
    /**
317
     * Hydrate timezones.
318
     *
319
     * @param $country
320
     * @return mixed
321
     */
322 5
    public function hydrateTimezones($country)
323
    {
324 5
        return $country->overwrite(['timezones' => $this->repository->findTimezones($country['cca3'])]);
325
    }
326
327
    /**
328
     * Hydrate all times for a country timezones.
329
     *
330
     * @param $country
331
     * @return mixed
332
     */
333 2
    public function hydrateTimezonesTimes($country)
334
    {
335 2
        $country = $this->hydrateTimezones($country);
336
337 2
        $country['timezones'] = $country->timezones->map(function ($timezone) {
338 2
            return $timezone->overwrite(['times' => $this->repository->findTimezoneTime($timezone['zone_id'])]);
339 2
        });
340
341 2
        return $country;
342
    }
343
344
    /**
345
     * Hydrate currencies.
346
     *
347
     * @param $country
348
     * @return mixed
349
     */
350 6
    public function hydrateCurrencies($country)
351
    {
352 6
        $currencies = [];
353
354 6
        $country = $this->fixCurrencies($country);
355
356 6
        if (isset($country['currencies'])) {
357 6
            $currencies = countriesCollect($country['currencies'])->mapWithKeys(function ($code) {
358 6
                if ($this->isCurrenciesArray($code)) {
359
                    return [
360
                        $code['ISO4217Code'] => $code,
361
                    ];
362
                }
363
364
                return [
365 6
                    $code => $this->repository->loadCurrenciesForCountry($code),
366
                ];
367 6
            });
368
        }
369
370 6
        $country['currencies'] = $currencies;
371
372 6
        return $country;
373
    }
374
375
    /**
376
     * Hydrate a countries collection with languages.
377
     *
378
     * @param \PragmaRX\Coollection\Package\Coollection|array|\stdClass $target
379
     * @param null $elements
380
     * @return \PragmaRX\Coollection\Package\Coollection
381
     */
382 32
    public function hydrate($target, $elements = null)
383
    {
384 32
        $elements = $this->getHydrationElements($elements);
385
386 32
        if (coollect($elements)->count() === 0) {
387
            return $target;
388
        }
389
390 32
        return $this->isCountry($target->toArray())
391 17
            ? $this->hydrateCountry($target, $elements)
392 32
            : $this->hydrateCountries($target, $elements);
393
    }
394
395
    /**
396
     * Get country by country code.
397
     *
398
     * @param $countryCode
399
     * @return mixed
400
     */
401 31
    public function getCountry($countryCode)
402
    {
403 31
        return countriesCollect($this->repository->countries[$countryCode]);
404
    }
405
406
    /**
407
     * Check and create a country in the repository.
408
     *
409
     * @param $country
410
     * @param $countryCode
411
     */
412 31
    public function addCountry($countryCode, $country)
413
    {
414 31
        if (! isset($this->repository->countries[$countryCode])) {
415 31
            $this->repository->countries[$countryCode] = $country;
416
        }
417 31
    }
418
419
    /**
420
     * Hydrate a country element.
421
     *
422
     * @param $countryCode
423
     * @param $element
424
     * @param $enabled
425
     */
426 31
    public function hydrateCountryElement($countryCode, $element, $enabled)
427
    {
428 31
        if ($this->needsHydration($countryCode, $element, $enabled)) {
429 31
            $this->repository->countries[$countryCode] = $this->{'hydrate'.Str::studly($element)}($this->repository->countries[$countryCode]);
430
        }
431 31
    }
432
433
    /**
434
     * Check hydration elements.
435
     *
436
     * @param $elements
437
     * @return static
438
     */
439
    protected function checkHydrationElements($elements)
440
    {
441 32
        $elements = countriesCollect($elements)->mapWithKeys(function ($value, $key) {
442 32
            if (is_numeric($key)) {
443
                $key = $value;
444
                $value = true;
445
            }
446
447 32
            return [$key => $value];
448
        })->filter(function ($element) {
449 32
            return $element;
450 32
        });
451
452 32
        return $elements;
453
    }
454
455
    /**
456
     * Repository setter.
457
     *
458
     * @param $repository
459
     */
460 34
    public function setRepository($repository)
461
    {
462 34
        $this->repository = $repository;
463 34
    }
464
465
    /**
466
     * Update hydrated.
467
     *
468
     * @param $countryCode
469
     * @param $element
470
     * @return bool
471
     */
472 31
    protected function updateHydrated($countryCode, $element)
473
    {
474 31
        $hydrated = $this->createHydrated($countryCode);
475
476 31
        $hydrated[$element] = true;
477
478 31
        $this->repository->countries[$countryCode]['hydrated'] = $hydrated;
479
480 31
        return true;
481
    }
482
}
483