From 2e09b45144e922df727fafcf7ab27f0c15737d64 Mon Sep 17 00:00:00 2001 From: IanM Date: Sat, 19 Aug 2023 22:49:06 +0100 Subject: [PATCH 01/60] feat: notification unsubscribe links --- .../Notification/GroupMentionedBlueprint.php | 6 ++- .../Notification/PostMentionedBlueprint.php | 7 ++- .../Notification/UserMentionedBlueprint.php | 7 ++- .../{ => html}/groupMentioned.blade.php | 4 ++ .../emails/{ => html}/postMentioned.blade.php | 4 ++ .../emails/{ => html}/userMentioned.blade.php | 4 ++ .../emails/plain/groupMentioned.blade.php | 11 ++++ .../emails/plain/postMentioned.blade.php | 12 +++++ .../emails/plain/userMentioned.blade.php | 11 ++++ .../src/Notification/NewPostBlueprint.php | 6 ++- .../views/emails/{ => html}/newPost.blade.php | 4 ++ .../views/emails/plain/newPost.blade.php | 11 ++++ .../Notification/UserSuspendedBlueprint.php | 6 ++- .../Notification/UserUnsuspendedBlueprint.php | 6 ++- .../emails/{ => plain}/suspended.blade.php | 4 ++ .../emails/{ => plain}/unsuspended.blade.php | 4 ++ ...000000_create_unsubscribe_tokens_table.php | 30 +++++++++++ .../Controller/UnsubscribeController.php | 53 +++++++++++++++++++ framework/core/src/Forum/routes.php | 6 +++ .../src/Notification/MailableInterface.php | 17 +++++- .../src/Notification/NotificationMailer.php | 33 +++++++----- .../src/Notification/UnsubscribeToken.php | 42 +++++++++++++++ .../views/notification/html/base.blade.php | 43 +++++++++++++++ .../views/notification/plain/base.blade.php | 11 ++++ .../views/unsubscribe-confirmation.blade.php | 8 +++ 25 files changed, 325 insertions(+), 25 deletions(-) rename extensions/mentions/views/emails/{ => html}/groupMentioned.blade.php (83%) rename extensions/mentions/views/emails/{ => html}/postMentioned.blade.php (84%) rename extensions/mentions/views/emails/{ => html}/userMentioned.blade.php (83%) create mode 100644 extensions/mentions/views/emails/plain/groupMentioned.blade.php create mode 100644 extensions/mentions/views/emails/plain/postMentioned.blade.php create mode 100644 extensions/mentions/views/emails/plain/userMentioned.blade.php rename extensions/subscriptions/views/emails/{ => html}/newPost.blade.php (83%) create mode 100644 extensions/subscriptions/views/emails/plain/newPost.blade.php rename extensions/suspend/views/emails/{ => plain}/suspended.blade.php (74%) rename extensions/suspend/views/emails/{ => plain}/unsuspended.blade.php (66%) create mode 100644 framework/core/migrations/2023_08_19_000000_create_unsubscribe_tokens_table.php create mode 100644 framework/core/src/Forum/Controller/UnsubscribeController.php create mode 100644 framework/core/src/Notification/UnsubscribeToken.php create mode 100644 framework/core/views/notification/html/base.blade.php create mode 100644 framework/core/views/notification/plain/base.blade.php create mode 100644 framework/core/views/unsubscribe-confirmation.blade.php diff --git a/extensions/mentions/src/Notification/GroupMentionedBlueprint.php b/extensions/mentions/src/Notification/GroupMentionedBlueprint.php index 50d9b5824d..6bca6da476 100644 --- a/extensions/mentions/src/Notification/GroupMentionedBlueprint.php +++ b/extensions/mentions/src/Notification/GroupMentionedBlueprint.php @@ -38,9 +38,11 @@ public function getData(): mixed return null; } - public function getEmailView(): string|array + public function getEmailView(): array { - return ['text' => 'flarum-mentions::emails.groupMentioned']; + return [ + 'text' => 'flarum-mentions::emails.plain.groupMentioned', + 'html' => 'flarum-mentions::emails.html.groupMentioned',]; } public function getEmailSubject(TranslatorInterface $translator): string diff --git a/extensions/mentions/src/Notification/PostMentionedBlueprint.php b/extensions/mentions/src/Notification/PostMentionedBlueprint.php index 465ee57ba9..4d594d2fbd 100644 --- a/extensions/mentions/src/Notification/PostMentionedBlueprint.php +++ b/extensions/mentions/src/Notification/PostMentionedBlueprint.php @@ -39,9 +39,12 @@ public function getData(): array return ['replyNumber' => (int) $this->reply->number]; } - public function getEmailView(): string|array + public function getEmailView(): array { - return ['text' => 'flarum-mentions::emails.postMentioned']; + return [ + 'text' => 'flarum-mentions::emails.plain.postMentioned', + 'html' => 'flarum-mentions::emails.html.postMentioned', + ]; } public function getEmailSubject(TranslatorInterface $translator): string diff --git a/extensions/mentions/src/Notification/UserMentionedBlueprint.php b/extensions/mentions/src/Notification/UserMentionedBlueprint.php index 1555693384..39d50e8325 100644 --- a/extensions/mentions/src/Notification/UserMentionedBlueprint.php +++ b/extensions/mentions/src/Notification/UserMentionedBlueprint.php @@ -38,9 +38,12 @@ public function getData(): mixed return null; } - public function getEmailView(): string|array + public function getEmailView(): array { - return ['text' => 'flarum-mentions::emails.userMentioned']; + return [ + 'text' => 'flarum-mentions::emails.plain.userMentioned', + 'html' => 'flarum-mentions::emails.html.userMentioned' + ]; } public function getEmailSubject(TranslatorInterface $translator): string diff --git a/extensions/mentions/views/emails/groupMentioned.blade.php b/extensions/mentions/views/emails/html/groupMentioned.blade.php similarity index 83% rename from extensions/mentions/views/emails/groupMentioned.blade.php rename to extensions/mentions/views/emails/html/groupMentioned.blade.php index 52b6f04582..42b8c82d49 100644 --- a/extensions/mentions/views/emails/groupMentioned.blade.php +++ b/extensions/mentions/views/emails/html/groupMentioned.blade.php @@ -1,3 +1,6 @@ +@extends('flarum.forum::notification.html.base') + +@section('content') {!! $translator->trans('flarum-mentions.email.group_mentioned.body', [ '{recipient_display_name}' => $user->display_name, '{mentioner_display_name}' => $blueprint->post->user->display_name, @@ -5,3 +8,4 @@ '{url}' => $url->to('forum')->route('discussion', ['id' => $blueprint->post->discussion_id, 'near' => $blueprint->post->number]), '{content}' => $blueprint->post->content ]) !!} +@endsection diff --git a/extensions/mentions/views/emails/postMentioned.blade.php b/extensions/mentions/views/emails/html/postMentioned.blade.php similarity index 84% rename from extensions/mentions/views/emails/postMentioned.blade.php rename to extensions/mentions/views/emails/html/postMentioned.blade.php index 73ce3d7a63..2dea90da0b 100644 --- a/extensions/mentions/views/emails/postMentioned.blade.php +++ b/extensions/mentions/views/emails/html/postMentioned.blade.php @@ -1,3 +1,6 @@ +@extends('flarum.forum::notification.html.base') + +@section('content') {!! $translator->trans('flarum-mentions.email.post_mentioned.body', [ '{recipient_display_name}' => $user->display_name, '{replier_display_name}' => $blueprint->reply->user->display_name, @@ -6,3 +9,4 @@ '{url}' => $url->to('forum')->route('discussion', ['id' => $blueprint->reply->discussion_id, 'near' => $blueprint->reply->number]), '{content}' => $blueprint->reply->content ]) !!} +@endsection diff --git a/extensions/mentions/views/emails/userMentioned.blade.php b/extensions/mentions/views/emails/html/userMentioned.blade.php similarity index 83% rename from extensions/mentions/views/emails/userMentioned.blade.php rename to extensions/mentions/views/emails/html/userMentioned.blade.php index 9d3881607a..586031c746 100644 --- a/extensions/mentions/views/emails/userMentioned.blade.php +++ b/extensions/mentions/views/emails/html/userMentioned.blade.php @@ -1,3 +1,6 @@ +@extends('flarum.forum::notification.html.base') + +@section('content') {!! $translator->trans('flarum-mentions.email.user_mentioned.body', [ '{recipient_display_name}' => $user->display_name, '{mentioner_display_name}' => $blueprint->post->user->display_name, @@ -5,3 +8,4 @@ '{url}' => $url->to('forum')->route('discussion', ['id' => $blueprint->post->discussion_id, 'near' => $blueprint->post->number]), '{content}' => $blueprint->post->content ]) !!} +@endsection diff --git a/extensions/mentions/views/emails/plain/groupMentioned.blade.php b/extensions/mentions/views/emails/plain/groupMentioned.blade.php new file mode 100644 index 0000000000..fcee97cb77 --- /dev/null +++ b/extensions/mentions/views/emails/plain/groupMentioned.blade.php @@ -0,0 +1,11 @@ +@extends('flarum.forum::notification.plain.base') + +@section('content') +{!! $translator->trans('flarum-mentions.email.group_mentioned.body', [ +'{recipient_display_name}' => $user->display_name, +'{mentioner_display_name}' => $blueprint->post->user->display_name, +'{title}' => $blueprint->post->discussion->title, +'{url}' => $url->to('forum')->route('discussion', ['id' => $blueprint->post->discussion_id, 'near' => $blueprint->post->number]), +'{content}' => $blueprint->post->content +]) !!} +@endsection diff --git a/extensions/mentions/views/emails/plain/postMentioned.blade.php b/extensions/mentions/views/emails/plain/postMentioned.blade.php new file mode 100644 index 0000000000..08ba96dc65 --- /dev/null +++ b/extensions/mentions/views/emails/plain/postMentioned.blade.php @@ -0,0 +1,12 @@ +@extends('flarum.forum::notification.plain.base') + +@section('content') +{!! $translator->trans('flarum-mentions.email.post_mentioned.body', [ +'{recipient_display_name}' => $user->display_name, +'{replier_display_name}' => $blueprint->reply->user->display_name, +'{post_number}' => $blueprint->post->number, +'{title}' => $blueprint->post->discussion->title, +'{url}' => $url->to('forum')->route('discussion', ['id' => $blueprint->reply->discussion_id, 'near' => $blueprint->reply->number]), +'{content}' => $blueprint->reply->content +]) !!} +@endsection diff --git a/extensions/mentions/views/emails/plain/userMentioned.blade.php b/extensions/mentions/views/emails/plain/userMentioned.blade.php new file mode 100644 index 0000000000..cc0b797b43 --- /dev/null +++ b/extensions/mentions/views/emails/plain/userMentioned.blade.php @@ -0,0 +1,11 @@ +@extends('flarum.forum::notification.plain.base') + +@section('content') +{!! $translator->trans('flarum-mentions.email.user_mentioned.body', [ +'{recipient_display_name}' => $user->display_name, +'{mentioner_display_name}' => $blueprint->post->user->display_name, +'{title}' => $blueprint->post->discussion->title, +'{url}' => $url->to('forum')->route('discussion', ['id' => $blueprint->post->discussion_id, 'near' => $blueprint->post->number]), +'{content}' => $blueprint->post->content +]) !!} +@endsection diff --git a/extensions/subscriptions/src/Notification/NewPostBlueprint.php b/extensions/subscriptions/src/Notification/NewPostBlueprint.php index 58664bc42c..043169aef8 100644 --- a/extensions/subscriptions/src/Notification/NewPostBlueprint.php +++ b/extensions/subscriptions/src/Notification/NewPostBlueprint.php @@ -39,9 +39,11 @@ public function getData(): array return ['postNumber' => (int) $this->post->number]; } - public function getEmailView(): string|array + public function getEmailView(): array { - return ['text' => 'flarum-subscriptions::emails.newPost']; + return [ + 'text' => 'flarum-subscriptions::emails.plain.newPost', + 'html' => 'flarum-subscriptions::emails.html.newPost',]; } public function getEmailSubject(TranslatorInterface $translator): string diff --git a/extensions/subscriptions/views/emails/newPost.blade.php b/extensions/subscriptions/views/emails/html/newPost.blade.php similarity index 83% rename from extensions/subscriptions/views/emails/newPost.blade.php rename to extensions/subscriptions/views/emails/html/newPost.blade.php index e1c11e7d4e..596b3da3ac 100644 --- a/extensions/subscriptions/views/emails/newPost.blade.php +++ b/extensions/subscriptions/views/emails/html/newPost.blade.php @@ -1,3 +1,6 @@ +@extends('flarum.forum::notification.html.base') + +@section('content') {!! $translator->trans('flarum-subscriptions.email.new_post.body', [ '{recipient_display_name}' => $user->display_name, '{poster_display_name}' => $blueprint->post->user->display_name, @@ -5,3 +8,4 @@ '{url}' => $url->to('forum')->route('discussion', ['id' => $blueprint->post->discussion_id, 'near' => $blueprint->post->number]), '{content}' => $blueprint->post->content ]) !!} +@endsection diff --git a/extensions/subscriptions/views/emails/plain/newPost.blade.php b/extensions/subscriptions/views/emails/plain/newPost.blade.php new file mode 100644 index 0000000000..d14728196e --- /dev/null +++ b/extensions/subscriptions/views/emails/plain/newPost.blade.php @@ -0,0 +1,11 @@ +@extends('flarum.forum::notification.plain.base') + +@section('content') +{!! $translator->trans('flarum-subscriptions.email.new_post.body', [ +'{recipient_display_name}' => $user->display_name, +'{poster_display_name}' => $blueprint->post->user->display_name, +'{title}' => $blueprint->post->discussion->title, +'{url}' => $url->to('forum')->route('discussion', ['id' => $blueprint->post->discussion_id, 'near' => $blueprint->post->number]), +'{content}' => $blueprint->post->content +]) !!} +@endsection diff --git a/extensions/suspend/src/Notification/UserSuspendedBlueprint.php b/extensions/suspend/src/Notification/UserSuspendedBlueprint.php index 53b1f3807d..819ff83d4c 100644 --- a/extensions/suspend/src/Notification/UserSuspendedBlueprint.php +++ b/extensions/suspend/src/Notification/UserSuspendedBlueprint.php @@ -48,9 +48,11 @@ public static function getSubjectModel(): string return User::class; } - public function getEmailView(): string|array + public function getEmailView(): array { - return ['text' => 'flarum-suspend::emails.suspended']; + return [ + 'text' => 'flarum-suspend::emails.plain.suspended', + 'html' => 'flarum-suspend::emails.html.suspended',]; } public function getEmailSubject(TranslatorInterface $translator): string diff --git a/extensions/suspend/src/Notification/UserUnsuspendedBlueprint.php b/extensions/suspend/src/Notification/UserUnsuspendedBlueprint.php index 8660b12d35..6cf4939086 100644 --- a/extensions/suspend/src/Notification/UserUnsuspendedBlueprint.php +++ b/extensions/suspend/src/Notification/UserUnsuspendedBlueprint.php @@ -49,9 +49,11 @@ public static function getSubjectModel(): string return User::class; } - public function getEmailView(): string|array + public function getEmailView(): array { - return ['text' => 'flarum-suspend::emails.unsuspended']; + return [ + 'text' => 'flarum-suspend::emails.plain.unsuspended', + 'html' => 'flarum-suspend::emails.html.unsuspended',]; } public function getEmailSubject(TranslatorInterface $translator): string diff --git a/extensions/suspend/views/emails/suspended.blade.php b/extensions/suspend/views/emails/plain/suspended.blade.php similarity index 74% rename from extensions/suspend/views/emails/suspended.blade.php rename to extensions/suspend/views/emails/plain/suspended.blade.php index 924733e838..de5a89bedb 100644 --- a/extensions/suspend/views/emails/suspended.blade.php +++ b/extensions/suspend/views/emails/plain/suspended.blade.php @@ -1,4 +1,8 @@ +@extends('flarum.forum::notification.plain.base') + +@section('content') {!! $translator->trans('flarum-suspend.email.suspended.body', [ '{recipient_display_name}' => $user->display_name, '{suspension_message}' => $blueprint->user->suspend_message ?? $translator->trans('flarum-suspend.email.no_reason_given'), ]) !!} +@endsection diff --git a/extensions/suspend/views/emails/unsuspended.blade.php b/extensions/suspend/views/emails/plain/unsuspended.blade.php similarity index 66% rename from extensions/suspend/views/emails/unsuspended.blade.php rename to extensions/suspend/views/emails/plain/unsuspended.blade.php index 1237e6c2cc..679f3e760a 100644 --- a/extensions/suspend/views/emails/unsuspended.blade.php +++ b/extensions/suspend/views/emails/plain/unsuspended.blade.php @@ -1,4 +1,8 @@ +@extends('flarum.forum::notification.plain.base') + +@section('content') {!! $translator->trans('flarum-suspend.email.unsuspended.body', [ '{recipient_display_name}' => $user->display_name, '{forum_url}' => $url->to('forum')->base(), ]) !!} +@endsection diff --git a/framework/core/migrations/2023_08_19_000000_create_unsubscribe_tokens_table.php b/framework/core/migrations/2023_08_19_000000_create_unsubscribe_tokens_table.php new file mode 100644 index 0000000000..2bf7e5d3b7 --- /dev/null +++ b/framework/core/migrations/2023_08_19_000000_create_unsubscribe_tokens_table.php @@ -0,0 +1,30 @@ +id(); + $table->unsignedInteger('user_id'); + $table->string('email_type'); + $table->string('token', 100)->unique(); + $table->timestamp('unsubscribed_at')->nullable(); + $table->timestamps(); + + $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); + + $table->index('user_id'); + $table->index('email_type'); + $table->index('token'); + $table->index(['user_id', 'email_type']); + } +); diff --git a/framework/core/src/Forum/Controller/UnsubscribeController.php b/framework/core/src/Forum/Controller/UnsubscribeController.php new file mode 100644 index 0000000000..35561cbd0a --- /dev/null +++ b/framework/core/src/Forum/Controller/UnsubscribeController.php @@ -0,0 +1,53 @@ +getQueryParams(), 'userId'); + $token = Arr::get($request->getQueryParams(), 'token'); + + // Fetch the unsubscribe token record + $unsubscribeRecord = UnsubscribeToken::where('user_id', $userId) + ->where('token', $token) + ->first(); + + // If record exists and has not been used before + if ($unsubscribeRecord && !$unsubscribeRecord->unsubscribed_at) { + // Mark as unsubscribed + $unsubscribeRecord->unsubscribed_at = Carbon::now(); + $unsubscribeRecord->save(); + + // Update user preferences + /** @var User $user */ + $user = User::find($userId); + $user->setPreference('notify_' . $unsubscribeRecord->email_type . '_email', false); + $user->save(); + + $message = 'You have successfully unsubscribed from this type of email notification. If you wish to receive it again, please update your settings.'; + } else { + // If the token doesn't exist or has already been used + $message = 'This unsubscribe link is invalid or has already been used. Please check your settings if you wish to manage your email notifications.'; + } + + return $this->view->make('flarum.forum::unsubscribe-confirmation')->with('message', $message); + } +} diff --git a/framework/core/src/Forum/routes.php b/framework/core/src/Forum/routes.php index d0264cb8c1..2823ad7670 100644 --- a/framework/core/src/Forum/routes.php +++ b/framework/core/src/Forum/routes.php @@ -43,6 +43,12 @@ $route->toForum(Content\AssertRegistered::class) ); + $map->get( + '/notifications/unsubscribe/{userId}/{token}', + 'notifications.unsubscribe', + $route->toController(Controller\UnsubscribeController::class) + ); + $map->get( '/logout', 'logout', diff --git a/framework/core/src/Notification/MailableInterface.php b/framework/core/src/Notification/MailableInterface.php index a5cf4a7608..198b31395f 100644 --- a/framework/core/src/Notification/MailableInterface.php +++ b/framework/core/src/Notification/MailableInterface.php @@ -15,11 +15,26 @@ interface MailableInterface { /** * Get the name of the view to construct a notification email with. + * + * To provide the best experince for the user, provide both a `text` and `html` view. + * + * Example: + * ```php + * return [ + * 'text' => 'flarum-subscriptions::emails.plain.newPost', + * 'html' => 'flarum-subscriptions::emails.html.newPost' + * ]; + * ``` */ - public function getEmailView(): string|array; + public function getEmailView(): array; /** * Get the subject line for a notification email. */ public function getEmailSubject(TranslatorInterface $translator): string; + + /** + * Get the serialized type of this activity. + */ + public static function getType(): string; } diff --git a/framework/core/src/Notification/NotificationMailer.php b/framework/core/src/Notification/NotificationMailer.php index b847f9a4c9..24f187e856 100644 --- a/framework/core/src/Notification/NotificationMailer.php +++ b/framework/core/src/Notification/NotificationMailer.php @@ -1,41 +1,50 @@ translator->setLocale($user->getPreference('locale') ?? $this->settings->get('default_locale')); + // Generate and save the unsubscribe token: + $token = Str::random(60); + $unsubscribeRecord = new UnsubscribeToken([ + 'user_id' => $user->id, + 'email_type' => $blueprint::getType(), + 'token' => $token + ]); + $unsubscribeRecord->save(); + + $unsubscribeLink = $this->url->to('forum')->route('notifications.unsubscribe', ['userId' => $user->id, 'token' => $token]); + $settingsLink = $this->url->to('forum')->route('settings'); + $this->mailer->send( $blueprint->getEmailView(), - compact('blueprint', 'user'), - function (Message $message) use ($blueprint, $user) { + compact('blueprint', 'user', 'unsubscribeLink', 'settingsLink'), + function (Message $message) use ($blueprint, $user, $unsubscribeLink) { $message->to($user->email, $user->display_name) - ->subject($blueprint->getEmailSubject($this->translator)); + ->subject($blueprint->getEmailSubject($this->translator)) + ->getHeaders() + ->addTextHeader('List-Unsubscribe', '<' . $unsubscribeLink . '>'); } ); } diff --git a/framework/core/src/Notification/UnsubscribeToken.php b/framework/core/src/Notification/UnsubscribeToken.php new file mode 100644 index 0000000000..ff00f52eaf --- /dev/null +++ b/framework/core/src/Notification/UnsubscribeToken.php @@ -0,0 +1,42 @@ + 'int', + 'unsubscribed_at' => 'datetime' + ]; + + /** + * The attributes that are mass assignable. + * + * @var array + */ + protected $fillable = ['user_id', 'email_type', 'token']; + + /** + * Define a relation to the User model. + */ + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } +} diff --git a/framework/core/views/notification/html/base.blade.php b/framework/core/views/notification/html/base.blade.php new file mode 100644 index 0000000000..e45bc8f805 --- /dev/null +++ b/framework/core/views/notification/html/base.blade.php @@ -0,0 +1,43 @@ + + + + + + {{ $settings->get('forum_title') }} Notification + + + +
+

{{ $settings->get('forum_title') }} Notification

+
+ @yield('content') +
+ +
+ + diff --git a/framework/core/views/notification/plain/base.blade.php b/framework/core/views/notification/plain/base.blade.php new file mode 100644 index 0000000000..de2efc498c --- /dev/null +++ b/framework/core/views/notification/plain/base.blade.php @@ -0,0 +1,11 @@ +{{ $settings->get('forum_title') }} Notification + +--------------------------------------------------- + +@yield('content') + +--------------------------------------------------- + +If you'd like to stop receiving this type of notification, unsubscribe here: {{ $unsubscribeLink }} + +Manage your notification settings: {{ $settingsLink }} diff --git a/framework/core/views/unsubscribe-confirmation.blade.php b/framework/core/views/unsubscribe-confirmation.blade.php new file mode 100644 index 0000000000..af2b1ba81b --- /dev/null +++ b/framework/core/views/unsubscribe-confirmation.blade.php @@ -0,0 +1,8 @@ +@extends('flarum.forum::layouts.basic') + +@section('content') +
+

Unsubscribe Confirmation

+

{{ $message }}

+
+@endsection From d247b408e212f9e9e69dcea2e87791538030b729 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Sat, 19 Aug 2023 21:49:44 +0000 Subject: [PATCH 02/60] Apply fixes from StyleCI --- .../src/Notification/GroupMentionedBlueprint.php | 2 +- .../src/Notification/NewPostBlueprint.php | 2 +- .../src/Notification/UserSuspendedBlueprint.php | 2 +- .../src/Notification/UserUnsuspendedBlueprint.php | 2 +- .../src/Forum/Controller/UnsubscribeController.php | 13 ++++++++++--- .../core/src/Notification/MailableInterface.php | 6 +++--- .../core/src/Notification/NotificationMailer.php | 11 +++++++++-- .../core/src/Notification/UnsubscribeToken.php | 7 +++++++ 8 files changed, 33 insertions(+), 12 deletions(-) diff --git a/extensions/mentions/src/Notification/GroupMentionedBlueprint.php b/extensions/mentions/src/Notification/GroupMentionedBlueprint.php index 6bca6da476..1598306f10 100644 --- a/extensions/mentions/src/Notification/GroupMentionedBlueprint.php +++ b/extensions/mentions/src/Notification/GroupMentionedBlueprint.php @@ -42,7 +42,7 @@ public function getEmailView(): array { return [ 'text' => 'flarum-mentions::emails.plain.groupMentioned', - 'html' => 'flarum-mentions::emails.html.groupMentioned',]; + 'html' => 'flarum-mentions::emails.html.groupMentioned', ]; } public function getEmailSubject(TranslatorInterface $translator): string diff --git a/extensions/subscriptions/src/Notification/NewPostBlueprint.php b/extensions/subscriptions/src/Notification/NewPostBlueprint.php index 043169aef8..4fcf03f662 100644 --- a/extensions/subscriptions/src/Notification/NewPostBlueprint.php +++ b/extensions/subscriptions/src/Notification/NewPostBlueprint.php @@ -43,7 +43,7 @@ public function getEmailView(): array { return [ 'text' => 'flarum-subscriptions::emails.plain.newPost', - 'html' => 'flarum-subscriptions::emails.html.newPost',]; + 'html' => 'flarum-subscriptions::emails.html.newPost', ]; } public function getEmailSubject(TranslatorInterface $translator): string diff --git a/extensions/suspend/src/Notification/UserSuspendedBlueprint.php b/extensions/suspend/src/Notification/UserSuspendedBlueprint.php index 819ff83d4c..a40cf6c490 100644 --- a/extensions/suspend/src/Notification/UserSuspendedBlueprint.php +++ b/extensions/suspend/src/Notification/UserSuspendedBlueprint.php @@ -52,7 +52,7 @@ public function getEmailView(): array { return [ 'text' => 'flarum-suspend::emails.plain.suspended', - 'html' => 'flarum-suspend::emails.html.suspended',]; + 'html' => 'flarum-suspend::emails.html.suspended', ]; } public function getEmailSubject(TranslatorInterface $translator): string diff --git a/extensions/suspend/src/Notification/UserUnsuspendedBlueprint.php b/extensions/suspend/src/Notification/UserUnsuspendedBlueprint.php index 6cf4939086..0d90b49194 100644 --- a/extensions/suspend/src/Notification/UserUnsuspendedBlueprint.php +++ b/extensions/suspend/src/Notification/UserUnsuspendedBlueprint.php @@ -53,7 +53,7 @@ public function getEmailView(): array { return [ 'text' => 'flarum-suspend::emails.plain.unsuspended', - 'html' => 'flarum-suspend::emails.html.unsuspended',]; + 'html' => 'flarum-suspend::emails.html.unsuspended', ]; } public function getEmailSubject(TranslatorInterface $translator): string diff --git a/framework/core/src/Forum/Controller/UnsubscribeController.php b/framework/core/src/Forum/Controller/UnsubscribeController.php index 35561cbd0a..aaa5310483 100644 --- a/framework/core/src/Forum/Controller/UnsubscribeController.php +++ b/framework/core/src/Forum/Controller/UnsubscribeController.php @@ -1,11 +1,18 @@ first(); // If record exists and has not been used before - if ($unsubscribeRecord && !$unsubscribeRecord->unsubscribed_at) { + if ($unsubscribeRecord && ! $unsubscribeRecord->unsubscribed_at) { // Mark as unsubscribed $unsubscribeRecord->unsubscribed_at = Carbon::now(); $unsubscribeRecord->save(); @@ -39,7 +46,7 @@ public function render(Request $request): View // Update user preferences /** @var User $user */ $user = User::find($userId); - $user->setPreference('notify_' . $unsubscribeRecord->email_type . '_email', false); + $user->setPreference('notify_'.$unsubscribeRecord->email_type.'_email', false); $user->save(); $message = 'You have successfully unsubscribed from this type of email notification. If you wish to receive it again, please update your settings.'; diff --git a/framework/core/src/Notification/MailableInterface.php b/framework/core/src/Notification/MailableInterface.php index 198b31395f..a14ca18720 100644 --- a/framework/core/src/Notification/MailableInterface.php +++ b/framework/core/src/Notification/MailableInterface.php @@ -15,13 +15,13 @@ interface MailableInterface { /** * Get the name of the view to construct a notification email with. - * + * * To provide the best experince for the user, provide both a `text` and `html` view. - * + * * Example: * ```php * return [ - * 'text' => 'flarum-subscriptions::emails.plain.newPost', + * 'text' => 'flarum-subscriptions::emails.plain.newPost', * 'html' => 'flarum-subscriptions::emails.html.newPost' * ]; * ``` diff --git a/framework/core/src/Notification/NotificationMailer.php b/framework/core/src/Notification/NotificationMailer.php index 24f187e856..cf64f510d9 100644 --- a/framework/core/src/Notification/NotificationMailer.php +++ b/framework/core/src/Notification/NotificationMailer.php @@ -1,11 +1,18 @@ to($user->email, $user->display_name) ->subject($blueprint->getEmailSubject($this->translator)) ->getHeaders() - ->addTextHeader('List-Unsubscribe', '<' . $unsubscribeLink . '>'); + ->addTextHeader('List-Unsubscribe', '<'.$unsubscribeLink.'>'); } ); } diff --git a/framework/core/src/Notification/UnsubscribeToken.php b/framework/core/src/Notification/UnsubscribeToken.php index ff00f52eaf..93f0005923 100644 --- a/framework/core/src/Notification/UnsubscribeToken.php +++ b/framework/core/src/Notification/UnsubscribeToken.php @@ -1,5 +1,12 @@ Date: Sun, 20 Aug 2023 15:28:19 +0100 Subject: [PATCH 03/60] use PHPStan array shape --- .../core/src/Notification/MailableInterface.php | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/framework/core/src/Notification/MailableInterface.php b/framework/core/src/Notification/MailableInterface.php index a14ca18720..b4fe61df14 100644 --- a/framework/core/src/Notification/MailableInterface.php +++ b/framework/core/src/Notification/MailableInterface.php @@ -16,15 +16,12 @@ interface MailableInterface /** * Get the name of the view to construct a notification email with. * - * To provide the best experince for the user, provide both a `text` and `html` view. + * To provide the best experience for the user, Flarum expects both a `text` and `html` view. * - * Example: - * ```php - * return [ - * 'text' => 'flarum-subscriptions::emails.plain.newPost', - * 'html' => 'flarum-subscriptions::emails.html.newPost' - * ]; - * ``` + * @return array{ + * text: string, + * html: string + * } */ public function getEmailView(): array; From 76604bb3d431232a006cd2a0ff43e22079561b14 Mon Sep 17 00:00:00 2001 From: IanM Date: Sun, 20 Aug 2023 15:31:32 +0100 Subject: [PATCH 04/60] remove docblocks --- .../core/src/Notification/UnsubscribeToken.php | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/framework/core/src/Notification/UnsubscribeToken.php b/framework/core/src/Notification/UnsubscribeToken.php index 93f0005923..0ee77be0d1 100644 --- a/framework/core/src/Notification/UnsubscribeToken.php +++ b/framework/core/src/Notification/UnsubscribeToken.php @@ -15,33 +15,15 @@ class UnsubscribeToken extends AbstractModel { - /** - * The table associated with the model. - * - * @var string - */ protected $table = 'unsubscribe_tokens'; - /** - * The attributes that should be cast to native types. - * - * @var array - */ protected $casts = [ 'user_id' => 'int', 'unsubscribed_at' => 'datetime' ]; - /** - * The attributes that are mass assignable. - * - * @var array - */ protected $fillable = ['user_id', 'email_type', 'token']; - /** - * Define a relation to the User model. - */ public function user(): BelongsTo { return $this->belongsTo(User::class); From 79928b01c7726e6629a1249c2943f4ad05e3d391 Mon Sep 17 00:00:00 2001 From: IanM Date: Sun, 20 Aug 2023 15:43:28 +0100 Subject: [PATCH 05/60] docblock types for UnsubscibeToken model --- .../src/Forum/Controller/UnsubscribeController.php | 2 +- framework/core/src/Notification/UnsubscribeToken.php | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/framework/core/src/Forum/Controller/UnsubscribeController.php b/framework/core/src/Forum/Controller/UnsubscribeController.php index aaa5310483..5bb03f3a1e 100644 --- a/framework/core/src/Forum/Controller/UnsubscribeController.php +++ b/framework/core/src/Forum/Controller/UnsubscribeController.php @@ -9,6 +9,7 @@ namespace Flarum\Forum\Controller; +use Carbon\Carbon; use Flarum\Http\Controller\AbstractHtmlController; use Flarum\Http\UrlGenerator; use Flarum\Notification\UnsubscribeToken; @@ -16,7 +17,6 @@ use Illuminate\Contracts\View\Factory; use Illuminate\Contracts\View\View; use Illuminate\Support\Arr; -use Illuminate\Support\Carbon; use Psr\Http\Message\ServerRequestInterface as Request; class UnsubscribeController extends AbstractHtmlController diff --git a/framework/core/src/Notification/UnsubscribeToken.php b/framework/core/src/Notification/UnsubscribeToken.php index 0ee77be0d1..da3e6fd685 100644 --- a/framework/core/src/Notification/UnsubscribeToken.php +++ b/framework/core/src/Notification/UnsubscribeToken.php @@ -13,6 +13,16 @@ use Flarum\User\User; use Illuminate\Database\Eloquent\Relations\BelongsTo; +/** + * @property int $id + * @property int $user_id + * @property string $email_type + * @property string $token + * @property \Carbon\Carbon $$unsubscribed_at + * @property \Carbon\Carbon $created_at + * @property \Carbon\Carbon $updated_at + * @property-read \Flarum\User\User|null $user + */ class UnsubscribeToken extends AbstractModel { protected $table = 'unsubscribe_tokens'; From 5df71971031afd0f070666d1b6ea9a4d6d32f3ce Mon Sep 17 00:00:00 2001 From: IanM Date: Sun, 20 Aug 2023 15:45:32 +0100 Subject: [PATCH 06/60] typo --- framework/core/src/Notification/UnsubscribeToken.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/core/src/Notification/UnsubscribeToken.php b/framework/core/src/Notification/UnsubscribeToken.php index da3e6fd685..db696314c1 100644 --- a/framework/core/src/Notification/UnsubscribeToken.php +++ b/framework/core/src/Notification/UnsubscribeToken.php @@ -18,7 +18,7 @@ * @property int $user_id * @property string $email_type * @property string $token - * @property \Carbon\Carbon $$unsubscribed_at + * @property \Carbon\Carbon $unsubscribed_at * @property \Carbon\Carbon $created_at * @property \Carbon\Carbon $updated_at * @property-read \Flarum\User\User|null $user From e1ab8e5c2c9ba8a6c31f54bd0205da6eff1f7fdc Mon Sep 17 00:00:00 2001 From: IanM Date: Sun, 20 Aug 2023 15:58:49 +0100 Subject: [PATCH 07/60] create setNotificationPreference on the User model --- .../src/Forum/Controller/UnsubscribeController.php | 3 ++- framework/core/src/User/User.php | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/framework/core/src/Forum/Controller/UnsubscribeController.php b/framework/core/src/Forum/Controller/UnsubscribeController.php index 5bb03f3a1e..6a2f17c5ae 100644 --- a/framework/core/src/Forum/Controller/UnsubscribeController.php +++ b/framework/core/src/Forum/Controller/UnsubscribeController.php @@ -33,6 +33,7 @@ public function render(Request $request): View $token = Arr::get($request->getQueryParams(), 'token'); // Fetch the unsubscribe token record + /** @var UnsubscribeToken|null $unsubscribeRecord */ $unsubscribeRecord = UnsubscribeToken::where('user_id', $userId) ->where('token', $token) ->first(); @@ -46,7 +47,7 @@ public function render(Request $request): View // Update user preferences /** @var User $user */ $user = User::find($userId); - $user->setPreference('notify_'.$unsubscribeRecord->email_type.'_email', false); + $user->setNotificationPreference($unsubscribeRecord->email_type, 'email', false); $user->save(); $message = 'You have successfully unsubscribed from this type of email notification. If you wish to receive it again, please update your settings.'; diff --git a/framework/core/src/User/User.php b/framework/core/src/User/User.php index a96f63adb1..1c44496b12 100644 --- a/framework/core/src/User/User.php +++ b/framework/core/src/User/User.php @@ -687,4 +687,14 @@ public function refreshDiscussionCount(): static return $this; } + + /** + * Set the value of a notification preference. + */ + public function setNotificationPreference(string $type, string $method, bool $value): static + { + $this->setPreference(static::getNotificationPreferenceKey($type, $method), $value); + + return $this; + } } From ad4fc00d47a4f3ab4375a379d29f538ab817dc24 Mon Sep 17 00:00:00 2001 From: IanM Date: Sun, 20 Aug 2023 16:08:53 +0100 Subject: [PATCH 08/60] attempt to fix phpstan error --- framework/core/src/Forum/Controller/UnsubscribeController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/core/src/Forum/Controller/UnsubscribeController.php b/framework/core/src/Forum/Controller/UnsubscribeController.php index 6a2f17c5ae..11c91c0f7a 100644 --- a/framework/core/src/Forum/Controller/UnsubscribeController.php +++ b/framework/core/src/Forum/Controller/UnsubscribeController.php @@ -39,7 +39,7 @@ public function render(Request $request): View ->first(); // If record exists and has not been used before - if ($unsubscribeRecord && ! $unsubscribeRecord->unsubscribed_at) { + if ($unsubscribeRecord && empty($unsubscribeRecord->unsubscribed_at)) { // Mark as unsubscribed $unsubscribeRecord->unsubscribed_at = Carbon::now(); $unsubscribeRecord->save(); From c3ce914099631a35fd2a7008604c1861687c23e2 Mon Sep 17 00:00:00 2001 From: IanM Date: Sun, 20 Aug 2023 19:22:26 +0100 Subject: [PATCH 09/60] Rename getEmailView to getEmailViews to better reflect the function. Begin adding translations --- .../src/Notification/GroupMentionedBlueprint.php | 2 +- .../mentions/src/Notification/PostMentionedBlueprint.php | 2 +- .../mentions/src/Notification/UserMentionedBlueprint.php | 2 +- .../subscriptions/src/Notification/NewPostBlueprint.php | 2 +- .../suspend/src/Notification/UserSuspendedBlueprint.php | 2 +- .../src/Notification/UserUnsuspendedBlueprint.php | 2 +- framework/core/locale/core.yml | 5 +++++ framework/core/src/Notification/MailableInterface.php | 4 ++-- framework/core/src/Notification/NotificationMailer.php | 2 +- framework/core/views/notification/html/base.blade.php | 9 +++++++-- framework/core/views/unsubscribe-confirmation.blade.php | 8 +++++++- 11 files changed, 28 insertions(+), 12 deletions(-) diff --git a/extensions/mentions/src/Notification/GroupMentionedBlueprint.php b/extensions/mentions/src/Notification/GroupMentionedBlueprint.php index 1598306f10..f70c9f4851 100644 --- a/extensions/mentions/src/Notification/GroupMentionedBlueprint.php +++ b/extensions/mentions/src/Notification/GroupMentionedBlueprint.php @@ -38,7 +38,7 @@ public function getData(): mixed return null; } - public function getEmailView(): array + public function getEmailViews(): array { return [ 'text' => 'flarum-mentions::emails.plain.groupMentioned', diff --git a/extensions/mentions/src/Notification/PostMentionedBlueprint.php b/extensions/mentions/src/Notification/PostMentionedBlueprint.php index 4d594d2fbd..81594d8d9a 100644 --- a/extensions/mentions/src/Notification/PostMentionedBlueprint.php +++ b/extensions/mentions/src/Notification/PostMentionedBlueprint.php @@ -39,7 +39,7 @@ public function getData(): array return ['replyNumber' => (int) $this->reply->number]; } - public function getEmailView(): array + public function getEmailViews(): array { return [ 'text' => 'flarum-mentions::emails.plain.postMentioned', diff --git a/extensions/mentions/src/Notification/UserMentionedBlueprint.php b/extensions/mentions/src/Notification/UserMentionedBlueprint.php index 39d50e8325..acdf2ab6fe 100644 --- a/extensions/mentions/src/Notification/UserMentionedBlueprint.php +++ b/extensions/mentions/src/Notification/UserMentionedBlueprint.php @@ -38,7 +38,7 @@ public function getData(): mixed return null; } - public function getEmailView(): array + public function getEmailViews(): array { return [ 'text' => 'flarum-mentions::emails.plain.userMentioned', diff --git a/extensions/subscriptions/src/Notification/NewPostBlueprint.php b/extensions/subscriptions/src/Notification/NewPostBlueprint.php index 4fcf03f662..e96c803ddb 100644 --- a/extensions/subscriptions/src/Notification/NewPostBlueprint.php +++ b/extensions/subscriptions/src/Notification/NewPostBlueprint.php @@ -39,7 +39,7 @@ public function getData(): array return ['postNumber' => (int) $this->post->number]; } - public function getEmailView(): array + public function getEmailViews(): array { return [ 'text' => 'flarum-subscriptions::emails.plain.newPost', diff --git a/extensions/suspend/src/Notification/UserSuspendedBlueprint.php b/extensions/suspend/src/Notification/UserSuspendedBlueprint.php index a40cf6c490..b54aa70f99 100644 --- a/extensions/suspend/src/Notification/UserSuspendedBlueprint.php +++ b/extensions/suspend/src/Notification/UserSuspendedBlueprint.php @@ -48,7 +48,7 @@ public static function getSubjectModel(): string return User::class; } - public function getEmailView(): array + public function getEmailViews(): array { return [ 'text' => 'flarum-suspend::emails.plain.suspended', diff --git a/extensions/suspend/src/Notification/UserUnsuspendedBlueprint.php b/extensions/suspend/src/Notification/UserUnsuspendedBlueprint.php index 0d90b49194..31745dbb85 100644 --- a/extensions/suspend/src/Notification/UserUnsuspendedBlueprint.php +++ b/extensions/suspend/src/Notification/UserUnsuspendedBlueprint.php @@ -49,7 +49,7 @@ public static function getSubjectModel(): string return User::class; } - public function getEmailView(): array + public function getEmailViews(): array { return [ 'text' => 'flarum-suspend::emails.plain.unsuspended', diff --git a/framework/core/locale/core.yml b/framework/core/locale/core.yml index 6c6de0b9c9..d492a62dd3 100644 --- a/framework/core/locale/core.yml +++ b/framework/core/locale/core.yml @@ -727,6 +727,11 @@ core: submit_button: => core.ref.save_changes title: => core.ref.reset_your_password + # Translations in this namespace are displayed by the email unsubscribe interface. + unsubscribe_email: + title: Unsubscribe Confirmation + return_to_forum: Back to {forumTitle} + # Translations in this namespace are used in messages output by the API. api: invalid_username_message: "The username may only contain letters, numbers, and dashes." diff --git a/framework/core/src/Notification/MailableInterface.php b/framework/core/src/Notification/MailableInterface.php index b4fe61df14..68ecb7ca25 100644 --- a/framework/core/src/Notification/MailableInterface.php +++ b/framework/core/src/Notification/MailableInterface.php @@ -14,7 +14,7 @@ interface MailableInterface { /** - * Get the name of the view to construct a notification email with. + * Get the names of the views to construct a notification email with. * * To provide the best experience for the user, Flarum expects both a `text` and `html` view. * @@ -23,7 +23,7 @@ interface MailableInterface * html: string * } */ - public function getEmailView(): array; + public function getEmailViews(): array; /** * Get the subject line for a notification email. diff --git a/framework/core/src/Notification/NotificationMailer.php b/framework/core/src/Notification/NotificationMailer.php index cf64f510d9..a7701a0da6 100644 --- a/framework/core/src/Notification/NotificationMailer.php +++ b/framework/core/src/Notification/NotificationMailer.php @@ -45,7 +45,7 @@ public function send(MailableInterface $blueprint, User $user): void $settingsLink = $this->url->to('forum')->route('settings'); $this->mailer->send( - $blueprint->getEmailView(), + $blueprint->getEmailViews(), compact('blueprint', 'user', 'unsubscribeLink', 'settingsLink'), function (Message $message) use ($blueprint, $user, $unsubscribeLink) { $message->to($user->email, $user->display_name) diff --git a/framework/core/views/notification/html/base.blade.php b/framework/core/views/notification/html/base.blade.php index e45bc8f805..234fd29eaf 100644 --- a/framework/core/views/notification/html/base.blade.php +++ b/framework/core/views/notification/html/base.blade.php @@ -1,12 +1,17 @@ +@php + $primaryColor = $settings->get('theme_primary_color'); + $secondaryColor = $settings->get('theme_secondary_color'); +@endphp + - + {{ $settings->get('forum_title') }} Notification -
-

{{ $settings->get('forum_title') }} Notification

-
- @yield('content') -
- -
+ +
+ + @yield('header') +
+ +
+ + @yield('content') +
+ + + diff --git a/framework/core/views/email/html/information/base.blade.php b/framework/core/views/email/html/information/base.blade.php new file mode 100644 index 0000000000..7e9a695844 --- /dev/null +++ b/framework/core/views/email/html/information/base.blade.php @@ -0,0 +1,16 @@ +@extends('flarum.forum::email.html.base') + +@section('header') + +

{{ $title ?? 'Information' }}

+@endsection + +@section('content') + +

{{ $infoContent }}

+@endsection + +@section('footer') + +

This email was sent to {{ $userEmail}} as an informational service related to your account on {{ $forumTitle }}.

+@endsection diff --git a/framework/core/views/email/html/notification/base.blade.php b/framework/core/views/email/html/notification/base.blade.php new file mode 100644 index 0000000000..79fa2fb6c1 --- /dev/null +++ b/framework/core/views/email/html/notification/base.blade.php @@ -0,0 +1,18 @@ +@extends('flarum.forum::email.html.base') + +@section('header') + +

{{ $title ?? 'Notification' }}

+@endsection + +@section('content') + + @yield('notificationContent') +@endsection + +@section('footer') + +

This email was sent to {{ $user->email }} because you are subcribed to "{{ $type }}" notifications on {{ $forumTitle }}.

+

If you'd like to stop receiving this type of notification, unsubscribe here.

+

Manage your notification settings here.

+@endsection diff --git a/framework/core/views/email/plain/base.blade.php b/framework/core/views/email/plain/base.blade.php new file mode 100644 index 0000000000..d2d1511dce --- /dev/null +++ b/framework/core/views/email/plain/base.blade.php @@ -0,0 +1,11 @@ +{{ $title ?? 'Flarum Email' }} + +--------------------- +@yield('header') +--------------------- + +@yield('content') + +--------------------- +@yield('footer') +--------------------- diff --git a/framework/core/views/email/plain/information/base.blade.php b/framework/core/views/email/plain/information/base.blade.php new file mode 100644 index 0000000000..dfcbe9c73b --- /dev/null +++ b/framework/core/views/email/plain/information/base.blade.php @@ -0,0 +1,16 @@ +@extends('flarum.forum::email.plain.base') + +@section('header') + + {{ $title ?? 'Information' }} +@endsection + +@section('content') + + {{ $infoContent }} +@endsection + +@section('footer') + + This email was sent to {{ $userEmail}} as an informational service related to your account on {{ $forumTitle }}. +@endsection diff --git a/framework/core/views/email/plain/notification/base.blade.php b/framework/core/views/email/plain/notification/base.blade.php new file mode 100644 index 0000000000..6e05acf5d9 --- /dev/null +++ b/framework/core/views/email/plain/notification/base.blade.php @@ -0,0 +1,20 @@ +@extends('flarum.forum::email.plain.base') + +@section('header') + + {{ $title ?? 'Notification' }} +@endsection + +@section('content') + + @yield('notificationContent') +@endsection + +@section('footer') + + This email was sent to {{ $user->email }} because you are subcribed to "{{ $type }}" notifications on {{ $forumTitle }}. + + If you'd like to stop receiving this type of notification, unsubscribe here: {{ $unsubscribeLink }} + + Manage your notification settings: {{ $settingsLink }} +@endsection diff --git a/framework/core/views/notification/plain/base.blade.php b/framework/core/views/notification/plain/base.blade.php deleted file mode 100644 index de2efc498c..0000000000 --- a/framework/core/views/notification/plain/base.blade.php +++ /dev/null @@ -1,11 +0,0 @@ -{{ $settings->get('forum_title') }} Notification - ---------------------------------------------------- - -@yield('content') - ---------------------------------------------------- - -If you'd like to stop receiving this type of notification, unsubscribe here: {{ $unsubscribeLink }} - -Manage your notification settings: {{ $settingsLink }} From c4c86a24a01f2d26089786ed2b055bdc5f85a33d Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Mon, 21 Aug 2023 09:54:54 +0000 Subject: [PATCH 20/60] Apply fixes from StyleCI --- framework/core/src/User/EmailConfirmationMailer.php | 1 - framework/core/src/User/Job/RequestPasswordResetJob.php | 1 - 2 files changed, 2 deletions(-) diff --git a/framework/core/src/User/EmailConfirmationMailer.php b/framework/core/src/User/EmailConfirmationMailer.php index e56a9d4acf..185171e53a 100644 --- a/framework/core/src/User/EmailConfirmationMailer.php +++ b/framework/core/src/User/EmailConfirmationMailer.php @@ -12,7 +12,6 @@ use Flarum\Http\UrlGenerator; use Flarum\Locale\TranslatorInterface; use Flarum\Mail\Job\SendInformationalEmailJob; -use Flarum\Mail\Job\SendRawEmailJob; use Flarum\Settings\SettingsRepositoryInterface; use Flarum\User\Event\EmailChangeRequested; use Illuminate\Contracts\Queue\Queue; diff --git a/framework/core/src/User/Job/RequestPasswordResetJob.php b/framework/core/src/User/Job/RequestPasswordResetJob.php index e93faca92a..1141fd82e2 100644 --- a/framework/core/src/User/Job/RequestPasswordResetJob.php +++ b/framework/core/src/User/Job/RequestPasswordResetJob.php @@ -12,7 +12,6 @@ use Flarum\Http\UrlGenerator; use Flarum\Locale\TranslatorInterface; use Flarum\Mail\Job\SendInformationalEmailJob; -use Flarum\Mail\Job\SendRawEmailJob; use Flarum\Queue\AbstractJob; use Flarum\Settings\SettingsRepositoryInterface; use Flarum\User\PasswordToken; From 670a323fe8dd404f1c8513b084ce5f17915025df Mon Sep 17 00:00:00 2001 From: IanM Date: Mon, 21 Aug 2023 11:04:13 +0100 Subject: [PATCH 21/60] update path --- framework/core/src/Api/Controller/SendTestMailController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/core/src/Api/Controller/SendTestMailController.php b/framework/core/src/Api/Controller/SendTestMailController.php index 0d004655a8..f591aeb850 100644 --- a/framework/core/src/Api/Controller/SendTestMailController.php +++ b/framework/core/src/Api/Controller/SendTestMailController.php @@ -41,8 +41,8 @@ public function handle(ServerRequestInterface $request): ResponseInterface $this->mailer->send( [ - 'plain' => 'flarum.forum::email.information.plain.base', - 'html' => 'flarum.forum::email.information.html.base' + 'plain' => 'flarum.forum::email.plain.information.base', + 'html' => 'flarum.forum::email.html.information.base' ], compact('infoContent', 'userEmail', 'forumTitle', 'title'), function (Message $message) use ($actor) { From 900cd73790ea3b61591d22811c09ff3581479195 Mon Sep 17 00:00:00 2001 From: IanM Date: Mon, 21 Aug 2023 12:35:43 +0100 Subject: [PATCH 22/60] extract greeting and handle globally --- extensions/mentions/locale/en.yml | 6 ----- extensions/subscriptions/locale/en.yml | 2 -- extensions/suspend/locale/en.yml | 4 ---- framework/core/locale/core.yml | 22 ++++++++++++------- .../Api/Controller/SendTestMailController.php | 3 ++- .../src/Notification/NotificationMailer.php | 3 ++- .../src/User/AccountActivationMailerTrait.php | 3 ++- .../core/src/User/EmailConfirmationMailer.php | 3 ++- .../core/views/email/html/base.blade.php | 9 +++++++- .../email/html/information/base.blade.php | 4 ++-- .../email/html/notification/base.blade.php | 10 ++++----- .../core/views/email/plain/base.blade.php | 2 ++ 12 files changed, 39 insertions(+), 32 deletions(-) diff --git a/extensions/mentions/locale/en.yml b/extensions/mentions/locale/en.yml index 108af93797..4c8f11aa6f 100644 --- a/extensions/mentions/locale/en.yml +++ b/extensions/mentions/locale/en.yml @@ -71,8 +71,6 @@ flarum-mentions: post_mentioned: subject: "{replier_display_name} replied to your post in {title}" body: | - Hey {recipient_display_name}! - {replier_display_name} replied to your post (#{post_number}) in {title}. {url} @@ -85,8 +83,6 @@ flarum-mentions: user_mentioned: subject: "{mentioner_display_name} mentioned you in {title}" body: | - Hey {recipient_display_name}! - {mentioner_display_name} mentioned you in a post in {title}. {url} @@ -98,8 +94,6 @@ flarum-mentions: group_mentioned: subject: "{mentioner_display_name} mentioned a group you're a member of in {title}" body: | - Hey {recipient_display_name}! - {mentioner_display_name} mentioned a group you're a member of in {title}. {url} diff --git a/extensions/subscriptions/locale/en.yml b/extensions/subscriptions/locale/en.yml index e724708fcb..a08a231e70 100644 --- a/extensions/subscriptions/locale/en.yml +++ b/extensions/subscriptions/locale/en.yml @@ -52,8 +52,6 @@ flarum-subscriptions: new_post: subject: "[New Post] {title}" body: | - Hey {recipient_display_name}! - {poster_display_name} made a post in a discussion you're following: {title}. To view the new activity, check out the following link: diff --git a/extensions/suspend/locale/en.yml b/extensions/suspend/locale/en.yml index 495c28d5f3..d7ef375ddc 100644 --- a/extensions/suspend/locale/en.yml +++ b/extensions/suspend/locale/en.yml @@ -53,8 +53,6 @@ flarum-suspend: suspended: subject: Your account has been suspended body: | - Hey {recipient_display_name}, - You have been suspended for the following reason: --- @@ -64,8 +62,6 @@ flarum-suspend: unsuspended: subject: Your account has been unsuspended body: | - Hey {recipient_display_name}, - You have been unsuspended. You can head back to the forum by clicking on the following link: {forum_url} diff --git a/framework/core/locale/core.yml b/framework/core/locale/core.yml index 649a32f9d2..855f0d9159 100644 --- a/framework/core/locale/core.yml +++ b/framework/core/locale/core.yml @@ -747,13 +747,25 @@ core: # Translations in this namespace are used in emails sent by the forum. email: + greeting: "Hey {displayName}!" + + # These translations are used by the "informational" email template. + informational: + default_title: "Information" + footer: "This email was sent to {userEmail} as an informational service related to your account on {forumTitle}."# + + # These translations are used by the "notification" email template. + notification: + default_title: "Notification" + footer: + main_text: "This email was sent to {email} because you are subscribed to \"{type}\" notifications on {forumTitle}." + unsubscribe_text: "If you'd like to stop receiving this type of notification, unsubscribe here." + settings_text: "Manage your notification settings here." # These translations are used in emails sent when users register new accounts. activate_account: subject: Activate Your New Account body: | - Hey {username}! - Someone (hopefully you!) has signed up to {forum} with this email address. If this was you, simply click the following link and your account will be activated: @@ -765,8 +777,6 @@ core: confirm_email: subject: Confirm Your New Email Address body: | - Hey {username}! - Someone (hopefully you!) has changed their email address on {forum} to this one. If this was you, simply click the following link and your email will be confirmed: @@ -778,8 +788,6 @@ core: reset_password: subject: => core.ref.reset_your_password body: | - Hey {username}! - Someone (hopefully you!) has submitted a forgotten password request for your account on {forum}. If this was you, click the following link to reset your password: @@ -791,8 +799,6 @@ core: send_test: subject: Flarum Email Test body: | - Hey {username}! - This is a test email to confirm that your Flarum email configuration is working properly. If this was you, this email means that your configuration works! diff --git a/framework/core/src/Api/Controller/SendTestMailController.php b/framework/core/src/Api/Controller/SendTestMailController.php index f591aeb850..c9112271e4 100644 --- a/framework/core/src/Api/Controller/SendTestMailController.php +++ b/framework/core/src/Api/Controller/SendTestMailController.php @@ -38,13 +38,14 @@ public function handle(ServerRequestInterface $request): ResponseInterface $title = $this->translator->trans('core.email.send_test.subject'); $forumTitle = $this->settings->get('forum_title'); $userEmail = $actor->email; + $username = $actor->display_name; $this->mailer->send( [ 'plain' => 'flarum.forum::email.plain.information.base', 'html' => 'flarum.forum::email.html.information.base' ], - compact('infoContent', 'userEmail', 'forumTitle', 'title'), + compact('infoContent', 'userEmail', 'forumTitle', 'title', 'username'), function (Message $message) use ($actor) { $message->to($actor->email); $message->subject($this->translator->trans('core.email.send_test.subject')); diff --git a/framework/core/src/Notification/NotificationMailer.php b/framework/core/src/Notification/NotificationMailer.php index a05f3acbce..9288326ce5 100644 --- a/framework/core/src/Notification/NotificationMailer.php +++ b/framework/core/src/Notification/NotificationMailer.php @@ -40,10 +40,11 @@ public function send(MailableInterface $blueprint, User $user): void $settingsLink = $this->url->to('forum')->route('settings'); $type = $blueprint::getType(); $forumTitle = $this->settings->get('forum_title'); + $username = $user->display_name; $this->mailer->send( $this->getEmailViews($blueprint), - compact('blueprint', 'user', 'unsubscribeLink', 'settingsLink', 'type', 'forumTitle'), + compact('blueprint', 'user', 'unsubscribeLink', 'settingsLink', 'type', 'forumTitle', 'username'), function (Message $message) use ($blueprint, $user) { $message->to($user->email, $user->display_name) ->subject($blueprint->getEmailSubject($this->translator)); diff --git a/framework/core/src/User/AccountActivationMailerTrait.php b/framework/core/src/User/AccountActivationMailerTrait.php index c4b9cc7692..a43e4bf30e 100644 --- a/framework/core/src/User/AccountActivationMailerTrait.php +++ b/framework/core/src/User/AccountActivationMailerTrait.php @@ -10,6 +10,7 @@ namespace Flarum\User; use Flarum\Mail\Job\SendInformationalEmailJob; +use Illuminate\Support\Arr; trait AccountActivationMailerTrait { @@ -38,6 +39,6 @@ protected function sendConfirmationEmail(User $user, array $data): void $body = $this->translator->trans('core.email.activate_account.body', $data); $subject = $this->translator->trans('core.email.activate_account.subject'); - $this->queue->push(new SendInformationalEmailJob($user->email, $subject, $body, $this->settings->get('forum_title'))); + $this->queue->push(new SendInformationalEmailJob($user->email, $subject, $body, Arr::get($data, 'forum'))); } } diff --git a/framework/core/src/User/EmailConfirmationMailer.php b/framework/core/src/User/EmailConfirmationMailer.php index 185171e53a..28b6fc990a 100644 --- a/framework/core/src/User/EmailConfirmationMailer.php +++ b/framework/core/src/User/EmailConfirmationMailer.php @@ -15,6 +15,7 @@ use Flarum\Settings\SettingsRepositoryInterface; use Flarum\User\Event\EmailChangeRequested; use Illuminate\Contracts\Queue\Queue; +use Illuminate\Support\Arr; class EmailConfirmationMailer { @@ -34,7 +35,7 @@ public function handle(EmailChangeRequested $event): void $body = $this->translator->trans('core.email.confirm_email.body', $data); $subject = $this->translator->trans('core.email.confirm_email.subject'); - $this->queue->push(new SendInformationalEmailJob($email, $subject, $body, $this->settings->get('forum_title'))); + $this->queue->push(new SendInformationalEmailJob($email, $subject, $body, Arr::get($data, 'forum'))); } protected function generateToken(User $user, string $email): EmailToken diff --git a/framework/core/views/email/html/base.blade.php b/framework/core/views/email/html/base.blade.php index 407615734f..9cb2b31497 100644 --- a/framework/core/views/email/html/base.blade.php +++ b/framework/core/views/email/html/base.blade.php @@ -1,3 +1,5 @@ +@inject('url', 'Flarum\Http\UrlGenerator') + @php $primaryColor = $settings->get('theme_primary_color'); $secondaryColor = $settings->get('theme_secondary_color'); @@ -41,7 +43,12 @@
- @yield('content') +
+ {!! $translator->trans('core.email.greeting', ['displayName' => $username]) !!} +
+
+ @yield('content') +