TKK_E32230273/PushHelper.php

111 lines
4.6 KiB
PHP

<?php
// PushHelper.php
require_once __DIR__ . '/vendor/autoload.php';
use Minishlink\WebPush\WebPush;
use Minishlink\WebPush\Subscription;
class PushHelper {
public static function sendPush($pdo, $id_account, $title, $body, $url = '/dashboard.php') {
try {
// Validate: only send push if account exists
$checkStmt = $pdo->prepare("SELECT id_account FROM account WHERE id_account = ?");
$checkStmt->execute([$id_account]);
$accountData = $checkStmt->fetch(PDO::FETCH_ASSOC);
if (!$accountData) {
return; // Account deleted
}
$keys = require __DIR__ . '/push_config.php';
$auth = [
'VAPID' => [
'subject' => $keys['VAPID_SUBJECT'],
'publicKey' => $keys['VAPID_PUBLIC_KEY'],
'privateKey' => $keys['VAPID_PRIVATE_KEY'],
],
];
// Instantiate WebPush
$webPush = new WebPush($auth);
$pdo->exec("CREATE TABLE IF NOT EXISTS push_subscriptions (
id INT AUTO_INCREMENT PRIMARY KEY,
id_account INT NOT NULL,
endpoint TEXT NOT NULL,
p256dh VARCHAR(255) NOT NULL,
auth VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
// Fetch subscriptions for this specific account
$stmt = $pdo->prepare("SELECT endpoint, p256dh, auth FROM push_subscriptions WHERE id_account = ?");
$stmt->execute([$id_account]);
$subs = $stmt->fetchAll(PDO::FETCH_ASSOC);
$payload = json_encode([
'title' => $title,
'body' => $body,
'url' => $url,
'icon' => '/images/myn.png'
]);
foreach ($subs as $subData) {
$subscription = Subscription::create([
'endpoint' => $subData['endpoint'],
'publicKey' => $subData['p256dh'], // corresponds to p256dh
'authToken' => $subData['auth'], // corresponds to auth
]);
// Queue the notification with High Urgency for immediate delivery
$webPush->queueNotification($subscription, $payload, ['urgency' => 'high']);
}
// Send all queued notifications
foreach ($webPush->flush() as $report) {
$endpoint = $report->getRequest()->getUri()->__toString();
if (!$report->isSuccess()) {
// If endpoint is expired/invalid, remove it from DB to clean up
if ($report->isSubscriptionExpired()) {
$del = $pdo->prepare("DELETE FROM push_subscriptions WHERE endpoint = ?");
$del->execute([$endpoint]);
}
$errReason = "Push Failed for {$endpoint}: " . $report->getReason();
file_put_contents(__DIR__ . '/push_error.log', "[" . date('Y-m-d H:i:s') . "] " . $errReason . "\n", FILE_APPEND);
error_log($errReason);
}
}
} catch (\Exception $e) {
$err = "[" . date('Y-m-d H:i:s') . "] PushHelper Fatal Error: " . $e->getMessage() . "\n";
file_put_contents(__DIR__ . '/push_error.log', $err, FILE_APPEND);
error_log($err);
}
}
public static function broadcastToAdmins($pdo, $title, $body, $url = '/dashboard.php') {
// Broadcast to all subscribed accounts (admins)
try {
$pdo->exec("CREATE TABLE IF NOT EXISTS push_subscriptions (
id INT AUTO_INCREMENT PRIMARY KEY,
id_account INT NOT NULL,
endpoint TEXT NOT NULL,
p256dh VARCHAR(255) NOT NULL,
auth VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
$stmt = $pdo->query("SELECT DISTINCT id_account FROM push_subscriptions WHERE id_account > 0");
$admins = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($admins as $admin) {
self::sendPush($pdo, $admin['id_account'], $title, $body, $url);
}
} catch (\PDOException $e) {
$err = "[" . date('Y-m-d H:i:s') . "] PushHelper DB Error: " . $e->getMessage() . "\n";
file_put_contents(__DIR__ . '/push_error.log', $err, FILE_APPEND);
error_log($err);
}
}
}