events yogibook
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/bootstrap.php';
|
||||
|
||||
/**
|
||||
* Endpoint pubblico LISTA eventi (sola lettura).
|
||||
* Ritorna gli eventi PUBBLICATI e NON ancora terminati, con posti/prezzo/gallery.
|
||||
*
|
||||
* Parametri (query string):
|
||||
* ?id=12 -> un solo evento
|
||||
* ?ids=12,15,20 -> solo questi eventi (nell'ordine per data)
|
||||
* ?limit=3 -> massimo N eventi
|
||||
* Senza parametri: tutti i pubblicati futuri, per data crescente.
|
||||
*
|
||||
* Regole di visibilità:
|
||||
* status = 'published' AND COALESCE(ends_at, starts_at) >= NOW()
|
||||
* (l'evento sparisce da solo quando è terminato)
|
||||
*/
|
||||
try {
|
||||
$pdo = pdo_conn();
|
||||
|
||||
$id = isset($_GET['id']) ? (int) $_GET['id'] : 0;
|
||||
$idsParam = trim($_GET['ids'] ?? '');
|
||||
$limit = isset($_GET['limit']) ? max(1, min(50, (int) $_GET['limit'])) : 0;
|
||||
|
||||
$where = ["e.status = 'published'", "COALESCE(e.ends_at, e.starts_at) >= NOW()"];
|
||||
$params = [];
|
||||
|
||||
if ($id > 0) {
|
||||
$where[] = 'e.id = ?';
|
||||
$params[] = $id;
|
||||
} elseif ($idsParam !== '') {
|
||||
$ids = array_values(array_filter(array_map('intval', explode(',', $idsParam)), function ($v) {
|
||||
return $v > 0;
|
||||
}));
|
||||
if (!empty($ids)) {
|
||||
$where[] = 'e.id IN (' . implode(',', array_fill(0, count($ids), '?')) . ')';
|
||||
foreach ($ids as $v) {
|
||||
$params[] = $v;
|
||||
}
|
||||
} else {
|
||||
send_json(['ok' => true, 'count' => 0, 'events' => []]);
|
||||
}
|
||||
}
|
||||
|
||||
$sql = "SELECT e.*, u.first_name AS cf, u.last_name AS cl,
|
||||
COALESCE(b.occupied, 0) AS occupied,
|
||||
COALESCE(w.waiting, 0) AS waiting
|
||||
FROM events e
|
||||
LEFT JOIN auth_users u ON u.id = e.user_id
|
||||
LEFT JOIN (
|
||||
SELECT event_id, SUM(seats) AS occupied
|
||||
FROM event_bookings WHERE status IN ('confirmed','pending')
|
||||
GROUP BY event_id
|
||||
) b ON b.event_id = e.id
|
||||
LEFT JOIN (
|
||||
SELECT event_id, SUM(seats) AS waiting
|
||||
FROM event_bookings WHERE status = 'waiting'
|
||||
GROUP BY event_id
|
||||
) w ON w.event_id = e.id
|
||||
WHERE " . implode(' AND ', $where) . "
|
||||
ORDER BY e.starts_at ASC";
|
||||
|
||||
if ($limit > 0) {
|
||||
$sql .= ' LIMIT ' . (int) $limit;
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$symbols = ['EUR' => '€', 'USD' => '$', 'GBP' => '£', 'CHF' => 'CHF'];
|
||||
$events = [];
|
||||
|
||||
foreach ($rows as $r) {
|
||||
$maxSeats = (int) $r['max_seats'];
|
||||
$occupied = (int) $r['occupied'];
|
||||
$remaining = max(0, $maxSeats - $occupied);
|
||||
|
||||
$gallery = [];
|
||||
if (!empty($r['gallery'])) {
|
||||
$g = json_decode($r['gallery'], true);
|
||||
if (is_array($g)) {
|
||||
foreach ($g as $path) {
|
||||
if (is_string($path) && $path !== '') {
|
||||
$gallery[] = public_url($path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$organizer = trim((string) $r['organizer_name']) !== ''
|
||||
? $r['organizer_name']
|
||||
: trim(($r['cf'] ?? '') . ' ' . ($r['cl'] ?? ''));
|
||||
|
||||
$events[] = [
|
||||
'id' => (int) $r['id'],
|
||||
'title' => $r['title'],
|
||||
'slug' => $r['slug'],
|
||||
'description' => $r['description'], // HTML (sanificare al rendering in WP)
|
||||
'instructions' => $r['instructions'],
|
||||
'what_to_bring' => $r['what_to_bring'],
|
||||
'suitable_for' => $r['suitable_for'],
|
||||
'organizer' => $organizer !== '' ? $organizer : null,
|
||||
'starts_at' => $r['starts_at'],
|
||||
'ends_at' => $r['ends_at'],
|
||||
'address' => $r['address'],
|
||||
'lat' => $r['lat'] !== null ? (float) $r['lat'] : null,
|
||||
'lng' => $r['lng'] !== null ? (float) $r['lng'] : null,
|
||||
'cost' => (float) $r['cost'],
|
||||
'currency' => $r['currency'],
|
||||
'currency_symbol' => $symbols[$r['currency']] ?? $r['currency'],
|
||||
'color' => $r['color'],
|
||||
'cover_image' => public_url($r['cover_image']),
|
||||
'gallery' => $gallery,
|
||||
'max_seats' => $maxSeats,
|
||||
'max_per_booking' => (int) $r['max_per_booking'],
|
||||
'occupied' => $occupied,
|
||||
'remaining' => $remaining,
|
||||
'sold_out' => $remaining <= 0,
|
||||
'waitlist_enabled' => ($r['waitlist_enabled'] ?? 'N') === 'Y',
|
||||
'waiting' => (int) $r['waiting'],
|
||||
];
|
||||
}
|
||||
|
||||
send_json(['ok' => true, 'count' => count($events), 'events' => $events]);
|
||||
} catch (Throwable $ex) {
|
||||
error_log('[api/events] ' . $ex->getMessage());
|
||||
send_json(['ok' => false, 'error' => 'Errore nel recupero degli eventi.'], 500);
|
||||
}
|
||||
Reference in New Issue
Block a user