WizdomWeb/app/Services/NewsletterService.php

116 lines
4.3 KiB
PHP

<?php
/**
* File: NewsletterService.php
* Version: 1.1
* Path: app/Services/
* Purpose: Handles newsletter subscriptions including verification email flow.
* Project: Wizdom Networks Website
*/
namespace WizdomNetworks\WizeWeb\Services;
use WizdomNetworks\WizeWeb\Utilities\Logger;
use WizdomNetworks\WizeWeb\Utilities\ErrorHandler;
use WizdomNetworks\WizeWeb\Utilities\Database;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception as MailException;
class NewsletterService
{
/**
* Subscribes a user to the newsletter if not already subscribed.
* Sends a verification email with a unique code.
*
* @param string $email
* @param string $ip
* @param string $userAgent
* @return bool True if subscription initiated successfully, false otherwise
*/
public static function subscribeIfNew(string $email, string $ip, string $userAgent): bool
{
try {
$db = Database::getConnection();
// Check if already subscribed
$stmt = $db->prepare("SELECT is_verified FROM subscribers WHERE email = ?");
$stmt->execute([$email]);
$row = $stmt->fetch();
if ($row) {
if ((int) $row['is_verified'] === 1) {
Logger::info("Newsletter signup skipped (already verified): $email");
return false;
} else {
Logger::info("Newsletter re-verification triggered for $email");
// Optionally regenerate and resend code here
}
}
$verificationCode = bin2hex(random_bytes(16));
if ($row) {
// Update existing unverified entry
$stmt = $db->prepare("UPDATE subscribers SET verification_code = ?, ip_address = ?, user_agent = ?, created_at = NOW() WHERE email = ?");
$stmt->execute([$verificationCode, $ip, $userAgent, $email]);
} else {
// Insert new record
$stmt = $db->prepare("
INSERT INTO subscribers (email, verification_code, is_verified, ip_address, user_agent, created_at)
VALUES (?, ?, 0, ?, ?, NOW())
");
$stmt->execute([$email, $verificationCode, $ip, $userAgent]);
}
Logger::info("Newsletter subscription initiated for $email, verification code generated.");
return self::sendVerificationEmail($email, $verificationCode);
} catch (\Throwable $e) {
Logger::error("Newsletter subscription failed for $email: " . $e->getMessage());
ErrorHandler::exception($e);
return false;
}
}
/**
* Sends the newsletter verification email.
*
* @param string $email
* @param string $code
* @return bool True if sent successfully, false otherwise
*/
private static function sendVerificationEmail(string $email, string $code): bool
{
try {
$verifyUrl = $_ENV['APP_URL'] . "/verify?code=" . urlencode($code);
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = $_ENV['SMTP_HOST'];
$mail->SMTPAuth = true;
$mail->Username = $_ENV['SMTP_USER'];
$mail->Password = $_ENV['SMTP_PASS'];
$mail->SMTPSecure = $_ENV['SMTP_SECURE'] ?? 'tls';
$mail->Port = $_ENV['SMTP_PORT'] ?? 587;
$mail->setFrom($_ENV['MAIL_FROM'], $_ENV['MAIL_FROM_NAME']);
$mail->addAddress($email);
$mail->Subject = 'Confirm your subscription to Wizdom Networks';
$mail->isHTML(true);
$mail->Body = "
<p>Thank you for subscribing to the Wizdom Networks newsletter!</p>
<p>Please click the link below to confirm your subscription:</p>
<p><a href='{$verifyUrl}'>Confirm My Subscription</a></p>
<p>If you did not request this, you can safely ignore this email.</p>
";
$mail->send();
Logger::info("Verification email sent to $email");
return true;
} catch (MailException $e) {
Logger::error("Failed to send verification email to $email: " . $e->getMessage());
ErrorHandler::exception($e);
return false;
}
}
}