Skip to content

Commit 26cc96b

Browse files
Increase Phpstan Level to 9 (#21)
* Update .gitignore * Add some Types * Make Phpstan happy * Handle Models that no longer exist
1 parent 1d8c277 commit 26cc96b

File tree

6 files changed

+72
-14
lines changed

6 files changed

+72
-14
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
.php_cs
33
.php_cs.cache
44
.phpunit.result.cache
5+
.phpunit.cache/test-results
56
build
67
composer.lock
78
coverage

phpstan.neon.dist

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ includes:
22
- phpstan-baseline.neon
33

44
parameters:
5-
level: 8
5+
level: 9
66
paths:
77
- src
88
- config
@@ -11,4 +11,5 @@ parameters:
1111
checkOctaneCompatibility: true
1212
checkModelProperties: true
1313
checkMissingIterableValueType: false
14+
checkGenericClassInNonGenericObjectType: false
1415

src/Listeners/AttachSendUuidListener.php

+5-2
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,13 @@ class AttachSendUuidListener
1111
{
1212
public function handle(MessageSending $event): void
1313
{
14-
if ($event->message->getHeaders()->has(config('sends.headers.send_uuid'))) {
14+
/** @var string $sendUuidHeader */
15+
$sendUuidHeader = config('sends.headers.send_uuid');
16+
17+
if ($event->message->getHeaders()->has($sendUuidHeader)) {
1518
return;
1619
}
1720

18-
$event->message->getHeaders()->addTextHeader(config('sends.headers.send_uuid'), Str::uuid()->toString());
21+
$event->message->getHeaders()->addTextHeader($sendUuidHeader, Str::uuid()->toString());
1922
}
2023
}

src/Listeners/StoreOutgoingMailListener.php

+32-10
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ public function handle(MessageSent $event): void
2626

2727
protected function createSendModel(MessageSent $event): Send
2828
{
29-
return config('sends.send_model')::forceCreate(
29+
/** @var Send $modelClass */
30+
$modelClass = config('sends.send_model');
31+
32+
return $modelClass::forceCreate(
3033
$this->getSendAttributes($event, $this->getDefaultSendAttributes($event))
3134
);
3235
}
@@ -55,15 +58,18 @@ protected function getDefaultSendAttributes(MessageSent $event): array
5558

5659
protected function getSendUuid(MessageSent $event): ?string
5760
{
58-
if (config('sends.headers.send_uuid') === 'Message-ID') {
61+
/** @var string $sendUuidHeader */
62+
$sendUuidHeader = config('sends.headers.send_uuid');
63+
64+
if ($sendUuidHeader === 'Message-ID') {
5965
return $event->sent->getMessageId();
6066
}
6167

62-
if (! $event->message->getHeaders()->has(config('sends.headers.send_uuid'))) {
68+
if (! $event->message->getHeaders()->has($sendUuidHeader)) {
6369
return null;
6470
}
6571

66-
$headerValue = $event->message->getHeaders()->get(config('sends.headers.send_uuid'));
72+
$headerValue = $event->message->getHeaders()->get($sendUuidHeader);
6773

6874
if (is_null($headerValue)) {
6975
return null;
@@ -74,16 +80,20 @@ protected function getSendUuid(MessageSent $event): ?string
7480

7581
protected function getMailClassHeaderValue(MessageSent $event): ?string
7682
{
77-
if (! $event->message->getHeaders()->has(config('sends.headers.mail_class'))) {
83+
/** @var string $mailClassHeader */
84+
$mailClassHeader = config('sends.headers.mail_class');
85+
86+
if (! $event->message->getHeaders()->has($mailClassHeader)) {
7887
return null;
7988
}
8089

81-
$headerValue = $event->message->getHeaders()->get(config('sends.headers.mail_class'));
90+
$headerValue = $event->message->getHeaders()->get($mailClassHeader);
8291

8392
if (is_null($headerValue)) {
8493
return null;
8594
}
8695

96+
/** @phpstan-var string */
8797
return decrypt($headerValue->getBodyAsString());
8898
}
8999

@@ -93,6 +103,7 @@ protected function getMailClassHeaderValue(MessageSent $event): ?string
93103
protected function attachModelsToSendModel(MessageSent $event, Send $send): void
94104
{
95105
$this->getModels($event)
106+
/** @phpstan-ignore-next-line */
96107
->each(fn (HasSends $model) => $model->sends()->attach($send));
97108
}
98109

@@ -101,25 +112,35 @@ protected function attachModelsToSendModel(MessageSent $event, Send $send): void
101112
*/
102113
protected function getModels(MessageSent $event): Collection
103114
{
104-
if (! $event->message->getHeaders()->has(config('sends.headers.models'))) {
115+
/** @var string $modelsHeader */
116+
$modelsHeader = config('sends.headers.models');
117+
118+
if (! $event->message->getHeaders()->has($modelsHeader)) {
105119
return collect([]);
106120
}
107121

108-
$headerValue = $event->message->getHeaders()->get(config('sends.headers.models'));
122+
$headerValue = $event->message->getHeaders()->get($modelsHeader);
109123

110124
if (is_null($headerValue)) {
111125
return collect([]);
112126
}
113127

128+
/** @var string $models */
114129
$models = decrypt($headerValue->getBodyAsString());
115130

116-
return collect(json_decode($models, true, 512, JSON_THROW_ON_ERROR))
117-
->map(function (array $tuple): Model {
131+
/** @var array<array<string, mixed>> $modelsArray */
132+
$modelsArray = json_decode($models, true, 512, JSON_THROW_ON_ERROR);
133+
134+
return collect($modelsArray)
135+
->map(function (array $tuple): ?Model {
136+
/** @var Model $model */
118137
$model = $tuple['model'];
119138
$id = $tuple['id'];
120139

140+
/** @phpstan-var ?Model */
121141
return $model::find($id);
122142
})
143+
->filter()
123144
->filter(fn (Model $model) => (new ReflectionClass($model))->implementsInterface(HasSends::class));
124145
}
125146

@@ -129,6 +150,7 @@ protected function getContent(MessageSent $event): ?string
129150
return null;
130151
}
131152

153+
/** @phpstan-ignore-next-line */
132154
return $event->message->getHtmlBody();
133155
}
134156

src/Models/Send.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ class Send extends Model
7878
'rejected_at' => 'immutable_datetime',
7979
];
8080

81-
protected static function newFactory()
81+
protected static function newFactory(): SendFactory
8282
{
8383
return new SendFactory();
8484
}

tests/Listeners/StoreOutgoingMailListenerTest.php

+31
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,37 @@
181181
]);
182182
});
183183

184+
it('attaches related models to a send model by passing arguments to associateWith method but discard models that no longer exist', function () {
185+
$testModel = TestModel::create();
186+
$anotherTestModel = AnotherTestModel::create();
187+
188+
$mailable = new TestMailWithRelatedModelsHeaderPassAsArguments($testModel, $anotherTestModel);
189+
190+
$testModel->delete();
191+
192+
Mail::to('[email protected]')
193+
->send($mailable);
194+
195+
assertDatabaseHas('sends', [
196+
'mail_class' => null,
197+
'subject' => '::subject::',
198+
'to' => json_encode(['[email protected]' => null]),
199+
'cc' => null,
200+
'bcc' => null,
201+
['sent_at', '!=', null],
202+
]);
203+
assertDatabaseMissing('sendables', [
204+
'send_id' => 1,
205+
'sendable_type' => TestModel::class,
206+
'sendable_id' => 1,
207+
]);
208+
assertDatabaseHas('sendables', [
209+
'send_id' => 1,
210+
'sendable_type' => AnotherTestModel::class,
211+
'sendable_id' => 2,
212+
]);
213+
});
214+
184215
it('attaches related models to a send model based on the public properties of the mail class', function () {
185216
$testModel = TestModel::create();
186217

0 commit comments

Comments
 (0)