fox/app/Http/Controllers/FoxCitiesController.php

86 lines
3.0 KiB
PHP

<?php
namespace App\Http\Controllers;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
/**
* City-Lookup via Google Geocoding. Wenn nur ein Treffer → direkt flyTo.
* Wenn mehrere (z.B. "Linz" Österreich vs Pennsylvania) → array für User-Auswahl.
*/
class FoxCitiesController
{
public function __invoke(Request $request): JsonResponse
{
$request->validate([
'query' => 'required|string|max:120',
]);
$key = config('services.google.maps_key');
if (empty($key)) {
return response()->json(['error' => 'no_key'], 503);
}
$query = $request->string('query')->toString();
try {
$response = Http::timeout(8)->get('https://maps.googleapis.com/maps/api/geocode/json', [
'address' => $query,
'language' => 'de',
'key' => $key,
]);
if (! $response->successful()) {
return response()->json(['error' => 'api_error', 'status' => $response->status()], 502);
}
$data = $response->json();
if (($data['status'] ?? null) !== 'OK' || empty($data['results'])) {
return response()->json(['results' => []], 200);
}
// Nur Städte/Ortschaften behalten — keine POI/Adressen
$cityTypes = ['locality', 'administrative_area_level_1', 'administrative_area_level_2', 'political'];
$candidates = [];
foreach ($data['results'] as $r) {
$types = $r['types'] ?? [];
if (! array_intersect($cityTypes, $types)) {
continue;
}
$components = $r['address_components'] ?? [];
$country = '';
$region = '';
foreach ($components as $c) {
if (in_array('country', $c['types'] ?? [], true)) {
$country = $c['long_name'] ?? '';
}
if (in_array('administrative_area_level_1', $c['types'] ?? [], true)) {
$region = $c['long_name'] ?? '';
}
}
$candidates[] = [
'name' => $r['address_components'][0]['long_name'] ?? $query,
'formatted' => $r['formatted_address'] ?? '',
'country' => $country,
'region' => $region,
'lat' => $r['geometry']['location']['lat'] ?? null,
'lng' => $r['geometry']['location']['lng'] ?? null,
];
if (count($candidates) >= 5) {
break;
}
}
return response()->json(['results' => $candidates]);
} catch (\Throwable $e) {
Log::warning('Cities lookup exception', ['e' => $e->getMessage()]);
return response()->json(['error' => 'exception'], 500);
}
}
}