GeocodeCollection::get()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 1
c 1
b 0
f 1
nc 1
nop 2
dl 0
loc 3
rs 10
1
<?php
2
3
4
namespace talismanfr\geocode;
5
6
7
use talismanfr\geocode\contracts\Collection;
8
use talismanfr\geocode\contracts\Geocode;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, talismanfr\geocode\Geocode. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
9
use talismanfr\geocode\entity\Address;
10
use talismanfr\geocode\entity\AddressDetails;
11
use talismanfr\geocode\entity\Geo;
12
use talismanfr\geocode\entity\Point;
13
use talismanfr\geocode\exeptions\FormatResponseException;
14
use yii\helpers\ArrayHelper;
15
16
class GeocodeCollection implements Collection
17
{
18
    private $geocode;
19
20
    public function __construct(Geocode $geocode)
21
    {
22
        $this->geocode = $geocode;
23
    }
24
25
    /**
26
     * Get array Geo entity
27
     * @param $query
28
     * @param array $params params fro url to yandex geocode service
29
     * @return array
30
     * @throws FormatResponseException
31
     */
32
    public function get($query, $params = []): array
33
    {
34
        return $this->find($query, $params);
35
    }
36
37
    /**
38
     * @param $query
39
     * @param array $params
40
     * @return Geo
41
     * @throws FormatResponseException
42
     */
43
    public function one($query,$params=[])
44
    {
45
        $params['results']=1;
46
        $geos=$this->find($query,$params);
47
48
        if(count($geos)>0){
49
            return array_shift($geos);
50
        }
51
52
        return null;
53
    }
54
55
    /**
56
     * @param string $query
57
     * @param array $params
58
     * @return array
59
     * @throws FormatResponseException
60
     */
61
    private function find(string $query, $params = []): array
62
    {
63
        $geo_result = $this->geocode->get($query, $params);
64
65
        try {
66
            $geo_result = json_decode((string)$geo_result, true);
67
        } catch (\Exception $e) {
68
            throw new FormatResponseException($e->getMessage());
69
        }
70
71
        $data = ArrayHelper::getValue($geo_result, 'response.GeoObjectCollection.featureMember');
72
73
        if (!$data) {
74
            $meta=ArrayHelper::getValue($geo_result,'response.GeoObjectCollection.metaDataProperty.GeocoderResponseMetaData');
75
76
            if(!$meta) {
77
                throw new FormatResponseException('Error format response from query ' . $query);
78
            }
79
80
        }
81
82
        $geos = [];
83
        foreach ($data as $datum) {
84
            $geos[] = $this->mapsGeo($datum);
85
        }
86
87
        return $geos;
88
89
    }
90
91
    /**
92
     * @param array $data Data from response yandex geocode service
93
     * @return Geo
94
     */
95
    private function mapsGeo(array $data): Geo
96
    {
97
        $data = ArrayHelper::getValue($data, 'GeoObject');
98
        $name = ArrayHelper::getValue($data, 'name');
99
        $description = ArrayHelper::getValue($data, 'description');
100
        $meta = ArrayHelper::getValue($data, 'metaDataProperty.GeocoderMetaData');
101
102
        $kind = ArrayHelper::getValue($meta, 'kind');
103
        $text = ArrayHelper::getValue($meta, 'text');
104
105
        $address = Address::fromState(ArrayHelper::getValue($meta, 'Address'));
0 ignored issues
show
Bug introduced by
It seems like yii\helpers\ArrayHelper:...Value($meta, 'Address') can also be of type null; however, parameter $state of talismanfr\geocode\entity\Address::fromState() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

105
        $address = Address::fromState(/** @scrutinizer ignore-type */ ArrayHelper::getValue($meta, 'Address'));
Loading history...
106
        $addressDetails = AddressDetails::fromState(ArrayHelper::getValue($meta, 'AddressDetails'));
0 ignored issues
show
Bug introduced by
It seems like yii\helpers\ArrayHelper:...meta, 'AddressDetails') can also be of type null; however, parameter $state of talismanfr\geocode\entit...essDetails::fromState() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

106
        $addressDetails = AddressDetails::fromState(/** @scrutinizer ignore-type */ ArrayHelper::getValue($meta, 'AddressDetails'));
Loading history...
107
108
        $point = new Point(ArrayHelper::getValue($data, 'Point.pos'));
109
110
        $geo = new Geo($address, $addressDetails, $point, $name, $description, $kind, $text);
111
112
        return $geo;
113
    }
114
115
116
}