b14f4c1796
New licensed lake, picnic, dining, server, burger, and food photography. Rebuilt homepage gallery, logo, colors, copy, menu, specials, and exports. Added dashboard-configurable branding in [settings.php (line 18)](/Users/tyemeclifford/Documents/GH/fatbottomgrille/views/admin/settings.php:18). Added a public attribution page and full [image credits](/Users/tyemeclifford/Documents/GH/fatbottomgrille/public/assets/images/CREDITS.md). Migrated existing SQLite menu data and admin email to admin@lakesideorders.test. Verified 51 PHP files, JSON/JavaScript, storefront pages, database migration, admin settings, and menu PDF. All passed.
80 lines
2.4 KiB
PHP
80 lines
2.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace FatBottom\Services;
|
|
|
|
use FatBottom\Core\Config;
|
|
use RuntimeException;
|
|
|
|
final class Mailer
|
|
{
|
|
public function __construct(private readonly Config $config)
|
|
{
|
|
}
|
|
|
|
public function send(string $to, string $subject, string $html): bool
|
|
{
|
|
if (!(bool) $this->config->get('mailgun.enabled', false)) {
|
|
$this->writeToLog($to, $subject, $html);
|
|
return true;
|
|
}
|
|
|
|
if (!function_exists('curl_init')) {
|
|
throw new RuntimeException('The PHP cURL extension is required for Mailgun.');
|
|
}
|
|
|
|
$domain = (string) $this->config->get('mailgun.domain');
|
|
$apiKey = (string) $this->config->get('mailgun.api_key');
|
|
if ($domain === '' || $apiKey === '') {
|
|
throw new RuntimeException('Mailgun is enabled but its credentials are incomplete.');
|
|
}
|
|
|
|
$from = sprintf(
|
|
'%s <%s>',
|
|
$this->config->get('mailgun.from_name', 'Lakeside Orders'),
|
|
$this->config->get('mailgun.from_email')
|
|
);
|
|
|
|
$curl = curl_init('https://api.mailgun.net/v3/' . rawurlencode($domain) . '/messages');
|
|
curl_setopt_array($curl, [
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_USERPWD => 'api:' . $apiKey,
|
|
CURLOPT_POST => true,
|
|
CURLOPT_POSTFIELDS => [
|
|
'from' => $from,
|
|
'to' => $to,
|
|
'subject' => $subject,
|
|
'html' => $html,
|
|
],
|
|
CURLOPT_TIMEOUT => 20,
|
|
]);
|
|
$response = curl_exec($curl);
|
|
$status = (int) curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
|
|
$error = curl_error($curl);
|
|
curl_close($curl);
|
|
|
|
if ($response === false || $status < 200 || $status >= 300) {
|
|
throw new RuntimeException('Mailgun delivery failed: ' . ($error ?: 'HTTP ' . $status));
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private function writeToLog(string $to, string $subject, string $html): void
|
|
{
|
|
$directory = BASE_PATH . '/storage/logs';
|
|
if (!is_dir($directory)) {
|
|
mkdir($directory, 0775, true);
|
|
}
|
|
$line = sprintf(
|
|
"[%s] TO: %s | SUBJECT: %s\n%s\n\n",
|
|
date('c'),
|
|
$to,
|
|
$subject,
|
|
trim(strip_tags($html))
|
|
);
|
|
file_put_contents($directory . '/mail.log', $line, FILE_APPEND | LOCK_EX);
|
|
}
|
|
}
|