Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
96.50% covered (success)
96.50%
138 / 143
25.00% covered (danger)
25.00%
1 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
WeeklySummaryGetter
96.50% covered (success)
96.50%
138 / 143
25.00% covered (danger)
25.00%
1 / 4
27
0.00% covered (danger)
0.00%
0 / 1
 autogenerateSubscriptions
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getNotification
97.32% covered (success)
97.32%
109 / 112
0.00% covered (danger)
0.00%
0 / 1
22
 getPrettyDateAndMaybeTime
85.71% covered (warning)
85.71%
6 / 7
0.00% covered (danger)
0.00%
0 / 1
3.03
 getNewsCriteria
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace Olz\Command\SendDailyNotificationsCommand;
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;
11
12class WeeklySummaryGetter implements NotificationGetterInterface {
13    use WithUtilsTrait;
14
15    public const CUT_OFF_TIME = '16:00:00';
16
17    protected \DateTime $today;
18    protected \DateTime $lastWeek;
19
20    public function autogenerateSubscriptions(): void {
21        // Must be generated by user.
22    }
23
24    /** @param array<string, mixed> $args */
25    public function getNotification(array $args): ?Notification {
26        $current_weekday = intval($this->dateUtils()->getCurrentDateInFormat('N'));
27        $monday = 1;
28        if ($current_weekday != $monday) {
29            return null;
30        }
31
32        $this->today = new \DateTime($this->dateUtils()->getIsoToday());
33        $minus_one_week = \DateInterval::createFromDateString("-7 days");
34        $this->lastWeek = (new \DateTime($this->dateUtils()->getIsoToday()))->add($minus_one_week);
35
36        $today_at_cut_off = new \DateTime($this->today->format('Y-m-d').' '.self::CUT_OFF_TIME);
37        $last_week_at_cut_off = new \DateTime($this->lastWeek->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', $last_week_at_cut_off),
42                Criteria::expr()->eq('newsletter', 1),
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 = "Wochenzusammenfassung";
163        $text = "Hallo %%userFirstName%%,\n\nDas lief diese Woche auf [olzimmerberg.ch](https://olzimmerberg.ch):\n\n{$notification_text}";
164
165        return new Notification($title, $text, [
166            'notification_type' => NotificationSubscription::TYPE_WEEKLY_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()->lt('published_date', $this->today),
194                        Criteria::expr()->gt('published_date', $this->lastWeek),
195                    ),
196                    Criteria::expr()->andX(
197                        Criteria::expr()->eq('published_date', $this->lastWeek),
198                        Criteria::expr()->gt('published_time', new \DateTime(self::CUT_OFF_TIME)),
199                    ),
200                ),
201                Criteria::expr()->eq('on_off', 1),
202            ))
203            ->orderBy(['published_date' => Order::Ascending, 'published_time' => Order::Ascending])
204            ->setFirstResult(0)
205            ->setMaxResults(1000)
206        ;
207    }
208}