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']); |
|
|
|
|
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
|
|
|
|
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 thecomposer.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
orrequire-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 you have not tested against this specific condition, such errors might go unnoticed.