|
|
@@ -0,0 +1,130 @@
|
|
|
+<?php
|
|
|
+/**
|
|
|
+ * lib/mailer.php
|
|
|
+ *
|
|
|
+ * PHPMailer wrapper. All email sending goes through sendMail().
|
|
|
+ *
|
|
|
+ * Requires: vendor/autoload.php (run `composer install`)
|
|
|
+ * config/mail.php (SMTP constants)
|
|
|
+ */
|
|
|
+
|
|
|
+use PHPMailer\PHPMailer\PHPMailer;
|
|
|
+use PHPMailer\PHPMailer\SMTP;
|
|
|
+use PHPMailer\PHPMailer\Exception as MailerException;
|
|
|
+
|
|
|
+require_once __DIR__ . '/../config/mail.php';
|
|
|
+
|
|
|
+/**
|
|
|
+ * Send an email via SMTP.
|
|
|
+ *
|
|
|
+ * @param string $toEmail Recipient address
|
|
|
+ * @param string $toName Recipient display name
|
|
|
+ * @param string $subject Email subject
|
|
|
+ * @param string $htmlBody HTML message body
|
|
|
+ * @param string|null $textBody Plain-text fallback (auto-stripped from HTML if null)
|
|
|
+ *
|
|
|
+ * @return array{success: bool, error: string}
|
|
|
+ */
|
|
|
+function sendMail(string $toEmail, string $toName, string $subject, string $htmlBody, ?string $textBody = null): array
|
|
|
+{
|
|
|
+ $mail = new PHPMailer(true);
|
|
|
+
|
|
|
+ try {
|
|
|
+ $mail->isSMTP();
|
|
|
+ $mail->Host = MAIL_HOST;
|
|
|
+ $mail->SMTPAuth = true;
|
|
|
+ $mail->Username = MAIL_USERNAME;
|
|
|
+ $mail->Password = MAIL_PASSWORD;
|
|
|
+ $mail->SMTPSecure = MAIL_ENCRYPTION === 'ssl' ? PHPMailer::ENCRYPTION_SMTPS : PHPMailer::ENCRYPTION_STARTTLS;
|
|
|
+ $mail->Port = MAIL_PORT;
|
|
|
+ $mail->CharSet = 'UTF-8';
|
|
|
+
|
|
|
+ $mail->setFrom(MAIL_FROM, MAIL_FROM_NAME);
|
|
|
+ $mail->addAddress($toEmail, $toName);
|
|
|
+
|
|
|
+ $mail->isHTML(true);
|
|
|
+ $mail->Subject = $subject;
|
|
|
+ $mail->Body = $htmlBody;
|
|
|
+ $mail->AltBody = $textBody ?? strip_tags($htmlBody);
|
|
|
+
|
|
|
+ $mail->send();
|
|
|
+ return ['success' => true, 'error' => ''];
|
|
|
+
|
|
|
+ } catch (MailerException $e) {
|
|
|
+ error_log('Mailer error to ' . $toEmail . ': ' . $mail->ErrorInfo);
|
|
|
+ return ['success' => false, 'error' => $mail->ErrorInfo];
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Send a password reset email.
|
|
|
+ */
|
|
|
+function sendPasswordResetEmail(string $email, string $token): bool
|
|
|
+{
|
|
|
+ $resetUrl = 'https://cropmonitor.com.au/login/reset-password.php?token=' . urlencode($token);
|
|
|
+
|
|
|
+ $html = '
|
|
|
+<!DOCTYPE html>
|
|
|
+<html>
|
|
|
+<body style="font-family:Arial,sans-serif;background:#f4f4f4;padding:20px;">
|
|
|
+ <div style="max-width:560px;margin:0 auto;background:#fff;border-radius:6px;padding:32px;">
|
|
|
+ <h2 style="color:#2d6a2d;">Crop Monitor — Password Reset</h2>
|
|
|
+ <p>We received a request to reset your password. Click the button below to choose a new one.</p>
|
|
|
+ <p style="margin:28px 0;text-align:center;">
|
|
|
+ <a href="' . htmlspecialchars($resetUrl, ENT_QUOTES, 'UTF-8') . '"
|
|
|
+ style="background:#2d6a2d;color:#fff;padding:12px 28px;border-radius:4px;text-decoration:none;font-size:15px;">
|
|
|
+ Reset My Password
|
|
|
+ </a>
|
|
|
+ </p>
|
|
|
+ <p style="color:#666;font-size:13px;">This link expires in <strong>1 hour</strong>. If you did not request a password reset, you can safely ignore this email.</p>
|
|
|
+ <hr style="border:none;border-top:1px solid #eee;margin:24px 0;">
|
|
|
+ <p style="color:#999;font-size:12px;">Crop Monitor — Australian Crop Management Platform</p>
|
|
|
+ </div>
|
|
|
+</body>
|
|
|
+</html>';
|
|
|
+
|
|
|
+ $text = "Crop Monitor — Password Reset\n\n"
|
|
|
+ . "Click the link below to reset your password (expires in 1 hour):\n\n"
|
|
|
+ . $resetUrl . "\n\n"
|
|
|
+ . "If you did not request this, ignore this email.";
|
|
|
+
|
|
|
+ $result = sendMail($email, $email, 'Reset your Crop Monitor password', $html, $text);
|
|
|
+ return $result['success'];
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Send a welcome email after registration.
|
|
|
+ */
|
|
|
+function sendWelcomeEmail(string $email, string $fullname): bool
|
|
|
+{
|
|
|
+ $loginUrl = 'https://cropmonitor.com.au/login/login.php';
|
|
|
+
|
|
|
+ $html = '
|
|
|
+<!DOCTYPE html>
|
|
|
+<html>
|
|
|
+<body style="font-family:Arial,sans-serif;background:#f4f4f4;padding:20px;">
|
|
|
+ <div style="max-width:560px;margin:0 auto;background:#fff;border-radius:6px;padding:32px;">
|
|
|
+ <h2 style="color:#2d6a2d;">Welcome to Crop Monitor!</h2>
|
|
|
+ <p>Hi ' . htmlspecialchars($fullname, ENT_QUOTES, 'UTF-8') . ',</p>
|
|
|
+ <p>Your account has been created. You can now log in and start managing your crop analysis records.</p>
|
|
|
+ <p style="margin:28px 0;text-align:center;">
|
|
|
+ <a href="' . htmlspecialchars($loginUrl, ENT_QUOTES, 'UTF-8') . '"
|
|
|
+ style="background:#2d6a2d;color:#fff;padding:12px 28px;border-radius:4px;text-decoration:none;font-size:15px;">
|
|
|
+ Go to Crop Monitor
|
|
|
+ </a>
|
|
|
+ </p>
|
|
|
+ <p style="color:#666;font-size:13px;">If you have any questions, reply to this email and we will get back to you.</p>
|
|
|
+ <hr style="border:none;border-top:1px solid #eee;margin:24px 0;">
|
|
|
+ <p style="color:#999;font-size:12px;">Crop Monitor — Australian Crop Management Platform</p>
|
|
|
+ </div>
|
|
|
+</body>
|
|
|
+</html>';
|
|
|
+
|
|
|
+ $text = "Welcome to Crop Monitor, {$fullname}!\n\n"
|
|
|
+ . "Your account has been created. Log in here:\n\n"
|
|
|
+ . $loginUrl . "\n\n"
|
|
|
+ . "If you have any questions, reply to this email.";
|
|
|
+
|
|
|
+ $result = sendMail($email, $fullname, 'Welcome to Crop Monitor', $html, $text);
|
|
|
+ return $result['success'];
|
|
|
+}
|