diff --git a/src/App/Search.php b/src/App/Search.php index 9ecace0..7b4fa44 100644 --- a/src/App/Search.php +++ b/src/App/Search.php @@ -44,10 +44,13 @@ final class Search $whereParts[] = implode(' AND ', $conditions); } - $sql = "SELECT id, title, teaser_public, description, city, region, zip, starts_at, visibility, allow_kids, location_label, lat, lng, 5 AS distance_km"; $distanceFiltering = false; - if ($hasGeo) { + $sql = "SELECT id, title, teaser_public, description, city, region, zip, starts_at, visibility, allow_kids, location_label, lat, lng, + (6371 * ACOS(LEAST(1, + COS(RADIANS(?)) * COS(RADIANS(lat)) * COS(RADIANS(lng) - RADIANS(?)) + + SIN(RADIANS(?)) * SIN(RADIANS(lat)) + ))) AS distance_km"; $lat = (float)$geo['lat']; $lng = (float)$geo['lng']; $radius = isset($geo['radius']) && is_numeric($geo['radius']) ? max(0.1, (float)$geo['radius']) : 5.0; @@ -58,11 +61,19 @@ final class Search $whereParts[] = "(lat IS NOT NULL AND lng IS NOT NULL)"; $whereParts[] = "(lat BETWEEN ? AND ?)"; $whereParts[] = "(lng BETWEEN ? AND ?)"; + // Haversine params (order must match SQL) + $bind[] = $lat; // COS(RADIANS(?)) + $bind[] = $lng; // COS(RADIANS(lng) - RADIANS(?)) + $bind[] = $lat; // SIN(RADIANS(?)) + // Bounding box $bind[] = $lat - $latRange; $bind[] = $lat + $latRange; $bind[] = $lng - $lngRange; $bind[] = $lng + $lngRange; + // Radius for HAVING $bind[] = $radius; + } else { + $sql = "SELECT id, title, teaser_public, description, city, region, zip, starts_at, visibility, allow_kids, location_label, lat, lng, 30 AS distance_km"; } $where = $whereParts ? ('WHERE ' . implode(' AND ', $whereParts)) : '';