Issues (11)

BANFrance.php (1 issue)

Labels
Severity
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\BANFrance;
14
15
use Geocoder\Collection;
16
use Geocoder\Exception\InvalidCredentials;
17
use Geocoder\Exception\UnsupportedOperation;
18
use Geocoder\Model\Address;
19
use Geocoder\Model\AddressCollection;
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 Sébastien Barré <[email protected]>
28
 */
29
final class BANFrance extends AbstractHttpProvider implements Provider
30
{
31
    /**
32
     * @var string
33
     */
34
    const GEOCODE_ENDPOINT_URL = 'https://api-adresse.data.gouv.fr/search/?q=%s&limit=%d';
35
36
    /**
37
     * @var string
38
     */
39
    const REVERSE_ENDPOINT_URL = 'https://api-adresse.data.gouv.fr/reverse/?&lon=%F&lat=%F';
40
41
    /**
42
     * @param HttpClient $adapter An HTTP adapter.
43
     */
44
    public function __construct(HttpClient $client)
45
    {
46
        parent::__construct($client);
47
    }
48
49
    /**
50
     * {@inheritdoc}
51
     */
52
    public function geocodeQuery(GeocodeQuery $query): Collection
53
    {
54
        $address = $query->getText();
55
        $limit = $query->getLimit();
56
        // This API doesn't handle IPs
57
        if (filter_var($address, FILTER_VALIDATE_IP)) {
58
            throw new UnsupportedOperation('The BANFrance provider does not support IP addresses, only street addresses.');
59
        }
60
        // Save a request if no valid address entered
61
        if (empty($address)) {
62
            throw new InvalidArgument('Address cannot be empty.');
0 ignored issues
show
The type Geocoder\Provider\BANFrance\InvalidArgument was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
63
        }
64
65
        $url = sprintf(self::GEOCODE_ENDPOINT_URL, urlencode($query->getText()), $limit);
66
        return $this->executeQuery($url, $query->getLimit());
67
    }
68
69
    /**
70
     * {@inheritdoc}
71
     */
72
    public function reverseQuery(ReverseQuery $query): Collection
73
    {
74
        $coordinates = $query->getCoordinates();
75
        $url = sprintf(self::REVERSE_ENDPOINT_URL, $coordinates->getLongitude(), $coordinates->getLatitude());
76
        return $this->executeQuery($url);
77
    }
78
79
    /**
80
     * @param string $url
81
     * @param int    $limit
82
     *
83
     * @return \Geocoder\Collection
84
     */
85
    private function executeQuery(string $url, int $limit = null): Collection
86
    {
87
        $content = $this->getUrlContents($url);
88
        $json = json_decode($content, true);
89
90
91
        if (!isset($json['features']) || empty($json['features'])) {
92
            return new AddressCollection([]);
93
        }
94
95
        $locations = $json['features'];
96
97
        $results = [];
98
        foreach ($locations as $item) {
99
            $results[] = Address::createFromArray([
100
                'providedBy' => $this->getName(),
101
                'longitude' => $item['geometry']['coordinates'][0] ?? null,
102
                'latitude' => $item['geometry']['coordinates'][1] ?? null,
103
                'streetName' => $item['properties']['street'] ?? null,
104
                'streetNumber' => $item['properties']['housenumber'] ?? null,
105
                'locality' => $item['properties']['city'] ?? null,
106
                'postalCode' => $item['properties']['postcode'] ?? null,
107
            ]);
108
            if (count($results) >= $limit) {
109
                break;
110
            }
111
        }
112
113
        return new AddressCollection($results);
114
    }
115
116
    /**
117
     * {@inheritdoc}
118
     */
119
    public function getName(): string
120
    {
121
        return 'BANFrance';
122
    }
123
}
124