219 lines
7.7 KiB
PHP
219 lines
7.7 KiB
PHP
<?php
|
||
/**
|
||
* File: EmailHelper.php
|
||
* Version: 2.4
|
||
* Path: /app/Utilities/EmailHelper.php
|
||
* Purpose: Sends contact confirmations, sales notifications, and admin alerts with proper formatting and logic.
|
||
* Project: Wizdom Networks Website
|
||
*/
|
||
|
||
namespace WizdomNetworks\WizeWeb\Utilities;
|
||
|
||
use PHPMailer\PHPMailer\PHPMailer;
|
||
use PHPMailer\PHPMailer\Exception;
|
||
|
||
class EmailHelper
|
||
{
|
||
public static function configureMailer(PHPMailer $mail): void
|
||
{
|
||
$mail->isSMTP();
|
||
$mail->Host = $_ENV['SMTP_HOST'] ?? 'localhost';
|
||
$mail->Port = $_ENV['SMTP_PORT'] ?? 25;
|
||
|
||
$mail->SMTPAuth = filter_var($_ENV['SMTP_AUTH'] ?? false, FILTER_VALIDATE_BOOLEAN);
|
||
$mail->Username = $_ENV['SMTP_USER'] ?? '';
|
||
$mail->Password = $_ENV['SMTP_PASS'] ?? '';
|
||
|
||
$mail->SMTPAutoTLS = filter_var($_ENV['SMTP_AUTO_TLS'] ?? true, FILTER_VALIDATE_BOOLEAN);
|
||
|
||
$encryption = strtolower(trim($_ENV['SMTP_ENCRYPTION'] ?? ''));
|
||
if ($encryption === 'ssl') {
|
||
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
|
||
} elseif ($encryption === 'tls') {
|
||
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
|
||
} else {
|
||
$mail->SMTPSecure = '';
|
||
}
|
||
|
||
$fromEmail = $_ENV['SMTP_FROM_EMAIL'] ?? 'no-reply@localhost';
|
||
$fromName = $_ENV['SMTP_FROM_NAME'] ?? 'Wizdom Mailer';
|
||
$mail->setFrom($fromEmail, $fromName);
|
||
|
||
$mail->SMTPOptions = [
|
||
'ssl' => [
|
||
'verify_peer' => false,
|
||
'verify_peer_name' => false,
|
||
'allow_self_signed' => true
|
||
]
|
||
];
|
||
}
|
||
|
||
private static function parseRecipients(string $rawList): array
|
||
{
|
||
$emails = explode(',', $rawList);
|
||
$validEmails = [];
|
||
|
||
foreach ($emails as $email) {
|
||
$email = trim($email);
|
||
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||
$validEmails[] = $email;
|
||
}
|
||
}
|
||
|
||
return $validEmails;
|
||
}
|
||
|
||
private static function buildContactHtmlBody(array $data): string
|
||
{
|
||
return "
|
||
<strong>Name:</strong> {$data['first_name']} {$data['last_name']}<br>
|
||
<strong>Email:</strong> {$data['email']}<br>
|
||
<strong>Phone:</strong> {$data['phone']}<br>
|
||
<strong>Subject:</strong> {$data['subject']}<br>
|
||
<strong>Message:</strong><br>
|
||
<pre style='white-space:pre-wrap;'>{$data['message']}</pre>
|
||
";
|
||
}
|
||
|
||
private static function buildErrorReportHtml(string $context, string $errorMessage, $data = []): string
|
||
{
|
||
if (is_string($data)) {
|
||
$decoded = json_decode($data, true);
|
||
$data = is_array($decoded) ? $decoded : ['raw_data' => $data];
|
||
}
|
||
|
||
$body = "
|
||
<strong>Context:</strong> {$context}<br>
|
||
<strong>Error Message:</strong><br>
|
||
<pre style='white-space:pre-wrap;color:#8b0000;'>{$errorMessage}</pre>
|
||
";
|
||
|
||
if (!empty($data)) {
|
||
$body .= "<hr><strong>Associated Data:</strong><br><ul>";
|
||
foreach ($data as $key => $value) {
|
||
$safeKey = htmlspecialchars($key);
|
||
$safeValue = nl2br(htmlspecialchars((string)$value));
|
||
$body .= "<li><strong>{$safeKey}:</strong> {$safeValue}</li>";
|
||
}
|
||
$body .= "</ul>";
|
||
}
|
||
|
||
return $body;
|
||
}
|
||
|
||
private static function buildSalesHtmlBody(array $data): string
|
||
{
|
||
$submittedAt = date('Y-m-d H:i:s');
|
||
return "
|
||
<p><strong>New contact submission received</strong> on {$submittedAt}.</p>
|
||
<ul>
|
||
<li><strong>Name:</strong> {$data['first_name']} {$data['last_name']}</li>
|
||
<li><strong>Email:</strong> {$data['email']}</li>
|
||
<li><strong>Phone:</strong> {$data['phone']}</li>
|
||
<li><strong>Subject:</strong> {$data['subject']}</li>
|
||
<li><strong>Message:</strong><br><pre style='white-space:pre-wrap;'>{$data['message']}</pre></li>
|
||
</ul>
|
||
<hr>
|
||
<p style='font-size: 0.9em; color: #888;'>IP: {$data['ip_address']}<br>User-Agent: {$data['user_agent']}</p>
|
||
";
|
||
}
|
||
|
||
private static function buildConfirmationHtmlBody(array $data): string
|
||
{
|
||
$submittedAt = date('Y-m-d H:i:s');
|
||
return "
|
||
<p>Hi {$data['first_name']},</p>
|
||
<p>Thank you for contacting Wizdom Networks. This message confirms that we received your inquiry on <strong>{$submittedAt}</strong>.</p>
|
||
<ul>
|
||
<li><strong>Subject:</strong> {$data['subject']}</li>
|
||
<li><strong>Message:</strong><br><pre style='white-space:pre-wrap;'>{$data['message']}</pre></li>
|
||
</ul>
|
||
<p>We’ll be in touch shortly. If it’s urgent, call us at <strong>416-USE-WISE</strong>.</p>
|
||
<p style='font-size: 0.9em; color: #888;'>IP: {$data['ip_address']}<br>User-Agent: {$data['user_agent']}</p>
|
||
";
|
||
}
|
||
|
||
public static function sendContactNotification(array $data): bool
|
||
{
|
||
try {
|
||
$mail = new PHPMailer(true);
|
||
self::configureMailer($mail);
|
||
|
||
$recipients = self::parseRecipients($_ENV['SALES_EMAILS'] ?? '');
|
||
foreach ($recipients as $email) {
|
||
$mail->addAddress($email);
|
||
}
|
||
|
||
if (empty($mail->getToAddresses())) {
|
||
Logger::error("EmailHelper: No valid SALES_EMAILS configured.");
|
||
return false;
|
||
}
|
||
|
||
$mail->isHTML(true);
|
||
$mail->Subject = 'New Contact Form Submission';
|
||
$mail->Body = self::buildSalesHtmlBody($data);
|
||
|
||
$mail->send();
|
||
return true;
|
||
} catch (Exception $e) {
|
||
Logger::error("Email send failure to sales: " . $e->getMessage());
|
||
self::alertAdmins("sendContactNotification", $e->getMessage(), $data);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
public static function sendConfirmationToUser(array $data): bool
|
||
{
|
||
try {
|
||
$mail = new PHPMailer(true);
|
||
self::configureMailer($mail);
|
||
|
||
$mail->addAddress($data['email'], "{$data['first_name']} {$data['last_name']}");
|
||
$mail->isHTML(true);
|
||
$mail->Subject = 'Your Wizdom Networks Contact Form Submission';
|
||
$mail->Body = self::buildConfirmationHtmlBody($data);
|
||
|
||
$mail->send();
|
||
return true;
|
||
} catch (Exception $e) {
|
||
Logger::error("Email send failure to user: " . $e->getMessage());
|
||
self::alertAdmins("sendConfirmationToUser", $e->getMessage(), $data);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Sends a system alert to ADMIN_EMAILS with error context and message.
|
||
*
|
||
* @param string $context
|
||
* @param string $errorMessage
|
||
* @param array|string $data Data array or JSON string for the report
|
||
* @return void
|
||
*/
|
||
public static function alertAdmins(string $context, string $errorMessage, $data = []): void
|
||
{
|
||
try {
|
||
$mail = new PHPMailer(true);
|
||
self::configureMailer($mail);
|
||
|
||
$recipients = self::parseRecipients($_ENV['ADMIN_EMAILS'] ?? '');
|
||
foreach ($recipients as $email) {
|
||
$mail->addAddress($email);
|
||
}
|
||
|
||
if (empty($mail->getToAddresses())) {
|
||
Logger::error("EmailHelper: No valid ADMIN_EMAILS configured.");
|
||
return;
|
||
}
|
||
|
||
$mail->isHTML(true);
|
||
$mail->Subject = "[System Alert] Error in {$context}";
|
||
$mail->Body = self::buildErrorReportHtml($context, $errorMessage, $data);
|
||
|
||
$mail->send();
|
||
} catch (Exception $e) {
|
||
Logger::error("EmailHelper::alertAdmins failed: " . $e->getMessage());
|
||
}
|
||
}
|
||
}
|