116 lines
4.3 KiB
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;
|
|
}
|
|
}
|
|
}
|