1<?php
2
3// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0.
4// See the LICENCE file in the repository root for full licence text.
5
6namespace App\Mail;
7
8use App\Exceptions\InvalidNotificationException;
9use App\Jobs\Notifications\BroadcastNotificationBase;
10use App\Models\Notification;
11use App\Models\User;
12use Illuminate\Mail\Mailable;
13
14// Not queueable to avoid trap of too many serialize/unserialize.
15// Paired with App\Jobs\UserNotificationDigest
16class UserNotificationDigest extends Mailable
17{
18 private $groups = [];
19
20 /**
21 * Create a new message instance.
22 *
23 * @return void
24 */
25 public function __construct(private array $notifications, private User $user)
26 {
27 }
28
29 private function addToGroups(Notification $notification)
30 {
31 try {
32 $class = BroadcastNotificationBase::getNotificationClassFromNotification($notification);
33 $baseKey = 'notifications.mail.'.$class::getBaseKey($notification);
34 $key = $class::getMailGroupingKey($notification);
35
36 if (!isset($this->groups[$key])) {
37 // remove anything not a string because trans doesn't like it.
38 $details = array_filter($notification->details ?? [], function ($value) {
39 return is_string($value);
40 });
41
42 if (
43 $this->user->getKey() === $notification->source_user_id
44 && trans_exists("{$baseKey}_self", app()->getLocale())
45 ) {
46 $baseKey = "{$baseKey}_self";
47 }
48
49 $this->groups[$key] = [
50 'text' => osu_trans($baseKey, $details),
51 ];
52 }
53
54 $link = $class::getMailLink($notification);
55 $this->groups[$key]['links'][$link] = '';
56 } catch (InvalidNotificationException $e) {
57 log_error($e);
58 }
59 }
60
61 /**
62 * Build the message.
63 *
64 * @return $this
65 */
66 public function build()
67 {
68 foreach ($this->notifications as $notification) {
69 $this->addToGroups($notification);
70 }
71
72 $groups = array_values($this->groups);
73 $user = $this->user;
74
75 return $this
76 ->text('emails.user_notification_digest', compact('groups', 'user'))
77 ->subject(osu_trans('mail.user_notification_digest.subject'));
78 }
79}