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