Skip to content

Commit

Permalink
Added support to attachments. Optimized getSearchableFields method fo…
Browse files Browse the repository at this point in the history
…r Email model.
  • Loading branch information
marcogermani87 committed Apr 25, 2024
1 parent 6bf9e66 commit 0ba9712
Show file tree
Hide file tree
Showing 10 changed files with 161 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
public function up()
{
Schema::table('filament_email_log', function (Blueprint $table) {
$table->longText('attachments')->nullable()->default(null);
});
}

public function down()
{
Schema::table('filament_email_log', function (Blueprint $table) {
$table->dropColumn('attachments');
});
}
};
3 changes: 3 additions & 0 deletions resources/lang/en/filament-email.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,7 @@
'bcc' => 'Bcc',
'insert_multiple_email_placelholder' => 'Insert one or more e-mail',
'update_and_resend_email_heading' => 'Update and resend e-mail',
'attachments' => 'Attachments',
'download' => 'Download',
'download_attachment_error' => "Unable to download attachment!" ,
];
3 changes: 3 additions & 0 deletions resources/lang/it/filament-email.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,7 @@
'bcc' => 'Bcc',
'insert_multiple_email_placelholder' => 'Inserisci una o più e-mail',
'update_and_resend_email_heading' => 'Modifica and re-invia e-mail',
'attachments' => 'Allegati',
'download' => 'Scarica',
'download_attachment_error' => "Impossibile scaricare l'allegato!" ,
];
3 changes: 3 additions & 0 deletions resources/lang/nl/filament-email.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,7 @@
'bcc' => 'Bcc',
'insert_multiple_email_placelholder' => 'Type een of meerdere e-mailadressen in',
'update_and_resend_email_heading' => 'Bijwerken en e-mail opnieuw versturen',
'attachments' => 'Bijlagen',
'download' => 'Downloaden',
'download_attachment_error' => "Kan bijlage niet downloaden!" ,
];
20 changes: 20 additions & 0 deletions resources/views/attachments.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<div>
@if(!empty($getRecord()->attachments))
<ul class="max-w-md divide-y divide-gray-200 dark:divide-gray-700">
@foreach(json_decode($getRecord()->attachments) as $attachment)
<li class="pb-4 pt-4 sm:pb-4">
<div class="flex items-center space-x-4 rtl:space-x-reverse">
<div class="flex-1 min-w-0">
<p class="text-sm font-medium text-gray-900 truncate dark:text-white">
<strong>{{ $attachment->name }}</strong>
</p>
</div>
<div class="inline-flex items-center text-base font-semibold text-gray-900 dark:text-white">
{{ ($this->downloadAction)(['path' => $attachment->path, 'name' => $attachment->name , 'type' => $attachment->contentType]) }}
</div>
</div>
</li>
@endforeach
</ul>
@endif
</div>
43 changes: 26 additions & 17 deletions src/Filament/Resources/EmailResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@

use Filament\Forms\Components\DateTimePicker;
use Filament\Forms\Components\Fieldset;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Tabs;
use Filament\Forms\Components\TagsInput;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\View;
use Filament\Forms\Components\ViewField;
use Filament\Forms\Form;
use Filament\Notifications\Notification;
Expand Down Expand Up @@ -86,6 +89,12 @@ public static function form(Form $form): Form
->format(config('filament-email.resource.datetime_format'))
->label(__('filament-email::filament-email.created_at')),
])->columns(4),
Fieldset::make('attachments')
->label(__('filament-email::filament-email.attachments'))
->schema([
View::make('filament-email::attachments')
->columnSpanFull()
]),
Tabs::make('Content')->tabs([
Tabs\Tab::make(__('filament-email::filament-email.html'))
->schema([
Expand Down Expand Up @@ -123,7 +132,7 @@ public static function table(Table $table): Table
->icon('heroicon-o-eye')
->iconSize(IconSize::Medium)
->modalFooterActions(
fn ($action): array => [
fn($action): array => [
$action->getModalCancelAction(),
])
->fillForm(function ($record) {
Expand Down Expand Up @@ -181,21 +190,21 @@ public static function table(Table $table): Table
->nestedRecursiveRules([
'email',
])
->default(fn ($record): array => ! empty($record->to) ? explode(',', $record->to) : []),
->default(fn($record): array => !empty($record->to) ? explode(',', $record->to) : []),
TagsInput::make('cc')
->label(__('filament-email::filament-email.cc'))
->placeholder(__('filament-email::filament-email.insert_multiple_email_placelholder'))
->nestedRecursiveRules([
'email',
])
->default(fn ($record): array => ! empty($record->cc) ? explode(',', $record->cc) : []),
->default(fn($record): array => !empty($record->cc) ? explode(',', $record->cc) : []),
TagsInput::make('bcc')
->label(__('filament-email::filament-email.bcc'))
->placeholder(__('filament-email::filament-email.insert_multiple_email_placelholder'))
->nestedRecursiveRules([
'email',
])
->default(fn ($record): array => ! empty($record->bcc) ? explode(',', $record->bcc) : []),
->default(fn($record): array => !empty($record->bcc) ? explode(',', $record->bcc) : []),
])
->action(function (Email $record, array $data) {
try {
Expand All @@ -221,9 +230,9 @@ public static function table(Table $table): Table
])
->columns([
TextColumn::make('from')
->prefix(__('filament-email::filament-email.from').': ')
->prefix(__('filament-email::filament-email.from') . ': ')
->label(__('filament-email::filament-email.header'))
->description(fn (Email $record): string => Str::limit(__('filament-email::filament-email.to').': '.$record->to, 40))
->description(fn(Email $record): string => Str::limit(__('filament-email::filament-email.to') . ': ' . $record->to, 40))
->searchable(),
TextColumn::make('subject')
->label(__('filament-email::filament-email.subject'))
Expand Down Expand Up @@ -270,16 +279,16 @@ public static function table(Table $table): Table
$indicators = [];
$format = config('filament-email.resource.filter_date_format');

if (! empty($data['created_from'])) {
if (!empty($data['created_from'])) {
$from = Carbon::parse($data['created_from'])->format($format);
$indicators['created'] = __('filament-email::filament-email.from_filter')." $from";
$indicators['created'] = __('filament-email::filament-email.from_filter') . " $from";
}

if (! empty($data['created_until'])) {
if (!empty($data['created_until'])) {
$to = Carbon::parse($data['created_until'])->format($format);
$toText = __('filament-email::filament-email.to_filter');
if (! empty($indicators['created'])) {
$indicators['created'] .= ' '.strtolower($toText)." $to";
if (!empty($indicators['created'])) {
$indicators['created'] .= ' ' . strtolower($toText) . " $to";
} else {
$indicators['created'] = "$toText $to";
}
Expand All @@ -301,23 +310,23 @@ public static function table(Table $table): Table
return $query
->when(
$data['to'],
fn (Builder $query, $value): Builder => $query->where('to', 'like', "%$value%"),
fn(Builder $query, $value): Builder => $query->where('to', 'like', "%$value%"),
)
->when(
$data['cc'],
fn (Builder $query, $value): Builder => $query->where('cc', 'like', "%$value%"),
fn(Builder $query, $value): Builder => $query->where('cc', 'like', "%$value%"),
)
->when(
$data['bcc'],
fn (Builder $query, $value): Builder => $query->where('bcc', 'like', "%$value%"),
fn(Builder $query, $value): Builder => $query->where('bcc', 'like', "%$value%"),
)
->when(
$data['created_from'],
fn (Builder $query, $value): Builder => $query->where('created_at', '>=', $value),
fn(Builder $query, $value): Builder => $query->where('created_at', '>=', $value),
)
->when(
$data['created_until'],
fn (Builder $query, $value): Builder => $query->where('created_at', '<=', $value),
fn(Builder $query, $value): Builder => $query->where('created_at', '<=', $value),
);
}),
]);
Expand All @@ -335,7 +344,7 @@ public static function canAccess(): bool
{
$roles = config('filament-email.can_access.role') ?? [];

if (method_exists(auth()->user(), 'hasRole') && ! empty($roles)) {
if (method_exists(auth()->user(), 'hasRole') && !empty($roles)) {
return auth()->user()->hasRole($roles);
}

Expand Down
34 changes: 34 additions & 0 deletions src/Filament/Resources/EmailResource/Pages/ViewEmail.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,47 @@

namespace RickDBCN\FilamentEmail\Filament\Resources\EmailResource\Pages;

use Filament\Actions\Action;
use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\ViewRecord;
use Filament\Support\Enums\ActionSize;
use Filament\Support\Enums\IconSize;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use RickDBCN\FilamentEmail\Filament\Resources\EmailResource;
use RickDBCN\FilamentEmail\Models\Email;

class ViewEmail extends ViewRecord
{
use InteractsWithActions;

public Email $email;

public static function getResource(): string
{
return config('filament-email.resource.class', EmailResource::class);
}

public function downloadAction(): Action
{
return Action::make('download')
->label(__('filament-email::filament-email.download'))
->requiresConfirmation()
->icon('heroicon-c-arrow-down-tray')
->size(ActionSize::ExtraSmall)
->action(function (array $arguments) {
$filePath = storage_path('app' . DIRECTORY_SEPARATOR . $arguments['path']);
if (file_exists($filePath)) {
return Storage::download($arguments['path'], $arguments['name']);
} else {
Notification::make()
->title(__('filament-email::filament-email.download_attachment_error'))
->danger()
->duration(5000)
->send();
}
});
}
}
5 changes: 4 additions & 1 deletion src/FilamentEmailServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ public function configurePackage(Package $package): void
->hasConfigFile('filament-email')
->hasTranslations()
->hasViews()
->hasMigration('create_filament_email_table');
->hasMigrations([
'create_filament_email_table',
'add_attachments_field_to_filament_email_log_table',
]);

$this->app->register(EmailMessageServiceProvider::class);
}
Expand Down
20 changes: 19 additions & 1 deletion src/Listeners/FilamentEmailLogger.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
namespace RickDBCN\FilamentEmail\Listeners;

use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use RickDBCN\FilamentEmail\Models\Email;

class FilamentEmailLogger
Expand All @@ -27,6 +30,20 @@ public function handle(object $event): void

$model = Config::get('filament-email.resource.model') ?? Email::class;

$attachments = [];
$savePath = 'filament-email-log' . DIRECTORY_SEPARATOR . date('YmdHis') . '_' . Str::random(5) . DIRECTORY_SEPARATOR;

foreach ($event->message->getAttachments() as $attachment) {
$filePath = $savePath . Str::random(5) . '_' . $attachment->getFilename();
Storage::disk('local')
->put($filePath, $attachment->getBody());
$attachments[] = [
'name' => $attachment->getFilename(),
'contentType' => $attachment->getContentType(),
'path' => $filePath,
];
}

$model::create([
'from' => $this->recipientsToString($email->getFrom()),
'to' => $this->recipientsToString($email->getTo()),
Expand All @@ -37,6 +54,7 @@ public function handle(object $event): void
'text_body' => $email->getTextBody(),
'raw_body' => $rawMessage->getMessage()->toString(),
'sent_debug_info' => $rawMessage->getDebug(),
'attachments' => json_encode($attachments),
]);

}
Expand All @@ -46,7 +64,7 @@ private function recipientsToString(array $recipients): string
return implode(
',',
array_map(function ($email) {
return "{$email->getAddress()}".($email->getName() ? " <{$email->getName()}>" : '');
return "{$email->getAddress()}" . ($email->getName() ? " <{$email->getName()}>" : '');
}, $recipients)
);
}
Expand Down
29 changes: 27 additions & 2 deletions src/Models/Email.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
use Illuminate\Support\Arr;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;

/**
* Email
Expand Down Expand Up @@ -38,6 +40,28 @@ class Email extends Model
'to',
];

public static function boot()
{
parent::boot();

self::deleting(function ($record) {
if (!empty($record->attachments)) {
foreach (json_decode($record->attachments) as $attachment) {
$filePath = storage_path('app' . DIRECTORY_SEPARATOR . $attachment->path);
$parts = explode(DIRECTORY_SEPARATOR, $filePath);
array_pop($parts);
$folderPath = implode(DIRECTORY_SEPARATOR, $parts);
if (file_exists($filePath)) {
unlink($filePath);
}
if (file_exists($folderPath)) {
rmdir($folderPath);
}
}
}
});
}

public function prunable()
{
return static::where('created_at', '<=', now()->subDays(Config::get('filament-email.keep_email_for_days')));
Expand All @@ -50,10 +74,11 @@ private function getTableColumns()

private function getSearchableFields()
{
$columns = $this->getTableColumns();
$fields = Config::get('filament-email.resource.table_search_fields', $this->defaultSearchFields);

return Arr::where($fields, function ($value, $key) {
return in_array($value, $this->getTableColumns());
return Arr::where($fields, function ($value) use ($columns) {
return in_array($value, $columns);
});
}

Expand Down

0 comments on commit 0ba9712

Please sign in to comment.