Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make Mail model prunable #11

Merged
merged 5 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions config/mails.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,18 @@

// Table names for saving sent emails and polymorphic relations to database

'table_names' => [
'mails' => 'mails',
'attachments' => 'mails_attachments',
'events' => 'mails_events',
'polymorph' => 'mailables',
'database' => [
'tables' => [
'mails' => 'mails',
'attachments' => 'mail_attachments',
'events' => 'mail_events',
'polymorph' => 'mailables',
],

'pruning' => [
'enabled' => true,
'after' => 30, // days
],
],

'headers' => [
Expand Down
7 changes: 1 addition & 6 deletions database/factories/MailAttachmentFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,7 @@ class MailAttachmentFactory extends Factory
{
protected $model = MailAttachment::class;

/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition()
public function definition(): array
{
return [
'type' => '...',
Expand Down
7 changes: 1 addition & 6 deletions database/factories/MailEventFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,7 @@ class MailEventFactory extends Factory
{
protected $model = MailEvent::class;

/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition()
public function definition(): array
{
return [
'type' => 'delivery',
Expand Down
7 changes: 1 addition & 6 deletions database/factories/MailFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,7 @@ class MailFactory extends Factory
{
protected $model = Mail::class;

/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition()
public function definition(): array
{
return [
'uuid' => $this->faker->uuid,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ return new class extends Migration
{
public function up()
{
Schema::create(config('mails.table_names.attachments'), function (Blueprint $table) {
Schema::create(config('mails.database.tables.attachments', 'mail_attachments'), function (Blueprint $table) {
$table->id();
$table->foreignIdFor(config('mails.models.mail'));
$table->foreignIdFor(config('mails.models.mail'))
->constrained()
->cascadeOnDelete();
$table->string('disk');
$table->string('uuid');
$table->string('filename');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ return new class extends Migration
{
public function up()
{
Schema::create(config('mails.table_names.events'), function (Blueprint $table) {
Schema::create(config('mails.database.tables.events', 'mail_events'), function (Blueprint $table) {
$table->id();
$table->foreignIdFor(config('mails.models.mail'));
$table->foreignIdFor(config('mails.models.mail'))
->constrained()
->cascadeOnDelete();
$table->string('type');
$table->string('ip_address')->nullable();
$table->string('hostname')->nullable();
Expand Down
6 changes: 4 additions & 2 deletions database/migrations/create_mailables_table.php.stub
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ return new class extends Migration
{
public function up()
{
Schema::create(config('mails.table_names.polymorph'), function (Blueprint $table) {
Schema::create(config('mails.database.tables.polymorph'), function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('mail_id')->index();
$table->foreignIdFor(config('mails.models.mail'))
->constrained()
->cascadeOnDelete();
$table->morphs('mailable');
});
}
Expand Down
2 changes: 1 addition & 1 deletion database/migrations/create_mails_table.php.stub
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ return new class extends Migration
{
public function up()
{
Schema::create(config('mails.table_names.mails'), function (Blueprint $table) {
Schema::create(config('mails.database.tables.mails'), function (Blueprint $table) {
$table->id();
$table->string('uuid')->nullable()->index();
$table->string('mail_class')->nullable()->index();
Expand Down
9 changes: 5 additions & 4 deletions src/Actions/RegisterWebhooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Vormkracht10\Mails\Actions;

use Illuminate\Console\Concerns\InteractsWithIO;
use Illuminate\Support\Facades\URL;
use Postmark\Models\Webhooks\WebhookConfigurationBounceTrigger;
use Postmark\Models\Webhooks\WebhookConfigurationClickTrigger;
Expand All @@ -14,7 +15,7 @@

class RegisterWebhooks
{
use AsAction;
use AsAction, InteractsWithIO;

public function handle()
{
Expand All @@ -37,23 +38,23 @@ public function handle()
if ($broadcastStream->where('ID', 'broadcast')->count() === 0) {
$client->createMessageStream('broadcast', 'Broadcasts', 'Default Broadcast Stream');
} else {
console()->info('Broadcast stream already exists');
$this->components->info('Broadcast stream already exists');
}

$outboundWebhooks = collect($client->getWebhookConfigurations('outbound')['webhooks'] ?? []);

if ($outboundWebhooks->where('url', $url)->count() === 0) {
$client->createWebhookConfiguration($url, null, null, null, $triggers);
} else {
console()->info('Outbound webhook already exists');
$this->components->info('Outbound webhook already exists');
}

$broadcastWebhooks = collect($client->getWebhookConfigurations('broadcast')['webhooks'] ?? []);

if ($broadcastWebhooks->where('url', $url)->count() === 0) {
$client->createWebhookConfiguration($url, 'broadcast', null, null, $triggers);
} else {
console()->info('Broadcast webhook already exists');
$this->components->info('Broadcast webhook already exists');
}
}
}
11 changes: 11 additions & 0 deletions src/Commands/PruneMailCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ class PruneMailCommand extends Command

public function handle(): int
{
if (! $this->shouldPrune()) {
$this->components->warn('Pruning has been disabled in the config');

return self::SUCCESS;
}

$this->call('model:prune', [
'--model' => [Mail::class],
]);
Expand All @@ -21,4 +27,9 @@ public function handle(): int

return self::SUCCESS;
}

protected function shouldPrune(): bool
{
return config('mails.database.pruning.enabled', false);
}
}
22 changes: 9 additions & 13 deletions src/MailsServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,19 @@

class MailsServiceProvider extends PackageServiceProvider
{
public function register(): void
public function registeringPackage()
{
parent::register();
$this->app['events']->listen(MailEvent::class, LogMailEvent::class);

app('events')->listen(MailEvent::class, LogMailEvent::class);
$this->app['events']->listen(MessageSending::class, AttachMailLogUuid::class);
$this->app['events']->listen(MessageSending::class, LogSendingMail::class);
$this->app['events']->listen(MessageSent::class, LogSentMail::class);

app('events')->listen(MessageSending::class, AttachMailLogUuid::class);
app('events')->listen(MessageSending::class, LogSendingMail::class);
app('events')->listen(MessageSent::class, LogSentMail::class);

app('events')->listen(MailBounced::class, NotifyOnBounce::class);
$this->app['events']->listen(MailBounced::class, NotifyOnBounce::class);
}

public function boot(): void
public function bootingPackage()
{
parent::boot();

$this->app->singleton(MailProviderContract::class, fn ($app) => new MailProviderManager($app));
}

Expand All @@ -50,8 +46,8 @@ public function configurePackage(Package $package): void
->hasViews()
->hasMigrations(
'create_mailables_table',
'create_mails_attachments_table',
'create_mails_events_table',
'create_mail_attachments_table',
'create_mail_events_table',
'create_mails_table',
)
->hasRoutes('webhooks')
Expand Down
18 changes: 16 additions & 2 deletions src/Models/Mail.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

namespace Vormkracht10\Mails\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\MassPrunable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Vormkracht10\Mails\Database\Factories\MailFactory;
Expand All @@ -27,13 +30,15 @@
* @property ?Carbon $complained_at
* @property ?Carbon $soft_bounced_at
* @property ?Carbon $hard_bounced_at
* @property ?Carbon $created_at
* @property ?Carbon $updated_at
*
* @method static Builder forUuid(string $uuid)
* @method static Builder forMailClass(string $mailClass)
*/
class Mail extends Model
{
use HasFactory;
use HasFactory, MassPrunable;

protected $fillable = [
'uuid',
Expand Down Expand Up @@ -77,18 +82,27 @@ class Mail extends Model
'complained_at' => 'datetime',
'soft_bounced_at' => 'datetime',
'hard_bounced_at' => 'datetime',
'created_at' => 'datetime',
'updated_at' => 'datetime',
];

public function getTable()
{
return config('mails.table_names.mails');
return config('mails.database.tables.mails');
}

protected static function newFactory(): Factory
{
return MailFactory::new();
}

public function prunable(): Builder
{
$pruneAfter = config('mails.database.pruning.after', 30);

return static::where('created_at', '<=', now()->subDays($pruneAfter));
}

public function attachments(): HasMany
{
return $this->hasMany(config('mails.models.attachment'));
Expand Down
2 changes: 1 addition & 1 deletion src/Models/MailAttachment.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class MailAttachment extends Model

public function getTable()
{
return config('mails.table_names.attachments');
return config('mails.database.tables.attachments');
}

protected static function newFactory(): Factory
Expand Down
5 changes: 4 additions & 1 deletion src/Models/MailEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
use Vormkracht10\Mails\Enums\Events\MappingPastTense;
use Vormkracht10\Mails\Events\MailEventLogged;

/**
* @property Mail $mail
*/
class MailEvent extends Model
{
use HasFactory;
Expand All @@ -30,7 +33,7 @@ class MailEvent extends Model

public function getTable()
{
return config('mails.table_names.events');
return config('mails.database.tables.events');
}

protected static function booted(): void
Expand Down
3 changes: 2 additions & 1 deletion tests/MailLogTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

use Illuminate\Mail\Message;
use Illuminate\Support\Facades\Mail;
use function Pest\Laravel\assertDatabaseHas;
use Vormkracht10\Mails\Models\Mail as MailModel;

use function Pest\Laravel\assertDatabaseHas;

it('can log sent mails', function () {
Mail::send([], [], function (Message $message) {
$message->to('[email protected]')
Expand Down
5 changes: 3 additions & 2 deletions tests/PostmarkTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
use Illuminate\Mail\Message;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\URL;
use function Pest\Laravel\assertDatabaseHas;
use function Pest\Laravel\post;
use Vormkracht10\Mails\Enums\Events\Mapping;
use Vormkracht10\Mails\Models\Mail as MailModel;
use Vormkracht10\Mails\Models\MailEvent;

use function Pest\Laravel\assertDatabaseHas;
use function Pest\Laravel\post;

it('can receive incoming delivery webhook from postmark', function () {
Mail::send([], [], function (Message $message) {
$message->to('[email protected]')
Expand Down
4 changes: 2 additions & 2 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ public function getEnvironmentSetUp($app)
$migration = include __DIR__.'/../database/migrations/create_mailables_table.php.stub';
$migration->up();

$migration = include __DIR__.'/../database/migrations/create_mails_attachments_table.php.stub';
$migration = include __DIR__.'/../database/migrations/create_mail_attachments_table.php.stub';
$migration->up();

$migration = include __DIR__.'/../database/migrations/create_mails_events_table.php.stub';
$migration = include __DIR__.'/../database/migrations/create_mail_events_table.php.stub';
$migration->up();

$migration = include __DIR__.'/../database/migrations/create_mails_table.php.stub';
Expand Down
Loading