Skip to content

Commit eee90f9

Browse files
committed
Make it possible to prune Email models
1 parent 31a4d90 commit eee90f9

File tree

3 files changed

+101
-0
lines changed

3 files changed

+101
-0
lines changed

README.md

+25
Original file line numberDiff line numberDiff line change
@@ -252,3 +252,28 @@ To enable, set the following environment variable:
252252
```
253253
LARAVEL_DATABASE_EMAILS_SEND_IMMEDIATELY=true
254254
```
255+
256+
### Pruning models
257+
258+
```php
259+
use Stackkit\LaravelDatabaseEmails\Email;
260+
261+
$schedule->command('model:prune', [
262+
'--model' => [Email::class],
263+
])->everyMinute();
264+
```
265+
266+
By default, e-mails are pruned when they are older than 6 months.
267+
268+
You may change that by adding the following to the AppServiceProvider.php:
269+
270+
```php
271+
use Stackkit\LaravelDatabaseEmails\Email;
272+
273+
public function register(): void
274+
{
275+
Email::pruneWhen(function (Email $email) {
276+
return $email->where(...);
277+
});
278+
}
279+
```

src/Email.php

+27
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44

55
namespace Stackkit\LaravelDatabaseEmails;
66

7+
use Closure;
78
use Exception;
89
use Carbon\Carbon;
10+
use Illuminate\Database\Eloquent\Builder;
911
use Illuminate\Database\Eloquent\Model;
12+
use Illuminate\Database\Eloquent\Prunable;
1013

1114
/**
1215
* @property $id
@@ -34,6 +37,7 @@
3437
class Email extends Model
3538
{
3639
use HasEncryptedAttributes;
40+
use Prunable;
3741

3842
/**
3943
* The table in which the e-mails are stored.
@@ -49,6 +53,8 @@ class Email extends Model
4953
*/
5054
protected $guarded = [];
5155

56+
public static ?Closure $pruneQuery = null;
57+
5258
/**
5359
* Compose a new e-mail.
5460
*
@@ -551,4 +557,25 @@ public function getRawDatabaseValue(string $key = null, $default = null)
551557

552558
return $this->getOriginal($key, $default);
553559
}
560+
561+
/**
562+
* @param Closure $closure
563+
* @return void
564+
*/
565+
public static function pruneWhen(Closure $closure)
566+
{
567+
static::$pruneQuery = $closure;
568+
}
569+
570+
/**
571+
* @return Builder
572+
*/
573+
public function prunable()
574+
{
575+
if (static::$pruneQuery) {
576+
return (static::$pruneQuery)($this);
577+
}
578+
579+
return $this->where('created_at', '<', now()->subMonths(6));
580+
}
554581
}

tests/PruneTest.php

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
namespace Tests;
4+
5+
use Illuminate\Database\Eloquent\Builder;
6+
use Illuminate\Support\Carbon;
7+
use Stackkit\LaravelDatabaseEmails\Email;
8+
9+
class PruneTest extends TestCase
10+
{
11+
/** @test */
12+
public function by_default_mails_are_pruned_after_6_months()
13+
{
14+
$email = $this->sendEmail();
15+
16+
Carbon::setTestNow($email->created_at . ' + 6 months');
17+
$this->artisan('model:prune', ['--model' => [Email::class]]);
18+
$this->assertInstanceOf(Email::class, $email->fresh());
19+
20+
Carbon::setTestNow($email->created_at . ' + 6 months + 1 day');
21+
22+
// Ensure the email object has to be passed manually, otherwise we are acidentally
23+
// deleting everyone's e-mails...
24+
$this->artisan('model:prune');
25+
$this->assertInstanceOf(Email::class, $email->fresh());
26+
27+
// Now test with it passed... then it should definitely be deleted.
28+
$this->artisan('model:prune', ['--model' => [Email::class]]);
29+
$this->assertNull($email->fresh());
30+
}
31+
32+
/** @test */
33+
public function can_change_when_emails_are_pruned()
34+
{
35+
Email::pruneWhen(function (Email $email) {
36+
return $email->where('created_at', '<', now()->subMonths(3));
37+
});
38+
39+
$email = $this->sendEmail();
40+
41+
Carbon::setTestNow($email->created_at . ' + 3 months');
42+
$this->artisan('model:prune', ['--model' => [Email::class]]);
43+
$this->assertInstanceOf(Email::class, $email->fresh());
44+
45+
Carbon::setTestNow($email->created_at . ' + 3 months + 1 day');
46+
$this->artisan('model:prune', ['--model' => [Email::class]]);
47+
$this->assertNull($email->fresh());
48+
}
49+
}

0 commit comments

Comments
 (0)