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