140 lines
5.9 KiB
PHP
140 lines
5.9 KiB
PHP
<?php
|
|
|
|
/**
|
|
* SchoolMail
|
|
* Email agli allievi a nome di una scuola, con il template standard (mail/emailtemplate2.php).
|
|
* Se l'invio fallisce registra l'errore e ritorna false: non blocca mai l'operazione.
|
|
*
|
|
* SchoolMail::toStudent($email, $firstname, 'Oggetto', ['riga 1', 'riga 2']);
|
|
* SchoolMail::toStudent($email, $firstname, 'Oggetto', $lines, '', $schoolRow, true); // copia alla scuola
|
|
* SchoolMail::toMany([['email'=>..,'first_name'=>..], ...], 'Oggetto', $lines); // invio di massa
|
|
*
|
|
* Le righe sono HTML: i dati variabili vanno passati già con htmlspecialchars().
|
|
*/
|
|
|
|
use PHPMailer\PHPMailer\PHPMailer;
|
|
use PHPMailer\PHPMailer\Exception;
|
|
|
|
require_once __DIR__ . '/mailer.php';
|
|
|
|
class SchoolMail
|
|
{
|
|
public static function toStudent(
|
|
string $to,
|
|
string $firstName,
|
|
string $subject,
|
|
array $lines,
|
|
string $altText = '',
|
|
?array $school = null,
|
|
bool $ccSchool = false
|
|
): bool {
|
|
if (!filter_var($to, FILTER_VALIDATE_EMAIL)) {
|
|
return false;
|
|
}
|
|
$school = $school ?? SchoolContext::get();
|
|
$mail = self::mailer($school);
|
|
try {
|
|
$mail->addAddress($to);
|
|
if ($ccSchool && !empty($school['email']) && filter_var($school['email'], FILTER_VALIDATE_EMAIL)) {
|
|
$mail->addCC($school['email'], (string) $school['name']);
|
|
}
|
|
$mail->Subject = $subject;
|
|
$mail->Body = self::render($firstName, $lines, $school);
|
|
$mail->AltBody = $altText !== '' ? $altText : strip_tags(implode("\n", $lines));
|
|
$mail->send();
|
|
return true;
|
|
} catch (Exception $e) {
|
|
error_log('SchoolMail error (' . $to . '): ' . $mail->ErrorInfo);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Invio di massa con una sola connessione SMTP.
|
|
* @param array $recipients [['email' => ..., 'first_name' => ...], ...]
|
|
* @return array{sent:int, failed:int}
|
|
*/
|
|
public static function toMany(array $recipients, string $subject, array $lines, ?array $school = null): array
|
|
{
|
|
$school = $school ?? SchoolContext::get();
|
|
$mail = self::mailer($school);
|
|
$mail->SMTPKeepAlive = true;
|
|
$sent = 0;
|
|
$failed = 0;
|
|
|
|
foreach ($recipients as $r) {
|
|
$to = (string) ($r['email'] ?? '');
|
|
if (!filter_var($to, FILTER_VALIDATE_EMAIL)) {
|
|
$failed++;
|
|
continue;
|
|
}
|
|
try {
|
|
$mail->clearAddresses();
|
|
$mail->addAddress($to);
|
|
$mail->Subject = $subject;
|
|
$mail->Body = self::render((string) ($r['first_name'] ?? ''), $lines, $school);
|
|
$mail->AltBody = strip_tags(implode("\n", $lines));
|
|
$mail->send();
|
|
$sent++;
|
|
} catch (Exception $e) {
|
|
error_log('SchoolMail bulk error (' . $to . '): ' . $mail->ErrorInfo);
|
|
$failed++;
|
|
$mail->getSMTPInstance()->reset();
|
|
}
|
|
}
|
|
$mail->smtpClose();
|
|
return ['sent' => $sent, 'failed' => $failed];
|
|
}
|
|
|
|
/* ------------------------------------------------------------------ */
|
|
|
|
private static function mailer(array $school): PHPMailer
|
|
{
|
|
$schoolName = (string) ($school['name'] ?? 'YogiBook');
|
|
$mail = new PHPMailer(true);
|
|
$mail->isSMTP();
|
|
$mail->Host = $_ENV['MAIL_HOST'];
|
|
$mail->SMTPAuth = true;
|
|
$mail->Username = $_ENV['MAIL_USERNAME'];
|
|
$mail->Password = $_ENV['MAIL_PASSWORD'];
|
|
$mail->SMTPSecure = $_ENV['MAIL_ENCRYPTION'];
|
|
$mail->Port = (int) $_ENV['MAIL_PORT'];
|
|
$mail->CharSet = 'UTF-8';
|
|
$mail->Timeout = 20;
|
|
$mail->isHTML(true);
|
|
$mail->setFrom($_ENV['MAIL_FROM_ADDRESS'], $schoolName ?: ($_ENV['MAIL_FROM_NAME'] ?? 'YogiBook'));
|
|
if (!empty($school['email']) && filter_var($school['email'], FILTER_VALIDATE_EMAIL)) {
|
|
$mail->addReplyTo($school['email'], $schoolName);
|
|
}
|
|
return $mail;
|
|
}
|
|
|
|
private static function render(string $firstName, array $lines, array $school): string
|
|
{
|
|
$schoolName = (string) ($school['name'] ?? 'YogiBook');
|
|
$appUrl = rtrim($_ENV['APP_URL'] ?? 'https://yogibook.yogasoul.it', '/');
|
|
$h = fn($v) => htmlspecialchars((string) $v, ENT_QUOTES, 'UTF-8');
|
|
$p = "<p style='font-size: 14px; line-height: 190%;'><span style='font-size: 16px; line-height: 30.4px;'>";
|
|
$pe = "</span></p>";
|
|
$btn = "box-sizing: border-box; display: inline-block; text-decoration: none; text-align: center; color: #FFFFFF; background-color: #3AAEE0; border-radius: 4px; font-size: 14px;";
|
|
|
|
$greeting = trim($firstName) !== '' ? 'Ciao ' . $h($firstName) . ',' : 'Ciao,';
|
|
$body = "<p style='font-size: 14px; line-height: 190%;'><span style='font-size: 18px; line-height: 34.2px;'><strong>{$greeting}</strong></span></p>";
|
|
foreach ($lines as $line) {
|
|
$body .= $p . $line . $pe;
|
|
}
|
|
$body .= "<br>{$p}Per vedere e gestire le tue lezioni: <a href='{$appUrl}'>YogiBook</a>{$pe}"
|
|
. "<br>{$p}Se non ricordi la password o non sei mai entrata/o in YogiBook, reimpostala da qui:{$pe}<br>"
|
|
. "<a href='{$appUrl}/password/reset' target='_blank' style='{$btn}'><span style='display: block; padding: 10px 20px; line-height: 120%;'>Reimposta password</span></a>"
|
|
. "<br><br>{$p}Ci vediamo sul tappetino!{$pe}{$p}" . $h($schoolName) . $pe;
|
|
|
|
// Variabili attese dal template
|
|
$messageedit = $body;
|
|
$buttonedit = "<a href='{$appUrl}/' target='_blank' class='v-button v-font-size' style='{$btn}'>"
|
|
. "<span style='display: block; padding: 10px 20px; line-height: 120%;'>YogiBook - " . $h($schoolName) . "</span></a>";
|
|
$mailmessage1 = '';
|
|
include __DIR__ . '/../mail/emailtemplate2.php';
|
|
return $mailmessage1 ?: $body;
|
|
}
|
|
}
|