| 1 | <?php |
||||
| 2 | |||||
| 3 | namespace LeKoala\GeoTools\Services; |
||||
| 4 | |||||
| 5 | use Exception; |
||||
| 6 | use SimpleXMLElement; |
||||
| 7 | use SilverStripe\Core\Environment; |
||||
| 8 | use LeKoala\GeoTools\Models\Address; |
||||
| 9 | use LeKoala\GeoTools\Models\Country; |
||||
| 10 | use LeKoala\GeoTools\Models\Coordinates; |
||||
| 11 | |||||
| 12 | /** |
||||
| 13 | * @link https://www.bingmapsportal.com/Application |
||||
| 14 | * @link https://learn.microsoft.com/en-us/bingmaps/articles/accessing-the-bing-maps-rest-services-using-php |
||||
| 15 | */ |
||||
| 16 | class BingMaps implements Geocoder |
||||
| 17 | { |
||||
| 18 | const API_URL = 'http://dev.virtualearth.net/REST/v1/Locations/'; |
||||
| 19 | |||||
| 20 | /** |
||||
| 21 | * @return string|null |
||||
| 22 | */ |
||||
| 23 | public static function getApiKey() |
||||
| 24 | { |
||||
| 25 | return Environment::getEnv('BING_MAPS_API_KEY'); |
||||
| 26 | } |
||||
| 27 | |||||
| 28 | /** |
||||
| 29 | * @param ?string $query |
||||
| 30 | * @param array<int|string,mixed> $params countrycodes |
||||
| 31 | * @return Address |
||||
| 32 | * @throws Exception when there is a problem with the api, otherwise may return an empty address |
||||
| 33 | */ |
||||
| 34 | protected function query($query, $params = []) |
||||
|
0 ignored issues
–
show
|
|||||
| 35 | { |
||||
| 36 | $key = self::getApiKey(); |
||||
| 37 | if (!$key) { |
||||
| 38 | throw new Exception('No api key defined in env'); |
||||
| 39 | } |
||||
| 40 | |||||
| 41 | $query = str_ireplace(" ", "%20", $query); |
||||
|
0 ignored issues
–
show
It seems like
$query can also be of type null; however, parameter $subject of str_ireplace() does only seem to accept array|string, 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
Loading history...
|
|||||
| 42 | $findURL = self::API_URL . "/" . $query . "?incl=ciso2&key=" . $key; |
||||
|
0 ignored issues
–
show
Are you sure
$query of type array|string can be used in concatenation?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 43 | $output = file_get_contents($findURL); |
||||
| 44 | |||||
| 45 | if (!$output) { |
||||
| 46 | throw new Exception("The api returned no result"); |
||||
| 47 | } |
||||
| 48 | |||||
| 49 | $result = json_decode($output, true); |
||||
| 50 | |||||
| 51 | if (!$result) { |
||||
| 52 | throw new Exception(json_last_error_msg()); |
||||
| 53 | } |
||||
| 54 | |||||
| 55 | $firstResult = $result['resourceSets'][0]['resources'][0] ?? null; |
||||
| 56 | if (!$firstResult) { |
||||
| 57 | throw new Exception("Empty resultset"); |
||||
| 58 | } |
||||
| 59 | |||||
| 60 | $point = $firstResult['point']['coordinates']; |
||||
| 61 | $lat = $point[0]; |
||||
| 62 | $lon = $point[1]; |
||||
| 63 | |||||
| 64 | $address = $firstResult['address']; |
||||
| 65 | $countryName = $address['countryRegion']; |
||||
| 66 | $countryCode = $address['countryRegionIso2']; |
||||
| 67 | |||||
| 68 | $streetAndNumber = $address['addressLine'] ?? null; |
||||
| 69 | $location = []; |
||||
| 70 | if ($streetAndNumber) { |
||||
| 71 | $number = null; |
||||
| 72 | $street = $streetAndNumber; |
||||
| 73 | $parts = explode(' ', $streetAndNumber, 2); |
||||
| 74 | if (intval($parts[0]) > 0) { |
||||
| 75 | $number = $parts[0]; |
||||
| 76 | $street = $parts[1]; |
||||
| 77 | } |
||||
| 78 | $location = [ |
||||
| 79 | 'streetName' => $street, |
||||
| 80 | 'streetNumber' => $number, |
||||
| 81 | 'postalCode' => $address['postalCode'] ?? null, |
||||
| 82 | 'locality' => $address['locality'] ?? null, |
||||
| 83 | ]; |
||||
| 84 | } |
||||
| 85 | |||||
| 86 | $country = new Country($countryCode, $countryName); |
||||
| 87 | $coordinates = new Coordinates($lat, $lon); |
||||
| 88 | |||||
| 89 | return new Address($location, $country, $coordinates); |
||||
| 90 | } |
||||
| 91 | |||||
| 92 | /** |
||||
| 93 | * @inheritDoc |
||||
| 94 | */ |
||||
| 95 | public function reverseGeocode($lat, $lon, $params = []) |
||||
| 96 | { |
||||
| 97 | return $this->query("$lat,$lon", $params); |
||||
| 98 | } |
||||
| 99 | |||||
| 100 | /** |
||||
| 101 | * @inheritDoc |
||||
| 102 | */ |
||||
| 103 | public function geocode($address, $params = []) |
||||
| 104 | { |
||||
| 105 | return $this->query($address, $params); |
||||
| 106 | } |
||||
| 107 | } |
||||
| 108 |
This check looks for parameters that have been defined for a function or method, but which are not used in the method body.