case 'Week':
case 'WorkWeek':
case 'Year':
- require_once KRONOLITH_BASE . '/lib/Views/' . basename($view) . '.php';
$class = 'Kronolith_View_' . $view;
return new $class(self::currentDate());
case 'Event':
- require_once KRONOLITH_BASE . '/lib/Views/Event.php';
-
if (Horde_Util::getFormData('calendar') == '**remote') {
$event = self::getDriver('Ical', Horde_Util::getFormData('remoteCal'))
->getEvent(Horde_Util::getFormData('eventID'));
return new Kronolith_View_Event($event);
case 'EditEvent':
- require_once KRONOLITH_BASE . '/lib/Views/EditEvent.php';
-
if (Horde_Util::getFormData('calendar') == '**remote') {
$event = self::getDriver('Ical', Horde_Util::getFormData('remoteCal'))
->getEvent(Horde_Util::getFormData('eventID'));
return new Kronolith_View_EditEvent($event);
case 'DeleteEvent':
- require_once KRONOLITH_BASE . '/lib/Views/DeleteEvent.php';
-
$event = self::getDriver(null, Horde_Util::getFormData('calendar'))
->getEvent(Horde_Util::getFormData('eventID'));
if (!is_a($event, 'PEAR_Error') &&
return new Kronolith_View_DeleteEvent($event);
case 'ExportEvent':
- require_once KRONOLITH_BASE . '/lib/Views/ExportEvent.php';
-
if (Horde_Util::getFormData('calendar') == '**remote') {
$event = self::getDriver('Ical', Horde_Util::getFormData('remoteCal'))
->getEvent(Horde_Util::getFormData('eventID'));
--- /dev/null
+<?php
+/**
+ * The Kronolith_View_Day:: class provides an API for viewing days.
+ *
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @author Jan Schneider <jan@horde.org>
+ * @package Kronolith
+ */
+class Kronolith_View_Day extends Kronolith_Day {
+
+ var $_events = array();
+ var $_all_day_events = array();
+ var $_all_day_rowspan = array();
+ var $_all_day_maxrowspan = 0;
+ var $_event_matrix = array();
+ var $_parsed = false;
+ var $_span = array();
+ var $_totalspan = 0;
+ var $_sidebyside = false;
+ var $_currentCalendars = array();
+ var $_first;
+ var $_last;
+
+ function Kronolith_View_Day($date, $events = null)
+ {
+ parent::Kronolith_Day($date->month, $date->mday, $date->year);
+
+ $this->_sidebyside = $GLOBALS['prefs']->getValue('show_shared_side_by_side');
+ if ($this->_sidebyside) {
+ $allCalendars = Kronolith::listCalendars();
+ foreach ($GLOBALS['display_calendars'] as $cid) {
+ $this->_currentCalendars[$cid] = &$allCalendars[$cid];
+ $this->_all_day_events[$cid] = array();
+ }
+ } else {
+ $this->_currentCalendars = array(0);
+ }
+
+ if ($events === null) {
+ $events = Kronolith::listEvents(
+ $this,
+ new Horde_Date(array('year' => $this->year,
+ 'month' => $this->month,
+ 'mday' => $this->mday)),
+ $GLOBALS['display_calendars']);
+ if (is_a($events, 'PEAR_Error')) {
+ $this->_events = $events;
+ } else {
+ $this->_events = array_shift($events);
+ }
+ } else {
+ $this->_events = $events;
+ }
+
+ if (is_a($this->_events, 'PEAR_Error')) {
+ $GLOBALS['notification']->push($this->_events, 'horde.error');
+ $this->_events = array();
+ }
+ if (!is_array($this->_events)) {
+ $this->_events = array();
+ }
+ }
+
+ function setEvents($events)
+ {
+ $this->_events = $events;
+ }
+
+ function html()
+ {
+ global $prefs;
+
+ if (!$this->_parsed) {
+ $this->parse();
+ }
+
+ $started = false;
+ $first_row = true;
+ $addLinks = Kronolith::getDefaultCalendar(PERMS_EDIT) &&
+ (!empty($GLOBALS['conf']['hooks']['permsdenied']) ||
+ Kronolith::hasPermission('max_events') === true ||
+ Kronolith::hasPermission('max_events') > Kronolith::countEvents());
+ $showLocation = Kronolith::viewShowLocation();
+ $showTime = Kronolith::viewShowTime();
+
+ require KRONOLITH_TEMPLATES . '/day/head.inc';
+ if ($this->_sidebyside) {
+ require KRONOLITH_TEMPLATES . '/day/head_side_by_side.inc';
+ }
+ echo '<tbody>';
+
+ if ($addLinks) {
+ $newEventUrl = Horde_Util::addParameter(
+ 'new.php',
+ array('datetime' => sprintf($this->dateString() . '%02d%02d00',
+ $this->slots[0]['hour'], $this->slots[0]['min']),
+ 'allday' => 1,
+ 'url' => $this->link(0, true)));
+ $newEventUrl = Horde::link(Horde::applicationUrl($newEventUrl), _("Create a New Event"), 'hour') . _("All day") .
+ Horde::img('new_small.png', '+', array('class' => 'iconAdd')) . '</a>';
+ } else {
+ $newEventUrl = '<span class="hour">' . _("All day") . '</span>';
+ }
+
+ /* The all day events are not listed in different columns, but in
+ * different rows. In side by side view we do not spread an event
+ * over multiple rows if there are different numbers of all day events
+ * for different calendars. We just put one event in a single row
+ * with no rowspan. We put in a rowspan in the row after the last
+ * event to fill all remaining rows. */
+ $row = '';
+ $rowspan = ($this->_all_day_maxrowspan) ? ' rowspan="' . $this->_all_day_maxrowspan . '"' : '';
+ for ($k = 0; $k < $this->_all_day_maxrowspan; ++$k) {
+ $row = '';
+ foreach ($this->_currentCalendars as $cid => $cal) {
+ if (count($this->_all_day_events[$cid]) === $k) {
+ // There are no events or all events for this calendar
+ // have already been printed.
+ $row .= '<td class="allday" width="1%" rowspan="' . ($this->_all_day_maxrowspan - $k) . '" colspan="'. $this->_span[$cid] . '"> </td>';
+ } elseif (count($this->_all_day_events[$cid]) > $k) {
+ // We have not printed every all day event yet. Put one
+ // into this row.
+ $event = $this->_all_day_events[$cid][$k];
+ $row .= '<td class="day-eventbox"'
+ . $event->getCSSColors()
+ . 'width="' . round(90 / count($this->_currentCalendars)) . '%" '
+ . 'valign="top" colspan="' . $this->_span[$cid] . '">'
+ . $event->getLink($this, true, $this->link(0, true));
+ if ($showLocation) {
+ $row .= '<div class="event-location">' . htmlspecialchars($event->getLocation()) . '</div>';
+ }
+ $row .= '</td>';
+ }
+ }
+ require KRONOLITH_TEMPLATES . '/day/all_day.inc';
+ $first_row = false;
+ }
+
+ if ($first_row) {
+ $row .= '<td colspan="' . $this->_totalspan . '" width="100%"> </td>';
+ require KRONOLITH_TEMPLATES . '/day/all_day.inc';
+ }
+
+ $day_hour_force = $prefs->getValue('day_hour_force');
+ $day_hour_start = $prefs->getValue('day_hour_start') / 2 * $this->_slotsPerHour;
+ $day_hour_end = $prefs->getValue('day_hour_end') / 2 * $this->_slotsPerHour;
+ $rows = array();
+ $covered = array();
+
+ for ($i = 0; $i < $this->_slotsPerDay; ++$i) {
+ if ($i >= $day_hour_end && $i > $this->_last) {
+ break;
+ }
+ if ($i < $this->_first && $i < $day_hour_start) {
+ continue;
+ }
+
+ $row = '';
+ if (($m = $i % $this->_slotsPerHour) != 0) {
+ $time = ':' . $m * $this->_slotLength;
+ $hourclass = 'halfhour';
+ } else {
+ $time = Kronolith_View_Day::prefHourFormat($this->slots[$i]['hour']);
+ $hourclass = 'hour';
+ }
+
+ if (!count($this->_currentCalendars)) {
+ $row .= '<td> </td>';
+ }
+
+ foreach ($this->_currentCalendars as $cid => $cal) {
+ $hspan = 0;
+ foreach ($this->_event_matrix[$cid][$i] as $key) {
+ $event = &$this->_events[$key];
+
+ // Since we've made sure that this event's overlap is a
+ // factor of the total span, we get this event's
+ // individual span by dividing the total span by this
+ // event's overlap.
+ $span = $this->_span[$cid] / $event->overlap;
+
+ // Store the indent we're starting this event at
+ // for future use.
+ if (!isset($event->indent)) {
+ $event->indent = $hspan;
+ }
+
+ // If the first node that we would cover is
+ // already covered, we can assume that table
+ // rendering will take care of pushing the event
+ // over. However, if the first node _isn't_
+ // covered but any others that we would cover
+ // _are_, we only cover the available nodes.
+ if (!isset($covered[$i][$event->indent])) {
+ $collision = false;
+ $available = 0;
+ for ($y = $event->indent; $y < ($span + $event->indent); ++$y) {
+ if (isset($covered[$i][$y])) {
+ $collision = true;
+ break;
+ }
+ $available++;
+ }
+
+ if ($collision) {
+ $span = $available;
+ }
+ }
+
+ $hspan += $span;
+
+ $start = new Horde_Date(array(
+ 'hour' => floor($i / $this->_slotsPerHour),
+ 'min' => ($i % $this->_slotsPerHour) * $this->_slotLength,
+ 'month' => $this->month,
+ 'mday' => $this->mday,
+ 'year' => $this->year));
+ $end_slot = new Horde_Date($start);
+ $end_slot->min += $this->_slotLength;
+ if (((!$day_hour_force || $i >= $day_hour_start) &&
+ $event->start->compareDateTime($start) >= 0 &&
+ $event->start->compareDateTime($end_slot) < 0 ||
+ $start->compareDateTime($this) == 0) ||
+ ($day_hour_force &&
+ $i == $day_hour_start &&
+ $event->start->compareDateTime($start) < 0)) {
+
+ // Store the nodes that we're covering for
+ // this event in the coverage graph.
+ for ($x = $i; $x < ($i + $event->rowspan); ++$x) {
+ for ($y = $event->indent; $y < $hspan; ++$y) {
+ $covered[$x][$y] = true;
+ }
+ }
+
+ $row .= '<td class="day-eventbox"'
+ . $event->getCSSColors()
+ . 'width="' . round((90 / count($this->_currentCalendars)) * ($span / $this->_span[$cid])) . '%" '
+ . 'valign="top" colspan="' . $span . '" rowspan="' . $event->rowspan . '">'
+ . $event->getLink($this, true, $this->link(0, true));
+ if ($showTime) {
+ $row .= '<div class="event-time">' . htmlspecialchars($event->getTimeRange()) . '</div>';
+ }
+ if ($showLocation) {
+ $row .= '<div class="event-location">' . htmlspecialchars($event->getLocation()) . '</div>';
+ }
+ $row .= '</td>';
+ }
+ }
+
+ $diff = $this->_span[$cid] - $hspan;
+ if ($diff > 0) {
+ $row .= str_repeat('<td> </td>', $diff);
+ }
+ }
+
+ if ($addLinks) {
+ $newEventUrl = Horde_Util::addParameter(
+ 'new.php',
+ array('datetime' => sprintf($this->dateString() . '%02d%02d00',
+ $this->slots[$i]['hour'], $this->slots[$i]['min']),
+ 'url' => $this->link(0, true)));
+ $newEventUrl = Horde::link(Horde::applicationUrl($newEventUrl), _("Create a New Event"), $hourclass) .
+ $time . Horde::img('new_small.png', '+', array('class' => 'iconAdd')) . '</a>';
+ } else {
+ $newEventUrl = '<span class="' . $hourclass . '">' . $time . '</span>';
+ }
+
+ $rows[] = array('row' => $row, 'slot' => $newEventUrl);
+ }
+
+ $template = new Horde_Template();
+ $template->set('row_height', round(20 / $this->_slotsPerHour));
+ $template->set('rows', $rows);
+ $template->set('show_slots', true, true);
+ echo $template->fetch(KRONOLITH_TEMPLATES . '/day/rows.html')
+ . '</tbody></table>';
+ }
+
+ /**
+ * This function runs through the events and tries to figure out
+ * what should be on each line of the output table. This is a
+ * little tricky.
+ */
+ function parse()
+ {
+ global $prefs;
+
+ $tmp = array();
+ $this->_all_day_maxrowspan = 0;
+ $day_hour_force = $prefs->getValue('day_hour_force');
+ $day_hour_start = $prefs->getValue('day_hour_start') / 2 * $this->_slotsPerHour;
+ $day_hour_end = $prefs->getValue('day_hour_end') / 2 * $this->_slotsPerHour;
+
+ // Separate out all day events and do some initialization/prep
+ // for parsing.
+ foreach ($this->_currentCalendars as $cid => $cal) {
+ $this->_all_day_events[$cid] = array();
+ $this->_all_day_rowspan[$cid] = 0;
+ }
+
+ foreach ($this->_events as $key => $event) {
+ // If we have side_by_side we only want to include the
+ // event in the proper calendar.
+ if ($this->_sidebyside) {
+ $cid = $event->getCalendar();
+ } else {
+ $cid = 0;
+ }
+
+ // All day events are easy; store them seperately.
+ if ($event->isAllDay()) {
+ $this->_all_day_events[$cid][] = clone $event;
+ ++$this->_all_day_rowspan[$cid];
+ $this->_all_day_maxrowspan = max($this->_all_day_maxrowspan, $this->_all_day_rowspan[$cid]);
+ } else {
+ // Initialize the number of events that this event
+ // overlaps with.
+ $event->overlap = 0;
+
+ // Initialize this event's vertical span.
+ $event->rowspan = 0;
+
+ $tmp[] = clone $event;
+ }
+ }
+ $this->_events = $tmp;
+
+ // Initialize the set of different rowspans needed.
+ $spans = array(1 => true);
+
+ // Track the first and last slots in which we have an event
+ // (they each start at the other end of the day and move
+ // towards/past each other as we find events).
+ $this->_first = $this->_slotsPerDay;
+ $this->_last = 0;
+
+ // Run through every slot, adding in entries for every event
+ // that we have here.
+ for ($i = 0; $i < $this->_slotsPerDay; ++$i) {
+ // Initialize this slot in the event matrix.
+ foreach ($this->_currentCalendars as $cid => $cal) {
+ $this->_event_matrix[$cid][$i] = array();
+ }
+
+ // Calculate the start and end times for this slot.
+ $start = new Horde_Date(array(
+ 'hour' => floor($i / $this->_slotsPerHour),
+ 'min' => ($i % $this->_slotsPerHour) * $this->_slotLength,
+ 'month' => $this->month,
+ 'mday' => $this->mday,
+ 'year' => $this->year));
+ $end = clone $start;
+ $end->min += $this->_slotLength;
+
+ // Search through our events.
+ foreach ($this->_events as $key => $event) {
+ // If we have side_by_side we only want to include the
+ // event in the proper calendar.
+ if ($this->_sidebyside) {
+ $cid = $event->getCalendar();
+ } else {
+ $cid = 0;
+ }
+
+ // If the event falls anywhere inside this slot, add
+ // it, make sure other events know that they overlap
+ // it, and increment the event's vertical span.
+ if (($event->end->compareDateTime($start) > 0 &&
+ $event->start->compareDateTime($end) < 0) ||
+ ($event->end->compareDateTime($event->start) == 0 &&
+ $event->start->compareDateTime($start) == 0)) {
+
+ // Make sure we keep the latest hour that an event
+ // reaches up-to-date.
+ if ($i > $this->_last &&
+ (!$day_hour_force || $i <= $day_hour_end)) {
+ $this->_last = $i;
+ }
+
+ // Make sure we keep the first hour that an event
+ // reaches up-to-date.
+ if ($i < $this->_first &&
+ (!$day_hour_force || $i >= $day_hour_start)) {
+ $this->_first = $i;
+ }
+
+ if (!$day_hour_force ||
+ ($i >= $day_hour_start && $i <= $day_hour_end)) {
+ // Add this event to the events which are in this row.
+ $this->_event_matrix[$cid][$i][] = $key;
+
+ // Increment the event's vertical span.
+ ++$this->_events[$key]->rowspan;
+ }
+ }
+ }
+
+ foreach (array_keys($this->_currentCalendars) as $cid) {
+ // Update the number of events that events in this row
+ // overlap with.
+ $max = 0;
+ $count = count($this->_event_matrix[$cid][$i]);
+ foreach ($this->_event_matrix[$cid][$i] as $ev) {
+ $this->_events[$ev]->overlap = max($this->_events[$ev]->overlap, $count);
+ $max = max($max, $this->_events[$ev]->overlap);
+ }
+
+ // Update the set of rowspans to include the value for
+ // this row.
+ $spans[$cid][$max] = true;
+ }
+ }
+
+ foreach (array_keys($this->_currentCalendars) as $cid) {
+ // Sort every row by start time so that events always show
+ // up here in the same order.
+ for ($i = $this->_first; $i <= $this->_last; ++$i) {
+ if (count($this->_event_matrix[$cid][$i])) {
+ usort($this->_event_matrix[$cid][$i], array($this, '_sortByStart'));
+ }
+ }
+
+ // Now that we have the number of events in each row, we
+ // can calculate the total span needed.
+ $span[$cid] = 1;
+
+ // Turn keys into array values.
+ $spans[$cid] = array_keys($spans[$cid]);
+
+ // Start with the biggest one first.
+ rsort($spans[$cid]);
+ foreach ($spans[$cid] as $s) {
+ // If the number of events in this row doesn't divide
+ // cleanly into the current total span, we need to
+ // multiply the total span by the number of events in
+ // this row.
+ if ($s != 0 && $span[$cid] % $s != 0) {
+ $span[$cid] *= $s;
+ }
+ }
+ $this->_totalspan += $span[$cid];
+ }
+ // Set the final span.
+ if (isset($span)) {
+ $this->_span = $span;
+ } else {
+ $this->_totalspan = 1;
+ }
+
+ // We're now parsed and ready to go.
+ $this->_parsed = true;
+ }
+
+ function link($offset = 0, $full = false)
+ {
+ return Horde::applicationUrl(
+ Horde_Util::addParameter('day.php', 'date', $this->getTime('%Y%m%d', $offset)),
+ $full);
+ }
+
+ function getName()
+ {
+ return 'Day';
+ }
+
+ function prefHourFormat($hour)
+ {
+ $hour = $hour % 24;
+ if ($GLOBALS['prefs']->getValue('twentyFour')) {
+ return $hour;
+ }
+ return ($hour % 12 == 0 ? 12 : $hour % 12)
+ . ($hour < 12 ? 'am' : 'pm');
+ }
+
+ function _sortByStart($evA, $evB)
+ {
+ $sA = $this->_events[$evA]->start;
+ $sB = $this->_events[$evB]->start;
+
+ return $sB->compareTime($sA);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Kronolith_View_DeleteEvent:: class provides an API for viewing
+ * event delete forms.
+ *
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @package Kronolith
+ */
+class Kronolith_View_DeleteEvent {
+
+ var $event;
+
+ /**
+ * @param Kronolith_Event &$event
+ */
+ function Kronolith_View_DeleteEvent(&$event)
+ {
+ $this->event =& $event;
+ }
+
+ function getTitle()
+ {
+ if (!$this->event || is_a($this->event, 'PEAR_Error')) {
+ return _("Not Found");
+ }
+ return sprintf(_("Delete %s"), $this->event->getTitle());
+ }
+
+ function link()
+ {
+ return $this->event->getDeleteUrl();
+ }
+
+ function html($active = true)
+ {
+ if (!$this->event || is_a($this->event, 'PEAR_Error')) {
+ echo '<h3>' . _("The requested event was not found.") . '</h3>';
+ return;
+ }
+
+ if ($datetime = Horde_Util::getFormData('datetime')) {
+ $datetime = new Horde_Date($datetime);
+ $month = $datetime->month;
+ $year = $datetime->year;
+ $day = $datetime->mday;
+ } else {
+ $month = Horde_Util::getFormData('month', date('n'));
+ $day = Horde_Util::getFormData('mday', date('j'));
+ $year = Horde_Util::getFormData('year', date('Y'));
+ }
+
+ $url = Horde_Util::getFormData('url');
+
+ echo '<div id="DeleteEvent"' . ($active ? '' : ' style="display:none"') . '>';
+ if (!$this->event->recurs()) {
+ require KRONOLITH_TEMPLATES . '/delete/one.inc';
+ } else {
+ require KRONOLITH_TEMPLATES . '/delete/delete.inc';
+ }
+ echo '</div>';
+
+ if ($active && $GLOBALS['browser']->hasFeature('dom')) {
+ if ($this->event->hasPermission(PERMS_READ)) {
+ $view = new Kronolith_View_Event($this->event);
+ $view->html(false);
+ }
+ if ($this->event->hasPermission(PERMS_EDIT)) {
+ $edit = new Kronolith_View_EditEvent($this->event);
+ $edit->html(false);
+ }
+ }
+ }
+
+ function getName()
+ {
+ return 'DeleteEvent';
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Kronolith_View_EditEvent:: class provides an API for viewing
+ * event edit forms.
+ *
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @package Kronolith
+ */
+class Kronolith_View_EditEvent {
+
+ var $event;
+
+ /**
+ * @param Kronolith_Event &$event
+ */
+ function Kronolith_View_EditEvent(&$event)
+ {
+ $this->event = &$event;
+ }
+
+ function getTitle()
+ {
+ if (!$this->event || is_a($this->event, 'PEAR_Error')) {
+ return _("Not Found");
+ }
+ return sprintf(_("Edit %s"), $this->event->getTitle());
+ }
+
+ function link()
+ {
+ return $this->event->getEditUrl();
+ }
+
+ function html($active = true)
+ {
+ require_once 'Horde/Identity.php';
+ $identity = &Identity::singleton();
+
+ if (!$this->event || is_a($this->event, 'PEAR_Error')) {
+ echo '<h3>' . _("The requested event was not found.") . '</h3>';
+ return;
+ }
+
+ if ($this->event->isRemote()) {
+ $calendar_id = Kronolith::getDefaultCalendar(PERMS_EDIT);
+ } else {
+ $calendar_id = $this->event->getCalendar();
+ }
+ if (!$this->event->hasPermission(PERMS_EDIT) &&
+ !is_a($share = &$this->event->getShare(), 'PEAR_Error')) {
+ $calendar_id .= ':' . $share->get('owner');
+ }
+ $_SESSION['kronolith']['attendees'] = $this->event->getAttendees();
+
+ if ($datetime = Horde_Util::getFormData('datetime')) {
+ $datetime = new Horde_Date($datetime);
+ $month = $datetime->month;
+ $year = $datetime->year;
+ } else {
+ $month = Horde_Util::getFormData('month', date('n'));
+ $year = Horde_Util::getFormData('year', date('Y'));
+ }
+
+ $url = Horde_Util::getFormData('url');
+ $perms = PERMS_EDIT;
+ if ($this->event->getCreatorId() == Horde_Auth::getAuth()) {
+ $perms |= PERMS_DELEGATE;
+ }
+ $calendars = Kronolith::listCalendars(false, $perms);
+
+ $buttons = array();
+ if (($this->event->isRemote() ||
+ !$this->event->hasPermission(PERMS_EDIT)) &&
+ (!empty($GLOBALS['conf']['hooks']['permsdenied']) ||
+ Kronolith::hasPermission('max_events') === true ||
+ Kronolith::hasPermission('max_events') > Kronolith::countEvents())) {
+ $buttons[] = '<input type="submit" class="button" name="saveAsNew" value="' . _("Save As New") . '" />';
+ } else {
+ if (!$this->event->isRemote()) {
+ $buttons[] = '<input type="submit" class="button" name="save" value="' . _("Save Event") . '" />';
+ }
+ if ($this->event->isInitialized()) {
+ if (!$this->event->recurs() &&
+ (!empty($conf['hooks']['permsdenied']) ||
+ Kronolith::hasPermission('max_events') === true ||
+ Kronolith::hasPermission('max_events') > Kronolith::countEvents())) {
+ $buttons[] = '<input type="submit" class="button" name="saveAsNew" value="' . _("Save As New") . '" />';
+ }
+ }
+ }
+
+ if (isset($url)) {
+ $cancelurl = $url;
+ } else {
+ $cancelurl = Horde_Util::addParameter('month.php', array('month' => $month,
+ 'year', $year));
+ $cancelurl = Horde::applicationUrl($cancelurl, true);
+ }
+
+ $event = &$this->event;
+
+ // Tags
+ $tagger = Kronolith::getTagger();
+ $tags = $tagger->getTags($event->getUID(), 'event');
+ $tags = implode(',', array_values($tags));
+
+ echo '<div id="EditEvent"' . ($active ? '' : ' style="display:none"') . '>';
+ require KRONOLITH_TEMPLATES . '/edit/javascript.inc';
+ require KRONOLITH_TEMPLATES . '/edit/edit.inc';
+ echo '</div>';
+
+ if ($active && $GLOBALS['browser']->hasFeature('dom')) {
+ if ($this->event->hasPermission(PERMS_READ)) {
+ $view = new Kronolith_View_Event($this->event);
+ $view->html(false);
+ }
+ if ($this->event->hasPermission(PERMS_DELETE)) {
+ $delete = new Kronolith_View_DeleteEvent($this->event);
+ $delete->html(false);
+ }
+ }
+ }
+
+ function getName()
+ {
+ return 'EditEvent';
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Kronolith_View_Event:: class provides an API for viewing events.
+ *
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @package Kronolith
+ */
+class Kronolith_View_Event {
+
+ var $event;
+
+ /**
+ * @param Kronolith_Event &$event
+ */
+ function Kronolith_View_Event(&$event)
+ {
+ $this->event = &$event;
+ }
+
+ function getTitle()
+ {
+ if (!$this->event || is_a($this->event, 'PEAR_Error')) {
+ return _("Not Found");
+ }
+ return $this->event->getTitle();
+ }
+
+ function link()
+ {
+ return $this->event->getViewUrl();
+ }
+
+ function html($active = true)
+ {
+ global $conf, $prefs;
+
+ if (!$this->event || is_a($this->event, 'PEAR_Error')) {
+ echo '<h3>' . _("The requested event was not found.") . '</h3>';
+ return;
+ }
+
+ $createdby = '';
+ $modifiedby = '';
+ $userId = Horde_Auth::getAuth();
+ if ($this->event->getUID()) {
+ /* Get the event's history. */
+ $history = &Horde_History::singleton();
+ $log = $history->getHistory('kronolith:' . $this->event->getCalendar() . ':' .
+ $this->event->getUID());
+ if ($log && !is_a($log, 'PEAR_Error')) {
+ foreach ($log->getData() as $entry) {
+ switch ($entry['action']) {
+ case 'add':
+ $created = new Horde_Date($entry['ts']);
+ if ($userId != $entry['who']) {
+ $createdby = sprintf(_("by %s"), Kronolith::getUserName($entry['who']));
+ } else {
+ $createdby = _("by me");
+ }
+ break;
+
+ case 'modify':
+ $modified = new Horde_Date($entry['ts']);
+ if ($userId != $entry['who']) {
+ $modifiedby = sprintf(_("by %s"), Kronolith::getUserName($entry['who']));
+ } else {
+ $modifiedby = _("by me");
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ $creatorId = $this->event->getCreatorId();
+ $description = $this->event->getDescription();
+ $location = $this->event->getLocation();
+ $private = $this->event->isPrivate() && $creatorId != Horde_Auth::getAuth();
+ $owner = Kronolith::getUserName($creatorId);
+ $status = Kronolith::statusToString($this->event->getStatus());
+ $attendees = $this->event->getAttendees();
+
+ if ($datetime = Horde_Util::getFormData('datetime')) {
+ $datetime = new Horde_Date($datetime);
+ $month = $datetime->month;
+ $year = $datetime->year;
+ } else {
+ $month = (int)Horde_Util::getFormData('month', date('n'));
+ $year = (int)Horde_Util::getFormData('year', date('Y'));
+ }
+
+ $dateFormat = $prefs->getValue('date_format');
+ $timeFormat = $prefs->getValue('twentyFour') ? 'G:i' : 'g:ia';
+
+ // Tags
+ $tags = implode(', ', $this->event->tags);
+
+
+ echo '<div id="Event"' . ($active ? '' : ' style="display:none"') . '>';
+ require KRONOLITH_TEMPLATES . '/view/view.inc';
+ echo '</div>';
+
+ if ($active && $GLOBALS['browser']->hasFeature('dom')) {
+ if ($this->event->hasPermission(PERMS_EDIT)) {
+ $edit = new Kronolith_View_EditEvent($this->event);
+ $edit->html(false);
+ }
+ if ($this->event->hasPermission(PERMS_DELETE)) {
+ $delete = new Kronolith_View_DeleteEvent($this->event);
+ $delete->html(false);
+ }
+ }
+ }
+
+ function getName()
+ {
+ return 'Event';
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Kronolith_View_ExportEvent:: class provides an API for exporting
+ * events.
+ *
+ * @author Jan Schneider <chuck@horde.org>
+ * @package Kronolith
+ */
+class Kronolith_View_ExportEvent {
+
+ /**
+ * @param Kronolith_Event &$event
+ */
+ function Kronolith_View_ExportEvent(&$event)
+ {
+ $iCal = new Horde_iCalendar('2.0');
+
+ if (!$event->isRemote()) {
+ $share = &$GLOBALS['kronolith_shares']->getShare($event->getCalendar());
+ if (!is_a($share, 'PEAR_Error')) {
+ $iCal->setAttribute('X-WR-CALNAME',
+ Horde_String::convertCharset($share->get('name'),
+ Horde_Nls::getCharset(),
+ 'utf-8'));
+ }
+ }
+
+ $vEvent = &$event->toiCalendar($iCal);
+ $iCal->addComponent($vEvent);
+ $content = $iCal->exportvCalendar();
+
+ $GLOBALS['browser']->downloadHeaders(
+ $event->getTitle() . '.ics',
+ 'text/calendar; charset=' . Horde_Nls::getCharset(),
+ true, strlen($content));
+ echo $content;
+ exit;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Kronolith_View_Month:: class provides an API for viewing
+ * months.
+ *
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @author Jan Schneider <jan@horde.org>
+ * @package Kronolith
+ */
+class Kronolith_View_Month {
+
+ /**
+ * @var integer
+ */
+ var $month;
+
+ /**
+ * @var integer
+ */
+ var $year;
+
+ /**
+ * @var Horde_Date
+ */
+ var $date;
+
+ /**
+ * @var array
+ */
+ var $_events = array();
+
+ /**
+ * @var array
+ */
+ var $_currentCalendars = array();
+
+ /**
+ * @var integer
+ */
+ var $_daysInView;
+
+ /**
+ * @var integer
+ */
+ var $_startOfView;
+
+ /**
+ * @var integer
+ */
+ var $_startday;
+
+ function Kronolith_View_Month($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::listCalendars();
+ $this->_currentCalendars = array();
+ foreach ($GLOBALS['display_calendars'] as $id) {
+ $this->_currentCalendars[$id] = &$allCalendars[$id];
+ }
+ } else {
+ $this->_currentCalendars = array(true);
+ }
+
+ $this->_events = Kronolith::listEvents($startDate, $endDate, $GLOBALS['display_calendars']);
+ if (is_a($this->_events, 'PEAR_Error')) {
+ $GLOBALS['notification']->push($this->_events, 'horde.error');
+ $this->_events = array();
+ }
+ if (!is_array($this->_events)) {
+ $this->_events = array();
+ }
+ }
+
+ function html()
+ {
+ global $prefs;
+
+ $sidebyside = $prefs->getValue('show_shared_side_by_side');
+ $twentyFour = $prefs->getValue('twentyFour');
+ $addLinks = Kronolith::getDefaultCalendar(PERMS_EDIT) &&
+ (!empty($GLOBALS['conf']['hooks']['permsdenied']) ||
+ Kronolith::hasPermission('max_events') === true ||
+ Kronolith::hasPermission('max_events') > Kronolith::countEvents());
+
+ if ($sidebyside) {
+ require KRONOLITH_TEMPLATES . '/month/head_side_by_side.inc';
+ } else {
+ require KRONOLITH_TEMPLATES . '/month/head.inc';
+ }
+
+ $html = '';
+ if (!$sidebyside && count($this->_currentCalendars)) {
+ $html .= '<tr>';
+ }
+
+ $showLocation = Kronolith::viewShowLocation();
+ $showTime = Kronolith::viewShowTime();
+
+ foreach ($this->_currentCalendars as $id => $cal) {
+ if ($sidebyside) {
+ $html .= '<tr>';
+ }
+
+ $cell = 0;
+ for ($day = $this->_startOfView; $day < $this->_startOfView + $this->_daysInView; ++$day) {
+ $date = new Kronolith_Day($this->month, $day, $this->year);
+ $date->hour = $twentyFour ? 12 : 6;
+ $week = $date->weekOfYear();
+
+ if ($cell % 7 == 0 && $cell != 0) {
+ if ($sidebyside) {
+ $html .= '<td>' . htmlspecialchars($cal->get('name')) . '</td>';
+ } else {
+ $html .= "</tr>\n<tr>";
+ }
+ }
+ if ($date->isToday()) {
+ $style = 'today';
+ } elseif ($date->month != $this->month) {
+ $style = 'othermonth';
+ } elseif ($date->dayOfWeek() == 0 || $date->dayOfWeek() == 6) {
+ $style = 'weekend';
+ } else {
+ $style = 'text';
+ }
+
+ $html .= '<td class="' . $style . '" height="70" width="14%" valign="top"><div>';
+
+ $url = Horde_Util::addParameter(Horde::applicationUrl('day.php'),
+ 'date', $date->dateString());
+ $html .= '<a class="day" href="' . $url . '">' . $date->mday . '</a>';
+
+ if ($addLinks) {
+ $url = Horde_Util::addParameter(Horde::applicationUrl('new.php'),
+ array('date' => $date->dateString(),
+ 'url' => $this->link(0, true)));
+ if ($sidebyside) {
+ $url = Horde_Util::addParameter($url, 'calendar', $id);
+ }
+ $html .= Horde::link($url, _("Create a New Event"), 'newEvent') .
+ Horde::img('new_small.png', '+') . '</a>';
+ }
+
+ if ($date->dayOfWeek() == Horde_Date::DATE_MONDAY) {
+ $url = Horde_Util::addParameter('week.php', 'date', $date->dateString());
+ $html .= Horde::link(Horde::applicationUrl($url), '', 'week') . sprintf(_("Week %d"), $week) . '</a>';
+ }
+
+ $html .= '</div><div class="clear"> </div>';
+
+ $date_stamp = $date->dateString();
+ if (!empty($this->_events[$date_stamp])) {
+ foreach ($this->_events[$date_stamp] as $event) {
+ if (!$sidebyside || $event->getCalendar() == $id) {
+ $html .= '<div class="month-eventbox"' . $event->getCSSColors() . '>'
+ . $event->getLink($date, true, $this->link(0, true));
+ if ($showTime) {
+ $html .= '<div class="event-time">' . htmlspecialchars($event->getTimeRange()) . '</div>';
+ }
+ if ($showLocation) {
+ $html .= '<div class="event-location">' . htmlspecialchars($event->getLocation()) . '</div>';
+ }
+ $html .= '</div>';
+ }
+ }
+ }
+
+ $html .= "</td>\n";
+ ++$cell;
+ }
+
+ if ($sidebyside) {
+ $html .= '</tr>';
+ }
+ }
+ if (!$sidebyside && count($this->_currentCalendars)) {
+ $html .= '</tr>';
+ }
+
+ echo $html . '</tbody></table>';
+ }
+
+ function getMonth($offset = 0)
+ {
+ $month = new Horde_Date($this->date);
+ $month->month += $offset;
+ return $month;
+ }
+
+ function link($offset = 0, $full = false)
+ {
+ $month = $this->getMonth($offset);
+ return Horde::applicationUrl(Horde_Util::addParameter('month.php', 'date', $month->dateString()), $full);
+ }
+
+ function getName()
+ {
+ return 'Month';
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Kronolith_View_Week:: class provides an API for viewing weeks.
+ *
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @author Jan Schneider <jan@horde.org>
+ * @package Kronolith
+ */
+class Kronolith_View_Week {
+
+ var $parsed = false;
+ var $days = array();
+ var $week = null;
+ var $year = null;
+ var $startDay = null;
+ var $endDay = null;
+ var $startDate = null;
+ var $_controller = 'week.php';
+ var $_sidebyside = false;
+ var $_currentCalendars = array();
+
+ /**
+ * How many time slots are we dividing each hour into?
+ *
+ * @var integer
+ */
+ var $_slotsPerHour = 2;
+
+ /**
+ * How many slots do we have per day? Calculated from $_slotsPerHour.
+ *
+ * @see $_slotsPerHour
+ * @var integer
+ */
+ var $_slotsPerDay;
+
+ function Kronolith_View_Week($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);
+ $allevents = Kronolith::listEvents($this->startDate, $endDate, $GLOBALS['display_calendars']);
+ if (is_a($allevents, 'PEAR_Error')) {
+ $GLOBALS['notification']->push($allevents, 'horde.error');
+ $allevents = array();
+ }
+ for ($i = $this->startDay; $i <= $this->endDay; ++$i) {
+ $date_stamp = $this->days[$i]->dateString();
+ $this->days[$i]->setEvents(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;
+ }
+
+ function html()
+ {
+ global $prefs;
+
+ $more_timeslots = $prefs->getValue('time_between_days');
+ $include_all_events = !$prefs->getValue('show_shared_side_by_side');
+ $showLocation = Kronolith::viewShowLocation();
+ $showTime = Kronolith::viewShowTime();
+
+ if (!$this->parsed) {
+ $this->parse();
+ }
+
+ $slots = $this->days[$this->startDay]->slots;
+ $cid = 0;
+ require KRONOLITH_TEMPLATES . '/week/head.inc';
+ if ($this->_sidebyside) {
+ require KRONOLITH_TEMPLATES . '/week/head_side_by_side.inc';
+ }
+ echo '</thead><tbody>';
+
+ $event_count = 0;
+ for ($j = $this->startDay; $j <= $this->endDay; ++$j) {
+ foreach ($this->_currentCalendars as $cid => $cal) {
+ $event_count = max($event_count, count($this->days[$j]->_all_day_events[$cid]));
+ reset($this->days[$j]->_all_day_events[$cid]);
+ }
+ }
+
+ if ($more_timeslots) {
+ $newEventUrl = null;
+ } else {
+ $newEventUrl = _("All day");
+ }
+
+ $row = '';
+ for ($j = $this->startDay; $j <= $this->endDay; ++$j) {
+ $row .= '<td class="hour rightAlign">' . ($more_timeslots ? _("All day") : ' ') . '</td>' .
+ '<td colspan="' . $this->days[$j]->_totalspan . '" valign="top"><table width="100%" cellspacing="0">';
+ if ($this->days[$j]->_all_day_maxrowspan > 0) {
+ for ($k = 0; $k < $this->days[$j]->_all_day_maxrowspan; ++$k) {
+ $row .= '<tr>';
+ foreach ($this->days[$j]->_currentCalendars as $cid => $cal) {
+ if (count($this->days[$j]->_all_day_events[$cid]) === $k) {
+ $row .= '<td rowspan="' . ($this->days[$j]->_all_day_maxrowspan - $k) . '" width="'. round(99 / count($this->days[$j]->_currentCalendars)) . '%"> </td>';
+ } elseif (count($this->days[$j]->_all_day_events[$cid]) > $k) {
+ $event = $this->days[$j]->_all_day_events[$cid][$k];
+ $row .= '<td class="week-eventbox"'
+ . $event->getCSSColors()
+ . 'width="' . round(99 / count($this->days[$j]->_currentCalendars)) . '%" '
+ . 'valign="top">'
+ . $event->getLink($this->days[$j], true, $this->link(0, true));
+ if ($showLocation) {
+ $row .= '<div class="event-location">' . htmlspecialchars($event->getLocation()) . '</div>';
+ }
+ $row .= '</td>';
+ }
+ }
+ $row .= '</tr>';
+ }
+ } else {
+ $row .= '<tr><td colspan="' . count($this->_currentCalendars) . '"> </td></tr>';
+ }
+ $row .= '</table></td>';
+ }
+
+ $rowspan = '';
+ $first_row = true;
+ require KRONOLITH_TEMPLATES . '/day/all_day.inc';
+
+ $day_hour_force = $prefs->getValue('day_hour_force');
+ $day_hour_start = $prefs->getValue('day_hour_start') / 2 * $this->_slotsPerHour;
+ $day_hour_end = $prefs->getValue('day_hour_end') / 2 * $this->_slotsPerHour;
+ $rows = array();
+ $covered = array();
+
+ for ($i = 0; $i < $this->_slotsPerDay; ++$i) {
+ if ($i >= $day_hour_end && $i > $this->last) {
+ break;
+ }
+ if ($i < $this->first && $i < $day_hour_start) {
+ continue;
+ }
+
+ if (($m = $i % $this->_slotsPerHour) != 0) {
+ $time = ':' . $m * $this->_slotLength;
+ $hourclass = 'halfhour';
+ } else {
+ $time = Kronolith_View_Day::prefHourFormat($slots[$i]['hour']);
+ $hourclass = 'hour';
+ }
+
+ $row = '';
+ for ($j = $this->startDay; $j <= $this->endDay; ++$j) {
+ // Add spacer between days, or timeslots.
+ if ($more_timeslots) {
+ $row .= '<td align="right" class="' . $hourclass . '">' . $time . '</td>';
+ } else {
+ $row .= '<td> </td>';
+ }
+
+ if (!count($this->_currentCalendars)) {
+ $row .= '<td> </td>';
+ }
+ foreach ($this->_currentCalendars as $cid => $cal) {
+ $hspan = 0;
+ foreach ($this->days[$j]->_event_matrix[$cid][$i] as $key) {
+ $event = &$this->days[$j]->_events[$key];
+ if ($include_all_events || $event->getCalendar() == $cid) {
+ // Since we've made sure that this event's
+ // overlap is a factor of the total span,
+ // we get this event's individual span by
+ // dividing the total span by this event's
+ // overlap.
+ $span = $this->days[$j]->_span[$cid] / $event->overlap;
+
+ // Store the indent we're starting this
+ // event at for future use.
+ if (!isset($event->indent)) {
+ $event->indent = $hspan;
+ }
+
+ // If the first node that we would cover
+ // is already covered, we can assume that
+ // table rendering will take care of
+ // pushing the event over. However, if the
+ // first node _isn't_ covered but any
+ // others that we would covered _are_, we
+ // only cover the available nodes.
+ if (!isset($covered[$j][$i][$event->indent])) {
+ $collision = false;
+ $available = 0;
+ for ($y = $event->indent; $y < ($span + $event->indent); ++$y) {
+ if (isset($covered[$j][$i][$y])) {
+ $collision = true;
+ break;
+ }
+ $available++;
+ }
+
+ if ($collision) {
+ $span = $available;
+ }
+ }
+
+ $hspan += $span;
+
+ $start = new Horde_Date(array(
+ 'hour' => floor($i / $this->_slotsPerHour),
+ 'min' => ($i % $this->_slotsPerHour) * $this->_slotLength,
+ 'month' => $this->days[$j]->month,
+ 'mday' => $this->days[$j]->mday,
+ 'year' => $this->days[$j]->year));
+ $slot_end = new Horde_Date($start);
+ $slot_end->min += $this->_slotLength;
+ if (((!$day_hour_force || $i >= $day_hour_start) &&
+ $event->start->compareDateTime($start) >= 0 &&
+ $event->start->compareDateTime($slot_end) < 0 ||
+ $start->compareDateTime($this->days[$j]) == 0) ||
+ ($day_hour_force &&
+ $i == $day_hour_start)) {
+
+ // Store the nodes that we're covering for
+ // this event in the coverage graph.
+ for ($x = $i; $x < ($i + $event->rowspan); ++$x) {
+ for ($y = $event->indent; $y < $hspan; ++$y) {
+ $covered[$j][$x][$y] = true;
+ }
+ }
+
+ $row .= '<td class="week-eventbox"'
+ . $event->getCSSColors()
+ . 'valign="top" '
+ . 'width="' . floor(((90 / count($this->days)) / count($this->_currentCalendars)) * ($span / $this->days[$j]->_span[$cid])) . '%" '
+ . 'colspan="' . $span . '" rowspan="' . $event->rowspan . '">'
+ . $event->getLink($this->days[$j], true, $this->link(0, true));
+ if ($showTime) {
+ $row .= '<div class="event-time">' . htmlspecialchars($event->getTimeRange()) . '</div>';
+ }
+ if ($showLocation) {
+ $row .= '<div class="event-location">' . htmlspecialchars($event->getLocation()) . '</div>';
+ }
+ $row .= '</td>';
+ }
+ }
+ }
+
+ $diff = $this->days[$j]->_span[$cid] - $hspan;
+ if ($diff > 0) {
+ $row .= str_repeat('<td> </td>', $diff);
+ }
+ }
+ }
+
+ $rows[] = array('row' => $row, 'slot' => '<span class="' . $hourclass . '">' . $time . '</span>');
+ }
+
+ $template = new Horde_Template();
+ $template->set('row_height', round(20 / $this->_slotsPerHour));
+ $template->set('rows', $rows);
+ $template->set('show_slots', !$more_timeslots, true);
+ echo $template->fetch(KRONOLITH_TEMPLATES . '/day/rows.html')
+ . '</tbody></table>';
+ }
+
+ /**
+ * Parse all events for all of the days that we're handling; then
+ * run through the results to get the total horizontal span for
+ * the week, and the latest event of the week.
+ */
+ function parse()
+ {
+ for ($i = $this->startDay; $i <= $this->endDay; ++$i) {
+ $this->days[$i]->parse();
+ }
+
+ $this->totalspan = 0;
+ $this->span = array();
+ for ($i = $this->startDay; $i <= $this->endDay; ++$i) {
+ $this->totalspan += $this->days[$i]->_totalspan;
+ foreach ($this->_currentCalendars as $cid => $key) {
+ if (isset($this->span[$cid])) {
+ $this->span[$cid] += $this->days[$i]->_span[$cid];
+ } else {
+ $this->span[$cid] = $this->days[$i]->_span[$cid];
+ }
+ }
+ }
+
+ $this->last = 0;
+ $this->first = $this->_slotsPerDay;
+ for ($i = $this->startDay; $i <= $this->endDay; ++$i) {
+ if ($this->days[$i]->last > $this->last) {
+ $this->last = $this->days[$i]->last;
+ }
+ if ($this->days[$i]->first < $this->first) {
+ $this->first = $this->days[$i]->first;
+ }
+ }
+ }
+
+ function getWeek($offset = 0)
+ {
+ $week = new Horde_Date($this->startDate);
+ $week->mday += $offset * 7;
+ return $week;
+ }
+
+ function link($offset = 0, $full = false)
+ {
+ $week = $this->getWeek($offset);
+ return Horde::applicationUrl(Horde_Util::addParameter($this->_controller,
+ 'date',
+ $week->dateString()),
+ $full);
+ }
+
+ function getName()
+ {
+ return 'Week';
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Kronolith_View_WorkWeek:: class provides a shortcut for a week
+ * view that is only Monday through Friday.
+ *
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @package Kronolith
+ */
+class Kronolith_View_WorkWeek extends Kronolith_View_Week {
+
+ var $startDay = Horde_Date::DATE_MONDAY;
+ var $endDay = Horde_Date::DATE_FRIDAY;
+ var $_controller = 'workweek.php';
+
+ function getName()
+ {
+ return 'WorkWeek';
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * The Kronolith_View_Year:: class provides an API for viewing years.
+ *
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @author Jan Schneider <jan@horde.org>
+ * @package Kronolith
+ */
+class Kronolith_View_Year {
+
+ var $year;
+ var $_events = array();
+
+ function Kronolith_View_Year($date)
+ {
+ $this->year = $date->year;
+ $startDate = new Horde_Date(array('year' => $this->year,
+ 'month' => 1,
+ 'mday' => 1));
+ $endDate = new Horde_Date(array('year' => $this->year,
+ 'month' => 12,
+ 'mday' => 31));
+
+ $this->_events = Kronolith::listEvents($startDate, $endDate, $GLOBALS['display_calendars']);
+ if (is_a($this->_events, 'PEAR_Error')) {
+ $GLOBALS['notification']->push($this->_events, 'horde.error');
+ $this->_events = array();
+ }
+ if (!is_array($this->_events)) {
+ $this->_events = array();
+ }
+ }
+
+ function html()
+ {
+ global $prefs;
+
+ require KRONOLITH_TEMPLATES . '/year/head.inc';
+
+ $html = '<table class="nopadding" cellspacing="5" width="100%"><tr>';
+ for ($month = 1; $month <= 12; ++$month) {
+ $html .= '<td valign="top">';
+
+ // Heading for each month.
+ $date = new Horde_Date(sprintf('%04d%02d01010101', $this->year, $month));
+ $mtitle = $date->strftime('%B');
+ $url = Horde_Util::addParameter(Horde::applicationUrl('month.php'), array('date' => $date->dateString()));
+ $html .= '<h2 class="smallheader"><a class="smallheader" href="' . $url . '">' . $mtitle . '</a></h2>' .
+ '<table class="nopadding monthgrid" cellspacing="0" width="100%"><thead><tr class="item">';
+ if (!$prefs->getValue('week_start_monday')) {
+ $html .= '<th>' . _("Su"). '</th>';
+ }
+ $html .= '<th>' . _("Mo") . '</th>' .
+ '<th>' . _("Tu") . '</th>' .
+ '<th>' . _("We") . '</th>' .
+ '<th>' . _("Th") . '</th>' .
+ '<th>' . _("Fr") . '</th>' .
+ '<th>' . _("Sa") . '</th>';
+ if ($prefs->getValue('week_start_monday')) {
+ $html .= '<th>' . _("Su") . '</th>';
+ }
+ $html .= '</tr></thead><tbody><tr>';
+
+ $startday = new Horde_Date(array('mday' => 1,
+ 'month' => $month,
+ 'year' => $this->year));
+ $startday = $startday->dayOfWeek();
+
+ $daysInView = Date_Calc::weeksInMonth($month, $this->year) * 7;
+ if (!$prefs->getValue('week_start_monday')) {
+ $startOfView = 1 - $startday;
+
+ // We may need to adjust the number of days in the
+ // view if we're starting weeks on Sunday.
+ if ($startday == Horde_Date::DATE_SUNDAY) {
+ $daysInView -= 7;
+ }
+ $endday = new Horde_Date(array('mday' => Horde_Date_Utils::daysInMonth($month, $this->year),
+ 'month' => $month,
+ 'year' => $this->year));
+ $endday = $endday->dayOfWeek();
+ if ($endday == Horde_Date::DATE_SUNDAY) {
+ $daysInView += 7;
+ }
+ } else {
+ if ($startday == Horde_Date::DATE_SUNDAY) {
+ $startOfView = -5;
+ } else {
+ $startOfView = 2 - $startday;
+ }
+ }
+
+ $currentCalendars = array(true);
+ foreach ($currentCalendars as $id => $cal) {
+ $cell = 0;
+ for ($day = $startOfView; $day < $startOfView + $daysInView; ++$day) {
+ $date = new Kronolith_Day($month, $day, $this->year);
+ $date->hour = $prefs->getValue('twentyFour') ? 12 : 6;
+ $week = $date->weekOfYear();
+
+ if ($cell % 7 == 0 && $cell != 0) {
+ $html .= "</tr>\n<tr>";
+ }
+ if ($date->month != $month) {
+ $style = 'monthgrid';
+ } elseif ($date->dayOfWeek() == 0 || $date->dayOfWeek() == 6) {
+ $style = 'weekend';
+ } else {
+ $style = 'text';
+ }
+
+ /* Set up the link to the day view. */
+ $url = Horde::applicationUrl('day.php', true);
+ $url = Horde_Util::addParameter($url, 'date', $date->dateString());
+
+ if ($date->month != $month) {
+ $cellday = ' ';
+ } elseif (!empty($this->_events[$date->dateString()])) {
+ /* There are events; create a cell with tooltip to list
+ * them. */
+ $day_events = '';
+ foreach ($this->_events[$date->dateString()] as $event) {
+ if ($event->getStatus() == Kronolith::STATUS_CONFIRMED) {
+ /* Set the background color to distinguish the day */
+ $style = 'year-event';
+ }
+
+ if ($event->isAllDay()) {
+ $day_events .= _("All day");
+ } else {
+ $day_events .= $event->start->strftime($prefs->getValue('twentyFour') ? '%R' : '%I:%M%p') . '-' . $event->end->strftime($prefs->getValue('twentyFour') ? '%R' : '%I:%M%p');
+ }
+ $day_events .= ':'
+ . (($event->getLocation()) ? ' (' . $event->getLocation() . ')' : '')
+ . ' ' . $event->getTitle() . "\n";
+ }
+ /* Bold the cell if there are events. */
+ $cellday = '<strong>' . Horde::linkTooltip($url, _("View Day"), '', '', '', $day_events) . $date->mday . '</a></strong>';
+ } else {
+ /* No events, plain link to the day. */
+ $cellday = Horde::linkTooltip($url, _("View Day")) . $date->mday . '</a>';
+ }
+ if ($date->isToday() && $date->month == $month) {
+ $style .= ' today';
+ }
+
+ $html .= '<td align="center" class="' . $style . '" height="10" width="5%" valign="top">' .
+ $cellday . '</td>';
+ ++$cell;
+ }
+ }
+
+ $html .= '</tr></tbody></table></td>';
+ if ($month % 3 == 0 && $month != 12) {
+ $html .= '</tr><tr>';
+ }
+ }
+
+ echo $html . '</tr></table>';
+ }
+
+ function link($offset = 0, $full = false)
+ {
+ return Horde::applicationUrl(Horde_Util::addParameter('year.php', 'date', $this->year + $offset) . '0101', $full);
+ }
+
+ function getName()
+ {
+ return 'Year';
+ }
+
+}
+++ /dev/null
-<?php
-/**
- * The Kronolith_View_Day:: class provides an API for viewing days.
- *
- * @author Chuck Hagenbuch <chuck@horde.org>
- * @author Jan Schneider <jan@horde.org>
- * @package Kronolith
- */
-class Kronolith_View_Day extends Kronolith_Day {
-
- var $_events = array();
- var $_all_day_events = array();
- var $_all_day_rowspan = array();
- var $_all_day_maxrowspan = 0;
- var $_event_matrix = array();
- var $_parsed = false;
- var $_span = array();
- var $_totalspan = 0;
- var $_sidebyside = false;
- var $_currentCalendars = array();
- var $_first;
- var $_last;
-
- function Kronolith_View_Day($date, $events = null)
- {
- parent::Kronolith_Day($date->month, $date->mday, $date->year);
-
- $this->_sidebyside = $GLOBALS['prefs']->getValue('show_shared_side_by_side');
- if ($this->_sidebyside) {
- $allCalendars = Kronolith::listCalendars();
- foreach ($GLOBALS['display_calendars'] as $cid) {
- $this->_currentCalendars[$cid] = &$allCalendars[$cid];
- $this->_all_day_events[$cid] = array();
- }
- } else {
- $this->_currentCalendars = array(0);
- }
-
- if ($events === null) {
- $events = Kronolith::listEvents(
- $this,
- new Horde_Date(array('year' => $this->year,
- 'month' => $this->month,
- 'mday' => $this->mday)),
- $GLOBALS['display_calendars']);
- if (is_a($events, 'PEAR_Error')) {
- $this->_events = $events;
- } else {
- $this->_events = array_shift($events);
- }
- } else {
- $this->_events = $events;
- }
-
- if (is_a($this->_events, 'PEAR_Error')) {
- $GLOBALS['notification']->push($this->_events, 'horde.error');
- $this->_events = array();
- }
- if (!is_array($this->_events)) {
- $this->_events = array();
- }
- }
-
- function setEvents($events)
- {
- $this->_events = $events;
- }
-
- function html()
- {
- global $prefs;
-
- if (!$this->_parsed) {
- $this->parse();
- }
-
- $started = false;
- $first_row = true;
- $addLinks = Kronolith::getDefaultCalendar(PERMS_EDIT) &&
- (!empty($GLOBALS['conf']['hooks']['permsdenied']) ||
- Kronolith::hasPermission('max_events') === true ||
- Kronolith::hasPermission('max_events') > Kronolith::countEvents());
- $showLocation = Kronolith::viewShowLocation();
- $showTime = Kronolith::viewShowTime();
-
- require KRONOLITH_TEMPLATES . '/day/head.inc';
- if ($this->_sidebyside) {
- require KRONOLITH_TEMPLATES . '/day/head_side_by_side.inc';
- }
- echo '<tbody>';
-
- if ($addLinks) {
- $newEventUrl = Horde_Util::addParameter(
- 'new.php',
- array('datetime' => sprintf($this->dateString() . '%02d%02d00',
- $this->slots[0]['hour'], $this->slots[0]['min']),
- 'allday' => 1,
- 'url' => $this->link(0, true)));
- $newEventUrl = Horde::link(Horde::applicationUrl($newEventUrl), _("Create a New Event"), 'hour') . _("All day") .
- Horde::img('new_small.png', '+', array('class' => 'iconAdd')) . '</a>';
- } else {
- $newEventUrl = '<span class="hour">' . _("All day") . '</span>';
- }
-
- /* The all day events are not listed in different columns, but in
- * different rows. In side by side view we do not spread an event
- * over multiple rows if there are different numbers of all day events
- * for different calendars. We just put one event in a single row
- * with no rowspan. We put in a rowspan in the row after the last
- * event to fill all remaining rows. */
- $row = '';
- $rowspan = ($this->_all_day_maxrowspan) ? ' rowspan="' . $this->_all_day_maxrowspan . '"' : '';
- for ($k = 0; $k < $this->_all_day_maxrowspan; ++$k) {
- $row = '';
- foreach ($this->_currentCalendars as $cid => $cal) {
- if (count($this->_all_day_events[$cid]) === $k) {
- // There are no events or all events for this calendar
- // have already been printed.
- $row .= '<td class="allday" width="1%" rowspan="' . ($this->_all_day_maxrowspan - $k) . '" colspan="'. $this->_span[$cid] . '"> </td>';
- } elseif (count($this->_all_day_events[$cid]) > $k) {
- // We have not printed every all day event yet. Put one
- // into this row.
- $event = $this->_all_day_events[$cid][$k];
- $row .= '<td class="day-eventbox"'
- . $event->getCSSColors()
- . 'width="' . round(90 / count($this->_currentCalendars)) . '%" '
- . 'valign="top" colspan="' . $this->_span[$cid] . '">'
- . $event->getLink($this, true, $this->link(0, true));
- if ($showLocation) {
- $row .= '<div class="event-location">' . htmlspecialchars($event->getLocation()) . '</div>';
- }
- $row .= '</td>';
- }
- }
- require KRONOLITH_TEMPLATES . '/day/all_day.inc';
- $first_row = false;
- }
-
- if ($first_row) {
- $row .= '<td colspan="' . $this->_totalspan . '" width="100%"> </td>';
- require KRONOLITH_TEMPLATES . '/day/all_day.inc';
- }
-
- $day_hour_force = $prefs->getValue('day_hour_force');
- $day_hour_start = $prefs->getValue('day_hour_start') / 2 * $this->_slotsPerHour;
- $day_hour_end = $prefs->getValue('day_hour_end') / 2 * $this->_slotsPerHour;
- $rows = array();
- $covered = array();
-
- for ($i = 0; $i < $this->_slotsPerDay; ++$i) {
- if ($i >= $day_hour_end && $i > $this->_last) {
- break;
- }
- if ($i < $this->_first && $i < $day_hour_start) {
- continue;
- }
-
- $row = '';
- if (($m = $i % $this->_slotsPerHour) != 0) {
- $time = ':' . $m * $this->_slotLength;
- $hourclass = 'halfhour';
- } else {
- $time = Kronolith_View_Day::prefHourFormat($this->slots[$i]['hour']);
- $hourclass = 'hour';
- }
-
- if (!count($this->_currentCalendars)) {
- $row .= '<td> </td>';
- }
-
- foreach ($this->_currentCalendars as $cid => $cal) {
- $hspan = 0;
- foreach ($this->_event_matrix[$cid][$i] as $key) {
- $event = &$this->_events[$key];
-
- // Since we've made sure that this event's overlap is a
- // factor of the total span, we get this event's
- // individual span by dividing the total span by this
- // event's overlap.
- $span = $this->_span[$cid] / $event->overlap;
-
- // Store the indent we're starting this event at
- // for future use.
- if (!isset($event->indent)) {
- $event->indent = $hspan;
- }
-
- // If the first node that we would cover is
- // already covered, we can assume that table
- // rendering will take care of pushing the event
- // over. However, if the first node _isn't_
- // covered but any others that we would cover
- // _are_, we only cover the available nodes.
- if (!isset($covered[$i][$event->indent])) {
- $collision = false;
- $available = 0;
- for ($y = $event->indent; $y < ($span + $event->indent); ++$y) {
- if (isset($covered[$i][$y])) {
- $collision = true;
- break;
- }
- $available++;
- }
-
- if ($collision) {
- $span = $available;
- }
- }
-
- $hspan += $span;
-
- $start = new Horde_Date(array(
- 'hour' => floor($i / $this->_slotsPerHour),
- 'min' => ($i % $this->_slotsPerHour) * $this->_slotLength,
- 'month' => $this->month,
- 'mday' => $this->mday,
- 'year' => $this->year));
- $end_slot = new Horde_Date($start);
- $end_slot->min += $this->_slotLength;
- if (((!$day_hour_force || $i >= $day_hour_start) &&
- $event->start->compareDateTime($start) >= 0 &&
- $event->start->compareDateTime($end_slot) < 0 ||
- $start->compareDateTime($this) == 0) ||
- ($day_hour_force &&
- $i == $day_hour_start &&
- $event->start->compareDateTime($start) < 0)) {
-
- // Store the nodes that we're covering for
- // this event in the coverage graph.
- for ($x = $i; $x < ($i + $event->rowspan); ++$x) {
- for ($y = $event->indent; $y < $hspan; ++$y) {
- $covered[$x][$y] = true;
- }
- }
-
- $row .= '<td class="day-eventbox"'
- . $event->getCSSColors()
- . 'width="' . round((90 / count($this->_currentCalendars)) * ($span / $this->_span[$cid])) . '%" '
- . 'valign="top" colspan="' . $span . '" rowspan="' . $event->rowspan . '">'
- . $event->getLink($this, true, $this->link(0, true));
- if ($showTime) {
- $row .= '<div class="event-time">' . htmlspecialchars($event->getTimeRange()) . '</div>';
- }
- if ($showLocation) {
- $row .= '<div class="event-location">' . htmlspecialchars($event->getLocation()) . '</div>';
- }
- $row .= '</td>';
- }
- }
-
- $diff = $this->_span[$cid] - $hspan;
- if ($diff > 0) {
- $row .= str_repeat('<td> </td>', $diff);
- }
- }
-
- if ($addLinks) {
- $newEventUrl = Horde_Util::addParameter(
- 'new.php',
- array('datetime' => sprintf($this->dateString() . '%02d%02d00',
- $this->slots[$i]['hour'], $this->slots[$i]['min']),
- 'url' => $this->link(0, true)));
- $newEventUrl = Horde::link(Horde::applicationUrl($newEventUrl), _("Create a New Event"), $hourclass) .
- $time . Horde::img('new_small.png', '+', array('class' => 'iconAdd')) . '</a>';
- } else {
- $newEventUrl = '<span class="' . $hourclass . '">' . $time . '</span>';
- }
-
- $rows[] = array('row' => $row, 'slot' => $newEventUrl);
- }
-
- $template = new Horde_Template();
- $template->set('row_height', round(20 / $this->_slotsPerHour));
- $template->set('rows', $rows);
- $template->set('show_slots', true, true);
- echo $template->fetch(KRONOLITH_TEMPLATES . '/day/rows.html')
- . '</tbody></table>';
- }
-
- /**
- * This function runs through the events and tries to figure out
- * what should be on each line of the output table. This is a
- * little tricky.
- */
- function parse()
- {
- global $prefs;
-
- $tmp = array();
- $this->_all_day_maxrowspan = 0;
- $day_hour_force = $prefs->getValue('day_hour_force');
- $day_hour_start = $prefs->getValue('day_hour_start') / 2 * $this->_slotsPerHour;
- $day_hour_end = $prefs->getValue('day_hour_end') / 2 * $this->_slotsPerHour;
-
- // Separate out all day events and do some initialization/prep
- // for parsing.
- foreach ($this->_currentCalendars as $cid => $cal) {
- $this->_all_day_events[$cid] = array();
- $this->_all_day_rowspan[$cid] = 0;
- }
-
- foreach ($this->_events as $key => $event) {
- // If we have side_by_side we only want to include the
- // event in the proper calendar.
- if ($this->_sidebyside) {
- $cid = $event->getCalendar();
- } else {
- $cid = 0;
- }
-
- // All day events are easy; store them seperately.
- if ($event->isAllDay()) {
- $this->_all_day_events[$cid][] = clone $event;
- ++$this->_all_day_rowspan[$cid];
- $this->_all_day_maxrowspan = max($this->_all_day_maxrowspan, $this->_all_day_rowspan[$cid]);
- } else {
- // Initialize the number of events that this event
- // overlaps with.
- $event->overlap = 0;
-
- // Initialize this event's vertical span.
- $event->rowspan = 0;
-
- $tmp[] = clone $event;
- }
- }
- $this->_events = $tmp;
-
- // Initialize the set of different rowspans needed.
- $spans = array(1 => true);
-
- // Track the first and last slots in which we have an event
- // (they each start at the other end of the day and move
- // towards/past each other as we find events).
- $this->_first = $this->_slotsPerDay;
- $this->_last = 0;
-
- // Run through every slot, adding in entries for every event
- // that we have here.
- for ($i = 0; $i < $this->_slotsPerDay; ++$i) {
- // Initialize this slot in the event matrix.
- foreach ($this->_currentCalendars as $cid => $cal) {
- $this->_event_matrix[$cid][$i] = array();
- }
-
- // Calculate the start and end times for this slot.
- $start = new Horde_Date(array(
- 'hour' => floor($i / $this->_slotsPerHour),
- 'min' => ($i % $this->_slotsPerHour) * $this->_slotLength,
- 'month' => $this->month,
- 'mday' => $this->mday,
- 'year' => $this->year));
- $end = clone $start;
- $end->min += $this->_slotLength;
-
- // Search through our events.
- foreach ($this->_events as $key => $event) {
- // If we have side_by_side we only want to include the
- // event in the proper calendar.
- if ($this->_sidebyside) {
- $cid = $event->getCalendar();
- } else {
- $cid = 0;
- }
-
- // If the event falls anywhere inside this slot, add
- // it, make sure other events know that they overlap
- // it, and increment the event's vertical span.
- if (($event->end->compareDateTime($start) > 0 &&
- $event->start->compareDateTime($end) < 0) ||
- ($event->end->compareDateTime($event->start) == 0 &&
- $event->start->compareDateTime($start) == 0)) {
-
- // Make sure we keep the latest hour that an event
- // reaches up-to-date.
- if ($i > $this->_last &&
- (!$day_hour_force || $i <= $day_hour_end)) {
- $this->_last = $i;
- }
-
- // Make sure we keep the first hour that an event
- // reaches up-to-date.
- if ($i < $this->_first &&
- (!$day_hour_force || $i >= $day_hour_start)) {
- $this->_first = $i;
- }
-
- if (!$day_hour_force ||
- ($i >= $day_hour_start && $i <= $day_hour_end)) {
- // Add this event to the events which are in this row.
- $this->_event_matrix[$cid][$i][] = $key;
-
- // Increment the event's vertical span.
- ++$this->_events[$key]->rowspan;
- }
- }
- }
-
- foreach (array_keys($this->_currentCalendars) as $cid) {
- // Update the number of events that events in this row
- // overlap with.
- $max = 0;
- $count = count($this->_event_matrix[$cid][$i]);
- foreach ($this->_event_matrix[$cid][$i] as $ev) {
- $this->_events[$ev]->overlap = max($this->_events[$ev]->overlap, $count);
- $max = max($max, $this->_events[$ev]->overlap);
- }
-
- // Update the set of rowspans to include the value for
- // this row.
- $spans[$cid][$max] = true;
- }
- }
-
- foreach (array_keys($this->_currentCalendars) as $cid) {
- // Sort every row by start time so that events always show
- // up here in the same order.
- for ($i = $this->_first; $i <= $this->_last; ++$i) {
- if (count($this->_event_matrix[$cid][$i])) {
- usort($this->_event_matrix[$cid][$i], array($this, '_sortByStart'));
- }
- }
-
- // Now that we have the number of events in each row, we
- // can calculate the total span needed.
- $span[$cid] = 1;
-
- // Turn keys into array values.
- $spans[$cid] = array_keys($spans[$cid]);
-
- // Start with the biggest one first.
- rsort($spans[$cid]);
- foreach ($spans[$cid] as $s) {
- // If the number of events in this row doesn't divide
- // cleanly into the current total span, we need to
- // multiply the total span by the number of events in
- // this row.
- if ($s != 0 && $span[$cid] % $s != 0) {
- $span[$cid] *= $s;
- }
- }
- $this->_totalspan += $span[$cid];
- }
- // Set the final span.
- if (isset($span)) {
- $this->_span = $span;
- } else {
- $this->_totalspan = 1;
- }
-
- // We're now parsed and ready to go.
- $this->_parsed = true;
- }
-
- function link($offset = 0, $full = false)
- {
- return Horde::applicationUrl(
- Horde_Util::addParameter('day.php', 'date', $this->getTime('%Y%m%d', $offset)),
- $full);
- }
-
- function getName()
- {
- return 'Day';
- }
-
- function prefHourFormat($hour)
- {
- $hour = $hour % 24;
- if ($GLOBALS['prefs']->getValue('twentyFour')) {
- return $hour;
- }
- return ($hour % 12 == 0 ? 12 : $hour % 12)
- . ($hour < 12 ? 'am' : 'pm');
- }
-
- function _sortByStart($evA, $evB)
- {
- $sA = $this->_events[$evA]->start;
- $sB = $this->_events[$evB]->start;
-
- return $sB->compareTime($sA);
- }
-
-}
+++ /dev/null
-<?php
-/**
- * The Kronolith_View_DeleteEvent:: class provides an API for viewing
- * event delete forms.
- *
- * @author Chuck Hagenbuch <chuck@horde.org>
- * @package Kronolith
- */
-class Kronolith_View_DeleteEvent {
-
- var $event;
-
- /**
- * @param Kronolith_Event &$event
- */
- function Kronolith_View_DeleteEvent(&$event)
- {
- $this->event =& $event;
- }
-
- function getTitle()
- {
- if (!$this->event || is_a($this->event, 'PEAR_Error')) {
- return _("Not Found");
- }
- return sprintf(_("Delete %s"), $this->event->getTitle());
- }
-
- function link()
- {
- return $this->event->getDeleteUrl();
- }
-
- function html($active = true)
- {
- if (!$this->event || is_a($this->event, 'PEAR_Error')) {
- echo '<h3>' . _("The requested event was not found.") . '</h3>';
- return;
- }
-
- if ($datetime = Horde_Util::getFormData('datetime')) {
- $datetime = new Horde_Date($datetime);
- $month = $datetime->month;
- $year = $datetime->year;
- $day = $datetime->mday;
- } else {
- $month = Horde_Util::getFormData('month', date('n'));
- $day = Horde_Util::getFormData('mday', date('j'));
- $year = Horde_Util::getFormData('year', date('Y'));
- }
-
- $url = Horde_Util::getFormData('url');
-
- echo '<div id="DeleteEvent"' . ($active ? '' : ' style="display:none"') . '>';
- if (!$this->event->recurs()) {
- require KRONOLITH_TEMPLATES . '/delete/one.inc';
- } else {
- require KRONOLITH_TEMPLATES . '/delete/delete.inc';
- }
- echo '</div>';
-
- if ($active && $GLOBALS['browser']->hasFeature('dom')) {
- if ($this->event->hasPermission(PERMS_READ)) {
- require_once KRONOLITH_BASE . '/lib/Views/Event.php';
- $view = new Kronolith_View_Event($this->event);
- $view->html(false);
- }
- if ($this->event->hasPermission(PERMS_EDIT)) {
- require_once KRONOLITH_BASE . '/lib/Views/EditEvent.php';
- $edit = new Kronolith_View_EditEvent($this->event);
- $edit->html(false);
- }
- }
- }
-
- function getName()
- {
- return 'DeleteEvent';
- }
-
-}
+++ /dev/null
-<?php
-/**
- * The Kronolith_View_EditEvent:: class provides an API for viewing
- * event edit forms.
- *
- * @author Chuck Hagenbuch <chuck@horde.org>
- * @package Kronolith
- */
-class Kronolith_View_EditEvent {
-
- var $event;
-
- /**
- * @param Kronolith_Event &$event
- */
- function Kronolith_View_EditEvent(&$event)
- {
- $this->event = &$event;
- }
-
- function getTitle()
- {
- if (!$this->event || is_a($this->event, 'PEAR_Error')) {
- return _("Not Found");
- }
- return sprintf(_("Edit %s"), $this->event->getTitle());
- }
-
- function link()
- {
- return $this->event->getEditUrl();
- }
-
- function html($active = true)
- {
- require_once 'Horde/Identity.php';
- $identity = &Identity::singleton();
-
- if (!$this->event || is_a($this->event, 'PEAR_Error')) {
- echo '<h3>' . _("The requested event was not found.") . '</h3>';
- return;
- }
-
- if ($this->event->isRemote()) {
- $calendar_id = Kronolith::getDefaultCalendar(PERMS_EDIT);
- } else {
- $calendar_id = $this->event->getCalendar();
- }
- if (!$this->event->hasPermission(PERMS_EDIT) &&
- !is_a($share = &$this->event->getShare(), 'PEAR_Error')) {
- $calendar_id .= ':' . $share->get('owner');
- }
- $_SESSION['kronolith']['attendees'] = $this->event->getAttendees();
-
- if ($datetime = Horde_Util::getFormData('datetime')) {
- $datetime = new Horde_Date($datetime);
- $month = $datetime->month;
- $year = $datetime->year;
- } else {
- $month = Horde_Util::getFormData('month', date('n'));
- $year = Horde_Util::getFormData('year', date('Y'));
- }
-
- $url = Horde_Util::getFormData('url');
- $perms = PERMS_EDIT;
- if ($this->event->getCreatorId() == Horde_Auth::getAuth()) {
- $perms |= PERMS_DELEGATE;
- }
- $calendars = Kronolith::listCalendars(false, $perms);
-
- $buttons = array();
- if (($this->event->isRemote() ||
- !$this->event->hasPermission(PERMS_EDIT)) &&
- (!empty($GLOBALS['conf']['hooks']['permsdenied']) ||
- Kronolith::hasPermission('max_events') === true ||
- Kronolith::hasPermission('max_events') > Kronolith::countEvents())) {
- $buttons[] = '<input type="submit" class="button" name="saveAsNew" value="' . _("Save As New") . '" />';
- } else {
- if (!$this->event->isRemote()) {
- $buttons[] = '<input type="submit" class="button" name="save" value="' . _("Save Event") . '" />';
- }
- if ($this->event->isInitialized()) {
- if (!$this->event->recurs() &&
- (!empty($conf['hooks']['permsdenied']) ||
- Kronolith::hasPermission('max_events') === true ||
- Kronolith::hasPermission('max_events') > Kronolith::countEvents())) {
- $buttons[] = '<input type="submit" class="button" name="saveAsNew" value="' . _("Save As New") . '" />';
- }
- }
- }
-
- if (isset($url)) {
- $cancelurl = $url;
- } else {
- $cancelurl = Horde_Util::addParameter('month.php', array('month' => $month,
- 'year', $year));
- $cancelurl = Horde::applicationUrl($cancelurl, true);
- }
-
- $event = &$this->event;
-
- // Tags
- $tagger = Kronolith::getTagger();
- $tags = $tagger->getTags($event->getUID(), 'event');
- $tags = implode(',', array_values($tags));
-
- echo '<div id="EditEvent"' . ($active ? '' : ' style="display:none"') . '>';
- require KRONOLITH_TEMPLATES . '/edit/javascript.inc';
- require KRONOLITH_TEMPLATES . '/edit/edit.inc';
- echo '</div>';
-
- if ($active && $GLOBALS['browser']->hasFeature('dom')) {
- if ($this->event->hasPermission(PERMS_READ)) {
- require_once KRONOLITH_BASE . '/lib/Views/Event.php';
- $view = new Kronolith_View_Event($this->event);
- $view->html(false);
- }
- if ($this->event->hasPermission(PERMS_DELETE)) {
- require_once KRONOLITH_BASE . '/lib/Views/DeleteEvent.php';
- $delete = new Kronolith_View_DeleteEvent($this->event);
- $delete->html(false);
- }
- }
- }
-
- function getName()
- {
- return 'EditEvent';
- }
-
-}
+++ /dev/null
-<?php
-/**
- * The Kronolith_View_Event:: class provides an API for viewing events.
- *
- * @author Chuck Hagenbuch <chuck@horde.org>
- * @package Kronolith
- */
-class Kronolith_View_Event {
-
- var $event;
-
- /**
- * @param Kronolith_Event &$event
- */
- function Kronolith_View_Event(&$event)
- {
- $this->event = &$event;
- }
-
- function getTitle()
- {
- if (!$this->event || is_a($this->event, 'PEAR_Error')) {
- return _("Not Found");
- }
- return $this->event->getTitle();
- }
-
- function link()
- {
- return $this->event->getViewUrl();
- }
-
- function html($active = true)
- {
- global $conf, $prefs;
-
- if (!$this->event || is_a($this->event, 'PEAR_Error')) {
- echo '<h3>' . _("The requested event was not found.") . '</h3>';
- return;
- }
-
- $createdby = '';
- $modifiedby = '';
- $userId = Horde_Auth::getAuth();
- if ($this->event->getUID()) {
- /* Get the event's history. */
- $history = &Horde_History::singleton();
- $log = $history->getHistory('kronolith:' . $this->event->getCalendar() . ':' .
- $this->event->getUID());
- if ($log && !is_a($log, 'PEAR_Error')) {
- foreach ($log->getData() as $entry) {
- switch ($entry['action']) {
- case 'add':
- $created = new Horde_Date($entry['ts']);
- if ($userId != $entry['who']) {
- $createdby = sprintf(_("by %s"), Kronolith::getUserName($entry['who']));
- } else {
- $createdby = _("by me");
- }
- break;
-
- case 'modify':
- $modified = new Horde_Date($entry['ts']);
- if ($userId != $entry['who']) {
- $modifiedby = sprintf(_("by %s"), Kronolith::getUserName($entry['who']));
- } else {
- $modifiedby = _("by me");
- }
- break;
- }
- }
- }
- }
-
- $creatorId = $this->event->getCreatorId();
- $description = $this->event->getDescription();
- $location = $this->event->getLocation();
- $private = $this->event->isPrivate() && $creatorId != Horde_Auth::getAuth();
- $owner = Kronolith::getUserName($creatorId);
- $status = Kronolith::statusToString($this->event->getStatus());
- $attendees = $this->event->getAttendees();
-
- if ($datetime = Horde_Util::getFormData('datetime')) {
- $datetime = new Horde_Date($datetime);
- $month = $datetime->month;
- $year = $datetime->year;
- } else {
- $month = (int)Horde_Util::getFormData('month', date('n'));
- $year = (int)Horde_Util::getFormData('year', date('Y'));
- }
-
- $dateFormat = $prefs->getValue('date_format');
- $timeFormat = $prefs->getValue('twentyFour') ? 'G:i' : 'g:ia';
-
- // Tags
- $tags = implode(', ', $this->event->tags);
-
-
- echo '<div id="Event"' . ($active ? '' : ' style="display:none"') . '>';
- require KRONOLITH_TEMPLATES . '/view/view.inc';
- echo '</div>';
-
- if ($active && $GLOBALS['browser']->hasFeature('dom')) {
- if ($this->event->hasPermission(PERMS_EDIT)) {
- require_once KRONOLITH_BASE . '/lib/Views/EditEvent.php';
- $edit = new Kronolith_View_EditEvent($this->event);
- $edit->html(false);
- }
- if ($this->event->hasPermission(PERMS_DELETE)) {
- require_once KRONOLITH_BASE . '/lib/Views/DeleteEvent.php';
- $delete = new Kronolith_View_DeleteEvent($this->event);
- $delete->html(false);
- }
- }
- }
-
- function getName()
- {
- return 'Event';
- }
-
-}
+++ /dev/null
-<?php
-/**
- * The Kronolith_View_ExportEvent:: class provides an API for exporting
- * events.
- *
- * @author Jan Schneider <chuck@horde.org>
- * @package Kronolith
- */
-class Kronolith_View_ExportEvent {
-
- /**
- * @param Kronolith_Event &$event
- */
- function Kronolith_View_ExportEvent(&$event)
- {
- $iCal = new Horde_iCalendar('2.0');
-
- if (!$event->isRemote()) {
- $share = &$GLOBALS['kronolith_shares']->getShare($event->getCalendar());
- if (!is_a($share, 'PEAR_Error')) {
- $iCal->setAttribute('X-WR-CALNAME',
- Horde_String::convertCharset($share->get('name'),
- Horde_Nls::getCharset(),
- 'utf-8'));
- }
- }
-
- $vEvent = &$event->toiCalendar($iCal);
- $iCal->addComponent($vEvent);
- $content = $iCal->exportvCalendar();
-
- $GLOBALS['browser']->downloadHeaders(
- $event->getTitle() . '.ics',
- 'text/calendar; charset=' . Horde_Nls::getCharset(),
- true, strlen($content));
- echo $content;
- exit;
- }
-
-}
+++ /dev/null
-<?php
-/**
- * The Kronolith_View_Month:: class provides an API for viewing
- * months.
- *
- * @author Chuck Hagenbuch <chuck@horde.org>
- * @author Jan Schneider <jan@horde.org>
- * @package Kronolith
- */
-class Kronolith_View_Month {
-
- /**
- * @var integer
- */
- var $month;
-
- /**
- * @var integer
- */
- var $year;
-
- /**
- * @var Horde_Date
- */
- var $date;
-
- /**
- * @var array
- */
- var $_events = array();
-
- /**
- * @var array
- */
- var $_currentCalendars = array();
-
- /**
- * @var integer
- */
- var $_daysInView;
-
- /**
- * @var integer
- */
- var $_startOfView;
-
- /**
- * @var integer
- */
- var $_startday;
-
- function Kronolith_View_Month($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::listCalendars();
- $this->_currentCalendars = array();
- foreach ($GLOBALS['display_calendars'] as $id) {
- $this->_currentCalendars[$id] = &$allCalendars[$id];
- }
- } else {
- $this->_currentCalendars = array(true);
- }
-
- $this->_events = Kronolith::listEvents($startDate, $endDate, $GLOBALS['display_calendars']);
- if (is_a($this->_events, 'PEAR_Error')) {
- $GLOBALS['notification']->push($this->_events, 'horde.error');
- $this->_events = array();
- }
- if (!is_array($this->_events)) {
- $this->_events = array();
- }
- }
-
- function html()
- {
- global $prefs;
-
- $sidebyside = $prefs->getValue('show_shared_side_by_side');
- $twentyFour = $prefs->getValue('twentyFour');
- $addLinks = Kronolith::getDefaultCalendar(PERMS_EDIT) &&
- (!empty($GLOBALS['conf']['hooks']['permsdenied']) ||
- Kronolith::hasPermission('max_events') === true ||
- Kronolith::hasPermission('max_events') > Kronolith::countEvents());
-
- if ($sidebyside) {
- require KRONOLITH_TEMPLATES . '/month/head_side_by_side.inc';
- } else {
- require KRONOLITH_TEMPLATES . '/month/head.inc';
- }
-
- $html = '';
- if (!$sidebyside && count($this->_currentCalendars)) {
- $html .= '<tr>';
- }
-
- $showLocation = Kronolith::viewShowLocation();
- $showTime = Kronolith::viewShowTime();
-
- foreach ($this->_currentCalendars as $id => $cal) {
- if ($sidebyside) {
- $html .= '<tr>';
- }
-
- $cell = 0;
- for ($day = $this->_startOfView; $day < $this->_startOfView + $this->_daysInView; ++$day) {
- $date = new Kronolith_Day($this->month, $day, $this->year);
- $date->hour = $twentyFour ? 12 : 6;
- $week = $date->weekOfYear();
-
- if ($cell % 7 == 0 && $cell != 0) {
- if ($sidebyside) {
- $html .= '<td>' . htmlspecialchars($cal->get('name')) . '</td>';
- } else {
- $html .= "</tr>\n<tr>";
- }
- }
- if ($date->isToday()) {
- $style = 'today';
- } elseif ($date->month != $this->month) {
- $style = 'othermonth';
- } elseif ($date->dayOfWeek() == 0 || $date->dayOfWeek() == 6) {
- $style = 'weekend';
- } else {
- $style = 'text';
- }
-
- $html .= '<td class="' . $style . '" height="70" width="14%" valign="top"><div>';
-
- $url = Horde_Util::addParameter(Horde::applicationUrl('day.php'),
- 'date', $date->dateString());
- $html .= '<a class="day" href="' . $url . '">' . $date->mday . '</a>';
-
- if ($addLinks) {
- $url = Horde_Util::addParameter(Horde::applicationUrl('new.php'),
- array('date' => $date->dateString(),
- 'url' => $this->link(0, true)));
- if ($sidebyside) {
- $url = Horde_Util::addParameter($url, 'calendar', $id);
- }
- $html .= Horde::link($url, _("Create a New Event"), 'newEvent') .
- Horde::img('new_small.png', '+') . '</a>';
- }
-
- if ($date->dayOfWeek() == Horde_Date::DATE_MONDAY) {
- $url = Horde_Util::addParameter('week.php', 'date', $date->dateString());
- $html .= Horde::link(Horde::applicationUrl($url), '', 'week') . sprintf(_("Week %d"), $week) . '</a>';
- }
-
- $html .= '</div><div class="clear"> </div>';
-
- $date_stamp = $date->dateString();
- if (!empty($this->_events[$date_stamp])) {
- foreach ($this->_events[$date_stamp] as $event) {
- if (!$sidebyside || $event->getCalendar() == $id) {
- $html .= '<div class="month-eventbox"' . $event->getCSSColors() . '>'
- . $event->getLink($date, true, $this->link(0, true));
- if ($showTime) {
- $html .= '<div class="event-time">' . htmlspecialchars($event->getTimeRange()) . '</div>';
- }
- if ($showLocation) {
- $html .= '<div class="event-location">' . htmlspecialchars($event->getLocation()) . '</div>';
- }
- $html .= '</div>';
- }
- }
- }
-
- $html .= "</td>\n";
- ++$cell;
- }
-
- if ($sidebyside) {
- $html .= '</tr>';
- }
- }
- if (!$sidebyside && count($this->_currentCalendars)) {
- $html .= '</tr>';
- }
-
- echo $html . '</tbody></table>';
- }
-
- function getMonth($offset = 0)
- {
- $month = new Horde_Date($this->date);
- $month->month += $offset;
- return $month;
- }
-
- function link($offset = 0, $full = false)
- {
- $month = $this->getMonth($offset);
- return Horde::applicationUrl(Horde_Util::addParameter('month.php', 'date', $month->dateString()), $full);
- }
-
- function getName()
- {
- return 'Month';
- }
-
-}
+++ /dev/null
-<?php
-/**
- * The Kronolith_View_Week:: class provides an API for viewing weeks.
- *
- * @author Chuck Hagenbuch <chuck@horde.org>
- * @author Jan Schneider <jan@horde.org>
- * @package Kronolith
- */
-class Kronolith_View_Week {
-
- var $parsed = false;
- var $days = array();
- var $week = null;
- var $year = null;
- var $startDay = null;
- var $endDay = null;
- var $startDate = null;
- var $_controller = 'week.php';
- var $_sidebyside = false;
- var $_currentCalendars = array();
-
- /**
- * How many time slots are we dividing each hour into?
- *
- * @var integer
- */
- var $_slotsPerHour = 2;
-
- /**
- * How many slots do we have per day? Calculated from $_slotsPerHour.
- *
- * @see $_slotsPerHour
- * @var integer
- */
- var $_slotsPerDay;
-
- function Kronolith_View_Week($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);
- $allevents = Kronolith::listEvents($this->startDate, $endDate, $GLOBALS['display_calendars']);
- if (is_a($allevents, 'PEAR_Error')) {
- $GLOBALS['notification']->push($allevents, 'horde.error');
- $allevents = array();
- }
- for ($i = $this->startDay; $i <= $this->endDay; ++$i) {
- $date_stamp = $this->days[$i]->dateString();
- $this->days[$i]->setEvents(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;
- }
-
- function html()
- {
- global $prefs;
-
- $more_timeslots = $prefs->getValue('time_between_days');
- $include_all_events = !$prefs->getValue('show_shared_side_by_side');
- $showLocation = Kronolith::viewShowLocation();
- $showTime = Kronolith::viewShowTime();
-
- if (!$this->parsed) {
- $this->parse();
- }
-
- $slots = $this->days[$this->startDay]->slots;
- $cid = 0;
- require KRONOLITH_TEMPLATES . '/week/head.inc';
- if ($this->_sidebyside) {
- require KRONOLITH_TEMPLATES . '/week/head_side_by_side.inc';
- }
- echo '</thead><tbody>';
-
- $event_count = 0;
- for ($j = $this->startDay; $j <= $this->endDay; ++$j) {
- foreach ($this->_currentCalendars as $cid => $cal) {
- $event_count = max($event_count, count($this->days[$j]->_all_day_events[$cid]));
- reset($this->days[$j]->_all_day_events[$cid]);
- }
- }
-
- if ($more_timeslots) {
- $newEventUrl = null;
- } else {
- $newEventUrl = _("All day");
- }
-
- $row = '';
- for ($j = $this->startDay; $j <= $this->endDay; ++$j) {
- $row .= '<td class="hour rightAlign">' . ($more_timeslots ? _("All day") : ' ') . '</td>' .
- '<td colspan="' . $this->days[$j]->_totalspan . '" valign="top"><table width="100%" cellspacing="0">';
- if ($this->days[$j]->_all_day_maxrowspan > 0) {
- for ($k = 0; $k < $this->days[$j]->_all_day_maxrowspan; ++$k) {
- $row .= '<tr>';
- foreach ($this->days[$j]->_currentCalendars as $cid => $cal) {
- if (count($this->days[$j]->_all_day_events[$cid]) === $k) {
- $row .= '<td rowspan="' . ($this->days[$j]->_all_day_maxrowspan - $k) . '" width="'. round(99 / count($this->days[$j]->_currentCalendars)) . '%"> </td>';
- } elseif (count($this->days[$j]->_all_day_events[$cid]) > $k) {
- $event = $this->days[$j]->_all_day_events[$cid][$k];
- $row .= '<td class="week-eventbox"'
- . $event->getCSSColors()
- . 'width="' . round(99 / count($this->days[$j]->_currentCalendars)) . '%" '
- . 'valign="top">'
- . $event->getLink($this->days[$j], true, $this->link(0, true));
- if ($showLocation) {
- $row .= '<div class="event-location">' . htmlspecialchars($event->getLocation()) . '</div>';
- }
- $row .= '</td>';
- }
- }
- $row .= '</tr>';
- }
- } else {
- $row .= '<tr><td colspan="' . count($this->_currentCalendars) . '"> </td></tr>';
- }
- $row .= '</table></td>';
- }
-
- $rowspan = '';
- $first_row = true;
- require KRONOLITH_TEMPLATES . '/day/all_day.inc';
-
- $day_hour_force = $prefs->getValue('day_hour_force');
- $day_hour_start = $prefs->getValue('day_hour_start') / 2 * $this->_slotsPerHour;
- $day_hour_end = $prefs->getValue('day_hour_end') / 2 * $this->_slotsPerHour;
- $rows = array();
- $covered = array();
-
- for ($i = 0; $i < $this->_slotsPerDay; ++$i) {
- if ($i >= $day_hour_end && $i > $this->last) {
- break;
- }
- if ($i < $this->first && $i < $day_hour_start) {
- continue;
- }
-
- if (($m = $i % $this->_slotsPerHour) != 0) {
- $time = ':' . $m * $this->_slotLength;
- $hourclass = 'halfhour';
- } else {
- $time = Kronolith_View_Day::prefHourFormat($slots[$i]['hour']);
- $hourclass = 'hour';
- }
-
- $row = '';
- for ($j = $this->startDay; $j <= $this->endDay; ++$j) {
- // Add spacer between days, or timeslots.
- if ($more_timeslots) {
- $row .= '<td align="right" class="' . $hourclass . '">' . $time . '</td>';
- } else {
- $row .= '<td> </td>';
- }
-
- if (!count($this->_currentCalendars)) {
- $row .= '<td> </td>';
- }
- foreach ($this->_currentCalendars as $cid => $cal) {
- $hspan = 0;
- foreach ($this->days[$j]->_event_matrix[$cid][$i] as $key) {
- $event = &$this->days[$j]->_events[$key];
- if ($include_all_events || $event->getCalendar() == $cid) {
- // Since we've made sure that this event's
- // overlap is a factor of the total span,
- // we get this event's individual span by
- // dividing the total span by this event's
- // overlap.
- $span = $this->days[$j]->_span[$cid] / $event->overlap;
-
- // Store the indent we're starting this
- // event at for future use.
- if (!isset($event->indent)) {
- $event->indent = $hspan;
- }
-
- // If the first node that we would cover
- // is already covered, we can assume that
- // table rendering will take care of
- // pushing the event over. However, if the
- // first node _isn't_ covered but any
- // others that we would covered _are_, we
- // only cover the available nodes.
- if (!isset($covered[$j][$i][$event->indent])) {
- $collision = false;
- $available = 0;
- for ($y = $event->indent; $y < ($span + $event->indent); ++$y) {
- if (isset($covered[$j][$i][$y])) {
- $collision = true;
- break;
- }
- $available++;
- }
-
- if ($collision) {
- $span = $available;
- }
- }
-
- $hspan += $span;
-
- $start = new Horde_Date(array(
- 'hour' => floor($i / $this->_slotsPerHour),
- 'min' => ($i % $this->_slotsPerHour) * $this->_slotLength,
- 'month' => $this->days[$j]->month,
- 'mday' => $this->days[$j]->mday,
- 'year' => $this->days[$j]->year));
- $slot_end = new Horde_Date($start);
- $slot_end->min += $this->_slotLength;
- if (((!$day_hour_force || $i >= $day_hour_start) &&
- $event->start->compareDateTime($start) >= 0 &&
- $event->start->compareDateTime($slot_end) < 0 ||
- $start->compareDateTime($this->days[$j]) == 0) ||
- ($day_hour_force &&
- $i == $day_hour_start)) {
-
- // Store the nodes that we're covering for
- // this event in the coverage graph.
- for ($x = $i; $x < ($i + $event->rowspan); ++$x) {
- for ($y = $event->indent; $y < $hspan; ++$y) {
- $covered[$j][$x][$y] = true;
- }
- }
-
- $row .= '<td class="week-eventbox"'
- . $event->getCSSColors()
- . 'valign="top" '
- . 'width="' . floor(((90 / count($this->days)) / count($this->_currentCalendars)) * ($span / $this->days[$j]->_span[$cid])) . '%" '
- . 'colspan="' . $span . '" rowspan="' . $event->rowspan . '">'
- . $event->getLink($this->days[$j], true, $this->link(0, true));
- if ($showTime) {
- $row .= '<div class="event-time">' . htmlspecialchars($event->getTimeRange()) . '</div>';
- }
- if ($showLocation) {
- $row .= '<div class="event-location">' . htmlspecialchars($event->getLocation()) . '</div>';
- }
- $row .= '</td>';
- }
- }
- }
-
- $diff = $this->days[$j]->_span[$cid] - $hspan;
- if ($diff > 0) {
- $row .= str_repeat('<td> </td>', $diff);
- }
- }
- }
-
- $rows[] = array('row' => $row, 'slot' => '<span class="' . $hourclass . '">' . $time . '</span>');
- }
-
- $template = new Horde_Template();
- $template->set('row_height', round(20 / $this->_slotsPerHour));
- $template->set('rows', $rows);
- $template->set('show_slots', !$more_timeslots, true);
- echo $template->fetch(KRONOLITH_TEMPLATES . '/day/rows.html')
- . '</tbody></table>';
- }
-
- /**
- * Parse all events for all of the days that we're handling; then
- * run through the results to get the total horizontal span for
- * the week, and the latest event of the week.
- */
- function parse()
- {
- for ($i = $this->startDay; $i <= $this->endDay; ++$i) {
- $this->days[$i]->parse();
- }
-
- $this->totalspan = 0;
- $this->span = array();
- for ($i = $this->startDay; $i <= $this->endDay; ++$i) {
- $this->totalspan += $this->days[$i]->_totalspan;
- foreach ($this->_currentCalendars as $cid => $key) {
- if (isset($this->span[$cid])) {
- $this->span[$cid] += $this->days[$i]->_span[$cid];
- } else {
- $this->span[$cid] = $this->days[$i]->_span[$cid];
- }
- }
- }
-
- $this->last = 0;
- $this->first = $this->_slotsPerDay;
- for ($i = $this->startDay; $i <= $this->endDay; ++$i) {
- if ($this->days[$i]->last > $this->last) {
- $this->last = $this->days[$i]->last;
- }
- if ($this->days[$i]->first < $this->first) {
- $this->first = $this->days[$i]->first;
- }
- }
- }
-
- function getWeek($offset = 0)
- {
- $week = new Horde_Date($this->startDate);
- $week->mday += $offset * 7;
- return $week;
- }
-
- function link($offset = 0, $full = false)
- {
- $week = $this->getWeek($offset);
- return Horde::applicationUrl(Horde_Util::addParameter($this->_controller,
- 'date',
- $week->dateString()),
- $full);
- }
-
- function getName()
- {
- return 'Week';
- }
-
-}
+++ /dev/null
-<?php
-/**
- * The Kronolith_View_WorkWeek:: class provides a shortcut for a week
- * view that is only Monday through Friday.
- *
- * @author Chuck Hagenbuch <chuck@horde.org>
- * @package Kronolith
- */
-class Kronolith_View_WorkWeek extends Kronolith_View_Week {
-
- var $startDay = Horde_Date::DATE_MONDAY;
- var $endDay = Horde_Date::DATE_FRIDAY;
- var $_controller = 'workweek.php';
-
- function getName()
- {
- return 'WorkWeek';
- }
-
-}
+++ /dev/null
-<?php
-/**
- * The Kronolith_View_Year:: class provides an API for viewing years.
- *
- * @author Chuck Hagenbuch <chuck@horde.org>
- * @author Jan Schneider <jan@horde.org>
- * @package Kronolith
- */
-class Kronolith_View_Year {
-
- var $year;
- var $_events = array();
-
- function Kronolith_View_Year($date)
- {
- $this->year = $date->year;
- $startDate = new Horde_Date(array('year' => $this->year,
- 'month' => 1,
- 'mday' => 1));
- $endDate = new Horde_Date(array('year' => $this->year,
- 'month' => 12,
- 'mday' => 31));
-
- $this->_events = Kronolith::listEvents($startDate, $endDate, $GLOBALS['display_calendars']);
- if (is_a($this->_events, 'PEAR_Error')) {
- $GLOBALS['notification']->push($this->_events, 'horde.error');
- $this->_events = array();
- }
- if (!is_array($this->_events)) {
- $this->_events = array();
- }
- }
-
- function html()
- {
- global $prefs;
-
- require KRONOLITH_TEMPLATES . '/year/head.inc';
-
- $html = '<table class="nopadding" cellspacing="5" width="100%"><tr>';
- for ($month = 1; $month <= 12; ++$month) {
- $html .= '<td valign="top">';
-
- // Heading for each month.
- $date = new Horde_Date(sprintf('%04d%02d01010101', $this->year, $month));
- $mtitle = $date->strftime('%B');
- $url = Horde_Util::addParameter(Horde::applicationUrl('month.php'), array('date' => $date->dateString()));
- $html .= '<h2 class="smallheader"><a class="smallheader" href="' . $url . '">' . $mtitle . '</a></h2>' .
- '<table class="nopadding monthgrid" cellspacing="0" width="100%"><thead><tr class="item">';
- if (!$prefs->getValue('week_start_monday')) {
- $html .= '<th>' . _("Su"). '</th>';
- }
- $html .= '<th>' . _("Mo") . '</th>' .
- '<th>' . _("Tu") . '</th>' .
- '<th>' . _("We") . '</th>' .
- '<th>' . _("Th") . '</th>' .
- '<th>' . _("Fr") . '</th>' .
- '<th>' . _("Sa") . '</th>';
- if ($prefs->getValue('week_start_monday')) {
- $html .= '<th>' . _("Su") . '</th>';
- }
- $html .= '</tr></thead><tbody><tr>';
-
- $startday = new Horde_Date(array('mday' => 1,
- 'month' => $month,
- 'year' => $this->year));
- $startday = $startday->dayOfWeek();
-
- $daysInView = Date_Calc::weeksInMonth($month, $this->year) * 7;
- if (!$prefs->getValue('week_start_monday')) {
- $startOfView = 1 - $startday;
-
- // We may need to adjust the number of days in the
- // view if we're starting weeks on Sunday.
- if ($startday == Horde_Date::DATE_SUNDAY) {
- $daysInView -= 7;
- }
- $endday = new Horde_Date(array('mday' => Horde_Date_Utils::daysInMonth($month, $this->year),
- 'month' => $month,
- 'year' => $this->year));
- $endday = $endday->dayOfWeek();
- if ($endday == Horde_Date::DATE_SUNDAY) {
- $daysInView += 7;
- }
- } else {
- if ($startday == Horde_Date::DATE_SUNDAY) {
- $startOfView = -5;
- } else {
- $startOfView = 2 - $startday;
- }
- }
-
- $currentCalendars = array(true);
- foreach ($currentCalendars as $id => $cal) {
- $cell = 0;
- for ($day = $startOfView; $day < $startOfView + $daysInView; ++$day) {
- $date = new Kronolith_Day($month, $day, $this->year);
- $date->hour = $prefs->getValue('twentyFour') ? 12 : 6;
- $week = $date->weekOfYear();
-
- if ($cell % 7 == 0 && $cell != 0) {
- $html .= "</tr>\n<tr>";
- }
- if ($date->month != $month) {
- $style = 'monthgrid';
- } elseif ($date->dayOfWeek() == 0 || $date->dayOfWeek() == 6) {
- $style = 'weekend';
- } else {
- $style = 'text';
- }
-
- /* Set up the link to the day view. */
- $url = Horde::applicationUrl('day.php', true);
- $url = Horde_Util::addParameter($url, 'date', $date->dateString());
-
- if ($date->month != $month) {
- $cellday = ' ';
- } elseif (!empty($this->_events[$date->dateString()])) {
- /* There are events; create a cell with tooltip to list
- * them. */
- $day_events = '';
- foreach ($this->_events[$date->dateString()] as $event) {
- if ($event->getStatus() == Kronolith::STATUS_CONFIRMED) {
- /* Set the background color to distinguish the day */
- $style = 'year-event';
- }
-
- if ($event->isAllDay()) {
- $day_events .= _("All day");
- } else {
- $day_events .= $event->start->strftime($prefs->getValue('twentyFour') ? '%R' : '%I:%M%p') . '-' . $event->end->strftime($prefs->getValue('twentyFour') ? '%R' : '%I:%M%p');
- }
- $day_events .= ':'
- . (($event->getLocation()) ? ' (' . $event->getLocation() . ')' : '')
- . ' ' . $event->getTitle() . "\n";
- }
- /* Bold the cell if there are events. */
- $cellday = '<strong>' . Horde::linkTooltip($url, _("View Day"), '', '', '', $day_events) . $date->mday . '</a></strong>';
- } else {
- /* No events, plain link to the day. */
- $cellday = Horde::linkTooltip($url, _("View Day")) . $date->mday . '</a>';
- }
- if ($date->isToday() && $date->month == $month) {
- $style .= ' today';
- }
-
- $html .= '<td align="center" class="' . $style . '" height="10" width="5%" valign="top">' .
- $cellday . '</td>';
- ++$cell;
- }
- }
-
- $html .= '</tr></tbody></table></td>';
- if ($month % 3 == 0 && $month != 12) {
- $html .= '</tr><tr>';
- }
- }
-
- echo $html . '</tr></table>';
- }
-
- function link($offset = 0, $full = false)
- {
- return Horde::applicationUrl(Horde_Util::addParameter('year.php', 'date', $this->year + $offset) . '0101', $full);
- }
-
- function getName()
- {
- return 'Year';
- }
-
-}