Completed
Push — master ( 57c3d7...21287b )
by Tobias
02:27
created

Yandex::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 2
crap 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\Provider;
24
use Http\Client\HttpClient;
25
26
/**
27
 * @author Antoine Corcy <[email protected]>
28
 */
29
final class Yandex extends AbstractHttpProvider implements Provider
30
{
31
    /**
32
     * @var string
33
     */
34
    const GEOCODE_ENDPOINT_URL = 'https://geocode-maps.yandex.ru/1.x/?format=json&geocode=%s';
35
36
    /**
37
     * @var string
38
     */
39
    const REVERSE_ENDPOINT_URL = 'https://geocode-maps.yandex.ru/1.x/?format=json&geocode=%F,%F';
40
41
    /**
42
     * @var string
43
     */
44
    private $toponym;
45
46
    /**
47
     * @param HttpClient $client  an HTTP adapter
48
     * @param string     $toponym toponym biasing only for reverse geocoding (optional)
49
     */
50 27
    public function __construct(HttpClient $client, string $toponym = null)
51
    {
52 27
        parent::__construct($client);
53
54 27
        $this->toponym = $toponym;
55 27
    }
56
57
    /**
58
     * {@inheritdoc}
59
     */
60 14
    public function geocodeQuery(GeocodeQuery $query): Collection
61
    {
62 14
        $address = $query->getText();
63
        // This API doesn't handle IPs
64 14
        if (filter_var($address, FILTER_VALIDATE_IP)) {
65 2
            throw new UnsupportedOperation('The Yandex provider does not support IP addresses, only street addresses.');
66
        }
67
68 12
        $url = sprintf(self::GEOCODE_ENDPOINT_URL, urlencode($address));
69
70 12
        return $this->executeQuery($url, $query->getLocale(), $query->getLimit());
71
    }
72
73
    /**
74
     * {@inheritdoc}
75
     */
76 12
    public function reverseQuery(ReverseQuery $query): Collection
77
    {
78 12
        $coordinates = $query->getCoordinates();
79 12
        $longitude = $coordinates->getLongitude();
80 12
        $latitude = $coordinates->getLatitude();
81 12
        $url = sprintf(self::REVERSE_ENDPOINT_URL, $longitude, $latitude);
82
83 12
        if (null !== $toponym = $query->getData('toponym', $this->toponym)) {
84 4
            $url = sprintf('%s&kind=%s', $url, $toponym);
85
        }
86
87 12
        return $this->executeQuery($url, $query->getLocale(), $query->getLimit());
88
    }
89
90
    /**
91
     * {@inheritdoc}
92
     */
93 10
    public function getName(): string
94
    {
95 10
        return 'yandex';
96
    }
97
98
    /**
99
     * @param string      $url
100
     * @param string|null $locale
101
     * @param int         $limit
102
     *
103
     * @return AddressCollection
104
     */
105 24
    private function executeQuery(string $url, string $locale = null, int $limit): AddressCollection
106
    {
107 24
        if (null !== $locale) {
108 8
            $url = sprintf('%s&lang=%s', $url, str_replace('_', '-', $locale));
109
        }
110
111 24
        $url = sprintf('%s&results=%d', $url, $limit);
112 24
        $content = $this->getUrlContents($url);
113 14
        $json = json_decode($content, true);
114
115 14
        if (empty($json) || isset($json['error']) ||
116 14
            (isset($json['response']) && '0' === $json['response']['GeoObjectCollection']['metaDataProperty']['GeocoderResponseMetaData']['found'])
117
        ) {
118 5
            return new AddressCollection([]);
119
        }
120
121 9
        $data = $json['response']['GeoObjectCollection']['featureMember'];
122
123 9
        $locations = [];
124 9
        foreach ($data as $item) {
125 9
            $builder = new AddressBuilder($this->getName());
126 9
            $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...
127 9
            $flatArray = ['pos' => ' '];
128
129 9
            array_walk_recursive(
130 9
                $item['GeoObject'],
131
132
                /**
133
                 * @param string $value
134
                 */
135 9
                function ($value, $key) use (&$flatArray) {
136 9
                    $flatArray[$key] = $value;
137 9
                }
138
            );
139
140 9
            if (!empty($flatArray['lowerCorner']) && !empty($flatArray['upperCorner'])) {
141 9
                $lowerCorner = explode(' ', $flatArray['lowerCorner']);
142 9
                $upperCorner = explode(' ', $flatArray['upperCorner']);
143 9
                $builder->setBounds(
144 9
                    (float) $lowerCorner[1],
145 9
                    (float) $lowerCorner[0],
146 9
                    (float) $upperCorner[1],
147 9
                    (float) $upperCorner[0]
148
                );
149
            }
150
151 9
            $coordinates = explode(' ', $flatArray['pos']);
152 9
            $builder->setCoordinates((float) $coordinates[1], (float) $coordinates[0]);
153
154 9
            foreach (['AdministrativeAreaName', 'SubAdministrativeAreaName'] as $i => $name) {
155 9
                if (isset($flatArray[$name])) {
156 9
                    $builder->addAdminLevel($i + 1, $flatArray[$name], null);
157
                }
158
            }
159
160 9
            $builder->setStreetNumber(isset($flatArray['PremiseNumber']) ? $flatArray['PremiseNumber'] : null);
161 9
            $builder->setStreetName(isset($flatArray['ThoroughfareName']) ? $flatArray['ThoroughfareName'] : null);
162 9
            $builder->setSubLocality(isset($flatArray['DependentLocalityName']) ? $flatArray['DependentLocalityName'] : null);
163 9
            $builder->setLocality(isset($flatArray['LocalityName']) ? $flatArray['LocalityName'] : null);
164 9
            $builder->setCountry(isset($flatArray['CountryName']) ? $flatArray['CountryName'] : null);
165 9
            $builder->setCountryCode(isset($flatArray['CountryNameCode']) ? $flatArray['CountryNameCode'] : null);
166
167
            /** @var YandexAddress $location */
168 9
            $location = $builder->build(YandexAddress::class);
169 9
            $location = $location->withPrecision(isset($flatArray['precision']) ? $flatArray['precision'] : null);
170 9
            $location = $location->withName(isset($flatArray['name']) ? $flatArray['name'] : null);
171 9
            $locations[] = $location;
172
        }
173
174 9
        return new AddressCollection($locations);
175
    }
176
}
177