publicKey = getSetting('vapid_public_key', 'YOUR_VAPID_PUBLIC_KEY'); $this->privateKey = getSetting('vapid_private_key', 'YOUR_VAPID_PRIVATE_KEY'); $this->subject = 'mailto:' . getSetting('admin_email', 'admin@tomsjavajive.com'); } /** * Get VAPID public key for client */ public function getPublicKey(): string { return $this->publicKey; } /** * Send push notification to a subscription */ public function send(array $subscription, string $title, string $body, array $options = []): array { $payload = json_encode([ 'title' => $title, 'body' => $body, 'icon' => $options['icon'] ?? '/assets/icons/icon-192.png', 'badge' => $options['badge'] ?? '/assets/icons/badge-72.png', 'url' => $options['url'] ?? '/', 'tag' => $options['tag'] ?? null, 'data' => $options['data'] ?? [] ]); // For now, we'll store notifications for when the user comes online // Full web push requires a library like minishlink/web-push // This is a simplified version that works with the service worker try { // Store notification for retrieval $notificationId = generateId('notif_'); db()->insert('push_notifications', [ 'notification_id' => $notificationId, 'subscription_endpoint' => $subscription['endpoint'], 'payload' => $payload, 'status' => 'pending', 'created_at' => date('Y-m-d H:i:s') ]); return ['success' => true, 'notification_id' => $notificationId]; } catch (Exception $e) { return ['success' => false, 'error' => $e->getMessage()]; } } /** * Send notification to all subscribed users */ public function broadcast(string $title, string $body, array $options = []): array { $subscriptions = db()->fetchAll("SELECT * FROM push_subscriptions WHERE is_active = 1"); $results = ['sent' => 0, 'failed' => 0]; foreach ($subscriptions as $sub) { $subscription = [ 'endpoint' => $sub['endpoint'], 'keys' => [ 'p256dh' => $sub['p256dh_key'], 'auth' => $sub['auth_key'] ] ]; $result = $this->send($subscription, $title, $body, $options); if ($result['success']) { $results['sent']++; } else { $results['failed']++; } } return $results; } /** * Send order status update notification */ public function sendOrderUpdate(string $customerId, array $order, string $status): array { $subscription = $this->getCustomerSubscription($customerId); if (!$subscription) { return ['success' => false, 'error' => 'No subscription found']; } $messages = [ 'confirmed' => "Your order #{$order['order_number']} has been confirmed!", 'processing' => "We're preparing your order #{$order['order_number']}", 'shipped' => "Your order #{$order['order_number']} is on its way!", 'delivered' => "Your order #{$order['order_number']} has been delivered!", 'ready' => "Your order #{$order['order_number']} is ready for pickup!" ]; return $this->send( $subscription, "Order Update", $messages[$status] ?? "Order #{$order['order_number']} status: {$status}", [ 'url' => "/account/order.php?id={$order['order_id']}", 'tag' => "order-{$order['order_id']}" ] ); } /** * Send promotional notification */ public function sendPromotion(string $customerId, string $title, string $message, string $url = '/shop.php'): array { $subscription = $this->getCustomerSubscription($customerId); if (!$subscription) { return ['success' => false, 'error' => 'No subscription found']; } return $this->send($subscription, $title, $message, ['url' => $url]); } /** * Send loyalty tier notification */ public function sendTierNotification(string $customerId, string $tierName, array $benefits): array { $subscription = $this->getCustomerSubscription($customerId); if (!$subscription) { return ['success' => false, 'error' => 'No subscription found']; } return $this->send( $subscription, "Congratulations! You're now {$tierName}!", "Enjoy new benefits: " . implode(', ', array_slice($benefits, 0, 2)), ['url' => '/account/'] ); } /** * Get customer's push subscription */ private function getCustomerSubscription(string $customerId): ?array { $sub = db()->fetch( "SELECT * FROM push_subscriptions WHERE customer_id = :id AND is_active = 1 ORDER BY created_at DESC LIMIT 1", ['id' => $customerId] ); if (!$sub) { return null; } return [ 'endpoint' => $sub['endpoint'], 'keys' => [ 'p256dh' => $sub['p256dh_key'], 'auth' => $sub['auth_key'] ] ]; } } // Helper function for easy access function pushNotify(): PushNotification { static $instance = null; if ($instance === null) { $instance = new PushNotification(); } return $instance; }