128 lines
5.2 KiB
PHP
128 lines
5.2 KiB
PHP
<?php
|
|
require_once __DIR__ . '/bootstrap.php';
|
|
require_once dirname(__DIR__) . '/include/event_waitlist.php';
|
|
require_once dirname(__DIR__) . '/include/event_mailer.php';
|
|
|
|
/**
|
|
* CRON unico del modulo Eventi. Da richiamare periodicamente (es. ogni 10 min).
|
|
* Protezione: chiave segreta in .env (YSE_CRON_KEY) passata come ?key=...
|
|
*
|
|
* Fa tre cose a ogni giro:
|
|
* 1) Pubblica gli eventi programmati arrivati alla data di apertura.
|
|
* 2) Invia i promemoria automatici (ore effettive per-evento o default), 1 sola volta.
|
|
* 3) Applica la scadenza delle offerte lista d'attesa (offered non riconfermati):
|
|
* li annulla e offre il posto al prossimo in coda (email E).
|
|
*/
|
|
|
|
$pdo = pdo_conn(); // carica anche il .env (per la chiave e le MAIL_*)
|
|
|
|
$expected = $_ENV['YSE_CRON_KEY'] ?? '';
|
|
$provided = (string) ($_GET['key'] ?? '');
|
|
if ($expected === '' || !hash_equals($expected, $provided)) {
|
|
send_json(['ok' => false, 'error' => 'Forbidden'], 403);
|
|
}
|
|
|
|
$report = ['published' => 0, 'reminders' => 0, 'offers_expired' => 0, 'promoted' => 0];
|
|
|
|
// Default scuola
|
|
$opt = [];
|
|
try {
|
|
$opt = $pdo->query("SELECT * FROM `option` LIMIT 1")->fetch(PDO::FETCH_ASSOC) ?: [];
|
|
} catch (Throwable $e) {
|
|
$opt = [];
|
|
}
|
|
$defRemEnabled = ($opt['event_reminder_enabled'] ?? 'N') === 'Y';
|
|
$defRemHours = (int) ($opt['event_reminder_hours'] ?? 24);
|
|
$defOfferHours = (int) ($opt['event_offer_expiry_hours'] ?? 24);
|
|
|
|
/* 1) Pubblica gli eventi programmati arrivati a scadenza */
|
|
try {
|
|
$pub = $pdo->prepare("UPDATE events SET status = 'published', updated_at = NOW()
|
|
WHERE status = 'scheduled' AND publish_at IS NOT NULL AND publish_at <= NOW()");
|
|
$pub->execute();
|
|
$report['published'] = $pub->rowCount();
|
|
} catch (Throwable $e) {
|
|
error_log('[cron publish] ' . $e->getMessage());
|
|
}
|
|
|
|
/* 2) Promemoria automatici (una sola volta per evento) */
|
|
try {
|
|
$evs = $pdo->query("SELECT * FROM events
|
|
WHERE status = 'published' AND reminder_sent_at IS NULL AND starts_at > NOW()")
|
|
->fetchAll(PDO::FETCH_ASSOC);
|
|
foreach ($evs as $ev) {
|
|
$enabled = $ev['reminder_enabled'] !== null ? ($ev['reminder_enabled'] === 'Y') : $defRemEnabled;
|
|
if (!$enabled) {
|
|
continue;
|
|
}
|
|
$hours = $ev['reminder_hours'] !== null ? (int) $ev['reminder_hours'] : $defRemHours;
|
|
if (strtotime($ev['starts_at']) - $hours * 3600 > time()) {
|
|
continue; // non ancora l'ora del promemoria
|
|
}
|
|
$ps = $pdo->prepare("SELECT * FROM event_bookings WHERE event_id = ? AND status = 'confirmed'");
|
|
$ps->execute([$ev['id']]);
|
|
foreach ($ps->fetchAll(PDO::FETCH_ASSOC) as $p) {
|
|
try {
|
|
yse_mail_reminder($p, $ev);
|
|
$report['reminders']++;
|
|
} catch (Throwable $me) {
|
|
error_log('[cron reminder] ' . $me->getMessage());
|
|
}
|
|
}
|
|
$pdo->prepare("UPDATE events SET reminder_sent_at = NOW() WHERE id = ?")->execute([$ev['id']]);
|
|
}
|
|
} catch (Throwable $e) {
|
|
error_log('[cron reminders] ' . $e->getMessage());
|
|
}
|
|
|
|
/* 3) Scadenza offerte lista d'attesa */
|
|
try {
|
|
$offers = $pdo->query("SELECT b.*, e.offer_expiry_hours AS ev_offer_hours
|
|
FROM event_bookings b JOIN events e ON e.id = b.event_id
|
|
WHERE b.status = 'offered' AND b.offered_at IS NOT NULL")
|
|
->fetchAll(PDO::FETCH_ASSOC);
|
|
foreach ($offers as $o) {
|
|
$hours = $o['ev_offer_hours'] !== null ? (int) $o['ev_offer_hours'] : $defOfferHours;
|
|
if (strtotime($o['offered_at']) + $hours * 3600 > time()) {
|
|
continue; // offerta ancora valida
|
|
}
|
|
$promoted = [];
|
|
try {
|
|
$pdo->beginTransaction();
|
|
$pdo->prepare("SELECT id FROM events WHERE id = ? FOR UPDATE")->execute([(int) $o['event_id']]);
|
|
$st = $pdo->prepare("SELECT status FROM event_bookings WHERE id = ?");
|
|
$st->execute([(int) $o['id']]);
|
|
if ($st->fetchColumn() === 'offered') {
|
|
$pdo->prepare("UPDATE event_bookings SET status = 'cancelled', updated_at = NOW() WHERE id = ?")
|
|
->execute([(int) $o['id']]);
|
|
$promoted = promoteFromWaitlist($pdo, (int) $o['event_id']);
|
|
$report['offers_expired']++;
|
|
}
|
|
$pdo->commit();
|
|
|
|
if (!empty($promoted)) {
|
|
$ev = $pdo->prepare("SELECT * FROM events WHERE id = ?");
|
|
$ev->execute([(int) $o['event_id']]);
|
|
$evRow = $ev->fetch(PDO::FETCH_ASSOC);
|
|
foreach ($promoted as $pr) {
|
|
try {
|
|
yse_mail_promotion($pr, $evRow);
|
|
$report['promoted']++;
|
|
} catch (Throwable $pe) {
|
|
error_log('[cron promo] ' . $pe->getMessage());
|
|
}
|
|
}
|
|
}
|
|
} catch (Throwable $te) {
|
|
if ($pdo->inTransaction()) {
|
|
$pdo->rollBack();
|
|
}
|
|
error_log('[cron offer] ' . $te->getMessage());
|
|
}
|
|
}
|
|
} catch (Throwable $e) {
|
|
error_log('[cron offers] ' . $e->getMessage());
|
|
}
|
|
|
|
send_json(['ok' => true, 'report' => $report, 'at' => date('c')]);
|