glastree_on_gitea
This commit is contained in:
@@ -0,0 +1,599 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\EmailFolder;
|
||||
use App\Models\EmailMessage;
|
||||
use App\Models\EmailAttachment;
|
||||
use App\Models\EmailSetting;
|
||||
use App\Models\MailingList;
|
||||
use App\Models\Gruppo;
|
||||
use App\Models\Individuo;
|
||||
use App\Models\Documento;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class EmailController extends Controller
|
||||
{
|
||||
public function index(Request $request, $folder = 'inbox')
|
||||
{
|
||||
$this->authorizeRead('email');
|
||||
if ($folder === 'compose' || $folder === 'nuovo') {
|
||||
return $this->compose($request);
|
||||
}
|
||||
|
||||
$folderModel = EmailFolder::where('type', $folder)->first();
|
||||
|
||||
if (!$folderModel) {
|
||||
$folderModel = EmailFolder::where('type', 'inbox')->first();
|
||||
if (!$folderModel) {
|
||||
$this->ensureFoldersExist();
|
||||
$folderModel = EmailFolder::where('type', 'inbox')->first();
|
||||
}
|
||||
}
|
||||
|
||||
$query = EmailMessage::where('email_folder_id', $folderModel->id);
|
||||
|
||||
if ($request->search) {
|
||||
$query->where(function ($q) use ($request) {
|
||||
$q->where('subject', 'like', '%' . $request->search . '%')
|
||||
->orWhere('from_email', 'like', '%' . $request->search . '%')
|
||||
->orWhere('to_email', 'like', '%' . $request->search . '%')
|
||||
->orWhere('body_text', 'like', '%' . $request->search . '%');
|
||||
});
|
||||
}
|
||||
|
||||
$sortField = $request->sort ?? 'received_at';
|
||||
$sortDir = $request->direction ?? 'desc';
|
||||
|
||||
$allowedSorts = ['subject', 'received_at', 'sent_at', 'from_email', 'to_email'];
|
||||
if (!in_array($sortField, $allowedSorts)) {
|
||||
$sortField = 'received_at';
|
||||
}
|
||||
if (!in_array($sortDir, ['asc', 'desc'])) {
|
||||
$sortDir = 'desc';
|
||||
}
|
||||
|
||||
$query->orderBy($sortField === 'sent_at' ? 'received_at' : $sortField, $sortDir);
|
||||
|
||||
$messages = $query->paginate(20)->withQueryString();
|
||||
$folders = EmailFolder::orderBy('sort_order')->get();
|
||||
$mailingLists = MailingList::where('attiva', true)->get();
|
||||
$gruppi = Gruppo::orderBy('nome')->get();
|
||||
|
||||
$emailSettings = EmailSetting::getActive();
|
||||
$syncInterval = $emailSettings ? $emailSettings->sync_interval_minutes : 0;
|
||||
|
||||
return view('email.index', compact('messages', 'folders', 'folder', 'folderModel', 'mailingLists', 'gruppi', 'syncInterval'));
|
||||
}
|
||||
|
||||
public function show($folder, $id)
|
||||
{
|
||||
$this->authorizeRead('email');
|
||||
$message = EmailMessage::with('attachments')->findOrFail($id);
|
||||
|
||||
if (!$message->is_read) {
|
||||
$message->update(['is_read' => true]);
|
||||
}
|
||||
|
||||
$folders = EmailFolder::orderBy('sort_order')->get();
|
||||
|
||||
return view('email.show', compact('message', 'folders', 'folder'));
|
||||
}
|
||||
|
||||
public function compose(Request $request)
|
||||
{
|
||||
$this->authorizeWrite('email');
|
||||
$folders = EmailFolder::orderBy('sort_order')->get();
|
||||
$mailingLists = MailingList::where('attiva', true)->get();
|
||||
$gruppi = Gruppo::orderBy('nome')->get();
|
||||
$individui = Individuo::orderBy('cognome')->orderBy('nome')->get();
|
||||
|
||||
$prefill = [];
|
||||
if ($request->reply_to) {
|
||||
$original = EmailMessage::find($request->reply_to);
|
||||
if ($original) {
|
||||
$prefill['to'] = $original->from_email;
|
||||
$prefill['subject'] = 'Re: ' . $original->subject;
|
||||
$prefill['body'] = "\n\n--- Messaggio originale ---\n" . ($original->body_text ?? $original->body_html);
|
||||
}
|
||||
}
|
||||
if ($request->forward) {
|
||||
$original = EmailMessage::find($request->forward);
|
||||
if ($original) {
|
||||
$prefill['subject'] = 'Fwd: ' . $original->subject;
|
||||
$prefill['body'] = "\n\n--- Messaggio inoltrato ---\n" . ($original->body_text ?? $original->body_html);
|
||||
}
|
||||
}
|
||||
|
||||
return view('email.compose', compact('folders', 'mailingLists', 'gruppi', 'individui', 'prefill'));
|
||||
}
|
||||
|
||||
public function send(Request $request)
|
||||
{
|
||||
$this->authorizeWrite('email');
|
||||
$rules = [
|
||||
'subject' => 'required',
|
||||
'body' => 'required',
|
||||
];
|
||||
|
||||
if ($request->destinatario_tipo === 'manuale' || !$request->destinatario_tipo) {
|
||||
$rules['to'] = 'required';
|
||||
}
|
||||
|
||||
$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', [
|
||||
'recipients' => $recipients,
|
||||
'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,
|
||||
]);
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
$imapSuccess = false;
|
||||
$imapError = null;
|
||||
|
||||
foreach ($recipients as $recipient) {
|
||||
try {
|
||||
$this->sendViaImap($settings, $recipient, $validated['subject'], $validated['body'], $request->cc);
|
||||
$imapSuccess = true;
|
||||
} catch (\Exception $e) {
|
||||
$imapError = $e->getMessage();
|
||||
\Illuminate\Support\Facades\Log::error('IMAP send error', ['error' => $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$this->storeSentMessage($settings, $recipients, $validated['subject'], $validated['body'], $request->cc);
|
||||
\Illuminate\Support\Facades\Log::info('Stored sent message');
|
||||
} 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('success', 'Email inviata con successo.');
|
||||
}
|
||||
|
||||
public function storeDraft(Request $request)
|
||||
{
|
||||
$this->authorizeWrite('email');
|
||||
$settings = EmailSetting::getActive();
|
||||
$folder = EmailFolder::where('type', 'drafts')->first();
|
||||
|
||||
$message = EmailMessage::create([
|
||||
'email_folder_id' => $folder->id,
|
||||
'subject' => $request->subject ?? '(senza oggetto)',
|
||||
'body_text' => $request->body,
|
||||
'to_email' => $request->to,
|
||||
'is_draft' => true,
|
||||
'from_email' => $settings->email_address ?? '',
|
||||
'from_name' => $settings->email_name ?? '',
|
||||
]);
|
||||
|
||||
return response()->json(['success' => true, 'draft_id' => $message->id]);
|
||||
}
|
||||
|
||||
public function bulkAction(Request $request)
|
||||
{
|
||||
try {
|
||||
$this->authorizeWrite('email');
|
||||
} catch (\Symfony\Component\HttpKernel\Exception\HttpException $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Non hai i permessi per questa azione'
|
||||
], 403);
|
||||
}
|
||||
|
||||
$ids = $request->input('ids', []);
|
||||
$action = $request->input('action');
|
||||
|
||||
if ($action === 'empty_trash') {
|
||||
$trashFolder = EmailFolder::where('type', 'trash')->first();
|
||||
if ($trashFolder) {
|
||||
EmailMessage::where('email_folder_id', $trashFolder->id)->delete();
|
||||
}
|
||||
return response()->json(['success' => true]);
|
||||
}
|
||||
|
||||
if (empty($ids)) {
|
||||
return response()->json(['success' => false, 'message' => 'Nessuna email selezionata']);
|
||||
}
|
||||
|
||||
$messages = EmailMessage::whereIn('id', $ids)->get();
|
||||
|
||||
switch ($action) {
|
||||
case 'mark_read':
|
||||
$messages->each->update(['is_read' => true]);
|
||||
break;
|
||||
case 'mark_unread':
|
||||
$messages->each->update(['is_read' => false]);
|
||||
break;
|
||||
case 'star':
|
||||
$messages->each->update(['is_starred' => true]);
|
||||
break;
|
||||
case 'unstar':
|
||||
$messages->each->update(['is_starred' => false]);
|
||||
break;
|
||||
case 'move_trash':
|
||||
$trashFolder = EmailFolder::where('type', 'trash')->first();
|
||||
if ($trashFolder) {
|
||||
$messages->each->update(['email_folder_id' => $trashFolder->id]);
|
||||
}
|
||||
break;
|
||||
case 'delete_permanent':
|
||||
$messages->each->delete();
|
||||
break;
|
||||
default:
|
||||
return response()->json(['success' => false, 'message' => 'Azione non valida']);
|
||||
}
|
||||
|
||||
return response()->json(['success' => true]);
|
||||
}
|
||||
|
||||
public function markRead($id)
|
||||
{
|
||||
try {
|
||||
$this->authorizeWrite('email');
|
||||
} catch (\Symfony\Component\HttpKernel\Exception\HttpException $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Non hai i permessi per questa azione'
|
||||
], 403);
|
||||
}
|
||||
$message = EmailMessage::findOrFail($id);
|
||||
$message->update(['is_read' => true]);
|
||||
return response()->json(['success' => true]);
|
||||
}
|
||||
|
||||
public function toggleStar($id)
|
||||
{
|
||||
try {
|
||||
$this->authorizeWrite('email');
|
||||
} catch (\Symfony\Component\HttpKernel\Exception\HttpException $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Non hai i permessi per questa azione'
|
||||
], 403);
|
||||
}
|
||||
$message = EmailMessage::findOrFail($id);
|
||||
$message->update(['is_starred' => !$message->is_starred]);
|
||||
return response()->json(['success' => true, 'is_starred' => $message->is_starred]);
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
$this->authorizeDelete('email');
|
||||
$message = EmailMessage::findOrFail($id);
|
||||
$trashFolder = EmailFolder::where('type', 'trash')->first();
|
||||
|
||||
if ($trashFolder) {
|
||||
$message->update(['is_trash' => true, 'email_folder_id' => $trashFolder->id]);
|
||||
} else {
|
||||
$message->delete();
|
||||
}
|
||||
|
||||
return back()->with('success', 'Email spostata nel cestino.');
|
||||
}
|
||||
|
||||
public function downloadAttachment($id)
|
||||
{
|
||||
$this->authorizeRead('email');
|
||||
$attachment = EmailAttachment::findOrFail($id);
|
||||
|
||||
if (!Storage::exists($attachment->file_path)) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
return Storage::download($attachment->file_path, $attachment->filename);
|
||||
}
|
||||
|
||||
public function saveAttachmentToDocumenti(Request $request, $id, $attachmentId)
|
||||
{
|
||||
$this->authorizeWrite('email');
|
||||
$this->authorizeWrite('documenti');
|
||||
$attachment = EmailAttachment::findOrFail($attachmentId);
|
||||
|
||||
$documento = Documento::create([
|
||||
'nome_file' => $attachment->filename,
|
||||
'file_path' => $attachment->file_path,
|
||||
'tipo' => 'upload',
|
||||
'tipologia' => 'email_attachment',
|
||||
'mime_type' => $attachment->mime_type,
|
||||
'dimensione' => $attachment->size,
|
||||
'visibilita' => null,
|
||||
'note' => 'Allegato email: ' . ($attachment->message->subject ?? ''),
|
||||
]);
|
||||
|
||||
$attachment->update(['is_saved_to_documenti' => true, 'documenti_id' => $documento->id]);
|
||||
|
||||
return back()->with('success', 'Allegato salvato nei documenti.');
|
||||
}
|
||||
|
||||
public function quickSync()
|
||||
{
|
||||
try {
|
||||
$this->syncEmails();
|
||||
return response()->json(['success' => true, 'message' => 'Sincronizzazione completata']);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(['success' => false, 'message' => $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
public function syncEmails()
|
||||
{
|
||||
$settings = EmailSetting::getActive();
|
||||
if (!$settings) {
|
||||
throw new \Exception('Nessuna configurazione email attiva');
|
||||
}
|
||||
|
||||
$this->ensureFoldersExist();
|
||||
|
||||
$mailbox = $this->connectImap($settings);
|
||||
|
||||
$folderMappings = [
|
||||
'INBOX' => 'inbox',
|
||||
'Sent' => 'sent',
|
||||
'[Gmail]/Sent Mail' => 'sent',
|
||||
'Sent Mail' => 'sent',
|
||||
'Drafts' => 'drafts',
|
||||
'[Gmail]/Drafts' => 'drafts',
|
||||
'Trash' => 'trash',
|
||||
'[Gmail]/Trash' => 'trash',
|
||||
];
|
||||
|
||||
foreach (array_keys($folderMappings) as $imapFolderName) {
|
||||
try {
|
||||
$folder = $mailbox->folders()->find($imapFolderName);
|
||||
if (!$folder) continue;
|
||||
|
||||
$messages = $folder->messages()
|
||||
->withHeaders()
|
||||
->withBody()
|
||||
->withBodyStructure()
|
||||
->limit(100)
|
||||
->get();
|
||||
|
||||
foreach ($messages as $imapMessage) {
|
||||
$this->processImapMessage($imapMessage, $imapFolderName);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function resolveRecipients(Request $request)
|
||||
{
|
||||
$recipients = [];
|
||||
|
||||
if ($request->destinatario_tipo === 'individui' && $request->individui) {
|
||||
$individui = Individuo::whereIn('id', $request->individui)->get();
|
||||
foreach ($individui as $ind) {
|
||||
$emails = $ind->contatti()->where('tipo', 'email')->pluck('valore')->toArray();
|
||||
$recipients = array_merge($recipients, $emails);
|
||||
}
|
||||
} elseif ($request->destinatario_tipo === 'gruppo' && $request->gruppo_id) {
|
||||
$gruppo = Gruppo::with('individui.contatti')->find($request->gruppo_id);
|
||||
foreach ($gruppo->individui as $ind) {
|
||||
$emails = $ind->contatti()->where('tipo', 'email')->pluck('valore')->toArray();
|
||||
$recipients = array_merge($recipients, $emails);
|
||||
}
|
||||
} elseif ($request->destinatario_tipo === 'mailing_list' && $request->mailing_list_id) {
|
||||
$list = MailingList::with('contatti.individuo')->find($request->mailing_list_id);
|
||||
foreach ($list->contatti as $contact) {
|
||||
if ($contact->opt_in && $contact->individuo) {
|
||||
$emails = $contact->individuo->contatti()->where('tipo', 'email')->pluck('valore')->toArray();
|
||||
$recipients = array_merge($recipients, $emails);
|
||||
}
|
||||
}
|
||||
} elseif ($request->to) {
|
||||
$recipients = is_array($request->to) ? $request->to : [$request->to];
|
||||
}
|
||||
|
||||
return array_filter(array_unique($recipients));
|
||||
}
|
||||
|
||||
private function appendSignature(string $body, ?string $signature, bool $enabled): string
|
||||
{
|
||||
if (empty($signature) || !$enabled) {
|
||||
return $body;
|
||||
}
|
||||
return $body . "\n\n---\n" . $signature;
|
||||
}
|
||||
|
||||
private function sendViaImap($settings, $to, $subject, $body, $cc = null)
|
||||
{
|
||||
$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();
|
||||
|
||||
$encryption = $settings->smtp_encryption ?? 'tls';
|
||||
$scheme = ($encryption === 'ssl') ? 'smtps' : 'smtp';
|
||||
|
||||
$dsn = sprintf(
|
||||
'%s://%s:%s@%s:%d?encryption=%s',
|
||||
$scheme,
|
||||
rawurlencode($settings->smtp_username ?? $settings->email_address),
|
||||
rawurlencode($smtpPassword),
|
||||
$settings->smtp_host ?? 'smtp.gmail.com',
|
||||
$settings->smtp_port ?? 587,
|
||||
$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);
|
||||
|
||||
$fromName = $settings->email_name ?? '';
|
||||
if (filter_var($fromName, FILTER_VALIDATE_EMAIL)) {
|
||||
$fromName = 'Glastree';
|
||||
} else {
|
||||
$fromName = preg_replace('/[^\p{L}\p{N}\s]/u', '', $fromName);
|
||||
$fromName = trim($fromName);
|
||||
if (empty($fromName)) {
|
||||
$fromName = 'Glastree';
|
||||
}
|
||||
}
|
||||
|
||||
$fromAddress = \Symfony\Component\Mime\Address::create($settings->email_address, $fromName);
|
||||
|
||||
$email = (new \Symfony\Component\Mime\Email())
|
||||
->from($fromAddress)
|
||||
->to($to)
|
||||
->subject($subject)
|
||||
->text($bodyWithSignature);
|
||||
|
||||
if ($cc) {
|
||||
$email->cc($cc);
|
||||
}
|
||||
|
||||
$mailer->send($email);
|
||||
|
||||
\Illuminate\Support\Facades\Log::info('Email sent via SMTP successfully');
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
\Illuminate\Support\Facades\Log::error('SMTP send error', ['error' => $e->getMessage()]);
|
||||
throw new \Exception('Errore invio SMTP: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function storeSentMessage($settings, $recipients, $subject, $body, $cc = null)
|
||||
{
|
||||
$sentFolder = EmailFolder::where('type', 'sent')->first();
|
||||
$bodyWithSignature = $this->appendSignature($body, $settings->getSignature(), $settings->signature_enabled ?? false);
|
||||
|
||||
$message = EmailMessage::create([
|
||||
'email_folder_id' => $sentFolder->id,
|
||||
'subject' => $subject,
|
||||
'body_text' => $bodyWithSignature,
|
||||
'from_email' => $settings->email_address,
|
||||
'from_name' => $settings->email_name,
|
||||
'to_email' => implode(', ', $recipients),
|
||||
'cc' => $cc,
|
||||
'is_sent' => true,
|
||||
'sent_at' => now(),
|
||||
'is_read' => true,
|
||||
]);
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
private function connectImap($settings)
|
||||
{
|
||||
if (!$settings->imap_host || !$settings->imap_username) {
|
||||
throw new \Exception('Configurazione IMAP non valida');
|
||||
}
|
||||
|
||||
$encryption = match ($settings->imap_encryption) {
|
||||
'ssl' => 'ssl',
|
||||
'tls' => 'tls',
|
||||
default => 'none',
|
||||
};
|
||||
|
||||
return new \DirectoryTree\ImapEngine\Mailbox([
|
||||
'host' => $settings->imap_host,
|
||||
'port' => $settings->imap_port ?? 993,
|
||||
'encryption' => $encryption,
|
||||
'validate_cert' => false,
|
||||
'username' => $settings->imap_username,
|
||||
'password' => $settings->getDecryptedPassword(),
|
||||
]);
|
||||
}
|
||||
|
||||
private function processImapMessage($imapMessage, $imapFolder)
|
||||
{
|
||||
$folderType = match ($imapFolder) {
|
||||
'INBOX', 'inbox' => 'inbox',
|
||||
'Sent', 'sent', '[Gmail]/Sent Mail' => 'sent',
|
||||
'Drafts', 'drafts', '[Gmail]/Drafts' => 'drafts',
|
||||
'Trash', 'trash', '[Gmail]/Trash' => 'trash',
|
||||
'Archive', 'archive', '[Gmail]/All Mail' => 'archive',
|
||||
'Starred', 'starred', '[Gmail]/Starred' => 'starred',
|
||||
default => 'inbox',
|
||||
};
|
||||
|
||||
$folder = EmailFolder::where('type', $folderType)->first();
|
||||
if (!$folder) return;
|
||||
|
||||
$messageId = $imapMessage->messageId() ?? uniqid('msg_');
|
||||
|
||||
$existing = EmailMessage::where('message_id', $messageId)->first();
|
||||
if ($existing) return;
|
||||
|
||||
$from = $imapMessage->from();
|
||||
$to = $imapMessage->to();
|
||||
|
||||
$message = EmailMessage::create([
|
||||
'email_folder_id' => $folder->id,
|
||||
'message_id' => $messageId,
|
||||
'subject' => $imapMessage->subject() ?? '(senza oggetto)',
|
||||
'from_name' => $from?->name() ?? '',
|
||||
'from_email' => $from?->email() ?? '',
|
||||
'to_email' => count($to) > 0 ? $to[0]->email() : '',
|
||||
'body_text' => $imapMessage->text() ?? '',
|
||||
'body_html' => $imapMessage->html() ?? '',
|
||||
'is_read' => $imapMessage->isSeen() ?? false,
|
||||
'is_starred' => $imapMessage->isFlagged() ?? false,
|
||||
'is_sent' => $folderType === 'sent',
|
||||
'received_at' => $imapMessage->date() ?? now(),
|
||||
'imap_uid' => $imapMessage->uid() ?? null,
|
||||
]);
|
||||
|
||||
$attachments = $imapMessage->attachments();
|
||||
if ($attachments && count($attachments) > 0) {
|
||||
foreach ($attachments as $attachment) {
|
||||
$filename = $attachment->filename() ?? 'attachment';
|
||||
$contents = $attachment->contents();
|
||||
$path = 'email-attachments/' . Str::uuid() . '_' . $filename;
|
||||
Storage::put($path, $contents);
|
||||
|
||||
EmailAttachment::create([
|
||||
'email_message_id' => $message->id,
|
||||
'filename' => $filename,
|
||||
'mime_type' => $attachment->contentType() ?? 'application/octet-stream',
|
||||
'size' => strlen($contents),
|
||||
'file_path' => $path,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function ensureFoldersExist()
|
||||
{
|
||||
$systemFolders = EmailFolder::getSystemFolders();
|
||||
|
||||
foreach ($systemFolders as $folder) {
|
||||
EmailFolder::updateOrCreate(
|
||||
['type' => $folder['type']],
|
||||
$folder
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user