Exemplo n.º 1
0
 /**
  * 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;
 }