WizdomWeb/app/Services/EmailService.php

166 lines
6.3 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* File: EmailService.php
* Version: 1.4
* Path: /app/Services/EmailService.php
* Purpose: Centralized service for composing and sending all application emails including contact, newsletter, and system notifications.
* Includes support for unified contact + newsletter welcome messages.
* Project: Wizdom Networks Website
*/
namespace WizdomNetworks\WizeWeb\Services;
use WizdomNetworks\WizeWeb\Utilities\Database;
use WizdomNetworks\WizeWeb\Utilities\Logger;
use WizdomNetworks\WizeWeb\Utilities\EmailHelper;
use WizdomNetworks\WizeWeb\Utilities\ErrorHandler;
use WizdomNetworks\WizeWeb\Services\VerificationService;
class EmailService
{
private const TEMPLATE_VERIFICATION_CONTACT = 'verify_contact';
private const TEMPLATE_VERIFICATION_NEWSLETTER = 'verify_newsletter';
private const TEMPLATE_CONFIRMATION_CONTACT = 'verified_confirmation';
private const TEMPLATE_SALES_ALERT = 'sales_lead_alert';
private const TEMPLATE_CONTACT_NEWSLETTER = 'contact_and_newsletter';
private const TABLE_SUBSCRIBERS = 'subscribers';
private VerificationService $verificationService;
/**
* Initializes the email service and loads the verification code service dependency.
*/
public function __construct()
{
$this->verificationService = new VerificationService();
}
/**
* Sends a verification email using the specified template and context.
*
* @param string $email Recipient email address
* @param string $code Verification code
* @param string $template Email template to render
* @param array $context Template variables to inject
* @return bool True on success, false on failure
*/
public function sendVerificationEmail(string $email, string $code, string $template, array $context = []): bool
{
$context['verification_link'] = rtrim($_ENV['APP_URL'], '/') . "/verify/" . $code;
$body = EmailHelper::renderTemplate($template, $context);
$subject = 'Please verify your email';
return EmailHelper::send($email, $subject, $body);
}
/**
* Handles a new or existing newsletter subscription and sends a verification email.
*
* @param string $email User's email address
* @param string $ip User's IP address
* @param string $userAgent User agent string
* @return bool True if verification email sent, false otherwise
*/
public function subscribeNewsletter(string $email, string $ip, string $userAgent): bool
{
try {
$db = Database::getConnection();
$stmt = $db->prepare("SELECT is_verified FROM subscribers WHERE email = ?");
$stmt->execute([$email]);
$row = $stmt->fetch();
if ($row && (int)$row['is_verified'] === 1) {
Logger::info("Newsletter signup skipped (already verified): $email");
return false;
}
$code = $this->verificationService->generateCode();
$expiresAt = $this->verificationService->getExpirationTime();
if ($row) {
$stmt = $db->prepare("UPDATE subscribers SET verification_code = ?, ip_address = ?, user_agent = ?, created_at = NOW() WHERE email = ?");
$stmt->execute([$code, $ip, $userAgent, $email]);
} else {
$stmt = $db->prepare("INSERT INTO subscribers (email, verification_code, is_verified, ip_address, user_agent, created_at) VALUES (?, ?, 0, ?, ?, NOW())");
$stmt->execute([$email, $code, $ip, $userAgent]);
}
Logger::info("Newsletter subscription initiated for $email, verification code generated.");
return $this->sendVerificationEmail($email, $code, self::TEMPLATE_VERIFICATION_NEWSLETTER);
} catch (\Throwable $e) {
Logger::error("Newsletter subscription failed for $email: " . $e->getMessage());
ErrorHandler::exception($e);
return false;
}
}
/**
* Sends a confirmation email to a contact form submitter after successful verification.
*
* @param array $data Associative array containing user data and message details
* @return bool True on success, false on failure
*/
public function sendConfirmationToUser(array $data): bool
{
$body = EmailHelper::renderTemplate(self::TEMPLATE_CONFIRMATION_CONTACT, $data);
$subject = 'Your Email is Verified Wizdom Networks';
return EmailHelper::send($data['email'], $subject, $body);
}
/**
* Sends a notification to the internal sales team when a new contact form submission is received.
*
* @param array $data The contact form data
* @return bool True if at least one email sent, false otherwise
*/
public function sendSalesNotification(array $data): bool
{
$recipients = $_ENV['SALES_EMAILS'] ?? '';
if (empty($recipients)) {
return false;
}
$body = EmailHelper::renderTemplate(self::TEMPLATE_SALES_ALERT, $data);
$subject = 'New Contact Form Submission';
foreach (explode(',', $recipients) as $email) {
$trimmed = trim($email);
if (!empty($trimmed)) {
EmailHelper::send($trimmed, $subject, $body);
}
}
return true;
}
/**
* Sends a unified welcome email when a user both contacts us and subscribes to the newsletter.
*
* @param array $data Associative array containing contact form fields and metadata
* @return bool True on successful send, false otherwise
*/
public function sendContactAndNewsletterWelcome(array $data): bool
{
$body = EmailHelper::renderTemplate(self::TEMPLATE_CONTACT_NEWSLETTER, $data);
$subject = 'Thanks for reaching out and welcome!';
return EmailHelper::send($data['email'], $subject, $body);
}
/**
* Sends a system alert to configured admin recipients.
*
* @param string $context Description of the error context or origin
* @param string $errorMessage The error message or exception
* @param array|string $data Optional contextual data to include in the alert
* @return void
*/
public function alertAdmins(string $context, string $errorMessage, $data = []): void
{
EmailHelper::alertAdmins($context, $errorMessage, $data);
}
}