/** * Returns an array with all days between start and end of this SingleCalendar. * The keys are the timestamps of the days (12:00) and the values are number * of events for a day. * * @param string $user_id Use the permissions of this user. * @param array $restrictions * @return array An array with year day as key and number of events per day as value. */ public function getListCountEvents($class_names = null, $user_id = null, $restrictions = null) { if (!is_array($class_names)) { $class_names = array('CalendarEvent', 'CourseEvent', 'CourseCancelledEvent', 'CourseMarkedEvent'); } $end = $this->getEnd(); $start = $this->getStart(); $year = date('Y', $start); $end_ts = mktime(12, 0, 0, date('n', $end), date('j', $end), date('Y', $end)); $start_ts = mktime(12, 0, 0, date('n', $start), date('j', $start), date('Y', $start)); $this->getEvents($class_names)->sortEvents(); $daylist = array(); $this->ts = mktime(12, 0, 0, 1, 1, $year); foreach ($this->events as $event) { if (!$event->havePermission(Event::PERMISSION_CONFIDENTIAL, $user_id)) { continue; } if (!SingleCalendar::checkRestriction($event, $restrictions)) { continue; } $properties = $event->getProperties(); $rep = $properties['RRULE']; $duration = (int) ((mktime(12, 0, 0, date('n', $properties['DTEND']), date('j', $properties['DTEND']), date('Y', $properties['DTEND'])) - mktime(12, 0, 0, date('n', $properties['DTSTART']), date('j', $properties['DTSTART']), date('Y', $properties['DTSTART']))) / 86400); // single event or first event $lwst = mktime(12, 0, 0, date('n', $properties['DTSTART']), date('j', $properties['DTSTART']), date('Y', $properties['DTSTART'])); if ($start_ts > $lwst) { $adate = $start_ts; } else { $adate = $lwst; } $hgst = $lwst + $duration * 86400; while ($adate >= $start_ts && $adate <= $end_ts && $adate <= $hgst) { $md_date = $adate - date('I', $adate) * 3600; $this->countListEvent($properties, $md_date, $properties['DTSTART'], $properties['DTEND'], $daylist); $adate += 86400; } switch ($rep['rtype']) { case 'DAILY': if ($rep['ts'] < $start) { // brauche den ersten Tag nach $start an dem dieser Termin wiederholt wird if ($rep['linterval'] == 1) { $adate = $this->ts; } else { $adate = $this->ts + ($rep['linterval'] - ($this->ts - $rep['ts']) / 86400 % $rep['linterval']) * 86400; } while ($adate <= $end_ts && $adate >= $this->ts && $adate <= $rep['expire']) { $hgst = $adate + $duration * 86400; $md_date = $adate; while ($md_date <= $end_ts && $md_date >= $this->ts && $md_date <= $hgst) { $md_date -= 3600 * date('I', $md_date); $this->countListEvent($properties, $md_date, $adate, $hgst, $daylist); $md_date += 86400; } $adate += $rep['linterval'] * 86400; } } else { $adate = $rep['ts']; } while ($adate <= $end_ts && $adate >= $this->ts && $adate <= $rep['expire']) { $hgst = $adate + $duration * 86400; $md_date = $adate; while ($md_date <= $end_ts && $md_date >= $this->ts && $md_date <= $hgst) { $md_date += 3600 * date('I', $md_date); $this->countListEvent($properties, $md_date, $adate, $hgst, $daylist); $md_date += 86400; } $adate += $rep['linterval'] * 86400; } break; case 'WEEKLY': if ($properties['DTSTART'] >= $start && $properties['DTSTART'] <= $end) { $lwst = mktime(12, 0, 0, date('n', $properties['DTSTART']), date('j', $properties['DTSTART']), date('Y', $properties['DTSTART'])); $hgst = $lwst + $duration * 86400; if ($rep['ts'] != $adate) { $wdate = $lwst; while ($wdate <= $end_ts && $wdate >= $start_ts && $wdate <= $hgst) { // $md_date = $wdate - date('I', $wdate) * 3600; $this->countListEvent($properties, $wdate, $lwst, $hgst, $daylist); $wdate += 86400; } } $aday = strftime('%u', $lwst) - 1; for ($i = 0; $i < strlen($rep['wdays']); $i++) { $awday = (int) substr($rep['wdays'], $i, 1) - 1; if ($awday > $aday) { $lwst = $lwst + ($awday - $aday) * 86400; $hgst = $lwst + $duration * 86400; $wdate = $lwst; while ($wdate >= $start_ts && $wdate <= $end_ts && $wdate <= $hgst) { // $md_date = $wdate - date('I', $wdate) * 3600; $this->countListEvent($properties, $wdate, $lwst, $hgst, $daylist); $wdate += 86400; } } } } if ($rep['ts'] < $start) { $adate = $start_ts - (strftime('%u', $start_ts) - 1) * 86400; $adate += ($rep['linterval'] - ($adate - $rep['ts']) / 604800 % $rep['linterval']) * 604800; $adate -= $rep['linterval'] * 604800; } else { $adate = $rep['ts'] + 604800 * $rep['linterval']; } while ($adate >= $properties['DTSTART'] && $adate <= $rep['expire'] && $adate <= $end) { // event is repeated on different week days for ($i = 0; $i < strlen($rep['wdays']); $i++) { $awday = (int) $rep['wdays'][$i]; $lwst = $adate + ($awday - 1) * 86400; $hgst = $lwst + $duration * 86400; if ($lwst < $start_ts) { $lwst = $start_ts; } $wdate = $lwst; while ($wdate >= $start_ts && $wdate <= $end_ts && $wdate <= $hgst) { // $md_date = $wdate - date('I', $wdate) * 3600; $this->countListEvent($properties, $wdate, $lwst, $hgst, $daylist); $wdate += 86400; } } $adate += 604800 * $rep['linterval']; } break; case 'MONTHLY': $bmonth = ($rep['linterval'] - (($year - date('Y', $rep['ts'])) * 12 - date('n', $rep['ts'])) % $rep['linterval']) % $rep['linterval']; for ($amonth = $bmonth - $rep['linterval']; $amonth <= $bmonth; $amonth += $rep['linterval']) { if ($rep['ts'] < $start) { // is repeated at X. week day of X. month... if (!$rep['day']) { $lwst = mktime(12, 0, 0, $amonth - (($year - date('Y', $rep['ts'])) * 12 + ($amonth - date('n', $rep['ts']))) % $rep['linterval'], 1, $year) + ($rep['sinterval'] - 1) * 604800; $aday = strftime('%u', $lwst); $lwst -= ($aday - $rep['wdays']) * 86400; if ($rep['sinterval'] == 5) { if (date('j', $lwst) < 10) { $lwst -= 604800; } if (date('n', $lwst) == date('n', $lwst + 604800)) { $lwst += 604800; } } else { if ($aday > $rep['wdays']) { $lwst += 604800; } } } else { // or at X. day of month ? $lwst = mktime(12, 0, 0, $amonth - (($year - date('Y', $rep['ts'])) * 12 + ($amonth - date('n', $rep['ts']))) % $rep['linterval'], $rep['day'], $year); } } else { // first recurrence $lwst = $rep['ts']; $lwst = mktime(12, 0, 0, $amonth - (($year - date('Y', $rep['ts'])) * 12 + ($amonth - date('n', $rep['ts']))) % $rep['linterval'], $rep['day'], $year); } $hgst = $lwst + $duration * 86400; $md_date = $lwst; // events last longer than one day while ($md_date >= $start_ts && $md_date <= $hgst && $md_date <= $end_ts) { $this->countListEvent($properties, $md_date, $lwst, $hgst, $daylist); $md_date += 86400; } } break; case 'YEARLY': for ($ayear = $this->year - 1; $ayear <= $this->year; $ayear++) { if ($rep['day']) { $lwst = mktime(12, 0, 0, $rep['month'], $rep['day'], $ayear); $hgst = $lwst + $duration * 86400; $wdate = $lwst; while ($hgst >= $start_ts && $wdate <= $hgst && $wdate <= $end_ts) { $this->countListEvent($properties, $wdate, $lwst, $hgst, $daylist); $wdate += 86400; } } else { if ($rep['ts'] < $start) { $adate = mktime(12, 0, 0, $rep['month'], 1, $ayear) + ($rep['sinterval'] - 1) * 604800; $aday = strftime('%u', $adate); $adate -= ($aday - $rep['wdays']) * 86400; if ($rep['sinterval'] == 5) { if (date('j', $adate) < 10) { $adate -= 604800; } } elseif ($aday > $rep['wdays']) { $adate += 604800; } } else { $adate = $rep['ts']; } $lwst = $adate; $hgst = $lwst + $duration * 86400; while ($hgst >= $start_ts && $adate <= $hgst && $adate <= $end_ts) { $this->countListEvent($properties, $adate, $lwst, $hgst, $daylist); $adate += 86400; } } } } } return $daylist; }