/** * * @global Horde_Prefs $prefs * @param Horde_Date $date * * @return Kronolith_View_Month */ public function __construct(Horde_Date $date) { global $prefs; $this->month = $date->month; $this->year = $date->year; // Need to calculate the start and length of the view. $this->date = new Horde_Date($date); $this->date->mday = 1; $this->_startday = $this->date->dayOfWeek(); $this->_daysInView = Date_Calc::weeksInMonth($this->month, $this->year) * 7; if (!$prefs->getValue('week_start_monday')) { $this->_startOfView = 1 - $this->_startday; // We may need to adjust the number of days in the view if // we're starting weeks on Sunday. if ($this->_startday == Horde_Date::DATE_SUNDAY) { $this->_daysInView -= 7; } $endday = new Horde_Date(array('mday' => Horde_Date_Utils::daysInMonth($this->month, $this->year), 'month' => $this->month, 'year' => $this->year)); $endday = $endday->dayOfWeek(); if ($endday == Horde_Date::DATE_SUNDAY) { $this->_daysInView += 7; } } else { if ($this->_startday == Horde_Date::DATE_SUNDAY) { $this->_startOfView = -5; } else { $this->_startOfView = 2 - $this->_startday; } } $startDate = new Horde_Date(array('year' => $this->year, 'month' => $this->month, 'mday' => $this->_startOfView)); $endDate = new Horde_Date(array('year' => $this->year, 'month' => $this->month, 'mday' => $this->_startOfView + $this->_daysInView)); if ($prefs->getValue('show_shared_side_by_side')) { $allCalendars = Kronolith::listInternalCalendars(); $this->_currentCalendars = array(); foreach ($GLOBALS['calendar_manager']->get(Kronolith::DISPLAY_CALENDARS) as $id) { $this->_currentCalendars[$id] = $allCalendars[$id]; } } else { $this->_currentCalendars = array('internal_0' => true); } try { $this->_events = Kronolith::listEvents($startDate, $endDate); } catch (Exception $e) { $GLOBALS['notification']->push($e, 'horde.error'); $this->_events = array(); } if (!is_array($this->_events)) { $this->_events = array(); } }
/** * Creates an iCalendar 2.0 recurrence rule. * * @link http://rfc.net/rfc2445.html#s4.3.10 * @link http://rfc.net/rfc2445.html#s4.8.5 * @link http://www.shuchow.com/vCalAddendum.html * * @param Horde_Icalendar $calendar A Horde_Icalendar object instance. * * @return string An iCalendar 2.0 conform RRULE value. */ public function toRRule20($calendar) { switch ($this->recurType) { case self::RECUR_NONE: return ''; case self::RECUR_DAILY: $rrule = 'FREQ=DAILY;INTERVAL=' . $this->recurInterval; break; case self::RECUR_WEEKLY: $rrule = 'FREQ=WEEKLY;INTERVAL=' . $this->recurInterval; $vcaldays = array('SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA'); for ($i = $flag = 0; $i <= 7; ++$i) { if ($this->recurOnDay(pow(2, $i))) { if ($flag == 0) { $rrule .= ';BYDAY='; $flag = 1; } else { $rrule .= ','; } $rrule .= $vcaldays[$i]; } } break; case self::RECUR_MONTHLY_DATE: $rrule = 'FREQ=MONTHLY;INTERVAL=' . $this->recurInterval; break; case self::RECUR_MONTHLY_WEEKDAY: $nth_weekday = (int) ($this->start->mday / 7); if ($this->start->mday % 7 > 0) { $nth_weekday++; } $vcaldays = array('SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA'); $rrule = 'FREQ=MONTHLY;INTERVAL=' . $this->recurInterval . ';BYDAY=' . $nth_weekday . $vcaldays[$this->start->dayOfWeek()]; break; case self::RECUR_YEARLY_DATE: $rrule = 'FREQ=YEARLY;INTERVAL=' . $this->recurInterval; break; case self::RECUR_YEARLY_DAY: $rrule = 'FREQ=YEARLY;INTERVAL=' . $this->recurInterval . ';BYYEARDAY=' . $this->start->dayOfYear(); break; case self::RECUR_YEARLY_WEEKDAY: $nth_weekday = (int) ($this->start->mday / 7); if ($this->start->mday % 7 > 0) { $nth_weekday++; } $vcaldays = array('SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA'); $rrule = 'FREQ=YEARLY;INTERVAL=' . $this->recurInterval . ';BYDAY=' . $nth_weekday . $vcaldays[$this->start->dayOfWeek()] . ';BYMONTH=' . $this->start->month; break; } if ($this->hasRecurEnd()) { $recurEnd = clone $this->recurEnd; $rrule .= ';UNTIL=' . $calendar->_exportDateTime($recurEnd); } if ($count = $this->getRecurCount()) { $rrule .= ';COUNT=' . $count; } return $rrule; }
/** * * @global Horde_Prefs $prefs * @param Horde_Date $date * * @return Kronolith_View_Month */ public function __construct(Horde_Date $date) { global $prefs; $this->month = $date->month; $this->year = $date->year; // Need to calculate the start and length of the view. $this->date = new Horde_Date($date); $this->date->mday = 1; $this->_startday = $this->date->dayOfWeek(); if (!$prefs->getValue('week_start_monday')) { $this->_startOfView = 1 - $this->_startday; } else { if ($this->_startday == Horde_Date::DATE_SUNDAY) { $this->_startOfView = -5; } else { $this->_startOfView = 2 - $this->_startday; } } $startDate = new Horde_Date($this->year, $this->month, $this->_startOfView); $this->_endDate = new Horde_Date($this->year, $this->month, Horde_Date_Utils::daysInMonth($this->month, $this->year) + 1); $this->_endDate->mday += (7 - ($this->_endDate->format('w') - $prefs->getValue('week_start_monday'))) % 7; if ($prefs->getValue('show_shared_side_by_side')) { $allCalendars = Kronolith::listInternalCalendars(); $this->_currentCalendars = array(); foreach ($GLOBALS['calendar_manager']->get(Kronolith::DISPLAY_CALENDARS) as $id) { $this->_currentCalendars[$id] = $allCalendars[$id]; } } else { $this->_currentCalendars = array('internal_0' => true); } try { $this->_events = Kronolith::listEvents($startDate, $this->_endDate); } catch (Exception $e) { $GLOBALS['notification']->push($e, 'horde.error'); $this->_events = array(); } if (!is_array($this->_events)) { $this->_events = array(); } }
public function __construct(Horde_Date $date) { $week = $date->weekOfYear(); $year = $date->year; if (!$GLOBALS['prefs']->getValue('week_start_monday') && $date->dayOfWeek() == Horde_Date::DATE_SUNDAY) { ++$week; } if ($week > 51 && $date->month == 1) { --$year; } elseif ($week == 1 && $date->month == 12) { ++$year; } $this->year = $year; $this->week = $week; $day = Horde_Date_Utils::firstDayOfWeek($week, $year); if (!isset($this->startDay)) { if ($GLOBALS['prefs']->getValue('week_start_monday')) { $this->startDay = Horde_Date::DATE_MONDAY; $this->endDay = Horde_Date::DATE_SUNDAY + 7; } else { $day->mday--; $this->startDay = Horde_Date::DATE_SUNDAY; $this->endDay = Horde_Date::DATE_SATURDAY; } } $this->startDate = new Horde_Date($day); for ($i = $this->startDay; $i <= $this->endDay; ++$i) { $this->days[$i] = new Kronolith_View_Day($day, array()); $day->mday++; } $endDate = new Horde_Date($day); try { $allevents = Kronolith::listEvents($this->startDate, $endDate); } catch (Exception $e) { $GLOBALS['notification']->push($e, 'horde.error'); $allevents = array(); } for ($i = $this->startDay; $i <= $this->endDay; ++$i) { $date_stamp = $this->days[$i]->dateString(); $this->days[$i]->events = isset($allevents[$date_stamp]) ? $allevents[$date_stamp] : array(); } $this->sidebyside = $this->days[$this->startDay]->sidebyside; $this->_currentCalendars = $this->days[$this->startDay]->currentCalendars; $this->slotsPerHour = $this->days[$this->startDay]->slotsPerHour; $this->slotsPerDay = $this->days[$this->startDay]->slotsPerDay; $this->slotLength = $this->days[$this->startDay]->slotLength; }
/** * Returns the number of weeks in the given year (52 or 53). * * @param integer $year The year to count the number of weeks in. * * @return integer $numWeeks The number of weeks in $year. */ public static function weeksInYear($year) { // Find the last Thursday of the year. $date = new Horde_Date($year . '-12-31'); while ($date->dayOfWeek() != self::DATE_THURSDAY) { --$date->mday; } return $date->weekOfYear(); }
/** * Adds rules from this ruleset to a VTIMEZONE component. * * @param Horde_Icalendar_Vtimezone $tz A VTIMEZONE component. * @param string $tzid The timezone ID of the component. * @param string $name A timezone name abbreviation. * May contain a placeholder that is * replaced the Rules' "Letter(s)" * entry. * @param array $startOffset An offset hash describing the * base offset of a timezone. * @param Horde_Date $start Start of the period to add rules * for. * @param Horde_Date $end End of the period to add rules * for. */ public function addRules(Horde_Icalendar_Vtimezone $tz, $tzid, $name, $startOffset, Horde_Date $start, Horde_Date $end = null) { $offset = $startOffset; foreach ($this->_rules as $rule) { $year = $rule[3]; if ($year[0] == 'o') { // TO is "only" $rule[3] = $rule[2]; } if ($rule[3][0] != 'm' && $rule[3] < $start->year) { // TO is not maximum and is before the searched period continue; } if ($end && $rule[2][0] != 'm' && $rule[2] > $end->year) { // FROM is not "minimum" and is after the searched period break; } if ($rule[2][0] != 'm' && $rule[2] < $start->year) { $rule[2] = $start->year; } if ($rule[8] == 0) { $component = new Horde_Icalendar_Standard(); $component->setAttribute('TZOFFSETFROM', $offset); $component->setAttribute('TZOFFSETTO', $startOffset); $offset = $startOffset; } else { $component = new Horde_Icalendar_Daylight(); $component->setAttribute('TZOFFSETFROM', $offset); $offset = $this->_getOffset($startOffset, $rule[8]); $component->setAttribute('TZOFFSETTO', $offset); } $month = Horde_Timezone::getMonth($rule[5]); // Retrieve time of rule start. preg_match('/(\\d+)(?::(\\d+))?(?::(\\d+))?(w|s|u)?/', $rule[7], $match); if (!isset($match[2])) { $match[2] = 0; } if ($rule[2] == $rule[3] && preg_match('/^\\d+$/', $rule[6])) { // Rule lasts only for a single year and starts on a specific // date. $rdate = new Horde_Date(array('year' => $rule[2], 'month' => Horde_Timezone::getMonth($rule[5]), 'mday' => $rule[6], 'hour' => $match[1], 'min' => $match[2], 'sec' => 0)); $component->setAttribute('DTSTART', $rdate); } elseif (substr($rule[6], 0, 4) == 'last') { // Rule starts on the last of a certain weekday of the month. $weekday = $this->_weekdays[substr($rule[6], 4, 3)]; $last = new Horde_Date(array('year' => $rule[2], 'month' => $month, 'mday' => Horde_Date_Utils::daysInMonth($month, $rule[2]), 'hour' => $match[1], 'min' => $match[2], 'sec' => 0)); while ($last->dayOfWeek() != $weekday) { $last->mday--; } $component->setAttribute('DTSTART', $last); if ($rule[3][0] == 'm') { $until = ''; } else { $last = new Horde_Date(array('year' => $rule[3], 'month' => $month, 'mday' => Horde_Date_Utils::daysInMonth($month, $rule[2]), 'hour' => $match[1], 'min' => $match[2], 'sec' => 0), $tzid); while ($last->dayOfWeek() != $weekday) { $last->mday--; } $last->setTimezone('UTC'); $until = ';UNTIL=' . $last->format('Ymd\\THIs') . 'Z'; } $component->setAttribute('RRULE', 'FREQ=YEARLY;BYDAY=-1' . Horde_String::upper(substr($rule[6], 4, 2)) . ';BYMONTH=' . $month . $until); } elseif (strpos($rule[6], '>=')) { // Rule starts on a certain weekday after a certain day of // month. list($weekday, $day) = explode('>=', $rule[6]); $weekdayInt = $this->_weekdays[substr($weekday, 0, 3)]; $first = new Horde_Date(array('year' => $rule[2], 'month' => $month, 'mday' => $day, 'hour' => $match[1], 'min' => $match[2], 'sec' => 0)); while ($first->dayOfWeek() != $weekdayInt) { $first->mday++; } $component->setAttribute('DTSTART', $first); if ($rule[3][0] == 'm') { $until = ''; } else { $last = new Horde_Date(array('year' => $rule[3], 'month' => $month, 'mday' => $day, 'hour' => $match[1], 'min' => $match[2], 'sec' => 0), $tzid); while ($last->dayOfWeek() != $weekday) { $last->mday++; } $last->setTimezone('UTC'); $until = ';UNTIL=' . $last->format('Ymd\\THIs') . 'Z'; } for ($days = array(), $i = $day, $lastDay = min(Horde_Date_Utils::daysInMonth($month, $rule[2]), $i + 6); $day > 1 && $i <= $lastDay; $i++) { $days[] = $i; } $component->setAttribute('RRULE', 'FREQ=YEARLY;BYMONTH=' . $month . ($days ? ';BYMONTHDAY=' . implode(',', $days) : '') . ';BYDAY=1' . Horde_String::upper(substr($weekday, 0, 2)) . $until); } elseif (strpos($rule[6], '<=')) { // Rule starts on a certain weekday before a certain day of // month. list($weekday, $day) = explode('>=', $rule[6]); $weekdayInt = $this->_weekdays[substr($weekday, 0, 3)]; $last = new Horde_Date(array('year' => $rule[2], 'month' => $month, 'mday' => $day, 'hour' => $match[1], 'min' => $match[2], 'sec' => 0)); while ($last->dayOfWeek() != $weekdayInt) { $last->mday--; } $component->setAttribute('DTSTART', $last); if ($rule[3][0] == 'm') { $until = ''; } else { $last = new Horde_Date(array('year' => $rule[3], 'month' => $month, 'mday' => $day, 'hour' => $match[1], 'min' => $match[2], 'sec' => 0), $tzid); while ($last->dayOfWeek() != $weekday) { $last->mday--; } $last->setTimezone('UTC'); $until = ';UNTIL=' . $last->format('Ymd\\THIs') . 'Z'; } for ($days = array(), $i = 1; $i <= $day; $i++) { $days[] = $i; } $component->setAttribute('RRULE', 'FREQ=YEARLY;BYMONTH=' . $month . ';BYMONTHDAY=' . implode(',', $days) . ';BYDAY=-1' . Horde_String::upper(substr($weekday, 0, 2)) . $until); } $component->setAttribute('TZNAME', sprintf($name, $rule[9])); $tz->addComponent($component); } }
/** * Finds a date matching a rule definition. * * @param array $rule A rule definition hash from addRules(). * @param integer $year A year when the rule should be applied. * * @return Horde_Date The first matching date. */ protected function _getFirstMatch($rule, $year) { $month = Horde_Timezone::getMonth($rule[5]); if (preg_match('/^\\d+$/', $rule[6])) { // Rule starts on a specific date. $date = new Horde_Date(array('year' => $year, 'month' => $month, 'mday' => $rule[6])); } elseif (substr($rule[6], 0, 4) == 'last') { // Rule starts on the last of a certain weekday of the month. $weekday = $this->_weekdays[substr($rule[6], 4, 3)]; $date = new Horde_Date(array('year' => $year, 'month' => $month, 'mday' => Horde_Date_Utils::daysInMonth($month, $rule[2]))); while ($date->dayOfWeek() != $weekday) { $date->mday--; } } elseif (strpos($rule[6], '>=')) { // Rule starts on a certain weekday after a certain day of month. list($weekday, $day) = explode('>=', $rule[6]); $weekdayInt = $this->_weekdays[substr($weekday, 0, 3)]; $date = new Horde_Date(array('year' => $year, 'month' => $month, 'mday' => $day)); while ($date->dayOfWeek() != $weekdayInt) { $date->mday++; } } elseif (strpos($rule[6], '<=')) { // Rule starts on a certain weekday before a certain day of month. list($weekday, $day) = explode('>=', $rule[6]); $weekdayInt = $this->_weekdays[substr($weekday, 0, 3)]; $date = new Horde_Date(array('year' => $year, 'month' => $month, 'mday' => $day)); while ($date->dayOfWeek() != $weekdayInt) { $date->mday--; } } else { throw new Horde_Timezone_Exception('Cannot parse rule ' . $rule[6]); } return $date; }
$attendees = new Kronolith_Attendee_List(); } $resources = $session->get('kronolith', 'resources', Horde_Session::TYPE_ARRAY); $editAttendee = null; // Get the current Free/Busy view; default to the 'day' view if none specified. $view = Horde_Util::getFormData('view', 'Day'); // Get the date information. $start = new Horde_Date(Horde_Util::getFormData('startdate'), date_default_timezone_get()); switch ($view) { case 'Day': $end = clone $start; $end->mday++; break; case 'Workweek': case 'Week': $diff = $start->dayOfWeek() - ($view == 'Workweek' ? 1 : $prefs->getValue('week_start_monday')); if ($diff < 0) { $diff += 7; } $start->mday -= $diff; $end = clone $start; $end->mday += $view == 'Workweek' ? 5 : 7; break; case 'Month': $start->mday = 1; $end = clone $start; $end->month++; break; } // Get the action ID and value. This specifies what action the user initiated. $actionID = Horde_Util::getFormData('actionID');