public function calendar($month = null, $year = null) { if ($this->shouldLockIfNoPermission('data.view')) { return; } $now = time(); if ($month === null) { $month = idate('m', $now); } $month = (int) $month; if ($year === null) { $year = idate('Y', $now); } $year = (int) $year; $realYear = idate('Y', $now); $realMonth = idate('m', $now); $realDay = idate('d', $now); $nextYear = $year; $nextMonth = $month + 1; if ($nextMonth > self::MONTHS_IN_YEAR) { $nextYear++; $nextMonth = 1; } $previousYear = $year; $previousMonth = $month - 1; if ($previousMonth < 1) { $previousYear--; $previousMonth = self::MONTHS_IN_YEAR; } $monthBeginning = mktime(0, 0, 0, $month, 1, $year); $monthEnding = mktime(0, 0, 0, $nextMonth, 1, $nextYear) - 1; /* This assumes mktime returns the number of seconds. */ $unixTime = mktime(0, 0, 0, $month, 1, $year); $monthName = date('F', $unixTime); $firstWeekDay = date('w', $unixTime); $numberOfDays = cal_days_in_month(CAL_GREGORIAN, $month, $year); $eventService = new Event($this->db); $items = $eventService->findWithinRange($monthBeginning, $monthEnding); if ($items === null) { $this->flash->error('Unable to get events information!'); return $this->redirect('/'); } /* Create an array of days. */ $days = []; $dayIndex = 1; while ($dayIndex <= $numberOfDays) { $day = ['class' => 'day non-filler day' . $dayIndex, 'text' => $dayIndex, 'events' => []]; if ($month === $realMonth && $year === $realYear && $dayIndex === $realDay) { $day['class'] .= ' today'; } $days[$dayIndex] = $day; $dayIndex++; } /* Associate each event with its day. */ foreach ($items as $item) { $tempDay = idate('d', $item['created']); $item['short_name'] = $item['name']; $days[$tempDay]['events'][] = $item; } /* Start creating the month's data structure. */ $weeks = [[]]; $dayIndex = 0; while ($dayIndex < $firstWeekDay) { /* Add in the blank days. */ $weeks[0][-$dayIndex] = ['class' => 'day filler', 'text' => '', 'events' => []]; $dayIndex++; } $dayOfWeek = $firstWeekDay; $numberOfWeeks = 0; foreach ($days as $dayNumber => $day) { if ($dayOfWeek >= self::DAYS_IN_WEEK) { $dayOfWeek = 0; $numberOfWeeks++; $weeks[] = []; } switch ($dayOfWeek) { case 0: $day['class'] .= ' sunday'; break; case 1: $day['class'] .= ' monday'; break; case 2: $day['class'] .= ' tuesday'; break; case 3: $day['class'] .= ' wednesday'; break; case 4: $day['class'] .= ' thursday'; break; case 5: $day['class'] .= ' friday'; break; case 6: $day['class'] .= ' saturday'; break; } $weeks[$numberOfWeeks][$dayOfWeek] = $day; $dayOfWeek++; } /* Add in the remaining blank days. */ $dayIndex = count($weeks[$numberOfWeeks]); while ($dayIndex < self::DAYS_IN_WEEK) { $weeks[$numberOfWeeks][-$dayIndex] = ['class' => 'day filler', 'text' => '', 'events' => []]; $dayIndex++; } /* Makes sure that the days are classifed as weekend or weekday. */ $lastDayOfAnyWeek = self::DAYS_IN_WEEK - 1; foreach ($weeks as &$week) { $dayIndex = 0; foreach ($week as &$day) { if ($dayIndex === 0 || $dayIndex === $lastDayOfAnyWeek) { $day['class'] .= ' weekend'; } else { $day['class'] .= ' weekday'; } $dayIndex++; } } $this->set('monthName', $monthName); $this->set('month', $month); $this->set('year', $year); $this->set('weeks', $weeks); $this->set('previousMonth', $previousMonth); $this->set('previousYear', $previousYear); $this->set('nextMonth', $nextMonth); $this->set('nextYear', $nextYear); }