getConnection(); $impostazioni = pushSettings($db, 'order'); if (!$impostazioni) { scriviLog($logFile, 'Nessuna impostazione attiva per gli ordini, esco.'); exit; } $sender = null; foreach ($impostazioni as $impostazione) { $giorniPrima = (int) $impostazione['daysbefore']; $oraPrevista = (int) substr((string) $impostazione['sendhour'], 0, 2); if (!$forza && (int) date('G') !== $oraPrevista) { continue; } // Data di scadenza che ci interessa in questo giro. $dataScadenza = date('Y-m-d', strtotime("+$giorniPrima days")); scriviLog($logFile, "Controllo ordini con scadenza $dataScadenza (anticipo $giorniPrima giorni)."); // ---------------------------------------------------------------------- // Ordini che scadono in quella data. // ---------------------------------------------------------------------- $stmt = $db->prepare(" SELECT ob.idorderbook, ob.iduser, ob.expireon, ob.nticket, ob.product_name, u.first_name, u.last_name FROM orderbook ob INNER JOIN auth_users u ON ob.iduser = u.id WHERE ob.expireon = :scadenza AND (ob.status IS NULL OR ob.status != 'cancelled') AND u.pushnotification = 'Y' AND u.status = 'Active' "); $stmt->execute([':scadenza' => $dataScadenza]); $ordini = $stmt->fetchAll(PDO::FETCH_ASSOC); scriviLog($logFile, 'Ordini trovati: ' . count($ordini)); if (!$ordini) { continue; } // ---------------------------------------------------------------------- // Raggruppiamo per utente: chi ha due abbonamenti in scadenza lo stesso // giorno riceve un messaggio solo. // ---------------------------------------------------------------------- $perUtente = []; $saltate = 0; foreach ($ordini as $ordine) { $iduser = (int) $ordine['iduser']; $idorderbook = (int) $ordine['idorderbook']; if (pushGiaInviata($db, $iduser, 'order', $idorderbook, $giorniPrima)) { $saltate++; continue; } $perUtente[$iduser][] = $ordine; } if (!$perUtente) { scriviLog($logFile, "Anticipo $giorniPrima gg -> niente da inviare (saltati: $saltate)."); continue; } if ($sender === null) { 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 => $ordiniUtente) { $primo = $ordiniUtente[0]; $quanti = count($ordiniUtente); // Elenco leggibile: "Abbonamento 10 lezioni, Lezione singola" $elenco = []; foreach ($ordiniUtente as $o) { $elenco[] = trim((string) ($o['product_name'] ?? 'Abbonamento')); } $valori = [ 'first_name' => $primo['first_name'] ?? '', 'last_name' => $primo['last_name'] ?? '', 'expiredate' => date('d/m/Y', strtotime((string) $primo['expireon'])), 'servicename' => $primo['product_name'] ?? '', 'count' => $quanti, 'orders' => implode(', ', $elenco), ]; $titolo = $impostazione['title']; $testo = $impostazione['body']; if ($quanti > 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' => 'order', 'idorderbook' => (int) $primo['idorderbook'], 'count' => $quanti] ); // Utente senza dispositivi registrati: non ha ancora aperto l'app. if ($esito['no_devices']) { $senzaApp++; continue; } // Registriamo tutti gli ordini inclusi nel messaggio. foreach ($ordiniUtente as $o) { pushRegistraInvio($db, (int) $iduser, 'order', (int) $o['idorderbook'], $giorniPrima, $esito); } if ($esito['sent'] > 0) { $inviate++; } else { $fallite++; if ($esito['errors']) { scriviLog($logFile, "Utente $iduser: " . implode(' | ', $esito['errors'])); } } } scriviLog( $logFile, "Anticipo $giorniPrima gg -> inviate: $inviate, saltate: $saltate, " . "fallite: $fallite, senza app: $senzaApp." ); }