From 3210f8de6641869613c28e16e83a905ee7b82bc5 Mon Sep 17 00:00:00 2001
From: Moritz Strohm <strohm@data-quest.de>
Date: Fri, 2 Sep 2022 08:46:00 +0000
Subject: [PATCH] fix for BIESt #1099

Merge request studip/studip!658
---
 app/controllers/calendar/calendar.php         |  4 +-
 app/controllers/calendar/single.php           |  1 -
 .../calendar/single/_calhead_label_day.php    |  2 +-
 app/views/calendar/single/_day_cell.php       |  7 ++-
 app/views/calendar/single/_include_month.php  | 45 +++++++++----------
 app/views/calendar/single/day.php             |  2 +-
 app/views/calendar/single/month.php           |  8 ++--
 app/views/calendar/single/week.php            |  2 +-
 app/views/calendar/single/year.php            | 43 +++++++++---------
 lib/classes/calendar/SingleCalendar.php       | 25 ++++++++---
 lib/models/CalendarEvent.class.php            |  2 +-
 11 files changed, 76 insertions(+), 65 deletions(-)

diff --git a/app/controllers/calendar/calendar.php b/app/controllers/calendar/calendar.php
index 939b9d32aef..65dafa20cbc 100644
--- a/app/controllers/calendar/calendar.php
+++ b/app/controllers/calendar/calendar.php
@@ -41,12 +41,14 @@ class Calendar_CalendarController extends AuthenticatedController
         $this->restrictions = [
             'STUDIP_CATEGORY'     => $this->category ?: null,
             // hide events with status 3 (CalendarEvent::PARTSTAT_DECLINED)
-            'STUDIP_GROUP_STATUS' => $this->settings['show_declined'] ? null : [0,1,2,5]
+            'STUDIP_GROUP_STATUS' => !empty($this->settings['show_declined']) ? null : [0,1,2,5]
         ];
         if ($this->category) {
             URLHelper::bindLinkParam('category', $this->category);
         }
 
+        $this->range_id = '';
+
         if (Config::get()->COURSE_CALENDAR_ENABLE
             && !Request::get('self')
             && Course::findCurrent()) {
diff --git a/app/controllers/calendar/single.php b/app/controllers/calendar/single.php
index 91525aabe25..2067e394d53 100644
--- a/app/controllers/calendar/single.php
+++ b/app/controllers/calendar/single.php
@@ -127,7 +127,6 @@ class Calendar_SingleController extends Calendar_CalendarController
         $cor = date('n', $this->atime) == 3 ? 1 : 0;
         $this->first_day = $month_start - $adow * 86400;
         $this->last_day = ((42 - ($adow + date('t', $this->atime))) % 7 + $cor) * 86400 + $month_end;
-
         $this->calendars = [];
         for ($start_day = $this->first_day; $start_day <= $this->last_day; $start_day += 86400) {
             $this->calendars[] = SingleCalendar::getDayCalendar($this->range_id,
diff --git a/app/views/calendar/single/_calhead_label_day.php b/app/views/calendar/single/_calhead_label_day.php
index 48d832fbbc9..0b856419e20 100644
--- a/app/views/calendar/single/_calhead_label_day.php
+++ b/app/views/calendar/single/_calhead_label_day.php
@@ -1,3 +1,3 @@
 <span class="hidden-tiny-down"><?= strftime('%A, ', $atime) ?></span>
 <?= strftime('%d.%m.%Y', $atime) ?>
-<span class="hidden-medium-down" style="font-size: 12pt; color: #bbb; font-weight: bold;"><? $hd = holiday($atime); echo $hd['name']; ?></span>
+<span class="hidden-medium-down" style="font-size: 12pt; color: #bbb; font-weight: bold;"><?= $hd = holiday($atime) ? $hd['name'] : '' ?></span>
diff --git a/app/views/calendar/single/_day_cell.php b/app/views/calendar/single/_day_cell.php
index 058f62815ad..92cf6fd464c 100644
--- a/app/views/calendar/single/_day_cell.php
+++ b/app/views/calendar/single/_day_cell.php
@@ -1,6 +1,6 @@
 <? $link_notset = true ?>
 <? $atime_new = $calendar->getStart() + $i * $step ?>
-<? if (!$em['term'][$row]) : ?>
+<? if (empty($em['term'][$row])) : ?>
     <? if ($calendar->havePermission(Calendar::PERMISSION_WRITABLE)) : ?>
     <td class="calendar-day-edit <?= $class_cell ?>" <?= ($em['max_cols'] > 0 ? ' colspan="' . ($em['max_cols'] + 1) . '"' : '') ?>>
         <a title="<?= strftime(_('Neuer Termin am %x, %R Uhr'), $atime_new) ?>" href="<?= $controller->url_for('calendar/single/edit/' . $calendar->getRangeId(), ['atime' => $atime_new]) ?>">+</a>
@@ -13,17 +13,16 @@
 <? else : ?>
     <? for ($j = 0; $j < $em['colsp'][$row]; $j++) : ?>
         <? $event = $em['term'][$row][$j]; ?>
-        <? $mapped_event = $calendar->events[$em['mapping'][$row][$j]]; ?>
         <? if (is_object($event)) : ?>
     <td data-tooltip<?= ($em['cspan'][$row][$j] > 1 ? ' colspan="' . $em['cspan'][$row][$j] . '"' : '') ?><?= ($em['rows'][$row][$j] > 1 ? ' rowspan="' . $em['rows'][$row][$j] . '"' : '') ?> class="<?= $event instanceof CourseEvent ? 'calendar-course-category' : 'calendar-category' ?><?= $event->getCategory() ?> calendar-day-event">
                 <? if ($em['rows'][$row][$j] > 1) : ?>
                 <div>
-                    <?= date('H.i-', $mapped_event->getStart()) . date('H.i', $mapped_event->getEnd()) ?>
+                    <?= date('H.i-', $event->getStart()) . date('H.i', $event->getEnd()) ?>
                 </div>
                 <? endif ?>
                 <div class="calendar-day-event-title">
                     <a title="<?= _('Termin bearbeiten') ?>" href="<?= $controller->url_for('calendar/single/edit/' . $calendar->getRangeId() . '/' . $event->event_id, ['atime' => $atime_new, 'evtype' => $event->getType()]) ?>"><?= htmlReady($event->getTitle()) ?></a>
-                    <?= $this->render_partial('calendar/single/_tooltip', ['event' => $mapped_event]) ?>
+                    <?= $this->render_partial('calendar/single/_tooltip', ['event' => $event]) ?>
                 </div>
             </td>
         <? elseif ($event == '#') : ?>
diff --git a/app/views/calendar/single/_include_month.php b/app/views/calendar/single/_include_month.php
index 342a386a6b2..c749c2b6a6f 100644
--- a/app/views/calendar/single/_include_month.php
+++ b/app/views/calendar/single/_include_month.php
@@ -70,9 +70,6 @@
                     $style = 'light';
                 }
                 $hday = holiday($i);
-                if ($j % 7 == 0) {
-                    $ret .= '<tr>';
-                }
                 ?>
                 <? if (abs($now - $i) < 43199 && !($style == 'light')) : ?>
                     <td class="celltoday" align="center" width="25" height="25">
@@ -82,7 +79,7 @@
                     <td class="month" align="center" width="25" height="25">
                 <? endif; ?>
                 <? $js_inc = ''; ?>
-                <? if (is_array($js_include)) : ?>
+                <? if (!empty($js_include) && is_array($js_include)) : ?>
                     <?
                     $js_inc = " onClick=\"{$js_include['function']}(";
                     if (sizeof($js_include['parameters'])) {
@@ -95,7 +92,7 @@
                     <? $aday = '<span class="current">'.$aday.'</span>' ?>
                 <? endif; ?>
                 <? if (($j + 1) % 7 == 0) : ?>
-                    <a class="<?= $style ?>sday" href="<?= $controller->url_for($href, ['atime' => $i]) ?>" <?= $hday['name'] ? tooltip($hday['name']) : '' ?> <?= $js_inc ?>>
+                    <a class="<?= $style ?>sday" href="<?= $controller->url_for($href, ['atime' => $i]) ?>" <?= is_array($hday) ? tooltip($hday['name'] ?: '') : '' ?> <?= $js_inc ?>>
                         <?= $aday ?>
                     </a>
                 </td>
@@ -106,27 +103,29 @@
                 </td>
             </tr>
                 <? else : ?>
-                    <? switch ($hday['col']) {
-                        case 1:
-                            ?><a class="<?= $style ?>day" href="<?= $controller->url_for($href, ['atime' => $i]) ?>" <?= tooltip($hday['name']) . $js_inc ?>>
-                               <?= $aday ?>
-                            </a><?
-                            break;
-                        case 2:
-                        case 3;
-                            ?><a class="<?= $style ?>hday" href="<?= $controller->url_for($href, ['atime' => $i]) ?>" <?= tooltip($hday['name']) . $js_inc ?>>
-                                <?= $aday ?>
-                            </a><?
-                            break;
-                        default:
-                            ?><a class="<?= $style ?>day" href="<?= $controller->url_for($href, ['atime' => $i]) ?>" <?= $js_inc ?>>
-                                <?= $aday ?>
-                            </a>
-                    <?}?>
+                    <? if (is_array($hday)) : ?>
+                        <? switch ($hday['col']) {
+                            case 1:
+                                ?><a class="<?= $style ?>day" href="<?= $controller->url_for($href, ['atime' => $i]) ?>" <?= tooltip($hday['name']) . $js_inc ?>>
+                                   <?= $aday ?>
+                                </a><?
+                                break;
+                            case 2:
+                            case 3;
+                                ?><a class="<?= $style ?>hday" href="<?= $controller->url_for($href, ['atime' => $i]) ?>" <?= tooltip($hday['name']) . $js_inc ?>>
+                                    <?= $aday ?>
+                                </a><?
+                                break;
+                            default:
+                                ?><a class="<?= $style ?>day" href="<?= $controller->url_for($href, ['atime' => $i]) ?>" <?= $js_inc ?>>
+                                    <?= $aday ?>
+                                </a>
+                        <?}?>
+                    <? endif ?>
                     </td>
                 <? endif; ?>
             <? endfor; ?>
             </table>
         </td>
     </tr>
-</table>
\ No newline at end of file
+</table>
diff --git a/app/views/calendar/single/day.php b/app/views/calendar/single/day.php
index 721c636a59d..448509cd172 100644
--- a/app/views/calendar/single/day.php
+++ b/app/views/calendar/single/day.php
@@ -4,7 +4,7 @@
     </div>
     <div class="hidden-medium-down" style="flex-grow:1; padding-left:1em;">
         <? $imt = Request::int('imt', mktime(12, 0, 0, date('n', $atime) - 1, date('j', $atime), date('Y', $atime))) ?>
-        <?= $this->render_partial('calendar/single/_include_month', ['imt' => $imt, 'href' => '']) ?>
+        <?= $this->render_partial('calendar/single/_include_month', ['imt' => $imt, 'href' => '', 'mod' => '']) ?>
         <? $imt = mktime(12, 0, 0, date('n', $imt) + 1, date('j', $imt), date('Y', $imt)) ?>
         <?= $this->render_partial('calendar/single/_include_month', ['imt' => $imt, 'href' => '', 'mod' => 'NONAVARROWS']) ?>
         <? $imt = mktime(12, 0, 0, date('n', $imt) + 1, date('j', $imt), date('Y', $imt)) ?>
diff --git a/app/views/calendar/single/month.php b/app/views/calendar/single/month.php
index 48cf2e5a178..da715f5e0fe 100644
--- a/app/views/calendar/single/month.php
+++ b/app/views/calendar/single/month.php
@@ -1,5 +1,3 @@
-<? $month = $calendar->view; ?>
-
 <nav class="calendar-nav" style="vertical-align: middle">
     <span style="white-space: nowrap;">
         <a class="hidden-medium-down" style="padding-right: 2em;" href="<?= $controller->url_for('calendar/single/month', ['atime' => strtotime('-1 year', $atime)]) ?>">
@@ -17,7 +15,7 @@
     $calLabel = htmlReady(strftime("%B ", $calendars[15]->getStart())) .' '. date('Y', $calendars[15]->getStart());
     ?>
 
-    <?= $this->render_partial('calendar/single/_calhead', compact('calendar', 'atime', 'calType', 'calLabel')) ?>
+    <?= $this->render_partial('calendar/single/_calhead', compact('atime', 'calType', 'calLabel')) ?>
 
     <span style="text-align: right; white-space: nowrap;">
         <a class="hidden-tiny-down" style="padding-right: 2em;" href="<?= $controller->url_for('calendar/single/month', ['atime' => strtotime('+1 month', $atime)]) ?>">
@@ -70,7 +68,7 @@
                 <a class="<?= $class_day . 'sday' ?>" href="<?= $controller->url_for('calendar/single/day', ['atime' => $i]) ?>">
                     <?= $aday ?>
                 </a>
-                <? if ($hday["name"] != "") : ?>
+                <? if (!empty($hday['name'])) : ?>
                     <div style="color: #aaaaaa;" class="inday"><?= $hday['name'] ?></div>
                 <? endif; ?>
                 <? foreach ($calendars[$j]->events as $event) : ?>
@@ -86,7 +84,7 @@
                 </tr>
             <? else : ?>
                 <? $hday_class = ['day', 'day', 'shday', 'hday'] ?>
-                <? if ($hday['col']) : ?>
+                <? if (!empty($hday['col'])) : ?>
                     <a class="<?= $class_day . $hday_class[$hday['col']] ?>" href="<?= $controller->url_for('calendar/single/day', ['atime' => $i]) ?>">
                         <?= $aday ?>
                     </a>
diff --git a/app/views/calendar/single/week.php b/app/views/calendar/single/week.php
index d3f6f3ab5e2..98f831773e5 100644
--- a/app/views/calendar/single/week.php
+++ b/app/views/calendar/single/week.php
@@ -52,7 +52,7 @@ if ($rowspan > 1) {
     $calLabel = $this->render_partial('calendar/single/_calhead_label_week', compact('week_type'));
     ?>
 
-    <?= $this->render_partial('calendar/single/_calhead', compact('calendar', 'atime', 'calType', 'calLabel')) ?>
+    <?= $this->render_partial('calendar/single/_calhead', compact('atime', 'calType', 'calLabel')) ?>
 
     <span style="white-space: nowrap; text-align: right;">
         <a href="<?= $controller->url_for('calendar/single/week', ['atime' => strtotime('+1 week', $atime)]) ?>">
diff --git a/app/views/calendar/single/year.php b/app/views/calendar/single/year.php
index f73c08f79d7..923b08556c3 100644
--- a/app/views/calendar/single/year.php
+++ b/app/views/calendar/single/year.php
@@ -33,6 +33,7 @@
 
             <thead>
                 <tr>
+                    <? $ts_month = 0; ?>
                     <? for ($i = 1; $i < 13; $i++) : ?>
                         <?  $ts_month += ( $days_per_month[$i] - 1) * 86400; ?>
                         <th align="center" width="8%">
@@ -76,28 +77,30 @@
 
                                     <span class="yday">
                                         <? $hday = holiday($aday); ?>
-                                        <? if ($hday['col'] == '1') : ?>
-                                            <? if (date('w', $aday) == '0') : ?>
-                                                <a style="font-weight:bold;" class="sday" href="<?= $controller->url_for('calendar/single/day', ['atime' => $aday]) ?>"><?= $i ?></a> <?= $weekday; ?>
-                                                <? $count++; ?>
-                                            <? else : ?>
-                                                <a style="font-weight:bold;" class="day" href="<?= $controller->url_for('calendar/single/day', ['atime' => $aday]) ?>"><?= $i ?></a> <?= $weekday; ?>
-                                            <? endif; ?>
-                                        <? elseif ($hday['col'] == '2' || $hday['col'] == '3') : ?>
-                                            <? if (date('w', $aday) == '0') : ?>
-                                                <a style="font-weight:bold;" class="sday" href="<?= $controller->url_for('calendar/single/day', ['atime' => $aday]) ?>"><?= $i ?></a> <?= $weekday; ?>
-                                                <? $count++; ?>
-                                            <? else : ?>
-                                                <a style="font-weight:bold;" class="hday" href="<?= $controller->url_for('calendar/single/day', ['atime' => $aday]) ?>"><?= $i ?></a> <?= $weekday; ?>
-                                            <? endif; ?>
-                                        <? else : ?>
-                                            <? if (date('w', $aday) == '0') : ?>
-                                                <a style="font-weight:bold;" class="sday" href="<?= $controller->url_for('calendar/single/day', ['atime' => $aday]) ?>"><?= $i ?></a> <?= $weekday; ?>
-                                                <? $count++; ?>
+                                        <? if (is_array($hday)) : ?>
+                                            <? if ($hday['col'] == '1') : ?>
+                                                <? if (date('w', $aday) == '0') : ?>
+                                                    <a style="font-weight:bold;" class="sday" href="<?= $controller->url_for('calendar/single/day', ['atime' => $aday]) ?>"><?= $i ?></a> <?= $weekday; ?>
+                                                    <? $count++; ?>
+                                                <? else : ?>
+                                                    <a style="font-weight:bold;" class="day" href="<?= $controller->url_for('calendar/single/day', ['atime' => $aday]) ?>"><?= $i ?></a> <?= $weekday; ?>
+                                                <? endif; ?>
+                                            <? elseif ($hday['col'] == '2' || $hday['col'] == '3') : ?>
+                                                <? if (date('w', $aday) == '0') : ?>
+                                                    <a style="font-weight:bold;" class="sday" href="<?= $controller->url_for('calendar/single/day', ['atime' => $aday]) ?>"><?= $i ?></a> <?= $weekday; ?>
+                                                    <? $count++; ?>
+                                                <? else : ?>
+                                                    <a style="font-weight:bold;" class="hday" href="<?= $controller->url_for('calendar/single/day', ['atime' => $aday]) ?>"><?= $i ?></a> <?= $weekday; ?>
+                                                <? endif; ?>
                                             <? else : ?>
-                                                <a style="font-weight:bold;" class="day" href="<?= $controller->url_for('calendar/single/day', ['atime' => $aday]) ?>"><?= $i ?></a> <?= $weekday; ?>
+                                                <? if (date('w', $aday) == '0') : ?>
+                                                    <a style="font-weight:bold;" class="sday" href="<?= $controller->url_for('calendar/single/day', ['atime' => $aday]) ?>"><?= $i ?></a> <?= $weekday; ?>
+                                                    <? $count++; ?>
+                                                <? else : ?>
+                                                    <a style="font-weight:bold;" class="day" href="<?= $controller->url_for('calendar/single/day', ['atime' => $aday]) ?>"><?= $i ?></a> <?= $weekday; ?>
+                                                <? endif; ?>
                                             <? endif; ?>
-                                        <? endif; ?>
+                                        <? endif ?>
                                     </span>
 
                                     <? if (isset($count_list[$iday]) && count($count_list[$iday])) : ?>
diff --git a/lib/classes/calendar/SingleCalendar.php b/lib/classes/calendar/SingleCalendar.php
index a3a1eaeaeb2..2b19de8bfd0 100644
--- a/lib/classes/calendar/SingleCalendar.php
+++ b/lib/classes/calendar/SingleCalendar.php
@@ -365,7 +365,7 @@ class SingleCalendar
 
         $user_id = $user_id ?: $GLOBALS['user']->id;
         $id = $user_id . $this->getRangeId();
-        if ($user_permission[$id]) {
+        if (!empty($user_permission[$id])) {
             return $user_permission[$id];
         }
         // own calendar
@@ -952,11 +952,12 @@ class SingleCalendar
                 || ($start >= $cl_start && $start < $cl_end)
                 || ($end > $cl_start && $end <= $cl_end)) {
 
-            if (!$events_created[implode('', (array) $event->getId()) . $start]) {
+            $key = implode('', (array) $event->getId()) . $start;
+            if (empty($events_created[$key])) {
                 $new_event = clone $event;
                 $new_event->setStart($start);
                 $new_event->setEnd($end);
-                $events_created[implode('', (array) $event->getId()) . $start] = $new_event;
+                $events_created[$key] = $new_event;
             }
         }
 
@@ -1263,6 +1264,7 @@ class SingleCalendar
         $term = [];
         $em = $this->adapt_events($start, $end, $step);
         $max_cols = 0;
+        $mapping = [];
         // calculate maximum number of columns
         $w = 0;
         for ($i = $start / $step; $i < $end / $step + 3600 / $step; $i++) {
@@ -1274,6 +1276,12 @@ class SingleCalendar
                 if ($rows < 1) {
                     $rows = 1;
                 }
+                if (empty($term[$row])) {
+                    $term[$row] = [];
+                }
+                if (empty($term[$row][$col])) {
+                    $term[$row][$col] = '';
+                }
                 while ($term[$row][$col] != '' && $term[$row][$col] != '#') {
                     $col++;
                 }
@@ -1300,8 +1308,8 @@ class SingleCalendar
         for ($i = $start / $step; $i < $end / $step + 3600 / $step; $i++) {
             $row = $i - $start / $step;
             $row_min = $row;
-            while ($this->maxValue($term[$row], $step) > 1) {
-                $row += $this->maxValue($term[$row], $step) - 1;
+            while ($this->maxValue($term[$row] ?? 0, $step) > 1) {
+                $row += $this->maxValue($term[$row] ?? 0, $step) - 1;
             }
             $size = 0;
             for ($j = $row_min; $j <= $row; $j++) {
@@ -1315,10 +1323,11 @@ class SingleCalendar
             $i = $row + $start / $step;
         }
         $rows = [];
+        $cspan = [];
         for ($i = $start / $step; $i < $end / $step + 3600 / $step; $i++) {
             $row = $i - $start / $step;
             $cspan_0 = 0;
-            if ($term[$row]) {
+            if (!empty($term[$row])) {
                 if ($colsp[$row] > 0) {
                     $cspan_0 = (int) ($max_cols / $colsp[$row]);
                 }
@@ -1332,7 +1341,7 @@ class SingleCalendar
                         // Wieviele Termine sind zum aktuellen Termin zeitgleich?
                         $p = 0;
                         $count = 0;
-                        while ($aterm = $em['events'][$p]) {
+                        while (array_key_exists($p, $em['events']) && ($aterm = $em['events'][$p])) {
                             if ($aterm->getStart() >= $term[$row][$j]->getStart()
                                     && $aterm->getStart() <= $term[$row][$j]->getEnd()) {
                                 $count++;
@@ -1430,6 +1439,8 @@ class SingleCalendar
     {
         $tmp_events = [];
         $map_events = [];
+        $tmp_day_event = [];
+        $map_day_events = [];
         for ($i = 0; $i < sizeof($this->events); $i++) {
             $event = $this->events[$i];
             if (($event->getEnd() > $this->getStart() + $start)
diff --git a/lib/models/CalendarEvent.class.php b/lib/models/CalendarEvent.class.php
index 6b4f1e0f765..96cc8699777 100644
--- a/lib/models/CalendarEvent.class.php
+++ b/lib/models/CalendarEvent.class.php
@@ -1194,7 +1194,7 @@ class CalendarEvent extends SimpleORMap implements Event, PrivacyObject
         if (is_null($user_id)) {
             $user_id = $this->permission_user_id ?: $GLOBALS['user']->id;
         }
-        if (!$permissions[$user_id][$this->event_id]) {
+        if (empty($permissions[$user_id][$this->event_id])) {
             if ($user_id == $this->event->author_id) {
                 $permissions[$user_id][$this->event_id] = Event::PERMISSION_OWN;
             } else
-- 
GitLab