111 lines
4.6 KiB
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);
|
|
}
|
|
}
|
|
}
|