Completed
Push — master ( c0b45f...c6f08b )
by Abdelrahman
01:11 queued 12s
created

Country::getTimezones()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 0
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Rinvex\Country;
6
7
use Locale;
8
use Exception;
9
use DateTimeZone;
10
use ResourceBundle;
11
12
class Country
13
{
14
    /**
15
     * The attributes array.
16
     *
17
     * @var array
18
     */
19
    protected $attributes;
20
21
    /**
22
     * Create a new Country instance.
23
     *
24
     * @param array $attributes
25
     *
26
     * @throws \Exception
27
     */
28
    public function __construct($attributes)
29
    {
30
        // Set the attributes
31
        $this->setAttributes($attributes);
32
33
        // Check required mandatory attributes
34
        if (empty($this->getName()) || empty($this->getOfficialName())
35
            || empty($this->getNativeName()) || empty($this->getNativeOfficialName())
36
            || empty($this->getIsoAlpha2()) || empty($this->getIsoAlpha3())) {
37
            throw new Exception('Missing mandatory country attributes!');
38
        }
39
    }
40
41
    /**
42
     * Set the attributes.
43
     *
44
     * @param array $attributes
45
     *
46
     * @return $this
47
     */
48
    public function setAttributes($attributes)
49
    {
50
        $this->attributes = $attributes;
51
52
        return $this;
53
    }
54
55
    /**
56
     * Get the attributes.
57
     *
58
     * @return array|null
59
     */
60
    public function getAttributes(): ?array
61
    {
62
        return $this->attributes;
63
    }
64
65
    /**
66
     * Set single attribute.
67
     *
68
     * @param string $key
69
     * @param mixed  $value
70
     *
71
     * @return $this
72
     */
73
    public function set($key, $value)
74
    {
75
        $this->attributes[$key] = $value;
76
77
        return $this;
78
    }
79
80
    /**
81
     * Get an item from attributes array using "dot" notation.
82
     *
83
     * @param string $key
84
     * @param mixed  $default
85
     *
86
     * @return mixed
87
     */
88
    public function get($key, $default = null)
89
    {
90
        $array = $this->attributes;
91
92
        if (is_null($key)) {
93
            return $array;
94
        }
95
96
        if (array_key_exists($key, $array)) {
97
            return $array[$key];
98
        }
99
100
        foreach (explode('.', $key) as $segment) {
101
            if (is_array($array) && array_key_exists($segment, $array)) {
102
                $array = $array[$segment];
103
            } else {
104
                return $default;
105
            }
106
        }
107
108
        return $array;
109
    }
110
111
    /**
112
     * Get the common name.
113
     *
114
     * @return string|null
115
     */
116
    public function getName(): ?string
117
    {
118
        return $this->get('name.common') ?: $this->get('name');
119
    }
120
121
    /**
122
     * Get the official name.
123
     *
124
     * @return string|null
125
     */
126
    public function getOfficialName(): ?string
127
    {
128
        return $this->get('name.official') ?: $this->get('official_name');
129
    }
130
131
    /**
132
     * Get the given native name or fallback to first native name.
133
     *
134
     * @param string|null $languageCode
135
     *
136
     * @return string|null
137
     */
138
    public function getNativeName($languageCode = null): ?string
139
    {
140
        $languageCode = $languageCode ? mb_strtolower($languageCode) : null;
141
142
        return $this->get("name.native.{$languageCode}.common")
143
            ?: (current($this->get('name.native', []))['common'] ?: $this->get('native_name'));
144
    }
145
146
    /**
147
     * Get the given native official name or fallback to first native official name.
148
     *
149
     * @param string|null $languageCode
150
     *
151
     * @return string|null
152
     */
153
    public function getNativeOfficialName($languageCode = null): ?string
154
    {
155
        $languageCode = $languageCode ? mb_strtolower($languageCode) : null;
156
157
        return $this->get("name.native.{$languageCode}.official")
158
            ?: (current($this->get('name.native', []))['official'] ?: $this->get('native_official_name'));
159
    }
160
161
    /**
162
     * Get the native names.
163
     *
164
     * @return array|null
165
     */
166
    public function getNativeNames(): ?array
167
    {
168
        return $this->get('name.native');
169
    }
170
171
    /**
172
     * Get the demonym.
173
     *
174
     * @return string|null
175
     */
176
    public function getDemonym(): ?string
177
    {
178
        return $this->get('demonym');
179
    }
180
181
    /**
182
     * Get the capital.
183
     *
184
     * @return string|null
185
     */
186
    public function getCapital(): ?string
187
    {
188
        return $this->get('capital');
189
    }
190
191
    /**
192
     * Get the ISO 3166-1 alpha2.
193
     *
194
     * @return string|null
195
     */
196
    public function getIsoAlpha2()
197
    {
198
        return $this->get('iso_3166_1_alpha2');
199
    }
200
201
    /**
202
     * Get the ISO 3166-1 alpha3.
203
     *
204
     * @return string|null
205
     */
206
    public function getIsoAlpha3()
207
    {
208
        return $this->get('iso_3166_1_alpha3');
209
    }
210
211
    /**
212
     * Get the ISO 3166-1 numeric.
213
     *
214
     * @return string|null
215
     */
216
    public function getIsoNumeric(): ?string
217
    {
218
        return $this->get('iso_3166_1_numeric');
219
    }
220
221
    /**
222
     * Get the given currency or fallback to first currency.
223
     *
224
     * @param string|null $currency
225
     *
226
     * @return array|null
227
     */
228
    public function getCurrency($currency = null): ?array
229
    {
230
        $currency = $currency ? mb_strtoupper($currency) : null;
231
232
        return $this->get("currency.{$currency}") ?: (current($this->get('currency', [])) ?: null);
233
    }
234
235
    /**
236
     * Get the currencies.
237
     *
238
     * @return array|null
239
     */
240
    public function getCurrencies(): ?array
241
    {
242
        return $this->get('currency');
243
    }
244
245
    /**
246
     * Get the TLD.
247
     *
248
     * @return string|null
249
     */
250
    public function getTld(): ?string
251
    {
252
        return current($this->get('tld', [])) ?: null;
253
    }
254
255
    /**
256
     * Get the TLDs.
257
     *
258
     * @return array|null
259
     */
260
    public function getTlds(): ?array
261
    {
262
        return $this->get('tld');
263
    }
264
265
    /**
266
     * Get the alternative spellings.
267
     *
268
     * @return array|null
269
     */
270
    public function getAltSpellings(): ?array
271
    {
272
        return $this->get('alt_spellings');
273
    }
274
275
    /**
276
     * Get the given language or fallback to first language.
277
     *
278
     * @param string|null $languageCode
279
     *
280
     * @return string|null
281
     */
282
    public function getLanguage($languageCode = null): ?string
283
    {
284
        $languageCode = $languageCode ? mb_strtoupper($languageCode) : null;
285
286
        return $this->get("languages.{$languageCode}") ?: (current($this->get('languages', [])) ?: null);
287
    }
288
289
    /**
290
     * Get the languages.
291
     *
292
     * @return array|null
293
     */
294
    public function getLanguages(): ?array
295
    {
296
        return $this->get('languages');
297
    }
298
299
    /**
300
     * Get the translations.
301
     *
302
     * @return array
303
     */
304
    public function getTranslations(): array
305
    {
306
        // Get english name
307
        $name = [
308
            'eng' => [
309
                'common' => $this->getName(),
310
                'official' => $this->getOfficialName(),
311
            ],
312
        ];
313
314
        // Get native names
315
        $natives = $this->getNativeNames() ?: [];
316
317
        // Get other translations
318
        $file = __DIR__.'/../resources/translations/'.mb_strtolower($this->getIsoAlpha2()).'.json';
319
        $translations = file_exists($file) ? json_decode(file_get_contents($file), true) : [];
320
321
        // Merge all names together
322
        $result = array_merge($translations, $natives, $name);
323
324
        // Sort alphabetically
325
        ksort($result);
326
327
        return $result;
328
    }
329
330
    /**
331
     * Get the translation.
332
     *
333
     * @param string|null $languageCode
334
     *
335
     * @return array
336
     */
337
    public function getTranslation($languageCode = null): array
338
    {
339
        return $this->getTranslations()[$languageCode] ?? current($this->getTranslations());
340
    }
341
342
    /**
343
     * Get the geodata.
344
     *
345
     * @return array|null
346
     */
347
    public function getGeodata(): ?array
348
    {
349
        return $this->get('geo');
350
    }
351
352
    /**
353
     * Get the continent.
354
     *
355
     * @return string|null
356
     */
357
    public function getContinent(): ?string
358
    {
359
        return current($this->get('geo.continent', [])) ?: null;
360
    }
361
362
    /**
363
     * Determine whether the country uses postal code.
364
     *
365
     * @return bool|null
366
     */
367
    public function usesPostalCode()
368
    {
369
        return $this->get('geo.postal_code');
370
    }
371
372
    /**
373
     * Get the latitude.
374
     *
375
     * @return string|null
376
     */
377
    public function getLatitude(): ?string
378
    {
379
        return $this->get('geo.latitude');
380
    }
381
382
    /**
383
     * Get the longitude.
384
     *
385
     * @return string|null
386
     */
387
    public function getLongitude(): ?string
388
    {
389
        return $this->get('geo.longitude');
390
    }
391
392
    /**
393
     * Get the described latitude.
394
     *
395
     * @return string|null
396
     */
397
    public function getLatitudeDesc(): ?string
398
    {
399
        return $this->get('geo.latitude_desc');
400
    }
401
402
    /**
403
     * Get the described longitude.
404
     *
405
     * @return string|null
406
     */
407
    public function getLongitudeDesc(): ?string
408
    {
409
        return $this->get('geo.longitude_desc');
410
    }
411
412
    /**
413
     * Get the maximum latitude.
414
     *
415
     * @return string|null
416
     */
417
    public function getMaxLatitude(): ?string
418
    {
419
        return $this->get('geo.max_latitude');
420
    }
421
422
    /**
423
     * Get the maximum longitude.
424
     *
425
     * @return string|null
426
     */
427
    public function getMaxLongitude(): ?string
428
    {
429
        return $this->get('geo.max_longitude');
430
    }
431
432
    /**
433
     * Get the minimum latitude.
434
     *
435
     * @return string|null
436
     */
437
    public function getMinLatitude(): ?string
438
    {
439
        return $this->get('geo.min_latitude');
440
    }
441
442
    /**
443
     * Get the minimum longitude.
444
     *
445
     * @return string|null
446
     */
447
    public function getMinLongitude(): ?string
448
    {
449
        return $this->get('geo.min_longitude');
450
    }
451
452
    /**
453
     * Get the area.
454
     *
455
     * @return int|null
456
     */
457
    public function getArea(): ?int
458
    {
459
        return $this->get('geo.area');
460
    }
461
462
    /**
463
     * Get the region.
464
     *
465
     * @return string|null
466
     */
467
    public function getRegion(): ?string
468
    {
469
        return $this->get('geo.region');
470
    }
471
472
    /**
473
     * Get the subregion.
474
     *
475
     * @return string|null
476
     */
477
    public function getSubregion(): ?string
478
    {
479
        return $this->get('geo.subregion');
480
    }
481
482
    /**
483
     * Get the world region.
484
     *
485
     * @return string|null
486
     */
487
    public function getWorldRegion(): ?string
488
    {
489
        return $this->get('geo.world_region');
490
    }
491
492
    /**
493
     * Get the region code.
494
     *
495
     * @return string|null
496
     */
497
    public function getRegionCode(): ?string
498
    {
499
        return $this->get('geo.region_code');
500
    }
501
502
    /**
503
     * Get the subregion code.
504
     *
505
     * @return string|null
506
     */
507
    public function getSubregionCode(): ?string
508
    {
509
        return $this->get('geo.subregion_code');
510
    }
511
512
    /**
513
     * Check the landlock status.
514
     *
515
     * @return bool|null
516
     */
517
    public function isLandlocked()
518
    {
519
        return $this->get('geo.landlocked');
520
    }
521
522
    /**
523
     * Get the borders.
524
     *
525
     * @return array|null
526
     */
527
    public function getBorders(): ?array
528
    {
529
        return $this->get('geo.borders');
530
    }
531
532
    /**
533
     * Determine whether the country is independent.
534
     *
535
     * @return string|null
536
     */
537
    public function isIndependent(): ?string
538
    {
539
        return $this->get('geo.independent');
540
    }
541
542
    /**
543
     * Get the given calling code or fallback to first calling code.
544
     *
545
     * @return string|null
546
     */
547
    public function getCallingCode(): ?string
548
    {
549
        return current($this->get('dialling.calling_code', [])) ?: (current($this->get('calling_code', [])) ?: null);
550
    }
551
552
    /**
553
     * Get the calling codes.
554
     *
555
     * @return array|null
556
     */
557
    public function getCallingCodes(): ?array
558
    {
559
        return $this->get('dialling.calling_code');
560
    }
561
562
    /**
563
     * Get the national prefix.
564
     *
565
     * @return string|null
566
     */
567
    public function getNationalPrefix(): ?string
568
    {
569
        return $this->get('dialling.national_prefix');
570
    }
571
572
    /**
573
     * Get the national number length.
574
     *
575
     * @return int|null
576
     */
577
    public function getNationalNumberLength(): ?int
578
    {
579
        return current($this->get('dialling.national_number_lengths', [])) ?: null;
580
    }
581
582
    /**
583
     * Get the national number lengths.
584
     *
585
     * @return array|null
586
     */
587
    public function getNationalNumberLengths(): ?array
588
    {
589
        return $this->get('dialling.national_number_lengths');
590
    }
591
592
    /**
593
     * Get the national destination code length.
594
     *
595
     * @return int|null
596
     */
597
    public function getNationalDestinationCodeLength(): ?int
598
    {
599
        return current($this->get('dialling.national_destination_code_lengths', [])) ?: null;
600
    }
601
602
    /**
603
     * Get the national destination code lengths.
604
     *
605
     * @return array|null
606
     */
607
    public function getnationaldestinationcodelengths(): ?array
608
    {
609
        return $this->get('dialling.national_destination_code_lengths');
610
    }
611
612
    /**
613
     * Get the international prefix.
614
     *
615
     * @return string|null
616
     */
617
    public function getInternationalPrefix(): ?string
618
    {
619
        return $this->get('dialling.international_prefix');
620
    }
621
622
    /**
623
     * Get the extras.
624
     *
625
     * @return array|null
626
     */
627
    public function getExtra(): ?array
628
    {
629
        return $this->get('extra');
630
    }
631
632
    /**
633
     * Get the geonameid.
634
     *
635
     * @return int|null
636
     */
637
    public function getGeonameid(): ?int
638
    {
639
        return $this->get('extra.geonameid');
640
    }
641
642
    /**
643
     * Get the edgar code.
644
     *
645
     * @return string|null
646
     */
647
    public function getEdgar(): ?string
648
    {
649
        return $this->get('extra.edgar');
650
    }
651
652
    /**
653
     * Get the itu code.
654
     *
655
     * @return string|null
656
     */
657
    public function getItu(): ?string
658
    {
659
        return $this->get('extra.itu');
660
    }
661
662
    /**
663
     * Get the marc code.
664
     *
665
     * @return string|null
666
     */
667
    public function getMarc(): ?string
668
    {
669
        return $this->get('extra.marc');
670
    }
671
672
    /**
673
     * Get the wmo code.
674
     *
675
     * @return string|null
676
     */
677
    public function getWmo(): ?string
678
    {
679
        return $this->get('extra.wmo');
680
    }
681
682
    /**
683
     * Get the ds code.
684
     *
685
     * @return string|null
686
     */
687
    public function getDs(): ?string
688
    {
689
        return $this->get('extra.ds');
690
    }
691
692
    /**
693
     * Get the fifa code.
694
     *
695
     * @return string|null
696
     */
697
    public function getFifa(): ?string
698
    {
699
        return $this->get('extra.fifa');
700
    }
701
702
    /**
703
     * Get the fips code.
704
     *
705
     * @return string|null
706
     */
707
    public function getFips(): ?string
708
    {
709
        return $this->get('extra.fips');
710
    }
711
712
    /**
713
     * Get the gaul code.
714
     *
715
     * @return int|null
716
     */
717
    public function getGaul(): ?int
718
    {
719
        return $this->get('extra.gaul');
720
    }
721
722
    /**
723
     * Get the ioc code.
724
     *
725
     * @return string|null
726
     */
727
    public function getIoc(): ?string
728
    {
729
        return $this->get('extra.ioc');
730
    }
731
732
    /**
733
     * Get the cowc code.
734
     *
735
     * @return string|null
736
     */
737
    public function getCowc(): ?string
738
    {
739
        return $this->get('extra.cowc');
740
    }
741
742
    /**
743
     * Get the cown code.
744
     *
745
     * @return int|null
746
     */
747
    public function getCown(): ?int
748
    {
749
        return $this->get('extra.cown');
750
    }
751
752
    /**
753
     * Get the fao code.
754
     *
755
     * @return int|null
756
     */
757
    public function getFao(): ?int
758
    {
759
        return $this->get('extra.fao');
760
    }
761
762
    /**
763
     * Get the imf code.
764
     *
765
     * @return int|null
766
     */
767
    public function getImf(): ?int
768
    {
769
        return $this->get('extra.imf');
770
    }
771
772
    /**
773
     * Get the ar5 code.
774
     *
775
     * @return string|null
776
     */
777
    public function getAr5()
778
    {
779
        return $this->get('extra.ar5');
780
    }
781
782
    /**
783
     * Get the address format.
784
     *
785
     * @return string|null
786
     */
787
    public function getAddressFormat(): ?string
788
    {
789
        return $this->get('extra.address_format');
790
    }
791
792
    /**
793
     * Determine whether the country is EU member.
794
     *
795
     * @return bool|null
796
     */
797
    public function isEuMember()
798
    {
799
        return $this->get('extra.eu_member');
800
    }
801
802
    /**
803
     * Get the VAT rates.
804
     *
805
     * @return array|null
806
     */
807
    public function getVatRates(): ?array
808
    {
809
        return $this->get('extra.vat_rates');
810
    }
811
812
    /**
813
     * Get the emoji.
814
     *
815
     * @return string|null
816
     */
817
    public function getEmoji(): ?string
818
    {
819
        return $this->get('extra.emoji') ?: $this->get('emoji');
820
    }
821
822
    /**
823
     * Get the geographic data structure.
824
     *
825
     * @return string|null
826
     */
827
    public function getGeoJson(): ?string
828
    {
829
        if (! ($code = $this->getIsoAlpha2())) {
830
            return null;
831
        }
832
833
        return file_exists($file = __DIR__.'/../resources/geodata/'.mb_strtolower($code).'.json') ? file_get_contents($file) : null;
834
    }
835
836
    /**
837
     * Get the flag.
838
     *
839
     * @return string|null
840
     */
841
    public function getFlag(): ?string
842
    {
843
        if (! ($code = $this->getIsoAlpha2())) {
844
            return null;
845
        }
846
847
        return file_exists($file = __DIR__.'/../resources/flags/'.mb_strtolower($code).'.svg') ? file_get_contents($file) : null;
848
    }
849
850
    /**
851
     * Get the divisions.
852
     *
853
     * @return array|null
854
     */
855
    public function getDivisions(): ?array
856
    {
857
        if (! ($code = $this->getIsoAlpha2())) {
858
            return null;
859
        }
860
861
        return file_exists($file = __DIR__.'/../resources/divisions/'.mb_strtolower($code).'.json') ? json_decode(file_get_contents($file), true) : null;
862
    }
863
864
    /**
865
     * Get the divisions.
866
     *
867
     * @param string $division
868
     *
869
     * @return array|null
870
     */
871
    public function getDivision($division): ?array
872
    {
873
        return ! empty($this->getDivisions()) && isset($this->getDivisions()[$division])
874
            ? $this->getDivisions()[$division] : null;
875
    }
876
877
    /**
878
     * Get the timezones.
879
     *
880
     * @return array|null
881
     */
882
    public function getTimezones()
883
    {
884
        if (! ($code = $this->getIsoAlpha2())) {
885
            return;
886
        }
887
888
        return DateTimeZone::listIdentifiers(DateTimeZone::PER_COUNTRY, $code);
889
    }
890
891
    /**
892
     * Get the locales.
893
     *
894
     * @return array|null
895
     */
896
    public function getLocales()
897
    {
898
        if (! ($code = $this->getIsoAlpha2())) {
899
            return;
900
        }
901
902
        $locales = [];
903
        foreach (ResourceBundle::getLocales('') as $localeCode) {
904
            if ($code === Locale::getRegion($localeCode)) {
905
                $locales[] = $localeCode;
906
            }
907
        }
908
909
        return $locales;
910
    }
911
}
912