Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
98.68% covered (success)
98.68%
75 / 76
75.00% covered (warning)
75.00%
3 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
SendEmailConfigurationReminderCommand
98.68% covered (success)
98.68%
75 / 76
75.00% covered (warning)
75.00%
3 / 4
21
0.00% covered (danger)
0.00%
0 / 1
 getNotificationSubscriptionType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 autogenerateSubscriptions
96.15% covered (success)
96.15%
25 / 26
0.00% covered (danger)
0.00%
0 / 1
10
 getEmailConfigReminderState
100.00% covered (success)
100.00%
31 / 31
100.00% covered (success)
100.00%
1 / 1
7
 getNotifications
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3namespace Olz\Command\Notifications;
4
5use Olz\Command\Notifications\Common\BaseSendNotificationsCommand;
6use Olz\Command\Notifications\Common\Notification;
7use Olz\Constants\NotificationDeliveryType;
8use Olz\Constants\NotificationType;
9use Olz\Entity\NotificationSubscription;
10use Olz\Entity\Users\User;
11use Olz\Utils\WithUtilsTrait;
12use Symfony\Component\Console\Attribute\AsCommand;
13
14#[AsCommand(name: 'olz:send-email-config-reminder')]
15class SendEmailConfigurationReminderCommand extends BaseSendNotificationsCommand {
16    use WithUtilsTrait;
17
18    public const DAY_OF_MONTH = 22;
19
20    public function getNotificationSubscriptionType(): NotificationType {
21        return NotificationType::EMAIL_CONFIG_REMINDER;
22    }
23
24    public function autogenerateSubscriptions(): void {
25        $this->log()->info("Generating email configuration reminder subscriptions...");
26        $email_notifications_state = $this->getEmailConfigReminderState();
27
28        $now_datetime = new \DateTime($this->dateUtils()->getIsoNow());
29        $notification_subscription_repo = $this->entityManager()->getRepository(NotificationSubscription::class);
30        $user_repo = $this->entityManager()->getRepository(User::class);
31        foreach ($email_notifications_state as $user_id => $state) {
32            $reminder_id = $state['reminder_id'] ?? false;
33            $needs_reminder = $state['needs_reminder'] ?? false;
34            $user = $user_repo->findOneBy(['id' => $user_id]);
35            if (!$user) {
36                $this->log()->warning("No user (ID:{$user_id}) for email reminder");
37            }
38            if ($needs_reminder && !$reminder_id && $user) {
39                $this->log()->info("Generating email configuration reminder subscription for '{$user}'...");
40                $subscription = new NotificationSubscription();
41                $subscription->setUser($user);
42                $subscription->setDeliveryType(NotificationDeliveryType::EMAIL);
43                $subscription->setNotificationType(NotificationType::EMAIL_CONFIG_REMINDER);
44                $subscription->setNotificationTypeArgs(json_encode(['cancelled' => false]) ?: '{}');
45                $subscription->setCreatedAt($now_datetime);
46                $this->entityManager()->persist($subscription);
47            }
48            if ($reminder_id && !$needs_reminder) {
49                $this->log()->info("Removing email configuration reminder subscription ({$reminder_id}) for '{$user}'...");
50                $subscription = $notification_subscription_repo->findOneBy(['id' => $reminder_id]);
51                if ($subscription) {
52                    $this->entityManager()->remove($subscription);
53                }
54            }
55        }
56        $this->entityManager()->flush();
57    }
58
59    /** @return array<int, array{reminder_id?: int, needs_reminder?: bool}> */
60    protected function getEmailConfigReminderState(): array {
61        $now_datetime = new \DateTime($this->dateUtils()->getIsoNow());
62        $minus_one_month = \DateInterval::createFromDateString("-1 months");
63        $one_month_ago = $now_datetime->add($minus_one_month);
64        $email_notifications_state = [];
65
66        // Find users with existing email config reminder notification subscriptions.
67        $notification_subscription_repo = $this->entityManager()->getRepository(NotificationSubscription::class);
68        $email_notification_subscriptions = $notification_subscription_repo->findBy([
69            'notification_type' => NotificationType::EMAIL_CONFIG_REMINDER,
70        ]);
71        foreach ($email_notification_subscriptions as $subscription) {
72            $user_id = $subscription->getUser()->getId() ?: 0;
73            $user_state = $email_notifications_state[$user_id] ?? [];
74            $subscription_id = $subscription->getId();
75            $this->generalUtils()->checkNotNull($subscription_id, "No subscription ID");
76            $user_state['reminder_id'] = $subscription_id;
77            $email_notifications_state[$user_id] = $user_state;
78        }
79
80        // Find users who should have email config reminder notification subscriptions.
81        $user_repo = $this->entityManager()->getRepository(User::class);
82        $users_with_email = $user_repo->getUsersWithLogin();
83        $non_config_reminder_notification_types = $this->getNonReminderNotificationTypes();
84        foreach ($users_with_email as $user_with_email) {
85            $joined_recently = ($user_with_email->getCreatedAt()->getTimestamp() > $one_month_ago->getTimestamp());
86            $subscription = $notification_subscription_repo->findOneBy([
87                'user' => $user_with_email,
88                'delivery_type' => NotificationDeliveryType::EMAIL,
89                'notification_type' => $non_config_reminder_notification_types,
90            ]);
91            if (!$subscription && $joined_recently) {
92                $user_id = $user_with_email->getId() ?: 0;
93                $user_state = $email_notifications_state[$user_id] ?? [];
94                $user_state['needs_reminder'] = true;
95                $email_notifications_state[$user_id] = $user_state;
96            }
97        }
98
99        return $email_notifications_state;
100    }
101
102    // ---
103
104    public function getNotifications(array $args): array {
105        if ($args['cancelled'] ?? false) {
106            return [];
107        }
108        $day_of_month = intval($this->dateUtils()->getCurrentDateInFormat('j'));
109        if ($day_of_month !== self::DAY_OF_MONTH) {
110            return [];
111        }
112
113        $base_href = $this->envUtils()->getBaseHref();
114        $code_href = $this->envUtils()->getCodeHref();
115        $newsletter_url = "{$base_href}{$code_href}apps/newsletter";
116
117        $title = "Kein Newsletter abonniert";
118        $text = <<<ZZZZZZZZZZ
119            Hallo %%userFirstName%%,
120
121            Leider hast du bisher keinerlei OLZ-Newsletter-Benachrichtigungen abonniert.
122
123
124            **Du möchtest eigentlich OLZ-Newsletter-Benachrichtigungen erhalten?**
125
126            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.
127
128            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.
129
130
131            **Du möchtest auch weiterhin keine OLZ-Newsletter-Benachrichtigungen erhalten?**
132
133            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".
134
135
136            ZZZZZZZZZZ;
137
138        return [
139            new Notification($title, $text, [
140                'notification_type' => NotificationType::EMAIL_CONFIG_REMINDER,
141            ]),
142        ];
143    }
144}