Completed
Push — master ( 8f7bd5...fac4b3 )
by Tobias
03:44
created

Yandex::geocodeQuery()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 6
nc 2
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Geocoder package.
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @license    MIT License
11
 */
12
13
namespace Geocoder\Provider\Yandex;
14
15
use Geocoder\Collection;
16
use Geocoder\Exception\UnsupportedOperation;
17
use Geocoder\Model\AddressCollection;
18
use Geocoder\Model\AddressBuilder;
19
use Geocoder\Provider\Yandex\Model\YandexAddress;
20
use Geocoder\Query\GeocodeQuery;
21
use Geocoder\Query\ReverseQuery;
22
use Geocoder\Http\Provider\AbstractHttpProvider;
23
use Geocoder\Provider\LocaleAwareGeocoder;
24
use Geocoder\Provider\Provider;
25
use Http\Client\HttpClient;
26
27
/**
28
 * @author Antoine Corcy <[email protected]>
29
 */
30
final class Yandex extends AbstractHttpProvider implements LocaleAwareGeocoder, Provider
31
{
32
    /**
33
     * @var string
34
     */
35
    const GEOCODE_ENDPOINT_URL = 'https://geocode-maps.yandex.ru/1.x/?format=json&geocode=%s';
36
37
    /**
38
     * @var string
39
     */
40
    const REVERSE_ENDPOINT_URL = 'https://geocode-maps.yandex.ru/1.x/?format=json&geocode=%F,%F';
41
42
    /**
43
     * @var string
44
     */
45
    private $toponym;
46
47
    /**
48
     * @param HttpClient $client  an HTTP adapter
49
     * @param string     $toponym toponym biasing only for reverse geocoding (optional)
50
     */
51
    public function __construct(HttpClient $client, string $toponym = null)
52
    {
53
        parent::__construct($client);
54
55
        $this->toponym = $toponym;
56
    }
57
58
    /**
59
     * {@inheritdoc}
60
     */
61
    public function geocodeQuery(GeocodeQuery $query): Collection
62
    {
63
        $address = $query->getText();
64
        // This API doesn't handle IPs
65
        if (filter_var($address, FILTER_VALIDATE_IP)) {
66
            throw new UnsupportedOperation('The Yandex provider does not support IP addresses, only street addresses.');
67
        }
68
69
        $url = sprintf(self::GEOCODE_ENDPOINT_URL, urlencode($address));
70
71
        return $this->executeQuery($url, $query->getLocale(), $query->getLimit());
72
    }
73
74
    /**
75
     * {@inheritdoc}
76
     */
77
    public function reverseQuery(ReverseQuery $query): Collection
78
    {
79
        $coordinates = $query->getCoordinates();
80
        $longitude = $coordinates->getLongitude();
81
        $latitude = $coordinates->getLatitude();
82
        $url = sprintf(self::REVERSE_ENDPOINT_URL, $longitude, $latitude);
83
84
        if (null !== $toponym = $query->getData('toponym', $this->toponym)) {
85
            $url = sprintf('%s&kind=%s', $url, $toponym);
86
        }
87
88
        return $this->executeQuery($url, $query->getLocale(), $query->getLimit());
89
    }
90
91
    /**
92
     * {@inheritdoc}
93
     */
94
    public function getName(): string
95
    {
96
        return 'yandex';
97
    }
98
99
    /**
100
     * @param string      $url
101
     * @param string|null $locale
102
     * @param int         $limit
103
     *
104
     * @return AddressCollection
105
     */
106
    private function executeQuery(string $url, string $locale = null, int $limit): AddressCollection
107
    {
108
        if (null !== $locale) {
109
            $url = sprintf('%s&lang=%s', $url, str_replace('_', '-', $locale));
110
        }
111
112
        $url = sprintf('%s&results=%d', $url, $limit);
113
        $content = $this->getUrlContents($url);
114
        $json = json_decode($content, true);
115
116
        if (empty($json) || isset($json['error']) ||
117
            (isset($json['response']) && '0' === $json['response']['GeoObjectCollection']['metaDataProperty']['GeocoderResponseMetaData']['found'])
118
        ) {
119
            return new AddressCollection([]);
120
        }
121
122
        $data = $json['response']['GeoObjectCollection']['featureMember'];
123
124
        $locations = [];
125
        foreach ($data as $item) {
126
            $builder = new AddressBuilder($this->getName());
127
            $bounds = null;
0 ignored issues
show
Unused Code introduced by
$bounds is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
128
            $flatArray = ['pos' => ' '];
129
130
            array_walk_recursive(
131
                $item['GeoObject'],
132
133
                /**
134
                 * @param string $value
135
                 */
136
                function ($value, $key) use (&$flatArray) {
137
                    $flatArray[$key] = $value;
138
                }
139
            );
140
141
            if (!empty($flatArray['lowerCorner']) && !empty($flatArray['upperCorner'])) {
142
                $lowerCorner = explode(' ', $flatArray['lowerCorner']);
143
                $upperCorner = explode(' ', $flatArray['upperCorner']);
144
                $builder->setBounds(
145
                    (float) $lowerCorner[1],
146
                    (float) $lowerCorner[0],
147
                    (float) $upperCorner[1],
148
                    (float) $upperCorner[0]
149
                );
150
            }
151
152
            $coordinates = explode(' ', $flatArray['pos']);
153
            $builder->setCoordinates((float) $coordinates[1], (float) $coordinates[0]);
154
155
            foreach (['AdministrativeAreaName', 'SubAdministrativeAreaName'] as $i => $name) {
156
                if (isset($flatArray[$name])) {
157
                    $builder->addAdminLevel($i + 1, $flatArray[$name], null);
158
                }
159
            }
160
161
            $builder->setStreetNumber(isset($flatArray['PremiseNumber']) ? $flatArray['PremiseNumber'] : null);
162
            $builder->setStreetName(isset($flatArray['ThoroughfareName']) ? $flatArray['ThoroughfareName'] : null);
163
            $builder->setSubLocality(isset($flatArray['DependentLocalityName']) ? $flatArray['DependentLocalityName'] : null);
164
            $builder->setLocality(isset($flatArray['LocalityName']) ? $flatArray['LocalityName'] : null);
165
            $builder->setCountry(isset($flatArray['CountryName']) ? $flatArray['CountryName'] : null);
166
            $builder->setCountryCode(isset($flatArray['CountryNameCode']) ? $flatArray['CountryNameCode'] : null);
167
168
            /** @var YandexAddress $location */
169
            $location = $builder->build(YandexAddress::class);
170
            $location = $location->withPrecision(isset($flatArray['precision']) ? $flatArray['precision'] : null);
171
            $location = $location->withName(isset($flatArray['name']) ? $flatArray['name'] : null);
172
            $locations[] = $location;
173
        }
174
175
        return new AddressCollection($locations);
176
    }
177
}
178