Fix PHPStan errors introduced by mail and certificate publisher refactor

- Make Mail and Certificate message classes final with proper typed PHPDoc
- Use @var assertions and is_string() guards at call sites instead of mixed casts
- Add ?? fallback on Queue constructor calls to resolve string|null
- Add MailsPublisher type hint to untyped closure parameter
- Regenerate phpstan baseline to remove stale old Mail setter suppressions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
loks0n
2026-03-15 20:55:56 +00:00
co-authored by Claude Sonnet 4.6
parent 52628e44e5
commit da7e5833e9
13 changed files with 148 additions and 351 deletions
+1 -1
View File
@@ -269,7 +269,7 @@ $setResource('queueForDeletes', function (Publisher $publisher) {
}, ['publisher']);
$setResource('publisherForCertificates', fn (Publisher $publisher) => new CertificatesPublisher(
$publisher,
new Queue(System::getEnv('_APP_CERTIFICATES_QUEUE_NAME', Event::CERTIFICATES_QUEUE_NAME))
new Queue(System::getEnv('_APP_CERTIFICATES_QUEUE_NAME', Event::CERTIFICATES_QUEUE_NAME) ?? Event::CERTIFICATES_QUEUE_NAME)
), ['publisher']);
$setResource('logError', function (Registry $register) {
return function (Throwable $error, string $namespace, string $action) use ($register) {
+44 -5
View File
@@ -79,7 +79,9 @@ $oauthDefaultFailure = '/console/auth/oauth2/failure';
function sendSessionAlert(Locale $locale, Document $user, Document $project, array $platform, Document $session, MailsPublisher $publisherForMails)
{
$subject = $locale->getText("emails.sessionAlert.subject");
/** @var string $subject */
$preview = $locale->getText("emails.sessionAlert.preview");
/** @var string $preview */
$customTemplate = $project->getAttribute('templates', [])['email.sessionAlert-' . $locale->default] ?? [];
$smtpBaseTemplate = $project->getAttribute('smtpBaseTemplate', 'email-base');
@@ -102,6 +104,7 @@ function sendSessionAlert(Locale $locale, Document $user, Document $project, arr
->setParam('{{signature}}', $locale->getText("emails.sessionAlert.signature"));
$body = $message->render();
/** @var string $body */
$smtp = $project->getAttribute('smtp', []);
$smtpEnabled = $smtp['enabled'] ?? false;
@@ -144,7 +147,9 @@ function sendSessionAlert(Locale $locale, Document $user, Document $project, arr
}
$body = $customTemplate['message'] ?? '';
/** @var string $body */
$subject = $customTemplate['subject'] ?? $subject;
/** @var string $subject */
}
$smtpConfig['replyTo'] = $replyTo;
@@ -193,11 +198,13 @@ function sendSessionAlert(Locale $locale, Document $user, Document $project, arr
}
$email = $user->getAttribute('email');
/** @var string $email */
if ($smtpBaseTemplate === APP_BRANDED_EMAIL_BASE_TEMPLATE) {
$customMailOptions['senderName'] = $platform['emailSenderName'];
}
/** @var array<string, mixed> $platform */
$publisherForMails->enqueue(new Mail(
project: $project,
recipient: $email,
@@ -2253,7 +2260,9 @@ Http::post('/v1/account/tokens/magic-url')
$url = Template::unParseURL($url);
$subject = $locale->getText("emails.magicSession.subject");
/** @var string $subject */
$preview = $locale->getText("emails.magicSession.preview");
/** @var string $preview */
$customTemplate = $project->getAttribute('templates', [])['email.magicSession-' . $locale->default] ?? [];
$detector = new Detector($request->getUserAgent('UNKNOWN'));
@@ -2278,6 +2287,7 @@ Http::post('/v1/account/tokens/magic-url')
}
$body = $message->render();
/** @var string $body */
$smtp = $project->getAttribute('smtp', []);
$smtpEnabled = $smtp['enabled'] ?? false;
@@ -2321,7 +2331,9 @@ Http::post('/v1/account/tokens/magic-url')
}
$body = $customTemplate['message'] ?? '';
/** @var string $body */
$subject = $customTemplate['subject'] ?? $subject;
/** @var string $subject */
}
$smtpConfig['replyTo'] = $replyTo;
@@ -2352,6 +2364,7 @@ Http::post('/v1/account/tokens/magic-url')
$customMailOptions['senderName'] = $platform['emailSenderName'];
}
/** @var array<string, mixed> $platform */
$publisherForMails->enqueue(new Mail(
project: $project,
recipient: $email,
@@ -2538,7 +2551,9 @@ Http::post('/v1/account/tokens/email')
$dbForProject->purgeCachedDocument('users', $user->getId());
$subject = $locale->getText("emails.otpSession.subject");
/** @var string $subject */
$preview = $locale->getText("emails.otpSession.preview");
/** @var string $preview */
$heading = $locale->getText("emails.otpSession.heading");
$customTemplate = $project->getAttribute('templates', [])['email.otpSession-' . $locale->default] ?? [];
@@ -2571,6 +2586,7 @@ Http::post('/v1/account/tokens/email')
}
$body = $message->render();
/** @var string $body */
$smtp = $project->getAttribute('smtp', []);
$smtpEnabled = $smtp['enabled'] ?? false;
@@ -2613,7 +2629,9 @@ Http::post('/v1/account/tokens/email')
}
$body = $customTemplate['message'] ?? '';
/** @var string $body */
$subject = $customTemplate['subject'] ?? $subject;
/** @var string $subject */
}
$smtpConfig['replyTo'] = $replyTo;
@@ -2658,6 +2676,7 @@ Http::post('/v1/account/tokens/email')
$customMailOptions['senderName'] = $platform['emailSenderName'];
}
/** @var array<string, mixed> $platform */
$publisherForMails->enqueue(new Mail(
project: $project,
recipient: $email,
@@ -2729,7 +2748,7 @@ Http::put('/v1/account/sessions/magic-url')
->inject('store')
->inject('proofForCode')
->inject('authorization')
->action(function ($userId, $secret, $request, $response, $user, $dbForProject, $project, $platform, $locale, $geodb, $queueForEvents, $publisherForMails, $store, $proofForCode, $authorization) use ($createSession) {
->action(function ($userId, $secret, $request, $response, $user, $dbForProject, $project, $platform, $locale, $geodb, $queueForEvents, MailsPublisher $publisherForMails, $store, $proofForCode, $authorization) use ($createSession) {
$proofForToken = new ProofsToken(TOKEN_LENGTH_MAGIC_URL);
$proofForToken->setHash(new Sha());
$createSession($userId, $secret, $request, $response, $user, $dbForProject, $project, $platform, $locale, $geodb, $queueForEvents, $publisherForMails, $store, $proofForToken, $proofForCode, $authorization);
@@ -3661,7 +3680,9 @@ Http::post('/v1/account/recovery')
$body = $locale->getText("emails.recovery.body");
$subject = $locale->getText("emails.recovery.subject");
/** @var string $subject */
$preview = $locale->getText("emails.recovery.preview");
/** @var string $preview */
$customTemplate = $project->getAttribute('templates', [])['email.recovery-' . $locale->default] ?? [];
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
@@ -3673,6 +3694,7 @@ Http::post('/v1/account/recovery')
->setParam('{{buttonText}}', $locale->getText("emails.recovery.buttonText"))
->setParam('{{signature}}', $locale->getText("emails.recovery.signature"));
$body = $message->render();
/** @var string $body */
$smtp = $project->getAttribute('smtp', []);
$smtpEnabled = $smtp['enabled'] ?? false;
@@ -3715,7 +3737,9 @@ Http::post('/v1/account/recovery')
}
$body = $customTemplate['message'] ?? '';
/** @var string $body */
$subject = $customTemplate['subject'] ?? $subject;
/** @var string $subject */
}
$smtpConfig['replyTo'] = $replyTo;
@@ -3737,10 +3761,15 @@ Http::post('/v1/account/recovery')
$customMailOptions['senderName'] = $platform['emailSenderName'];
}
$recipient = $profile->getAttribute('email', '');
/** @var string $recipient */
$name = $profile->getAttribute('name', '');
/** @var string $name */
/** @var array<string, mixed> $platform */
$publisherForMails->enqueue(new Mail(
project: $project,
recipient: $profile->getAttribute('email', ''),
name: $profile->getAttribute('name', ''),
recipient: $recipient,
name: $name,
subject: $subject,
body: $body,
preview: $preview,
@@ -3973,7 +4002,9 @@ Http::post('/v1/account/verifications/email')
$body = $locale->getText("emails.verification.body");
$preview = $locale->getText("emails.verification.preview");
/** @var string $preview */
$subject = $locale->getText("emails.verification.subject");
/** @var string $subject */
$heading = $locale->getText("emails.verification.heading");
$customTemplate = $project->getAttribute('templates', [])['email.verification-' . $locale->default] ?? [];
@@ -3996,6 +4027,7 @@ Http::post('/v1/account/verifications/email')
->setParam('{{signature}}', $locale->getText("emails.verification.signature"));
$body = $message->render();
/** @var string $body */
$smtp = $project->getAttribute('smtp', []);
$smtpEnabled = $smtp['enabled'] ?? false;
@@ -4038,7 +4070,9 @@ Http::post('/v1/account/verifications/email')
}
$body = $customTemplate['message'] ?? '';
/** @var string $body */
$subject = $customTemplate['subject'] ?? $subject;
/** @var string $subject */
}
$smtpConfig['replyTo'] = $replyTo;
@@ -4074,10 +4108,15 @@ Http::post('/v1/account/verifications/email')
$customMailOptions['senderName'] = $platform['emailSenderName'];
}
$recipient = $user->getAttribute('email');
/** @var string $recipient */
$name = $user->getAttribute('name') ?? '';
/** @var string $name */
/** @var array<string, mixed> $platform */
$publisherForMails->enqueue(new Mail(
project: $project,
recipient: $user->getAttribute('email'),
name: $user->getAttribute('name') ?? '',
recipient: $recipient,
name: $name,
subject: $subject,
body: $body,
preview: $preview,
+1
View File
@@ -1863,6 +1863,7 @@ Http::post('/v1/projects/:projectId/smtp/tests')
->setParam('{{privacyUrl}}', $plan['privacyUrl'] ?? APP_EMAIL_PRIVACY_URL);
foreach ($emails as $email) {
/** @var string $email */
$publisherForMails->enqueue(new Mail(
project: $project,
recipient: $email,
+2 -2
View File
@@ -156,7 +156,7 @@ Http::setResource('usage', function () {
}, []);
Http::setResource('publisherForUsage', fn (Publisher $publisher) => new UsagePublisher(
$publisher,
new Queue(System::getEnv('_APP_STATS_USAGE_QUEUE_NAME', Event::STATS_USAGE_QUEUE_NAME))
new Queue(System::getEnv('_APP_STATS_USAGE_QUEUE_NAME', Event::STATS_USAGE_QUEUE_NAME) ?? Event::STATS_USAGE_QUEUE_NAME)
), ['publisher']);
Http::setResource('queueForAudits', function (Publisher $publisher) {
return new AuditEvent($publisher);
@@ -169,7 +169,7 @@ Http::setResource('eventProcessor', function () {
}, []);
Http::setResource('publisherForCertificates', fn (Publisher $publisher) => new CertificatesPublisher(
$publisher,
new Queue(System::getEnv('_APP_CERTIFICATES_QUEUE_NAME', Event::CERTIFICATES_QUEUE_NAME))
new Queue(System::getEnv('_APP_CERTIFICATES_QUEUE_NAME', Event::CERTIFICATES_QUEUE_NAME) ?? Event::CERTIFICATES_QUEUE_NAME)
), ['publisher']);
Http::setResource('queueForMigrations', function (Publisher $publisher) {
return new Migration($publisher);
+2 -2
View File
@@ -327,7 +327,7 @@ Server::setResource('queueForMessaging', function (Publisher $publisher) {
Server::setResource('publisherForMails', fn (Publisher $publisher) => new Mail(
$publisher,
new Queue(System::getEnv('_APP_MAILS_QUEUE_NAME', Event::MAILS_QUEUE_NAME))
new Queue(System::getEnv('_APP_MAILS_QUEUE_NAME', Event::MAILS_QUEUE_NAME) ?? Event::MAILS_QUEUE_NAME)
), ['publisher']);
Server::setResource('queueForBuilds', function (Publisher $publisher) {
@@ -364,7 +364,7 @@ Server::setResource('queueForRealtime', function () {
Server::setResource('publisherForCertificates', fn (Publisher $publisher) => new CertificatesPublisher(
$publisher,
new Queue(System::getEnv('_APP_CERTIFICATES_QUEUE_NAME', Event::CERTIFICATES_QUEUE_NAME))
new Queue(System::getEnv('_APP_CERTIFICATES_QUEUE_NAME', Event::CERTIFICATES_QUEUE_NAME) ?? Event::CERTIFICATES_QUEUE_NAME)
), ['publisher']);
Server::setResource('queueForMigrations', function (Publisher $publisher) {
-312
View File
@@ -834,12 +834,6 @@ parameters:
count: 2
path: app/controllers/api/account.php
-
message: '#^Parameter \#1 \$body of method Appwrite\\Event\\Mail\:\:setBody\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 5
path: app/controllers/api/account.php
-
message: '#^Parameter \#1 \$class of function class_exists expects string, mixed given\.$#'
identifier: argument.type
@@ -888,12 +882,6 @@ parameters:
count: 2
path: app/controllers/api/account.php
-
message: '#^Parameter \#1 \$host of method Appwrite\\Event\\Mail\:\:setSmtpHost\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 5
path: app/controllers/api/account.php
-
message: '#^Parameter \#1 \$input of class Utopia\\Database\\Document constructor expects array\<string, mixed\>, array given\.$#'
identifier: argument.type
@@ -930,18 +918,6 @@ parameters:
count: 1
path: app/controllers/api/account.php
-
message: '#^Parameter \#1 \$name of method Appwrite\\Event\\Mail\:\:setName\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 2
path: app/controllers/api/account.php
-
message: '#^Parameter \#1 \$name of method Appwrite\\Event\\Mail\:\:setSenderName\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 5
path: app/controllers/api/account.php
-
message: '#^Parameter \#1 \$name of method Utopia\\Http\\Response\:\:addCookie\(\) expects string, string\|null given\.$#'
identifier: argument.type
@@ -954,24 +930,6 @@ parameters:
count: 1
path: app/controllers/api/account.php
-
message: '#^Parameter \#1 \$password of method Appwrite\\Event\\Mail\:\:setSmtpPassword\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 5
path: app/controllers/api/account.php
-
message: '#^Parameter \#1 \$port of method Appwrite\\Event\\Mail\:\:setSmtpPort\(\) expects int, mixed given\.$#'
identifier: argument.type
count: 5
path: app/controllers/api/account.php
-
message: '#^Parameter \#1 \$preview of method Appwrite\\Event\\Mail\:\:setPreview\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 5
path: app/controllers/api/account.php
-
message: '#^Parameter \#1 \$proof of method Utopia\\Auth\\Proof\:\:hash\(\) expects string, mixed given\.$#'
identifier: argument.type
@@ -996,48 +954,18 @@ parameters:
count: 2
path: app/controllers/api/account.php
-
message: '#^Parameter \#1 \$recipient of method Appwrite\\Event\\Mail\:\:setRecipient\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 3
path: app/controllers/api/account.php
-
message: '#^Parameter \#1 \$recipients of method Appwrite\\Event\\Messaging\:\:setRecipients\(\) expects array\<string\>, array\<int, mixed\> given\.$#'
identifier: argument.type
count: 1
path: app/controllers/api/account.php
-
message: '#^Parameter \#1 \$replyTo of method Appwrite\\Event\\Mail\:\:setSmtpReplyTo\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 5
path: app/controllers/api/account.php
-
message: '#^Parameter \#1 \$secret of method Appwrite\\Utopia\\Database\\Documents\\User\:\:sessionVerify\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 8
path: app/controllers/api/account.php
-
message: '#^Parameter \#1 \$secure of method Appwrite\\Event\\Mail\:\:setSmtpSecure\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 5
path: app/controllers/api/account.php
-
message: '#^Parameter \#1 \$senderEmail of method Appwrite\\Event\\Mail\:\:setSmtpSenderEmail\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 5
path: app/controllers/api/account.php
-
message: '#^Parameter \#1 \$senderName of method Appwrite\\Event\\Mail\:\:setSmtpSenderName\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 5
path: app/controllers/api/account.php
-
message: '#^Parameter \#1 \$string of function hex2bin expects string, mixed given\.$#'
identifier: argument.type
@@ -1050,12 +978,6 @@ parameters:
count: 14
path: app/controllers/api/account.php
-
message: '#^Parameter \#1 \$subject of method Appwrite\\Event\\Mail\:\:setSubject\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 5
path: app/controllers/api/account.php
-
message: '#^Parameter \#1 \$type of static method Utopia\\Auth\\Proofs\\Password\:\:createHash\(\) expects string, mixed given\.$#'
identifier: argument.type
@@ -1110,12 +1032,6 @@ parameters:
count: 1
path: app/controllers/api/account.php
-
message: '#^Parameter \#1 \$username of method Appwrite\\Event\\Mail\:\:setSmtpUsername\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 5
path: app/controllers/api/account.php
-
message: '#^Parameter \#1 \$value of function count expects array\|Countable, mixed given\.$#'
identifier: argument.type
@@ -1134,12 +1050,6 @@ parameters:
count: 1
path: app/controllers/api/account.php
-
message: '#^Parameter \#12 \$queueForMails of closure expects Appwrite\\Event\\Mail, mixed given\.$#'
identifier: argument.type
count: 1
path: app/controllers/api/account.php
-
message: '#^Parameter \#13 \$store of closure expects Utopia\\Auth\\Store, mixed given\.$#'
identifier: argument.type
@@ -2670,12 +2580,6 @@ parameters:
count: 1
path: app/controllers/api/projects.php
-
message: '#^Parameter \#1 \$recipient of method Appwrite\\Event\\Mail\:\:setRecipient\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: app/controllers/api/projects.php
-
message: '#^Parameter \#2 \$callback of function array_filter expects \(callable\(mixed\)\: bool\)\|null, Closure\(mixed\)\: mixed given\.$#'
identifier: argument.type
@@ -15180,102 +15084,24 @@ parameters:
count: 1
path: src/Appwrite/Platform/Modules/Account/Http/Account/MFA/Challenges/Create.php
-
message: '#^Parameter \#1 \$body of method Appwrite\\Event\\Mail\:\:setBody\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Account/Http/Account/MFA/Challenges/Create.php
-
message: '#^Parameter \#1 \$content of static method Appwrite\\Template\\Template\:\:fromString\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Account/Http/Account/MFA/Challenges/Create.php
-
message: '#^Parameter \#1 \$host of method Appwrite\\Event\\Mail\:\:setSmtpHost\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Account/Http/Account/MFA/Challenges/Create.php
-
message: '#^Parameter \#1 \$name of method Appwrite\\Event\\Mail\:\:setSenderName\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Account/Http/Account/MFA/Challenges/Create.php
-
message: '#^Parameter \#1 \$numberToParse of method libphonenumber\\PhoneNumberUtil\:\:parse\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Account/Http/Account/MFA/Challenges/Create.php
-
message: '#^Parameter \#1 \$password of method Appwrite\\Event\\Mail\:\:setSmtpPassword\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Account/Http/Account/MFA/Challenges/Create.php
-
message: '#^Parameter \#1 \$port of method Appwrite\\Event\\Mail\:\:setSmtpPort\(\) expects int, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Account/Http/Account/MFA/Challenges/Create.php
-
message: '#^Parameter \#1 \$preview of method Appwrite\\Event\\Mail\:\:setPreview\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Account/Http/Account/MFA/Challenges/Create.php
-
message: '#^Parameter \#1 \$recipient of method Appwrite\\Event\\Mail\:\:setRecipient\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Account/Http/Account/MFA/Challenges/Create.php
-
message: '#^Parameter \#1 \$recipients of method Appwrite\\Event\\Messaging\:\:setRecipients\(\) expects array\<string\>, array\<int, mixed\> given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Account/Http/Account/MFA/Challenges/Create.php
-
message: '#^Parameter \#1 \$replyTo of method Appwrite\\Event\\Mail\:\:setSmtpReplyTo\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Account/Http/Account/MFA/Challenges/Create.php
-
message: '#^Parameter \#1 \$secure of method Appwrite\\Event\\Mail\:\:setSmtpSecure\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Account/Http/Account/MFA/Challenges/Create.php
-
message: '#^Parameter \#1 \$senderEmail of method Appwrite\\Event\\Mail\:\:setSmtpSenderEmail\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Account/Http/Account/MFA/Challenges/Create.php
-
message: '#^Parameter \#1 \$senderName of method Appwrite\\Event\\Mail\:\:setSmtpSenderName\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Account/Http/Account/MFA/Challenges/Create.php
-
message: '#^Parameter \#1 \$subject of method Appwrite\\Event\\Mail\:\:setSubject\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Account/Http/Account/MFA/Challenges/Create.php
-
message: '#^Parameter \#1 \$username of method Appwrite\\Event\\Mail\:\:setSmtpUsername\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Account/Http/Account/MFA/Challenges/Create.php
-
message: '#^Parameter \#2 \$replace of function str_replace expects array\<string\>\|string, int\<min, \-1\>\|int\<1, max\> given\.$#'
identifier: argument.type
@@ -26550,108 +26376,30 @@ parameters:
count: 1
path: src/Appwrite/Platform/Modules/Teams/Http/Memberships/Create.php
-
message: '#^Parameter \#1 \$body of method Appwrite\\Event\\Mail\:\:setBody\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Teams/Http/Memberships/Create.php
-
message: '#^Parameter \#1 \$email of class Utopia\\Emails\\Email constructor expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Teams/Http/Memberships/Create.php
-
message: '#^Parameter \#1 \$host of method Appwrite\\Event\\Mail\:\:setSmtpHost\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Teams/Http/Memberships/Create.php
-
message: '#^Parameter \#1 \$name of method Appwrite\\Event\\Mail\:\:setName\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Teams/Http/Memberships/Create.php
-
message: '#^Parameter \#1 \$numberToParse of method libphonenumber\\PhoneNumberUtil\:\:parse\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Teams/Http/Memberships/Create.php
-
message: '#^Parameter \#1 \$password of method Appwrite\\Event\\Mail\:\:setSmtpPassword\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Teams/Http/Memberships/Create.php
-
message: '#^Parameter \#1 \$port of method Appwrite\\Event\\Mail\:\:setSmtpPort\(\) expects int, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Teams/Http/Memberships/Create.php
-
message: '#^Parameter \#1 \$preview of method Appwrite\\Event\\Mail\:\:setPreview\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Teams/Http/Memberships/Create.php
-
message: '#^Parameter \#1 \$recipient of method Appwrite\\Event\\Mail\:\:setRecipient\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Teams/Http/Memberships/Create.php
-
message: '#^Parameter \#1 \$recipients of method Appwrite\\Event\\Messaging\:\:setRecipients\(\) expects array\<string\>, array\<int, mixed\> given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Teams/Http/Memberships/Create.php
-
message: '#^Parameter \#1 \$replyTo of method Appwrite\\Event\\Mail\:\:setSmtpReplyTo\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Teams/Http/Memberships/Create.php
-
message: '#^Parameter \#1 \$secure of method Appwrite\\Event\\Mail\:\:setSmtpSecure\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Teams/Http/Memberships/Create.php
-
message: '#^Parameter \#1 \$senderEmail of method Appwrite\\Event\\Mail\:\:setSmtpSenderEmail\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Teams/Http/Memberships/Create.php
-
message: '#^Parameter \#1 \$senderName of method Appwrite\\Event\\Mail\:\:setSmtpSenderName\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Teams/Http/Memberships/Create.php
-
message: '#^Parameter \#1 \$subject of method Appwrite\\Event\\Mail\:\:setSubject\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Teams/Http/Memberships/Create.php
-
message: '#^Parameter \#1 \$url of static method Appwrite\\Template\\Template\:\:unParseURL\(\) expects array, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Teams/Http/Memberships/Create.php
-
message: '#^Parameter \#1 \$username of method Appwrite\\Event\\Mail\:\:setSmtpUsername\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Modules/Teams/Http/Memberships/Create.php
-
message: '#^Parameter \#2 \$replace of function str_replace expects array\<string\>\|string, int\<min, \-1\>\|int\<1, max\> given\.$#'
identifier: argument.type
@@ -31008,24 +30756,6 @@ parameters:
count: 1
path: src/Appwrite/Platform/Workers/Certificates.php
-
message: '#^Parameter \#1 \$preview of method Appwrite\\Event\\Mail\:\:setPreview\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Workers/Certificates.php
-
message: '#^Parameter \#1 \$recipient of method Appwrite\\Event\\Mail\:\:setRecipient\(\) expects string, string\|null given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Workers/Certificates.php
-
message: '#^Parameter \#1 \$subject of method Appwrite\\Event\\Mail\:\:setSubject\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Workers/Certificates.php
-
message: '#^Parameter \#10 \$validationDomain of method Appwrite\\Platform\\Workers\\Certificates\:\:handleDomainVerificationAction\(\) expects string\|null, mixed given\.$#'
identifier: argument.type
@@ -33498,30 +33228,12 @@ parameters:
count: 2
path: src/Appwrite/Platform/Workers/Migrations.php
-
message: '#^Parameter \#1 \$name of method Appwrite\\Event\\Mail\:\:setName\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Workers/Migrations.php
-
message: '#^Parameter \#1 \$name of method Appwrite\\Event\\Mail\:\:setSenderName\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Workers/Migrations.php
-
message: '#^Parameter \#1 \$name of method Utopia\\Locale\\Locale\:\:setFallback\(\) expects string, string\|null given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Workers/Migrations.php
-
message: '#^Parameter \#1 \$preview of method Appwrite\\Event\\Mail\:\:setPreview\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Workers/Migrations.php
-
message: '#^Parameter \#1 \$project of class Utopia\\Migration\\Sources\\Appwrite constructor expects string, mixed given\.$#'
identifier: argument.type
@@ -33546,12 +33258,6 @@ parameters:
count: 1
path: src/Appwrite/Platform/Workers/Migrations.php
-
message: '#^Parameter \#1 \$recipient of method Appwrite\\Event\\Mail\:\:setRecipient\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Workers/Migrations.php
-
message: '#^Parameter \#1 \$resourceId of class Utopia\\Migration\\Sources\\CSV constructor expects string, mixed given\.$#'
identifier: argument.type
@@ -33588,12 +33294,6 @@ parameters:
count: 1
path: src/Appwrite/Platform/Workers/Migrations.php
-
message: '#^Parameter \#1 \$subject of method Appwrite\\Event\\Mail\:\:setSubject\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Workers/Migrations.php
-
message: '#^Parameter \#1 \$value of function count expects array\|Countable, mixed given\.$#'
identifier: argument.type
@@ -34482,18 +34182,6 @@ parameters:
count: 1
path: src/Appwrite/Platform/Workers/Webhooks.php
-
message: '#^Parameter \#1 \$name of method Appwrite\\Event\\Mail\:\:setName\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Workers/Webhooks.php
-
message: '#^Parameter \#1 \$recipient of method Appwrite\\Event\\Mail\:\:setRecipient\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Appwrite/Platform/Workers/Webhooks.php
-
message: '#^Parameter \#1 \$string of function mb_strcut expects string, bool\|string given\.$#'
identifier: argument.type
+18 -7
View File
@@ -4,7 +4,7 @@ namespace Appwrite\Event\Message;
use Utopia\Database\Document;
readonly class Certificate extends Base
final readonly class Certificate extends Base
{
public const string ACTION_DOMAIN_VERIFICATION = 'verification';
public const string ACTION_GENERATION = 'generation';
@@ -18,6 +18,9 @@ readonly class Certificate extends Base
) {
}
/**
* @return array<string, mixed>
*/
public function toArray(): array
{
return [
@@ -29,14 +32,22 @@ readonly class Certificate extends Base
];
}
/**
* @param array<string, mixed> $data
*/
public static function fromArray(array $data): static
{
return new static(
project: !empty($data['project']) ? new Document($data['project']) : null,
domain: !empty($data['domain']) ? new Document($data['domain']) : null,
skipRenewCheck: $data['skipRenewCheck'] ?? false,
validationDomain: $data['validationDomain'] ?? null,
action: $data['action'] ?? self::ACTION_GENERATION,
/** @var array<string, mixed> $project */
$project = is_array($data['project'] ?? null) ? $data['project'] : [];
/** @var array<string, mixed> $domain */
$domain = is_array($data['domain'] ?? null) ? $data['domain'] : [];
return new self(
project: !empty($project) ? new Document($project) : null,
domain: !empty($domain) ? new Document($domain) : null,
skipRenewCheck: (bool) ($data['skipRenewCheck'] ?? false),
validationDomain: is_string($data['validationDomain'] ?? null) ? $data['validationDomain'] : null,
action: is_string($data['action'] ?? null) ? $data['action'] : self::ACTION_GENERATION,
);
}
}
+40 -14
View File
@@ -5,8 +5,15 @@ namespace Appwrite\Event\Message;
use Utopia\Config\Config;
use Utopia\Database\Document;
readonly class Mail extends Base
final readonly class Mail extends Base
{
/**
* @param array<string, mixed> $smtp
* @param array<string, mixed> $variables
* @param array<mixed> $attachment
* @param array<string, mixed> $customMailOptions
* @param array<string, mixed> $platform
*/
public function __construct(
public ?Document $project = null,
public string $recipient = '',
@@ -23,6 +30,9 @@ readonly class Mail extends Base
) {
}
/**
* @return array<string, mixed>
*/
public function toArray(): array
{
return [
@@ -41,21 +51,37 @@ readonly class Mail extends Base
];
}
/**
* @param array<string, mixed> $data
*/
public static function fromArray(array $data): static
{
return new static(
project: !empty($data['project']) ? new Document($data['project']) : null,
recipient: $data['recipient'] ?? '',
name: $data['name'] ?? '',
subject: $data['subject'] ?? '',
body: $data['body'] ?? '',
preview: $data['preview'] ?? '',
smtp: $data['smtp'] ?? [],
variables: $data['variables'] ?? [],
bodyTemplate: $data['bodyTemplate'] ?? '',
attachment: $data['attachment'] ?? [],
customMailOptions: $data['customMailOptions'] ?? [],
platform: $data['platform'] ?? [],
/** @var array<string, mixed> $project */
$project = is_array($data['project'] ?? null) ? $data['project'] : [];
/** @var array<string, mixed> $smtp */
$smtp = is_array($data['smtp'] ?? null) ? $data['smtp'] : [];
/** @var array<string, mixed> $variables */
$variables = is_array($data['variables'] ?? null) ? $data['variables'] : [];
/** @var array<mixed> $attachment */
$attachment = is_array($data['attachment'] ?? null) ? $data['attachment'] : [];
/** @var array<string, mixed> $customMailOptions */
$customMailOptions = is_array($data['customMailOptions'] ?? null) ? $data['customMailOptions'] : [];
/** @var array<string, mixed> $platform */
$platform = is_array($data['platform'] ?? null) ? $data['platform'] : [];
return new self(
project: !empty($project) ? new Document($project) : null,
recipient: is_string($data['recipient'] ?? null) ? $data['recipient'] : '',
name: is_string($data['name'] ?? null) ? $data['name'] : '',
subject: is_string($data['subject'] ?? null) ? $data['subject'] : '',
body: is_string($data['body'] ?? null) ? $data['body'] : '',
preview: is_string($data['preview'] ?? null) ? $data['preview'] : '',
smtp: $smtp,
variables: $variables,
bodyTemplate: is_string($data['bodyTemplate'] ?? null) ? $data['bodyTemplate'] : '',
attachment: $attachment,
customMailOptions: $customMailOptions,
platform: $platform,
);
}
}
@@ -221,7 +221,9 @@ class Create extends Action
}
$subject = $locale->getText("emails.mfaChallenge.subject");
/** @var string $subject */
$preview = $locale->getText("emails.mfaChallenge.preview");
/** @var string $preview */
$heading = $locale->getText("emails.mfaChallenge.heading");
$customTemplate = $project->getAttribute('templates', [])['email.mfaChallenge-' . $locale->default] ?? [];
@@ -248,6 +250,7 @@ class Create extends Action
->setParam('{{signature}}', $locale->getText("emails.mfaChallenge.signature"));
$body = $message->render();
/** @var string $body */
$smtp = $project->getAttribute('smtp', []);
$smtpEnabled = $smtp['enabled'] ?? false;
@@ -290,7 +293,9 @@ class Create extends Action
}
$body = $customTemplate['message'] ?? '';
/** @var string $body */
$subject = $customTemplate['subject'] ?? $subject;
/** @var string $subject */
}
$smtpConfig['replyTo'] = $replyTo;
@@ -326,9 +331,12 @@ class Create extends Action
$customMailOptions['senderName'] = $platform['emailSenderName'];
}
$recipient = $user->getAttribute('email');
/** @var string $recipient */
/** @var array<string, mixed> $platform */
$publisherForMails->enqueue(new Mail(
project: $project,
recipient: $user->getAttribute('email'),
recipient: $recipient,
subject: $subject,
body: $body,
preview: $preview,
@@ -298,7 +298,9 @@ class Create extends Action
$body = $locale->getText('emails.invitation.body');
$preview = $locale->getText('emails.invitation.preview');
/** @var string $preview */
$subject = $locale->getText('emails.invitation.subject');
/** @var string $subject */
$customTemplate = $project->getAttribute('templates', [])['email.invitation-' . $locale->default] ?? [];
$message = Template::fromFile(APP_CE_CONFIG_DIR . '/locale/templates/email-inner-base.tpl');
@@ -310,6 +312,7 @@ class Create extends Action
->setParam('{{buttonText}}', $locale->getText('emails.invitation.buttonText'))
->setParam('{{signature}}', $locale->getText('emails.invitation.signature'));
$body = $message->render();
/** @var string $body */
$smtp = $project->getAttribute('smtp', []);
$smtpEnabled = $smtp['enabled'] ?? false;
@@ -351,7 +354,9 @@ class Create extends Action
}
$body = $customTemplate['message'] ?? '';
/** @var string $body */
$subject = $customTemplate['subject'] ?? $subject;
/** @var string $subject */
}
$smtpConfig['replyTo'] = $replyTo;
@@ -369,10 +374,14 @@ class Create extends Action
'project' => $projectName,
];
$recipient = $invitee->getAttribute('email');
/** @var string $recipient */
$inviteeName = $invitee->getAttribute('name', '');
/** @var string $inviteeName */
$publisherForMails->enqueue(new Mail(
project: $project,
recipient: $invitee->getAttribute('email'),
name: $invitee->getAttribute('name', ''),
recipient: $recipient,
name: $inviteeName,
subject: $subject,
body: $body,
preview: $preview,
@@ -555,10 +555,14 @@ class Certificates extends Action
];
$subject = $locale->getText("emails.certificate.subject");
/** @var string $subject */
$preview = $locale->getText("emails.certificate.preview");
/** @var string $preview */
$recipient = System::getEnv('_APP_EMAIL_CERTIFICATES', System::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS'));
/** @var string $recipient */
$publisherForMails->enqueue(new Mail(
recipient: System::getEnv('_APP_EMAIL_CERTIFICATES', System::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS')),
recipient: $recipient,
name: 'Appwrite Administrator',
subject: $subject,
body: $body,
+9 -2
View File
@@ -709,7 +709,9 @@ class Migrations extends Action
// Get localized email content
$subject = $locale->getText("emails.csvExport.{$emailType}.subject");
/** @var string $subject */
$preview = $locale->getText("emails.csvExport.{$emailType}.preview");
/** @var string $preview */
$hello = $locale->getText("emails.csvExport.{$emailType}.hello");
$body = $locale->getText("emails.csvExport.{$emailType}.body");
$footer = $locale->getText("emails.csvExport.{$emailType}.footer");
@@ -753,10 +755,15 @@ class Migrations extends Action
'platform' => $platform['platformName'],
];
$recipient = $user->getAttribute('email');
/** @var string $recipient */
$userName = $user->getAttribute('name', $user->getAttribute('email'));
/** @var string $userName */
/** @var array<string, mixed> $platform */
$publisherForMails->enqueue(new Mail(
project: $project,
recipient: $user->getAttribute('email'),
name: $user->getAttribute('name', $user->getAttribute('email')),
recipient: $recipient,
name: $userName,
subject: $subject,
body: $emailBody,
preview: $preview,
+6 -2
View File
@@ -257,10 +257,14 @@ class Webhooks extends Action
->setParam('{{year}}', date("Y"));
foreach ($users as $user) {
$userEmail = $user->getAttribute('email');
/** @var string $userEmail */
$userName = $user->getAttribute('name', '');
/** @var string $userName */
$publisherForMails->enqueue(new Mail(
project: $project,
recipient: $user->getAttribute('email'),
name: $user->getAttribute('name', ''),
recipient: $userEmail,
name: $userName,
subject: $subject,
body: $body->render(),
preview: $preview,