Code

< 40 %
40-60 %
> 60 %
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\HostIp;
14
15
use Geocoder\Collection;
16
use Geocoder\Exception\UnsupportedOperation;
17
use Geocoder\Http\Provider\AbstractHttpProvider;
18
use Geocoder\Model\Address;
19
use Geocoder\Model\AddressCollection;
20
use Geocoder\Provider\Provider;
21
use Geocoder\Query\GeocodeQuery;
22
use Geocoder\Query\ReverseQuery;
23
24
/**
25
 * @author William Durand <[email protected]>
26
 * @author Oleg Andreyev <[email protected]>
27
 */
28
abstract class AbstractHostIp extends AbstractHttpProvider implements Provider
29
{
30
    abstract protected function executeQuery(string $url): AddressCollection;
31
32
    abstract protected function getEndpointURL(): string;
33
34 17
    public function geocodeQuery(GeocodeQuery $query): Collection
35
    {
36 17
        $address = $query->getText();
37 17
        if (!filter_var($address, FILTER_VALIDATE_IP)) {
38 2
            throw new UnsupportedOperation('The '.get_class($this).' provider does not support Street addresses.');
39
        }
40
41
        // This API does not support IPv6
42 15
        if (filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
43 4
            throw new UnsupportedOperation('The HostIp provider does not support IPv6 addresses.');
44
        }
45
46 11
        if ('127.0.0.1' === $address) {
47 2
            return new AddressCollection([$this->getLocationForLocalhost()]);
48
        }
49
50 9
        $url = sprintf($this->getEndpointURL(), $address);
51
52 9
        return $this->executeQuery($url);
53
    }
54
55 2
    public function reverseQuery(ReverseQuery $query): Collection
56
    {
57 2
        throw new UnsupportedOperation('The HostIp provider is not able to do reverse geocoding.');
58
    }
59
60 4
    protected function isUnknownLocation(array $data): bool
61
    {
62 4
        return empty($data['lat'])
63 4
            && empty($data['lng'])
64 4
            && '(Unknown City?)' === $data['city']
65 4
            && '(Unknown Country?)' === $data['country_name'];
66
    }
67
68 4
    protected function isPrivateLocation(array $data): bool
69
    {
70 4
        return empty($data['lat'])
71 4
            && empty($data['lng'])
72 4
            && '(Private Address)' === $data['city']
73 4
            && '(Private Address)' === $data['country_name'];
74
    }
75
76 4
    protected function prepareAddressCollection(array $data): AddressCollection
77
    {
78
        // Return empty collection if address was not found
79 4
        if ($this->isUnknownLocation($data)) {
80
            return new AddressCollection([]);
81
        }
82
83
        // Return empty collection if address was not found
84 4
        if ($this->isPrivateLocation($data)) {
85
            return new AddressCollection([]);
86
        }
87
88 4
        return new AddressCollection([
89 4
            Address::createFromArray([
90 4
                'providedBy' => $this->getName(),
91 4
                'latitude' => $data['lat'] ?? null,
92 4
                'longitude' => $data['lng'] ?? null,
93 4
                'locality' => $data['city'],
94 4
                'country' => $data['country_name'],
95 4
                'countryCode' => $data['country_code'],
96 4
            ]),
97 4
        ]);
98
    }
99
}
100