Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
80.82% covered (warning)
80.82%
118 / 146
60.00% covered (warning)
60.00%
3 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
SendWeeklySummaryCommand
80.82% covered (warning)
80.82%
118 / 146
60.00% covered (warning)
60.00%
3 / 5
33.53
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
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getNotifications
77.19% covered (warning)
77.19%
88 / 114
0.00% covered (danger)
0.00%
0 / 1
27.74
 getPrettyDateAndMaybeTime
71.43% covered (warning)
71.43%
5 / 7
0.00% covered (danger)
0.00%
0 / 1
3.21
 getNewsCriteria
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace Olz\Command\Notifications;
4
5use Doctrine\Common\Collections\Criteria;
6use Doctrine\Common\Collections\Order;
7use Olz\Command\Notifications\Common\BaseSendNotificationsCommand;
8use Olz\Command\Notifications\Common\Notification;
9use Olz\Constants\NotificationType;
10use Olz\Entity\News\NewsEntry;
11use Olz\Entity\Termine\Termin;
12use Olz\Utils\WithUtilsTrait;
13use Symfony\Component\Console\Attribute\AsCommand;
14
15#[AsCommand(name: 'olz:send-weekly-summary')]
16class SendWeeklySummaryCommand extends BaseSendNotificationsCommand {
17    use WithUtilsTrait;
18
19    public const CUT_OFF_TIME = '03:00:00';
20
21    protected \DateTime $today;
22    protected \DateTime $lastWeek;
23
24    public function getNotificationSubscriptionType(): NotificationType {
25        return NotificationType::WEEKLY_SUMMARY;
26    }
27
28    public function autogenerateSubscriptions(): void {
29        // Must be generated by user.
30    }
31
32    public function getNotifications(array $args): array {
33        $current_weekday = intval($this->dateUtils()->getCurrentDateInFormat('N'));
34        $monday = 1;
35        if ($current_weekday != $monday) {
36            return [];
37        }
38
39        $this->today = new \DateTime($this->dateUtils()->getIsoToday());
40        $minus_one_week = \DateInterval::createFromDateString("-7 days");
41        $this->lastWeek = (new \DateTime($this->dateUtils()->getIsoToday()))->add($minus_one_week);
42
43        $today_at_cut_off = new \DateTime($this->today->format('Y-m-d').' '.self::CUT_OFF_TIME);
44        $last_week_at_cut_off = new \DateTime($this->lastWeek->format('Y-m-d').' '.self::CUT_OFF_TIME);
45        $termine_criteria = Criteria::create()
46            ->where(Criteria::expr()->andX(
47                Criteria::expr()->lte('last_modified_at', $today_at_cut_off),
48                Criteria::expr()->gt('last_modified_at', $last_week_at_cut_off),
49                Criteria::expr()->eq('newsletter', true),
50                Criteria::expr()->eq('on_off', 1),
51            ))
52            ->orderBy(['start_date' => Order::Ascending, 'start_time' => Order::Ascending])
53            ->setFirstResult(0)
54            ->setMaxResults(1000)
55        ;
56
57        $notification_text = '';
58        $base_href = $this->envUtils()->getBaseHref();
59        $code_href = $this->envUtils()->getCodeHref();
60
61        if ($args['aktuell'] ?? false) {
62            $news_url = "{$base_href}{$code_href}news";
63            $aktuell_text = '';
64            $news_repo = $this->entityManager()->getRepository(NewsEntry::class);
65            $aktuell_criteria = $this->getNewsCriteria(['aktuell']);
66            $aktuells = $news_repo->matching($aktuell_criteria);
67            foreach ($aktuells as $aktuell) {
68                $id = $aktuell->getId();
69                $pretty_datetime = $this->getPrettyDateAndMaybeTime(
70                    $aktuell->getPublishedDate(),
71                    $aktuell->getPublishedTime()
72                );
73                $title = $this->htmlUtils()->escapeMarkdown($aktuell->getTitle());
74                $aktuell_text .= "- {$pretty_datetime}: [{$title}]({$news_url}/{$id})\n";
75            }
76            if (strlen($aktuell_text) > 0) {
77                $notification_text .= "\n**Aktuell**\n\n{$aktuell_text}\n";
78            }
79        }
80
81        if ($args['blog'] ?? false) {
82            $news_url = "{$base_href}{$code_href}news";
83            $blog_text = '';
84            $news_repo = $this->entityManager()->getRepository(NewsEntry::class);
85            $blog_criteria = $this->getNewsCriteria(['kaderblog']);
86            $blogs = $news_repo->matching($blog_criteria);
87            foreach ($blogs as $blog) {
88                $id = $blog->getId();
89                $pretty_datetime = $this->getPrettyDateAndMaybeTime(
90                    $blog->getPublishedDate(),
91                    $blog->getPublishedTime()
92                );
93                $title = $this->htmlUtils()->escapeMarkdown($blog->getTitle());
94                $blog_text .= "- {$pretty_datetime}: [{$title}]({$news_url}/{$id})\n";
95            }
96            if (strlen($blog_text) > 0) {
97                $notification_text .= "\n**Kaderblog**\n\n{$blog_text}\n";
98            }
99        }
100
101        if ($args['forum'] ?? false) {
102            $news_url = "{$base_href}{$code_href}news";
103            $forum_text = '';
104            $news_repo = $this->entityManager()->getRepository(NewsEntry::class);
105            $forum_criteria = $this->getNewsCriteria(['forum']);
106            $forums = $news_repo->matching($forum_criteria);
107            foreach ($forums as $forum) {
108                $id = $forum->getId();
109                $pretty_datetime = $this->getPrettyDateAndMaybeTime(
110                    $forum->getPublishedDate(),
111                    $forum->getPublishedTime()
112                );
113                $title = $this->htmlUtils()->escapeMarkdown($forum->getTitle());
114                if (strlen(trim($title)) > 0) {
115                    $forum_text .= "- {$pretty_datetime}: [{$title}]({$news_url}/{$id})\n";
116                }
117            }
118            if (strlen($forum_text) > 0) {
119                $notification_text .= "\n**Forum**\n\n{$forum_text}\n";
120            }
121        }
122
123        if ($args['galerie'] ?? false) {
124            $news_url = "{$base_href}{$code_href}news";
125            $galerie_text = '';
126            $news_repo = $this->entityManager()->getRepository(NewsEntry::class);
127            $galerie_criteria = $this->getNewsCriteria(['galerie', 'video']);
128            $galeries = $news_repo->matching($galerie_criteria);
129            foreach ($galeries as $galerie) {
130                $id = $galerie->getId();
131                $pretty_datetime = $this->getPrettyDateAndMaybeTime(
132                    $galerie->getPublishedDate(),
133                    $galerie->getPublishedTime()
134                );
135                $title = $this->htmlUtils()->escapeMarkdown($galerie->getTitle());
136                $galerie_text .= "- {$pretty_datetime}: [{$title}]({$news_url}/{$id})\n";
137            }
138            if (strlen($galerie_text) > 0) {
139                $notification_text .= "\n**Galerien**\n\n{$galerie_text}\n";
140            }
141        }
142
143        if ($args['termine'] ?? false) {
144            $termine_url = "{$base_href}{$code_href}termine";
145            $termine_text = '';
146            $termin_repo = $this->entityManager()->getRepository(Termin::class);
147            $termine = $termin_repo->matching($termine_criteria);
148            foreach ($termine as $termin) {
149                $id = $termin->getId();
150                $starts_on = $termin->getStartDate();
151                $ends_on = $termin->getEndDate();
152                $pretty_date = ($ends_on && $ends_on > $starts_on)
153                    ? $this->dateUtils()->compactDate($starts_on).' - '.$this->dateUtils()->compactDate($ends_on)
154                    : $this->dateUtils()->compactDate($starts_on);
155                $title = $this->htmlUtils()->escapeMarkdown($termin->getTitle() ?? '');
156                if (strlen(trim($title)) > 0) {
157                    $termine_text .= "- {$pretty_date}: [{$title}]({$termine_url}/{$id})\n";
158                }
159            }
160            if (strlen($termine_text) > 0) {
161                $notification_text .= "\n**Aktualisierte Termine**\n\n{$termine_text}\n";
162            }
163        }
164
165        if (strlen($notification_text) == 0) {
166            return [];
167        }
168
169        $title = "Wochenzusammenfassung";
170        $text = "Hallo %%userFirstName%%,\n\nDas lief diese Woche auf [olzimmerberg.ch](https://olzimmerberg.ch):\n\n{$notification_text}";
171
172        return [
173            new Notification($title, $text, [
174                'notification_type' => NotificationType::WEEKLY_SUMMARY,
175            ]),
176        ];
177    }
178
179    protected function getPrettyDateAndMaybeTime(?\DateTime $date, ?\DateTime $time = null): string {
180        if (!$date) {
181            return "??";
182        }
183        $pretty_date = $this->dateUtils()->compactDate($date);
184        if (!$time) {
185            return $pretty_date;
186        }
187        $pretty_time = $time->format('H:i');
188        return "{$pretty_date} {$pretty_time}";
189    }
190
191    /** @param array<string> $formats */
192    protected function getNewsCriteria(array $formats): Criteria {
193        return Criteria::create()
194            ->where(Criteria::expr()->andX(
195                Criteria::expr()->in('format', $formats),
196                Criteria::expr()->orX(
197                    Criteria::expr()->andX(
198                        Criteria::expr()->eq('published_date', $this->today),
199                        Criteria::expr()->lte('published_time', new \DateTime(self::CUT_OFF_TIME)),
200                    ),
201                    Criteria::expr()->andX(
202                        Criteria::expr()->lt('published_date', $this->today),
203                        Criteria::expr()->gt('published_date', $this->lastWeek),
204                    ),
205                    Criteria::expr()->andX(
206                        Criteria::expr()->eq('published_date', $this->lastWeek),
207                        Criteria::expr()->gt('published_time', new \DateTime(self::CUT_OFF_TIME)),
208                    ),
209                ),
210                Criteria::expr()->eq('on_off', 1),
211            ))
212            ->orderBy(['published_date' => Order::Ascending, 'published_time' => Order::Ascending])
213            ->setFirstResult(0)
214            ->setMaxResults(1000)
215        ;
216    }
217}