getConnection(); // -------------------------------------------------------------------------- // Impostazioni: per le lezioni c'e' una sola riga (daysbefore = 0) // -------------------------------------------------------------------------- $impostazioni = pushSettings($db, 'lesson'); if (!$impostazioni) { scriviLog($logFile, 'Nessuna impostazione attiva per le lezioni, esco.'); exit; } $impostazione = $impostazioni[0]; $oraPrevista = (int) substr((string) $impostazione['sendhour'], 0, 2); if (!$forza && (int) date('G') !== $oraPrevista) { // Non e' l'ora giusta: usciamo in silenzio (il cron gira ogni ora). exit; } $giorno = date('Y-m-d'); scriviLog($logFile, "Avvio invio lezioni del $giorno (ora impostata {$impostazione['sendhour']})."); // -------------------------------------------------------------------------- // Lezioni di oggi. // Stessi filtri usati da userpanel.php / api/my_lessons.php per le lezioni // valide: status 'booked', non perse, non scadute. // -------------------------------------------------------------------------- $stmt = $db->prepare(" SELECT bc.idbookingclass, bc.iduser, ss.dateschedule, s.servicename, u.first_name, u.last_name FROM bookingclass bc INNER JOIN serviceschedule ss ON bc.idserviceschedule = ss.idserviceschedule INNER JOIN auth_users u ON bc.iduser = u.id LEFT JOIN service s ON bc.idservice = s.idservice WHERE bc.status = 'booked' AND bc.lostlesson = 'N' AND bc.expirylesson = 'N' AND DATE(ss.dateschedule) = :giorno AND u.pushnotification = 'Y' AND u.status = 'Active' ORDER BY bc.iduser ASC, ss.dateschedule ASC "); $stmt->execute([':giorno' => $giorno]); $lezioni = $stmt->fetchAll(PDO::FETCH_ASSOC); // -------------------------------------------------------------------------- // Raggruppiamo per utente: una notifica a testa, non una per lezione. // Le lezioni gia' notificate (rilancio manuale dello script) vengono escluse; // se per un utente non ne resta nessuna, l'utente viene saltato del tutto. // -------------------------------------------------------------------------- $perUtente = []; foreach ($lezioni as $lezione) { $iduser = (int) $lezione['iduser']; if (pushGiaInviata($db, $iduser, 'lesson', (int) $lezione['idbookingclass'], 0)) { continue; } $perUtente[$iduser][] = $lezione; } scriviLog($logFile, 'Lezioni da notificare: ' . count($lezioni) . ', utenti da avvisare: ' . count($perUtente)); if (!$perUtente) { exit; } try { $sender = new PushSender(); } catch (Throwable $e) { scriviLog($logFile, 'ERRORE configurazione FCM: ' . $e->getMessage()); exit; } $inviate = 0; $fallite = 0; $senzaApp = 0; foreach ($perUtente as $iduser => $lezioniUtente) { $prima = $lezioniUtente[0]; $quante = count($lezioniUtente); // Elenco leggibile: "Hatha Yoga alle 19:30, Yin Yoga alle 21:00" $elenco = []; foreach ($lezioniUtente as $l) { $ora = (new DateTime($l['dateschedule']))->format('H:i'); $elenco[] = trim(($l['servicename'] ?? '') . " alle $ora"); } $dataPrima = new DateTime($prima['dateschedule']); $valori = [ 'first_name' => $prima['first_name'] ?? '', 'last_name' => $prima['last_name'] ?? '', 'servicename' => $prima['servicename'] ?? '', 'date' => $dataPrima->format('d/m/Y'), 'time' => $dataPrima->format('H:i'), 'count' => $quante, 'lessons' => implode(', ', $elenco), ]; // Con piu' lezioni usiamo i testi "multi", se l'admin li ha compilati. $titolo = $impostazione['title']; $testo = $impostazione['body']; if ($quante > 1) { if (!empty($impostazione['title_multi'])) { $titolo = $impostazione['title_multi']; } if (!empty($impostazione['body_multi'])) { $testo = $impostazione['body_multi']; } } $esito = $sender->sendToUser( $db, (int) $iduser, pushRender($titolo, $valori), pushRender($testo, $valori), ['type' => 'lesson', 'idbookingclass' => (int) $prima['idbookingclass'], 'count' => $quante] ); // Utente senza dispositivi registrati: non ha ancora aperto l'app. // Non e' un errore e non va segnato nello storico, altrimenti quando // installera' l'app risulterebbe gia' "notificato". if ($esito['no_devices']) { $senzaApp++; continue; } // Registriamo tutte le lezioni incluse nel messaggio: cosi' nessuna di // esse verra' rinotificata se lo script viene rilanciato. foreach ($lezioniUtente as $l) { pushRegistraInvio($db, (int) $iduser, 'lesson', (int) $l['idbookingclass'], 0, $esito); } if ($esito['sent'] > 0) { $inviate++; } else { $fallite++; if ($esito['errors']) { scriviLog($logFile, "Utente $iduser: " . implode(' | ', $esito['errors'])); } } } scriviLog($logFile, "Fine. Notifiche inviate: $inviate, fallite: $fallite, senza app: $senzaApp.");