Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
81.08% covered (warning)
81.08%
60 / 74
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
SendEmailConfigurationReminderCommand
81.08% covered (warning)
81.08%
60 / 74
0.00% covered (danger)
0.00%
0 / 4
23.99
0.00% covered (danger)
0.00%
0 / 1
 getNotificationSubscriptionType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 autogenerateSubscriptions
80.77% covered (warning)
80.77%
21 / 26
0.00% covered (danger)
0.00%
0 / 1
10.71
 getEmailConfigReminderState
80.65% covered (warning)
80.65%
25 / 31
0.00% covered (danger)
0.00%
0 / 1
7.36
 getNotification
87.50% covered (warning)
87.50%
14 / 16
0.00% covered (danger)
0.00%
0 / 1
3.02
1<?php
2
3namespace Olz\Command\Notifications;
4
5use Olz\Entity\NotificationSubscription;
6use Olz\Entity\Users\User;
7use Olz\Utils\WithUtilsTrait;
8use Symfony\Component\Console\Attribute\AsCommand;
9
10#[AsCommand(name: 'olz:send-email-config-reminder')]
11class SendEmailConfigurationReminderCommand extends BaseSendNotificationsCommand {
12    use WithUtilsTrait;
13
14    public const DAY_OF_MONTH = 22;
15
16    public function getNotificationSubscriptionType(): string {
17        return NotificationSubscription::TYPE_EMAIL_CONFIG_REMINDER;
18    }
19
20    public function autogenerateSubscriptions(): void {
21        $this->log()->info("Generating email configuration reminder subscriptions...");
22        $email_notifications_state = $this->getEmailConfigReminderState();
23
24        $now_datetime = new \DateTime($this->dateUtils()->getIsoNow());
25        $notification_subscription_repo = $this->entityManager()->getRepository(NotificationSubscription::class);
26        $user_repo = $this->entityManager()->getRepository(User::class);
27        foreach ($email_notifications_state as $user_id => $state) {
28            $reminder_id = $state['reminder_id'] ?? false;
29            $needs_reminder = $state['needs_reminder'] ?? false;
30            $user = $user_repo->findOneBy(['id' => $user_id]);
31            if (!$user) {
32                $this->log()->warning("No user (ID:{$user_id}) for telegram notification");
33            }
34            if ($needs_reminder && !$reminder_id && $user) {
35                $this->log()->info("Generating email configuration reminder subscription for '{$user}'...");
36                $subscription = new NotificationSubscription();
37                $subscription->setUser($user);
38                $subscription->setDeliveryType(NotificationSubscription::DELIVERY_EMAIL);
39                $subscription->setNotificationType(NotificationSubscription::TYPE_EMAIL_CONFIG_REMINDER);
40                $subscription->setNotificationTypeArgs(json_encode(['cancelled' => false]) ?: '{}');
41                $subscription->setCreatedAt($now_datetime);
42                $this->entityManager()->persist($subscription);
43            }
44            if ($reminder_id && !$needs_reminder) {
45                $this->log()->info("Removing email configuration reminder subscription ({$reminder_id}) for '{$user}'...");
46                $subscription = $notification_subscription_repo->findOneBy(['id' => $reminder_id]);
47                if ($subscription) {
48                    $this->entityManager()->remove($subscription);
49                }
50            }
51        }
52        $this->entityManager()->flush();
53    }
54
55    /** @return array<int, array{reminder_id?: int, needs_reminder?: bool}> */
56    protected function getEmailConfigReminderState(): array {
57        $now_datetime = new \DateTime($this->dateUtils()->getIsoNow());
58        $minus_one_month = \DateInterval::createFromDateString("-1 months");
59        $one_month_ago = $now_datetime->add($minus_one_month);
60        $email_notifications_state = [];
61
62        // Find users with existing email config reminder notification subscriptions.
63        $notification_subscription_repo = $this->entityManager()->getRepository(NotificationSubscription::class);
64        $email_notification_subscriptions = $notification_subscription_repo->findBy([
65            'notification_type' => NotificationSubscription::TYPE_EMAIL_CONFIG_REMINDER,
66        ]);
67        foreach ($email_notification_subscriptions as $subscription) {
68            $user_id = $subscription->getUser()->getId() ?: 0;
69            $user_state = $email_notifications_state[$user_id] ?? [];
70            $subscription_id = $subscription->getId();
71            $this->generalUtils()->checkNotNull($subscription_id, "No subscription ID");
72            $user_state['reminder_id'] = $subscription_id;
73            $email_notifications_state[$user_id] = $user_state;
74        }
75
76        // Find users who should have email config reminder notification subscriptions.
77        $user_repo = $this->entityManager()->getRepository(User::class);
78        $users_with_email = $user_repo->getUsersWithLogin();
79        $non_config_reminder_notification_types = $this->getNonReminderNotificationTypes();
80        foreach ($users_with_email as $user_with_email) {
81            $joined_recently = ($user_with_email->getCreatedAt()->getTimestamp() > $one_month_ago->getTimestamp());
82            $subscription = $notification_subscription_repo->findOneBy([
83                'user' => $user_with_email,
84                'delivery_type' => NotificationSubscription::DELIVERY_EMAIL,
85                'notification_type' => $non_config_reminder_notification_types,
86            ]);
87            if (!$subscription && $joined_recently) {
88                $user_id = $user_with_email->getId() ?: 0;
89                $user_state = $email_notifications_state[$user_id] ?? [];
90                $user_state['needs_reminder'] = true;
91                $email_notifications_state[$user_id] = $user_state;
92            }
93        }
94
95        return $email_notifications_state;
96    }
97
98    // ---
99
100    /** @param array<string, mixed> $args */
101    public function getNotification(array $args): ?Notification {
102        if ($args['cancelled'] ?? false) {
103            return null;
104        }
105        $day_of_month = intval($this->dateUtils()->getCurrentDateInFormat('j'));
106        if ($day_of_month !== self::DAY_OF_MONTH) {
107            return null;
108        }
109
110        $base_href = $this->envUtils()->getBaseHref();
111        $code_href = $this->envUtils()->getCodeHref();
112        $newsletter_url = "{$base_href}{$code_href}apps/newsletter";
113
114        $title = "Kein Newsletter abonniert";
115        $text = <<<ZZZZZZZZZZ
116            Hallo %%userFirstName%%,
117
118            Leider hast du bisher keinerlei OLZ-Newsletter-Benachrichtigungen abonniert.
119
120
121            **Du möchtest eigentlich OLZ-Newsletter-Benachrichtigungen erhalten?**
122
123            In diesem Fall musst du dich auf der Website [*einloggen*]({$newsletter_url}#login-dialog), und im ["Newsletter"-App]({$newsletter_url}) (ist auch unter "Service" zu finden) bei "E-Mail Newsletter" die gewünschten Benachrichtigungen auswählen.
124
125            Falls du dein Passwort vergessen hast, kannst du es im Login-Dialog bei "Passwort vergessen?" zurücksetzen. Du bist mit der E-Mail Adresse `%%userEmail%%` registriert.
126
127
128            **Du möchtest auch weiterhin keine OLZ-Newsletter-Benachrichtigungen erhalten?**
129
130            Dann ignoriere dieses E-Mail. Wenn du es nicht deaktivierst, wird dir dieses E-Mail nächsten Monat allerdings erneut zugesendet. Um dich abzumelden, klicke unten auf "Keine solchen E-Mails mehr".
131
132
133            ZZZZZZZZZZ;
134
135        return new Notification($title, $text, [
136            'notification_type' => NotificationSubscription::TYPE_EMAIL_CONFIG_REMINDER,
137        ]);
138    }
139}