add SMTP sender
This commit is contained in:
@@ -6,6 +6,7 @@ use App\Models\EmailFolder;
|
||||
use App\Models\EmailMessage;
|
||||
use App\Models\EmailAttachment;
|
||||
use App\Models\EmailSetting;
|
||||
use App\Models\SenderAccount;
|
||||
use App\Models\MailingList;
|
||||
use App\Models\Gruppo;
|
||||
use App\Models\Individuo;
|
||||
@@ -90,6 +91,7 @@ class EmailController extends Controller
|
||||
$mailingLists = MailingList::where('attiva', true)->get();
|
||||
$gruppi = Gruppo::orderBy('nome')->get();
|
||||
$individui = Individuo::orderBy('cognome')->orderBy('nome')->get();
|
||||
$senderAccounts = SenderAccount::active()->get();
|
||||
|
||||
$prefill = [];
|
||||
if ($request->reply_to) {
|
||||
@@ -108,7 +110,7 @@ class EmailController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
return view('email.compose', compact('folders', 'mailingLists', 'gruppi', 'individui', 'prefill'));
|
||||
return view('email.compose', compact('folders', 'mailingLists', 'gruppi', 'individui', 'prefill', 'senderAccounts'));
|
||||
}
|
||||
|
||||
public function send(Request $request)
|
||||
@@ -125,11 +127,6 @@ class EmailController extends Controller
|
||||
|
||||
$validated = $request->validate($rules);
|
||||
|
||||
$settings = EmailSetting::getActive();
|
||||
if (!$settings) {
|
||||
return back()->with('error', 'Account email non configurato.');
|
||||
}
|
||||
|
||||
$recipients = $this->resolveRecipients($request);
|
||||
|
||||
\Illuminate\Support\Facades\Log::info('Email send attempt', [
|
||||
@@ -137,44 +134,94 @@ class EmailController extends Controller
|
||||
'recipients_count' => count($recipients),
|
||||
'subject' => $validated['subject'],
|
||||
'destinatario_tipo' => $request->destinatario_tipo,
|
||||
'to' => $validated['to'] ?? null,
|
||||
'individui' => $request->individui,
|
||||
'gruppo_id' => $request->gruppo_id,
|
||||
'mailing_list_id' => $request->mailing_list_id,
|
||||
'mittente_id' => $request->mittente_id,
|
||||
]);
|
||||
|
||||
if (empty($recipients)) {
|
||||
return back()->with('error', 'Nessun destinatario trovato. Seleziona almeno un destinatario dal menu a tendina o inserisci un indirizzo email manuale.')->withInput();
|
||||
}
|
||||
|
||||
$useSender = $request->filled('mittente_id') && $request->mittente_id > 0;
|
||||
|
||||
if ($useSender) {
|
||||
return $this->sendWithSender($request, $validated, $recipients);
|
||||
}
|
||||
|
||||
$settings = EmailSetting::getActive();
|
||||
if (!$settings) {
|
||||
return back()->with('error', 'Account email non configurato.');
|
||||
}
|
||||
|
||||
$imapSuccess = false;
|
||||
$imapError = null;
|
||||
$attachments = $this->processAttachments($request);
|
||||
|
||||
foreach ($recipients as $recipient) {
|
||||
try {
|
||||
$this->sendViaImap($settings, $recipient, $validated['subject'], $validated['body'], $request->cc);
|
||||
$bodyWithSig = $this->appendSignature($validated['body'], $settings->getSignature(), $settings->signature_enabled ?? false);
|
||||
$this->sendViaImap($settings, $recipient, $validated['subject'], $bodyWithSig, $request->cc, $attachments);
|
||||
$imapSuccess = true;
|
||||
} catch (\Exception $e) {
|
||||
$imapError = $e->getMessage();
|
||||
\Illuminate\Support\Facades\Log::error('IMAP send error', ['error' => $e->getMessage()]);
|
||||
\Illuminate\Support\Facades\Log::error('SMTP send error', ['error' => $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$this->storeSentMessage($settings, $recipients, $validated['subject'], $validated['body'], $request->cc);
|
||||
\Illuminate\Support\Facades\Log::info('Stored sent message');
|
||||
$bodyWithSig = $this->appendSignature($validated['body'], $settings->getSignature(), $settings->signature_enabled ?? false);
|
||||
$this->storeSentMessage($settings, $recipients, $validated['subject'], $bodyWithSig, $request->cc);
|
||||
} catch (\Exception $e) {
|
||||
\Illuminate\Support\Facades\Log::error('Store sent message error', ['error' => $e->getMessage()]);
|
||||
return back()->with('error', 'Errore nel salvataggio: ' . $e->getMessage())->withInput();
|
||||
}
|
||||
|
||||
if (!$imapSuccess && $imapError) {
|
||||
return redirect()->route('email.index', 'sent')->with('warning', 'Email salvata in Invio ma non inviata via IMAP: ' . $imapError);
|
||||
return redirect()->route('email.index', 'sent')->with('warning', 'Email salvata in Invio ma non inviata via SMTP: ' . $imapError);
|
||||
}
|
||||
|
||||
return redirect()->route('email.index', 'sent')->with('success', 'Email inviata con successo.');
|
||||
}
|
||||
|
||||
private function sendWithSender(Request $request, array $validated, array $recipients)
|
||||
{
|
||||
$sender = SenderAccount::findOrFail($request->mittente_id);
|
||||
$attachmentPaths = $this->resolveAttachmentPaths($request);
|
||||
$ok = 0;
|
||||
$errors = [];
|
||||
|
||||
foreach ($recipients as $recipient) {
|
||||
try {
|
||||
$sender->sendEmail($recipient, $validated['subject'], $validated['body'], $attachmentPaths);
|
||||
$ok++;
|
||||
} catch (\Exception $e) {
|
||||
$errors[] = $recipient . ': ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
if ($sender->verify_email) {
|
||||
$reportSubject = '✅ Invio: ' . $validated['subject'] . ' - ' . $sender->email_address;
|
||||
$reportBody = "Report invio mittente: {$sender->email_address}\n"
|
||||
. "Destinatari totali: " . count($recipients) . "\n"
|
||||
. "Inviate con successo: {$ok}\n"
|
||||
. "Fallite: " . count($errors) . "\n";
|
||||
if (!empty($errors)) {
|
||||
$reportBody .= "\nDettaglio errori:\n" . implode("\n", $errors);
|
||||
}
|
||||
$sender->sendReport($reportSubject, $reportBody);
|
||||
}
|
||||
|
||||
if ($ok === 0 && !empty($errors)) {
|
||||
return redirect()->route('email.index', 'sent')->with('error', 'Invio fallito: ' . implode('; ', $errors));
|
||||
}
|
||||
|
||||
$message = $ok . ' email inviate con successo tramite "' . $sender->email_address . '".';
|
||||
if (!empty($errors)) {
|
||||
$message .= ' ' . count($errors) . ' fallite.';
|
||||
}
|
||||
|
||||
return redirect()->route('email.index', 'sent')->with('success', $message);
|
||||
}
|
||||
|
||||
public function storeDraft(Request $request)
|
||||
{
|
||||
$this->authorizeWrite('email');
|
||||
@@ -454,10 +501,8 @@ class EmailController extends Controller
|
||||
return $body . "\n\n---\n" . $signature;
|
||||
}
|
||||
|
||||
private function sendViaImap($settings, $to, $subject, $body, $cc = null)
|
||||
private function sendViaImap($settings, $to, $subject, $body, $cc = null, array $attachmentPaths = [])
|
||||
{
|
||||
$bodyWithSignature = $this->appendSignature($body, $settings->getSignature(), $settings->signature_enabled ?? false);
|
||||
|
||||
\Illuminate\Support\Facades\Log::info('sendViaSMTP start', ['to' => $to, 'subject' => $subject]);
|
||||
|
||||
$smtpPassword = $settings->getDecryptedSmtpPassword() ?? $settings->getDecryptedPassword();
|
||||
@@ -475,8 +520,6 @@ class EmailController extends Controller
|
||||
$encryption
|
||||
);
|
||||
|
||||
\Illuminate\Support\Facades\Log::info('SMTP DSN', ['dsn' => $dsn]);
|
||||
|
||||
try {
|
||||
$transport = \Symfony\Component\Mailer\Transport::fromDsn($dsn);
|
||||
$mailer = new \Symfony\Component\Mailer\Mailer($transport);
|
||||
@@ -498,11 +541,15 @@ class EmailController extends Controller
|
||||
->from($fromAddress)
|
||||
->to($to)
|
||||
->subject($subject)
|
||||
->text($bodyWithSignature);
|
||||
->text($body);
|
||||
|
||||
if ($cc) {
|
||||
$email->cc($cc);
|
||||
}
|
||||
|
||||
foreach ($attachmentPaths as $attachmentPath) {
|
||||
$email->attachFromPath($attachmentPath);
|
||||
}
|
||||
|
||||
$mailer->send($email);
|
||||
|
||||
@@ -514,6 +561,45 @@ class EmailController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
private function processAttachments(Request $request): array
|
||||
{
|
||||
$paths = [];
|
||||
if ($request->hasFile('allegati')) {
|
||||
foreach ($request->file('allegati') as $file) {
|
||||
if ($file->isValid()) {
|
||||
$paths[] = $file->getRealPath();
|
||||
}
|
||||
}
|
||||
}
|
||||
return $paths;
|
||||
}
|
||||
|
||||
private function resolveAttachmentPaths(Request $request): array
|
||||
{
|
||||
$paths = [];
|
||||
|
||||
if ($request->hasFile('allegati')) {
|
||||
foreach ($request->file('allegati') as $file) {
|
||||
if ($file->isValid()) {
|
||||
$paths[] = $file->getRealPath();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$documentIds = $request->input('documenti_selezionati');
|
||||
if (!empty($documentIds)) {
|
||||
$ids = is_array($documentIds) ? $documentIds : explode(',', $documentIds);
|
||||
$docs = Documento::whereIn('id', $ids)->get();
|
||||
foreach ($docs as $doc) {
|
||||
if ($doc->file_path && \Illuminate\Support\Facades\Storage::exists($doc->file_path)) {
|
||||
$paths[] = \Illuminate\Support\Facades\Storage::path($doc->file_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $paths;
|
||||
}
|
||||
|
||||
private function storeSentMessage($settings, $recipients, $subject, $body, $cc = null)
|
||||
{
|
||||
$sentFolder = EmailFolder::where('type', 'sent')->first();
|
||||
|
||||
Reference in New Issue
Block a user