Files
easystream-main/f_jobs/SendNotificationJob.php
SamiAhmed7777 0b7e2d0a5b feat: Add comprehensive documentation suite and reorganize project structure
- Created complete documentation in docs/ directory
- Added PROJECT_OVERVIEW.md with feature highlights and getting started guide
- Added ARCHITECTURE.md with system design and technical details
- Added SECURITY.md with comprehensive security implementation guide
- Added DEVELOPMENT.md with development workflows and best practices
- Added DEPLOYMENT.md with production deployment instructions
- Added API.md with complete REST API documentation
- Added CONTRIBUTING.md with contribution guidelines
- Added CHANGELOG.md with version history and migration notes
- Reorganized all documentation files into docs/ directory for better organization
- Updated README.md with proper documentation links and quick navigation
- Enhanced project structure with professional documentation standards
2025-10-21 00:39:45 -07:00

385 lines
13 KiB
PHP

<?php
/*******************************************************************************************************************
| Send Notification Job
| Handles sending notifications to users
|*******************************************************************************************************************/
class SendNotificationJob extends BaseJob
{
/**
* Handle notification sending
* @param array $data Notification data
* @return bool Success status
*/
public function handle($data)
{
$this->validateData($data, ['user_id', 'type', 'message']);
$userId = $data['user_id'];
$type = $data['type'];
$message = $data['message'];
$title = $data['title'] ?? 'EasyStream Notification';
$actionUrl = $data['action_url'] ?? null;
$metadata = $data['metadata'] ?? [];
$this->logProgress('Sending notification', [
'user_id' => $userId,
'type' => $type,
'title' => $title
]);
try {
// Store notification in database
$notificationId = $this->storeNotification($userId, $type, $title, $message, $actionUrl, $metadata);
// Send real-time notification if user is online
$this->sendRealTimeNotification($userId, $notificationId, $type, $title, $message, $actionUrl);
// Send email notification if enabled for user
$this->sendEmailNotification($userId, $type, $title, $message, $actionUrl);
// Send push notification if user has enabled it
$this->sendPushNotification($userId, $type, $title, $message, $actionUrl);
$this->logProgress('Notification sent successfully', [
'user_id' => $userId,
'notification_id' => $notificationId,
'type' => $type
]);
return true;
} catch (Exception $e) {
$this->logError('Failed to send notification', [
'user_id' => $userId,
'type' => $type,
'error' => $e->getMessage()
]);
throw $e;
}
}
/**
* Store notification in database
* @param int $userId User ID
* @param string $type Notification type
* @param string $title Title
* @param string $message Message
* @param string $actionUrl Action URL
* @param array $metadata Metadata
* @return int Notification ID
*/
private function storeNotification($userId, $type, $title, $message, $actionUrl, $metadata)
{
$db = $this->getDatabase();
// Create table if it doesn't exist
$this->createNotificationTable();
$notificationData = [
'user_id' => $userId,
'type' => $type,
'title' => $title,
'message' => $message,
'action_url' => $actionUrl,
'metadata' => json_encode($metadata),
'is_read' => 0,
'created_at' => date('Y-m-d H:i:s')
];
$success = $db->doInsert('db_notifications', $notificationData);
if (!$success) {
throw new Exception('Failed to store notification in database');
}
// Get the inserted notification ID
global $db as $adodb;
return $adodb->Insert_ID();
}
/**
* Send real-time notification via WebSocket/Server-Sent Events
* @param int $userId User ID
* @param int $notificationId Notification ID
* @param string $type Type
* @param string $title Title
* @param string $message Message
* @param string $actionUrl Action URL
*/
private function sendRealTimeNotification($userId, $notificationId, $type, $title, $message, $actionUrl)
{
try {
$redis = $this->getRedis();
$notificationData = [
'id' => $notificationId,
'type' => $type,
'title' => $title,
'message' => $message,
'action_url' => $actionUrl,
'timestamp' => time()
];
// Store in Redis for real-time delivery
$redis->lpush("notifications:user:{$userId}", json_encode($notificationData));
// Limit to last 50 notifications per user
$redis->getRedis()->ltrim("notifications:user:{$userId}", 0, 49);
// Publish to notification channel for WebSocket delivery
$redis->getRedis()->publish("notifications", json_encode([
'user_id' => $userId,
'notification' => $notificationData
]));
$this->logProgress('Real-time notification queued', [
'user_id' => $userId,
'notification_id' => $notificationId
]);
} catch (Exception $e) {
$this->logError('Failed to send real-time notification', [
'user_id' => $userId,
'error' => $e->getMessage()
]);
}
}
/**
* Send email notification if user has enabled it
* @param int $userId User ID
* @param string $type Type
* @param string $title Title
* @param string $message Message
* @param string $actionUrl Action URL
*/
private function sendEmailNotification($userId, $type, $title, $message, $actionUrl)
{
try {
// Check if user wants email notifications for this type
if (!$this->userWantsEmailNotification($userId, $type)) {
return;
}
// Get user email
$userEmail = $this->getUserEmail($userId);
if (!$userEmail) {
return;
}
// Prepare email content
$emailSubject = "EasyStream: {$title}";
$emailMessage = $this->buildEmailTemplate($title, $message, $actionUrl);
// Queue email job
$queue = new VQueue();
$queue->enqueue('SendEmailJob', [
'to' => $userEmail,
'subject' => $emailSubject,
'message' => $emailMessage,
'from' => 'notifications@easystream.com'
], 'email');
$this->logProgress('Email notification queued', [
'user_id' => $userId,
'email' => $userEmail,
'type' => $type
]);
} catch (Exception $e) {
$this->logError('Failed to queue email notification', [
'user_id' => $userId,
'error' => $e->getMessage()
]);
}
}
/**
* Send push notification
* @param int $userId User ID
* @param string $type Type
* @param string $title Title
* @param string $message Message
* @param string $actionUrl Action URL
*/
private function sendPushNotification($userId, $type, $title, $message, $actionUrl)
{
try {
// Get user's push notification tokens
$pushTokens = $this->getUserPushTokens($userId);
if (empty($pushTokens)) {
return;
}
// Queue push notification job for each token
$queue = new VQueue();
foreach ($pushTokens as $token) {
$queue->enqueue('SendPushNotificationJob', [
'token' => $token,
'title' => $title,
'message' => $message,
'action_url' => $actionUrl,
'user_id' => $userId
], 'notifications');
}
$this->logProgress('Push notifications queued', [
'user_id' => $userId,
'token_count' => count($pushTokens),
'type' => $type
]);
} catch (Exception $e) {
$this->logError('Failed to queue push notifications', [
'user_id' => $userId,
'error' => $e->getMessage()
]);
}
}
/**
* Check if user wants email notifications for this type
* @param int $userId User ID
* @param string $type Notification type
* @return bool
*/
private function userWantsEmailNotification($userId, $type)
{
try {
$db = $this->getDatabase();
// Check user notification preferences
$preference = $db->singleFieldValue('db_user_preferences', 'email_notifications', 'user_id', $userId);
if ($preference === null) {
return true; // Default to enabled
}
$preferences = json_decode($preference, true);
return isset($preferences[$type]) ? $preferences[$type] : true;
} catch (Exception $e) {
return true; // Default to enabled on error
}
}
/**
* Get user email address
* @param int $userId User ID
* @return string|null Email address
*/
private function getUserEmail($userId)
{
try {
$db = $this->getDatabase();
return $db->singleFieldValue('db_accountuser', 'usr_email', 'usr_id', $userId);
} catch (Exception $e) {
return null;
}
}
/**
* Get user push notification tokens
* @param int $userId User ID
* @return array Push tokens
*/
private function getUserPushTokens($userId)
{
try {
$db = $this->getDatabase();
// This would need a push_tokens table
// For now, return empty array
return [];
} catch (Exception $e) {
return [];
}
}
/**
* Build email template
* @param string $title Title
* @param string $message Message
* @param string $actionUrl Action URL
* @return string HTML email content
*/
private function buildEmailTemplate($title, $message, $actionUrl)
{
$actionButton = '';
if ($actionUrl) {
$actionButton = '<p style="text-align: center; margin: 30px 0;">
<a href="' . htmlspecialchars($actionUrl) . '"
style="background: #4A90E2; color: white; padding: 12px 24px; text-decoration: none; border-radius: 4px; display: inline-block;">
View Details
</a>
</p>';
}
return '
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>' . htmlspecialchars($title) . '</title>
</head>
<body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 600px; margin: 0 auto; padding: 20px;">
<div style="text-align: center; margin-bottom: 30px;">
<h1 style="color: #4A90E2;">EasyStream</h1>
</div>
<h2 style="color: #333;">' . htmlspecialchars($title) . '</h2>
<div style="background: #f9f9f9; padding: 20px; border-radius: 5px; margin: 20px 0;">
' . nl2br(htmlspecialchars($message)) . '
</div>
' . $actionButton . '
<hr style="border: none; border-top: 1px solid #eee; margin: 30px 0;">
<p style="font-size: 12px; color: #666; text-align: center;">
This is an automated message from EasyStream. Please do not reply to this email.
</p>
</body>
</html>';
}
/**
* Create notification table if it doesn't exist
*/
private function createNotificationTable()
{
global $db;
$sql = "CREATE TABLE IF NOT EXISTS `db_notifications` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`type` varchar(50) NOT NULL,
`title` varchar(255) NOT NULL,
`message` text NOT NULL,
`action_url` varchar(500) DEFAULT NULL,
`metadata` text,
`is_read` tinyint(1) NOT NULL DEFAULT 0,
`created_at` datetime NOT NULL,
`read_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_type` (`type`),
KEY `idx_is_read` (`is_read`),
KEY `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4";
try {
$db->Execute($sql);
} catch (Exception $e) {
$this->logError('Failed to create notification table', [
'error' => $e->getMessage()
]);
}
}
}