diff --git a/public/class/SchoolMail.php b/public/class/SchoolMail.php
index 26c466d..ee1b07f 100644
--- a/public/class/SchoolMail.php
+++ b/public/class/SchoolMail.php
@@ -8,6 +8,7 @@
* SchoolMail::toStudent($email, $firstname, 'Oggetto', ['riga 1', 'riga 2']);
* SchoolMail::toStudent($email, $firstname, 'Oggetto', $lines, '', $schoolRow, true); // copia alla scuola
* SchoolMail::toMany([['email'=>..,'first_name'=>..], ...], 'Oggetto', $lines); // invio di massa
+ * SchoolMail::sendHtml($email, $nome, 'Oggetto', $htmlCompleto, $schoolRow, $ccEmail); // HTML già pronto
*
* Le righe sono HTML: i dati variabili vanno passati già con htmlspecialchars().
*/
@@ -86,8 +87,48 @@ class SchoolMail
return ['sent' => $sent, 'failed' => $failed];
}
+ /**
+ * Invio di un'email con HTML già composto (es. layout degli eventi).
+ * Funziona anche senza sessione se si passa $school (endpoint pubblici, cron).
+ * $cc: indirizzo in copia (ignorato se non valido o uguale al destinatario).
+ */
+ public static function sendHtml(
+ string $to,
+ string $toName,
+ string $subject,
+ string $html,
+ ?array $school = null,
+ string $cc = ''
+ ): bool {
+ if (!filter_var($to, FILTER_VALIDATE_EMAIL)) {
+ return false;
+ }
+ try {
+ $school = $school ?? SchoolContext::get();
+ $mail = self::mailer($school);
+ $mail->addAddress($to, $toName);
+ if ($cc !== '' && filter_var($cc, FILTER_VALIDATE_EMAIL) && strcasecmp($cc, $to) !== 0) {
+ $mail->addCC($cc, (string) ($school['name'] ?? ''));
+ }
+ $mail->Subject = $subject;
+ $mail->Body = $html;
+ $mail->AltBody = self::htmlToText($html);
+ $mail->send();
+ return true;
+ } catch (\Throwable $e) {
+ error_log('SchoolMail sendHtml error (' . $to . '): ' . $e->getMessage());
+ return false;
+ }
+ }
+
/* ------------------------------------------------------------------ */
+ private static function htmlToText(string $html): string
+ {
+ $text = str_replace(['
', '
', '
', '
', '', ''], "\n", $html);
+ return trim(preg_replace('/\n{3,}/', "\n\n", html_entity_decode(strip_tags($text), ENT_QUOTES, 'UTF-8')));
+ }
+
private static function mailer(array $school): PHPMailer
{
$schoolName = (string) ($school['name'] ?? 'YogiBook');
diff --git a/public/event_form.php b/public/event_form.php
index 46ba911..c8d5fa2 100644
--- a/public/event_form.php
+++ b/public/event_form.php
@@ -1,17 +1,17 @@
nuovo evento
- * - event_form.php?id=123 -> modifica evento esistente
+ * - event_form.php?id=123 -> modifica evento esistente (solo se della scuola)
* Invia a event_save.php (insert/update + redirect).
*
- * Extra rispetto alla v1:
* - flatpickr per data/ora (fine = inizio + 1h automatica)
- * - sede da event_locations (default scuola) o indirizzo personalizzato
+ * - sede da event_locations della scuola (default) o indirizzo personalizzato
* - "Calcola coordinate" da indirizzo (geocoding via event_geocode.php)
- * - copertina drag&drop -> event_upload_cover.php -> assets/uploads/events/
+ * - copertina drag&drop -> event_upload_cover.php
*/
$pdo = DBHandlerSelect::getInstance()->getConnection();
@@ -24,8 +24,8 @@ $id = isset($_GET['id']) ? (int) $_GET['id'] : 0;
$ev = null;
if ($id > 0) {
- $stmt = $pdo->prepare("SELECT * FROM events WHERE id = ?");
- $stmt->execute([$id]);
+ $stmt = $pdo->prepare("SELECT * FROM events WHERE id = ? AND idschool = ?");
+ $stmt->execute([$id, $idschool]);
$ev = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$ev) {
header('Location: events.php?message=error');
@@ -33,19 +33,21 @@ if ($id > 0) {
}
}
-// Default dal record unico di `option`
-$opt = $pdo->query("SELECT * FROM `option` LIMIT 1")->fetch(PDO::FETCH_ASSOC);
-$defaultColor = $opt['event_default_color'] ?? '#4CAF50';
-$defaultMaxPerBooking = (int) ($opt['event_default_max_per_booking'] ?? 1);
-$defReminderEnabled = ($opt['event_reminder_enabled'] ?? 'N') === 'Y';
-$defReminderHours = (int) ($opt['event_reminder_hours'] ?? 24);
-$defOfferHours = (int) ($opt['event_offer_expiry_hours'] ?? 24);
+// Default dalle impostazioni della scuola
+$defaultColor = (string) SchoolSettings::get('event_default_color', '#4CAF50');
+$defaultMaxPerBooking = (int) SchoolSettings::get('event_default_max_per_booking', 1);
+$defReminderEnabled = SchoolSettings::get('event_reminder_enabled', 'N') === 'Y';
+$defReminderHours = (int) SchoolSettings::get('event_reminder_hours', 24);
+$defOfferHours = (int) SchoolSettings::get('event_offer_expiry_hours', 24);
-// Sedi salvate (se la tabella non esiste ancora, si degrada su indirizzo libero)
+// Sedi salvate della scuola (se la query fallisce si degrada su indirizzo libero)
$locations = [];
try {
- $locations = $pdo->query("SELECT * FROM event_locations ORDER BY is_default DESC, name ASC")->fetchAll(PDO::FETCH_ASSOC);
-} catch (Throwable $e) {
+ $st = $pdo->prepare("SELECT * FROM event_locations WHERE idschool = ? ORDER BY is_default DESC, name ASC");
+ $st->execute([$idschool]);
+ $locations = $st->fetchAll(PDO::FETCH_ASSOC);
+} catch (PDOException $ex) {
+ error_log('[event_form] sedi: ' . $ex->getMessage());
$locations = [];
}
diff --git a/public/event_save.php b/public/event_save.php
index 7015048..23b653d 100644
--- a/public/event_save.php
+++ b/public/event_save.php
@@ -1,9 +1,11 @@
getConnection();
-// --- ID insegnante loggato -------------------------------------------------
-// headscript.php popola $iduserlogin da Auth::user()->present()->id
-$currentUserId = $iduserlogin ?? ($_SESSION['iduserlogin'] ?? null);
-
// --- Helper ----------------------------------------------------------------
function slugify(string $text): string
{
@@ -32,18 +30,14 @@ function slugify(string $text): string
return $text !== '' ? $text : 'evento';
}
-function uniqueSlug(PDO $pdo, string $base, int $excludeId): string
+/** Slug unico all'interno della scuola (esclude l'evento in modifica) */
+function uniqueSlug(PDO $pdo, string $base, int $excludeId, int $idschool): string
{
+ $st = $pdo->prepare("SELECT COUNT(*) FROM events WHERE slug = ? AND idschool = ? AND id <> ?");
$slug = $base;
$i = 2;
while (true) {
- if ($excludeId > 0) {
- $st = $pdo->prepare("SELECT COUNT(*) FROM events WHERE slug = ? AND id <> ?");
- $st->execute([$slug, $excludeId]);
- } else {
- $st = $pdo->prepare("SELECT COUNT(*) FROM events WHERE slug = ?");
- $st->execute([$slug]);
- }
+ $st->execute([$slug, $idschool, $excludeId]);
if ((int) $st->fetchColumn() === 0) {
return $slug;
}
@@ -63,9 +57,15 @@ function toDateTime(?string $v): ?string
}
// --- Lettura e validazione input -------------------------------------------
-$id = isset($_POST['id']) ? (int) $_POST['id'] : 0;
-$title = trim($_POST['title'] ?? '');
+$id = isset($_POST['id']) ? (int) $_POST['id'] : 0;
+// In modifica l'evento deve appartenere alla scuola corrente
+if ($id > 0 && !SchoolScope::belongs('events', $id)) {
+ header('Location: events.php?message=error');
+ exit();
+}
+
+$title = trim($_POST['title'] ?? '');
$startsAt = toDateTime($_POST['starts_at'] ?? null);
$maxSeats = (int) ($_POST['max_seats'] ?? 0);
@@ -77,7 +77,7 @@ if ($title === '' || $startsAt === null || $maxSeats < 1) {
$slugInput = trim($_POST['slug'] ?? '');
$slugBase = slugify($slugInput !== '' ? $slugInput : $title);
-$slug = uniqueSlug($pdo, $slugBase, $id);
+$slug = uniqueSlug($pdo, $slugBase, $id, $idschool);
$endsAt = toDateTime($_POST['ends_at'] ?? null);
$address = trim($_POST['address'] ?? '');
@@ -121,7 +121,7 @@ $suitableFor = trim($_POST['suitable_for'] ?? '');
$waitlistEnabled = (isset($_POST['waitlist_enabled']) && $_POST['waitlist_enabled'] === 'Y') ? 'Y' : 'N';
-// Override per-evento (NULL = usa default scuola)
+// Override per evento (NULL = usa default scuola)
$reminderEnabled = (isset($_POST['reminder_enabled']) && in_array($_POST['reminder_enabled'], ['Y', 'N'], true)) ? $_POST['reminder_enabled'] : null;
$reminderHours = (($_POST['reminder_hours'] ?? '') !== '') ? max(1, min(168, (int) $_POST['reminder_hours'])) : null;
$offerHours = (($_POST['offer_expiry_hours'] ?? '') !== '') ? max(1, min(336, (int) $_POST['offer_expiry_hours'])) : null;
@@ -154,52 +154,52 @@ try {
waitlist_enabled = :waitlist_enabled,
reminder_enabled = :reminder_enabled, reminder_hours = :reminder_hours, offer_expiry_hours = :offer_expiry_hours,
cover_image = :cover_image, gallery = :gallery, status = :status, publish_at = :publish_at, updated_at = NOW()
- WHERE id = :id";
- $params = [':id' => $id];
+ WHERE id = :id AND idschool = :idschool";
+ $params = [':id' => $id, ':idschool' => $idschool];
} else {
$sql = "INSERT INTO events
- (user_id, title, slug, description, instructions, what_to_bring, suitable_for,
+ (idschool, user_id, title, slug, description, instructions, what_to_bring, suitable_for,
organizer_name, starts_at, ends_at,
address, lat, lng, cost, currency, max_seats, max_per_booking, color,
waitlist_enabled,
reminder_enabled, reminder_hours, offer_expiry_hours,
cover_image, gallery, status, publish_at, created_at, updated_at)
VALUES
- (:user_id, :title, :slug, :description, :instructions, :what_to_bring, :suitable_for,
+ (:idschool, :user_id, :title, :slug, :description, :instructions, :what_to_bring, :suitable_for,
:organizer_name, :starts_at, :ends_at,
:address, :lat, :lng, :cost, :currency, :max_seats, :max_per_booking, :color,
:waitlist_enabled,
:reminder_enabled, :reminder_hours, :offer_expiry_hours,
:cover_image, :gallery, :status, :publish_at, NOW(), NOW())";
- $params = [':user_id' => $currentUserId];
+ $params = [':idschool' => $idschool, ':user_id' => (int) $iduserlogin];
}
$params += [
- ':title' => $title,
- ':slug' => $slug,
- ':description' => $description !== '' ? $description : null,
- ':instructions' => $instructions !== '' ? $instructions : null,
- ':what_to_bring' => $whatToBring !== '' ? $whatToBring : null,
- ':suitable_for' => $suitableFor !== '' ? $suitableFor : null,
- ':organizer_name' => $organizer !== '' ? $organizer : null,
- ':starts_at' => $startsAt,
- ':ends_at' => $endsAt,
- ':address' => $address !== '' ? $address : null,
- ':lat' => $lat,
- ':lng' => $lng,
- ':cost' => $cost,
- ':currency' => $currency,
- ':max_seats' => $maxSeats,
- ':max_per_booking' => $maxPerBooking,
- ':waitlist_enabled' => $waitlistEnabled,
- ':reminder_enabled' => $reminderEnabled,
- ':reminder_hours' => $reminderHours,
+ ':title' => $title,
+ ':slug' => $slug,
+ ':description' => $description !== '' ? $description : null,
+ ':instructions' => $instructions !== '' ? $instructions : null,
+ ':what_to_bring' => $whatToBring !== '' ? $whatToBring : null,
+ ':suitable_for' => $suitableFor !== '' ? $suitableFor : null,
+ ':organizer_name' => $organizer !== '' ? $organizer : null,
+ ':starts_at' => $startsAt,
+ ':ends_at' => $endsAt,
+ ':address' => $address !== '' ? $address : null,
+ ':lat' => $lat,
+ ':lng' => $lng,
+ ':cost' => $cost,
+ ':currency' => $currency,
+ ':max_seats' => $maxSeats,
+ ':max_per_booking' => $maxPerBooking,
+ ':waitlist_enabled' => $waitlistEnabled,
+ ':reminder_enabled' => $reminderEnabled,
+ ':reminder_hours' => $reminderHours,
':offer_expiry_hours' => $offerHours,
- ':color' => $color,
- ':cover_image' => $coverImage !== '' ? $coverImage : null,
- ':gallery' => $gallery,
- ':publish_at' => $publishAt,
- ':status' => $status,
+ ':color' => $color,
+ ':cover_image' => $coverImage !== '' ? $coverImage : null,
+ ':gallery' => $gallery,
+ ':publish_at' => $publishAt,
+ ':status' => $status,
];
$stmt = $pdo->prepare($sql);
@@ -207,7 +207,7 @@ try {
header('Location: events.php?message=success');
exit();
-} catch (Throwable $ex) {
+} catch (PDOException $ex) {
error_log('[event_save] ' . $ex->getMessage());
header("Location: {$redirectOnError}");
exit();
diff --git a/public/events.php b/public/events.php
index a3a23d5..4b76f8b 100644
--- a/public/events.php
+++ b/public/events.php
@@ -1,8 +1,9 @@
event_participants.php
* - Modifica -> event_form.php?id=
@@ -31,18 +32,23 @@ $sql = "SELECT e.*,
SUM(seats) AS booked,
COUNT(*) AS bookings_count
FROM event_bookings
- WHERE status IN ('confirmed','pending','offered')
+ WHERE idschool = ?
+ AND status IN ('confirmed','pending','offered')
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'
+ WHERE idschool = ?
+ AND status = 'waiting'
GROUP BY event_id
) w ON w.event_id = e.id
LEFT JOIN auth_users u ON u.id = e.user_id
+ WHERE e.idschool = ?
ORDER BY e.starts_at ASC";
-$events = $pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC);
+$st = $pdo->prepare($sql);
+$st->execute([$idschool, $idschool, $idschool]);
+$events = $st->fetchAll(PDO::FETCH_ASSOC);
$mesi = [
1 => 'gennaio',
@@ -87,7 +93,7 @@ function statusBadge(string $status): array
YogiBook - Eventi
-
+
diff --git a/public/include/event_mailer.php b/public/include/event_mailer.php
index 40d3368..ba589bd 100644
--- a/public/include/event_mailer.php
+++ b/public/include/event_mailer.php
@@ -1,299 +1,71 @@
le prenotazioni promosse (per inviare le email)
*/
+if (!function_exists('promoteFromWaitlist')) {
+ function promoteFromWaitlist(PDO $pdo, int $eventId): array
+ {
+ $ev = $pdo->prepare("SELECT max_seats, idschool FROM events WHERE id = ?");
+ $ev->execute([$eventId]);
+ $event = $ev->fetch(PDO::FETCH_ASSOC);
+ if (!$event) {
+ return [];
+ }
+ $maxSeats = (int) $event['max_seats'];
+ $idschool = (int) $event['idschool'];
+ if ($maxSeats <= 0 || $idschool <= 0) {
+ return [];
+ }
-// Assicura l'autoload (di norma già caricato da db-functions.php)
-if (!class_exists('PHPMailer\\PHPMailer\\PHPMailer')) {
- $__al = dirname(__DIR__, 2) . '/vendor/autoload.php';
- if (is_file($__al)) {
- require_once $__al;
- }
-}
+ $os = $pdo->prepare("SELECT COALESCE(SUM(seats),0) FROM event_bookings
+ WHERE event_id = ? AND idschool = ?
+ AND status IN ('confirmed','pending','offered')");
+ $os->execute([$eventId, $idschool]);
+ $free = $maxSeats - (int) $os->fetchColumn();
+ if ($free <= 0) {
+ return [];
+ }
-if (!defined('YB_PUBLIC_BASE')) {
- define('YB_PUBLIC_BASE', 'https://yogibook.yogasoul.it/');
-}
+ $ws = $pdo->prepare("SELECT * FROM event_bookings
+ WHERE event_id = ? AND idschool = ? AND status = 'waiting'
+ ORDER BY created_at ASC, id ASC");
+ $ws->execute([$eventId, $idschool]);
+ $waiting = $ws->fetchAll(PDO::FETCH_ASSOC);
-/* ---------- Opzioni ---------- */
-function yse_mail_options(): array
-{
- static $opt = null;
- if ($opt !== null) {
- return $opt;
- }
- $row = [];
- try {
- $pdo = DBHandlerSelect::getInstance()->getConnection();
- $row = $pdo->query("SELECT * FROM `option` LIMIT 1")->fetch(PDO::FETCH_ASSOC) ?: [];
- } catch (Throwable $e) {
- $row = [];
- }
- $opt = [
- 'cc_email' => trim((string) ($row['event_notify_email'] ?? '')),
- 'cc' => [
- 'booking' => ($row['event_cc_booking'] ?? 'N') === 'Y',
- 'user_cancel' => ($row['event_cc_user_cancel'] ?? 'N') === 'Y',
- 'event_cancel' => ($row['event_cc_event_cancel'] ?? 'N') === 'Y',
- 'reminder' => ($row['event_cc_reminder'] ?? 'N') === 'Y',
- 'promotion' => ($row['event_cc_promotion'] ?? 'N') === 'Y',
- ],
- ];
- return $opt;
-}
-
-/* ---------- Invio base ---------- */
-function yse_send(string $to, string $toName, string $subject, string $html, bool $ccSchool): bool
-{
- $env = $_ENV;
- try {
- $mail = new \PHPMailer\PHPMailer\PHPMailer(true);
- $mail->isSMTP();
- $mail->Host = $env['MAIL_HOST'] ?? '';
- $mail->SMTPAuth = true;
- $mail->Username = $env['MAIL_USERNAME'] ?? '';
- $mail->Password = $env['MAIL_PASSWORD'] ?? '';
- $enc = strtolower($env['MAIL_ENCRYPTION'] ?? 'ssl');
- $mail->SMTPSecure = ($enc === 'tls')
- ? \PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_STARTTLS
- : \PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_SMTPS;
- $mail->Port = (int) ($env['MAIL_PORT'] ?? 465);
- $mail->CharSet = 'UTF-8';
-
- $mail->setFrom($env['MAIL_FROM_ADDRESS'] ?? 'info@yogasoul.it', $env['MAIL_FROM_NAME'] ?? 'YogiBook');
- $mail->addAddress($to, $toName);
-
- if ($ccSchool) {
- $ccEmail = yse_mail_options()['cc_email'];
- if ($ccEmail !== '' && strcasecmp($ccEmail, $to) !== 0) {
- $mail->addCC($ccEmail);
+ $promoted = [];
+ // Promozione = "offerta": tiene il posto ma richiede riconferma (confirm.php)
+ $upd = $pdo->prepare("UPDATE event_bookings
+ SET status = 'offered', offered_at = NOW(), updated_at = NOW()
+ WHERE id = ? AND idschool = ?");
+ foreach ($waiting as $w) {
+ $need = (int) $w['seats'];
+ if ($need <= $free) {
+ $upd->execute([$w['id'], $idschool]);
+ $free -= $need;
+ $w['status'] = 'offered';
+ $promoted[] = $w;
+ if ($free <= 0) {
+ break;
+ }
+ } else {
+ break; // rispetta la coda
}
}
-
- $mail->isHTML(true);
- $mail->Subject = $subject;
- $mail->Body = $html;
- $mail->AltBody = trim(preg_replace(
- '/\n{3,}/',
- "\n\n",
- strip_tags(str_replace(['', '
', '
', '
', ''], "\n", $html))
- ));
-
- return $mail->send();
- } catch (Throwable $e) {
- error_log('[event mail] ' . $e->getMessage());
- return false;
+ return $promoted;
}
}
-
-/* ---------- Helper contenuto ---------- */
-function yse_h($v): string
-{
- return htmlspecialchars((string) $v, ENT_QUOTES, 'UTF-8');
-}
-
-function yse_fmt_datetime(array $event): string
-{
- $mesi = [
- 1 => 'gennaio',
- 2 => 'febbraio',
- 3 => 'marzo',
- 4 => 'aprile',
- 5 => 'maggio',
- 6 => 'giugno',
- 7 => 'luglio',
- 8 => 'agosto',
- 9 => 'settembre',
- 10 => 'ottobre',
- 11 => 'novembre',
- 12 => 'dicembre'
- ];
- $t = strtotime($event['starts_at']);
- $s = (int) date('j', $t) . ' ' . $mesi[(int) date('n', $t)] . ' ' . date('Y', $t) . ' · ' . date('H:i', $t);
- if (!empty($event['ends_at'])) {
- $s .= '–' . date('H:i', strtotime($event['ends_at']));
- }
- return $s;
-}
-
-function yse_maps_link(array $event): string
-{
- $q = trim((string) ($event['address'] ?? ''));
- if ($q === '' && !empty($event['lat']) && !empty($event['lng'])) {
- $q = $event['lat'] . ',' . $event['lng'];
- }
- return $q !== '' ? 'https://www.google.com/maps/search/?api=1&query=' . rawurlencode($q) : '';
-}
-
-function yse_event_info_block(array $event): string
-{
- $accent = (isset($event['color']) && preg_match('/^#[0-9a-fA-F]{6}$/', $event['color'])) ? $event['color'] : '#4CAF50';
- $when = yse_h(yse_fmt_datetime($event));
- $addr = trim((string) ($event['address'] ?? ''));
- $maps = yse_maps_link($event);
-
- $rows = '| Quando | ' . $when . ' |
';
- if ($addr !== '') {
- $mapsLink = $maps !== '' ? ' apri mappa' : '';
- $rows .= '| Dove | ' . yse_h($addr) . $mapsLink . ' |
';
- }
-
- $info = '';
- foreach ([['suitable_for', 'Per chi è adatto'], ['what_to_bring', 'Cosa portare'], ['instructions', 'Istruzioni']] as $f) {
- $val = trim((string) ($event[$f[0]] ?? ''));
- if ($val !== '') {
- $info .= '' . $f[1] . ':
' . nl2br(yse_h($val)) . '
';
- }
- }
-
- $html = '';
- if ($info !== '') {
- $html .= '' . $info . '
';
- }
- return $html;
-}
-
-function yse_email_layout(array $event, string $heading, string $bodyHtml): string
-{
- $accent = (isset($event['color']) && preg_match('/^#[0-9a-fA-F]{6}$/', $event['color'])) ? $event['color'] : '#4CAF50';
- $from = $_ENV['MAIL_FROM_NAME'] ?? 'YogaSoul';
- $title = yse_h($event['title'] ?? '');
- return '
-
-
-
- |
- |
- ' . yse_h($from) . '
- ' . $heading . '
- ' . $title . '
- |
- | ' . $bodyHtml . ' |
- | Questa email è stata inviata da ' . yse_h($from) . '. |
-
- |
-
';
-}
-
-function yse_button(string $url, string $label, string $accent): string
-{
- return '' . yse_h($label) . '';
-}
-
-function yse_cancel_url(array $booking): string
-{
- return YB_PUBLIC_BASE . 'apiwp/cancel.php?token=' . rawurlencode($booking['token']);
-}
-
-function yse_confirm_url(array $booking): string
-{
- return YB_PUBLIC_BASE . 'apiwp/confirm.php?token=' . rawurlencode($booking['token']);
-}
-
-/* ---------- Builder per tipo ---------- */
-
-/** A) Prenotazione (confermata o lista d'attesa) */
-function yse_mail_booking(array $booking, array $event): bool
-{
- $accent = $event['color'] ?? '#4CAF50';
- $waiting = ($booking['status'] ?? '') === 'waiting';
- $parts = explode(' ', trim($booking['name']));
- $name = $parts[0] ?? '';
-
- if ($waiting) {
- $heading = "Sei in lista d'attesa";
- $intro = 'Ciao ' . yse_h($name) . ", ti abbiamo messo in lista d'attesa per questo evento. Ti avviseremo appena si libera un posto.
";
- } else {
- $heading = 'Prenotazione confermata';
- $intro = 'Ciao ' . yse_h($name) . ', la tua prenotazione è confermata. Ecco i dettagli:
';
- }
-
- $body = $intro;
- $body .= yse_event_info_block($event);
- $body .= 'Posti prenotati: ' . (int) $booking['seats'] . '
';
- $body .= 'Se non puoi più partecipare, puoi annullare qui:
';
- $body .= '' . yse_button(yse_cancel_url($booking), 'Annulla prenotazione', $accent) . '
';
-
- $subject = ($waiting ? "Lista d'attesa: " : 'Prenotazione confermata: ') . $event['title'];
- $html = yse_email_layout($event, $heading, $body);
- return yse_send($booking['email'], $booking['name'], $subject, $html, yse_mail_options()['cc']['booking']);
-}
-
-/** B) Disdetta fatta dall'utente */
-function yse_mail_user_cancel(array $booking, array $event): bool
-{
- $parts = explode(' ', trim($booking['name']));
- $name = $parts[0] ?? '';
- $body = 'Ciao ' . yse_h($name) . ', la tua prenotazione per questo evento è stata annullata.
';
- $body .= yse_event_info_block($event);
- $body .= 'Ci dispiace non vederti questa volta. A presto!
';
-
- $subject = 'Prenotazione annullata: ' . $event['title'];
- $html = yse_email_layout($event, 'Prenotazione annullata', $body);
- return yse_send($booking['email'], $booking['name'], $subject, $html, yse_mail_options()['cc']['user_cancel']);
-}
-
-/** C) Evento annullato dall'insegnante (a ciascun iscritto) */
-function yse_mail_event_cancel(array $booking, array $event): bool
-{
- $parts = explode(' ', trim($booking['name']));
- $name = $parts[0] ?? '';
- $body = 'Ciao ' . yse_h($name) . ", ci dispiace: l'evento è stato annullato.
";
- $body .= yse_event_info_block($event);
- $body .= 'La tua prenotazione è stata annullata automaticamente. Per informazioni, rispondi pure a questa email.
';
-
- $subject = 'Evento annullato: ' . $event['title'];
- $html = yse_email_layout($event, 'Evento annullato', $body);
- return yse_send($booking['email'], $booking['name'], $subject, $html, yse_mail_options()['cc']['event_cancel']);
-}
-
-/** E) Promozione da lista d'attesa — con RICONFERMA */
-function yse_mail_promotion(array $booking, array $event): bool
-{
- $accent = $event['color'] ?? '#4CAF50';
- $parts = explode(' ', trim($booking['name']));
- $name = $parts[0] ?? '';
- $body = 'Ciao ' . yse_h($name) . ", buone notizie: si è liberato un posto e tocca a te!
";
- $body .= yse_event_info_block($event);
- $body .= 'Conferma entro breve per tenere il posto:
';
- $body .= '' . yse_button(yse_confirm_url($booking), 'Confermo, ci sarò', $accent) . '
';
- $body .= 'Se non puoi partecipare, annulla qui così offriamo il posto a un\'altra persona.
';
-
- $subject = 'Si è liberato un posto: ' . $event['title'];
- $html = yse_email_layout($event, 'Un posto per te', $body);
- return yse_send($booking['email'], $booking['name'], $subject, $html, yse_mail_options()['cc']['promotion']);
-}
-
-/** D) Promemoria prima dell'evento (testo e punto di ritrovo opzionali) */
-function yse_mail_reminder(array $booking, array $event, string $message = '', string $meetingLink = ''): bool
-{
- $accent = $event['color'] ?? '#4CAF50';
- $parts = explode(' ', trim($booking['name']));
- $name = $parts[0] ?? '';
- $note = $message !== '' ? nl2br(yse_h($message)) : 'Ti ricordiamo il tuo prossimo appuntamento.';
-
- $body = 'Ciao ' . yse_h($name) . ',
' . $note . '
';
- $body .= yse_event_info_block($event);
- if ($meetingLink !== '') {
- $body .= 'Punto di ritrovo: apri la posizione sulla mappa
';
- }
- $body .= 'Se non puoi più partecipare, avvisaci annullando:
';
- $body .= '' . yse_button(yse_cancel_url($booking), 'Annulla prenotazione', $accent) . '
';
-
- $subject = 'Promemoria: ' . $event['title'];
- $html = yse_email_layout($event, 'Ci vediamo presto', $body);
- return yse_send($booking['email'], $booking['name'], $subject, $html, yse_mail_options()['cc']['reminder']);
-}