From: Jan Schneider Date: Wed, 29 Jul 2009 07:40:41 +0000 (+0200) Subject: Allow autoloading of Kronolith_View classes. X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=87077bc57ebac466431554555675917990bc4289;p=horde.git Allow autoloading of Kronolith_View classes. --- diff --git a/kronolith/lib/Kronolith.php b/kronolith/lib/Kronolith.php index 964cb408d..eecebff1f 100644 --- a/kronolith/lib/Kronolith.php +++ b/kronolith/lib/Kronolith.php @@ -1988,13 +1988,10 @@ class Kronolith 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')); @@ -2012,8 +2009,6 @@ class Kronolith 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')); @@ -2029,8 +2024,6 @@ class Kronolith 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') && @@ -2041,8 +2034,6 @@ class Kronolith 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')); diff --git a/kronolith/lib/View/Day.php b/kronolith/lib/View/Day.php new file mode 100644 index 000000000..92791fedb --- /dev/null +++ b/kronolith/lib/View/Day.php @@ -0,0 +1,485 @@ + + * @author Jan Schneider + * @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 ''; + + 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')) . ''; + } else { + $newEventUrl = '' . _("All day") . ''; + } + + /* 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 .= ' '; + } 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 .= 'getCSSColors() + . 'width="' . round(90 / count($this->_currentCalendars)) . '%" ' + . 'valign="top" colspan="' . $this->_span[$cid] . '">' + . $event->getLink($this, true, $this->link(0, true)); + if ($showLocation) { + $row .= '
' . htmlspecialchars($event->getLocation()) . '
'; + } + $row .= ''; + } + } + require KRONOLITH_TEMPLATES . '/day/all_day.inc'; + $first_row = false; + } + + if ($first_row) { + $row .= ' '; + 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 .= ' '; + } + + 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 .= '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 .= '
' . htmlspecialchars($event->getTimeRange()) . '
'; + } + if ($showLocation) { + $row .= '
' . htmlspecialchars($event->getLocation()) . '
'; + } + $row .= ''; + } + } + + $diff = $this->_span[$cid] - $hspan; + if ($diff > 0) { + $row .= str_repeat(' ', $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')) . ''; + } else { + $newEventUrl = '' . $time . ''; + } + + $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') + . ''; + } + + /** + * 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); + } + +} diff --git a/kronolith/lib/View/DeleteEvent.php b/kronolith/lib/View/DeleteEvent.php new file mode 100644 index 000000000..9624707eb --- /dev/null +++ b/kronolith/lib/View/DeleteEvent.php @@ -0,0 +1,79 @@ + + * @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 '

' . _("The requested event was not found.") . '

'; + 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 ''; + + 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'; + } + +} diff --git a/kronolith/lib/View/EditEvent.php b/kronolith/lib/View/EditEvent.php new file mode 100644 index 000000000..0c6c6fda9 --- /dev/null +++ b/kronolith/lib/View/EditEvent.php @@ -0,0 +1,129 @@ + + * @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 '

' . _("The requested event was not found.") . '

'; + 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[] = ''; + } else { + if (!$this->event->isRemote()) { + $buttons[] = ''; + } + if ($this->event->isInitialized()) { + if (!$this->event->recurs() && + (!empty($conf['hooks']['permsdenied']) || + Kronolith::hasPermission('max_events') === true || + Kronolith::hasPermission('max_events') > Kronolith::countEvents())) { + $buttons[] = ''; + } + } + } + + 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 ''; + + 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'; + } + +} diff --git a/kronolith/lib/View/Event.php b/kronolith/lib/View/Event.php new file mode 100644 index 000000000..cebe7df2e --- /dev/null +++ b/kronolith/lib/View/Event.php @@ -0,0 +1,120 @@ + + * @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 '

' . _("The requested event was not found.") . '

'; + 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 ''; + + 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'; + } + +} diff --git a/kronolith/lib/View/ExportEvent.php b/kronolith/lib/View/ExportEvent.php new file mode 100644 index 000000000..7e46df20e --- /dev/null +++ b/kronolith/lib/View/ExportEvent.php @@ -0,0 +1,40 @@ + + * @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; + } + +} diff --git a/kronolith/lib/View/Month.php b/kronolith/lib/View/Month.php new file mode 100644 index 000000000..6628300b8 --- /dev/null +++ b/kronolith/lib/View/Month.php @@ -0,0 +1,241 @@ + + * @author Jan Schneider + * @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 .= ''; + } + + $showLocation = Kronolith::viewShowLocation(); + $showTime = Kronolith::viewShowTime(); + + foreach ($this->_currentCalendars as $id => $cal) { + if ($sidebyside) { + $html .= ''; + } + + $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 .= '' . htmlspecialchars($cal->get('name')) . ''; + } else { + $html .= "\n"; + } + } + 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 .= '
'; + + $url = Horde_Util::addParameter(Horde::applicationUrl('day.php'), + 'date', $date->dateString()); + $html .= '' . $date->mday . ''; + + 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', '+') . ''; + } + + 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) . ''; + } + + $html .= '
 
'; + + $date_stamp = $date->dateString(); + if (!empty($this->_events[$date_stamp])) { + foreach ($this->_events[$date_stamp] as $event) { + if (!$sidebyside || $event->getCalendar() == $id) { + $html .= '
getCSSColors() . '>' + . $event->getLink($date, true, $this->link(0, true)); + if ($showTime) { + $html .= '
' . htmlspecialchars($event->getTimeRange()) . '
'; + } + if ($showLocation) { + $html .= '
' . htmlspecialchars($event->getLocation()) . '
'; + } + $html .= '
'; + } + } + } + + $html .= "\n"; + ++$cell; + } + + if ($sidebyside) { + $html .= ''; + } + } + if (!$sidebyside && count($this->_currentCalendars)) { + $html .= ''; + } + + echo $html . ''; + } + + 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'; + } + +} diff --git a/kronolith/lib/View/Week.php b/kronolith/lib/View/Week.php new file mode 100644 index 000000000..23a57100d --- /dev/null +++ b/kronolith/lib/View/Week.php @@ -0,0 +1,352 @@ + + * @author Jan Schneider + * @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 ''; + + $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 .= '' . ($more_timeslots ? _("All day") : ' ') . '' . + ''; + if ($this->days[$j]->_all_day_maxrowspan > 0) { + for ($k = 0; $k < $this->days[$j]->_all_day_maxrowspan; ++$k) { + $row .= ''; + foreach ($this->days[$j]->_currentCalendars as $cid => $cal) { + if (count($this->days[$j]->_all_day_events[$cid]) === $k) { + $row .= ''; + } elseif (count($this->days[$j]->_all_day_events[$cid]) > $k) { + $event = $this->days[$j]->_all_day_events[$cid][$k]; + $row .= ''; + } + } + $row .= ''; + } + } else { + $row .= ''; + } + $row .= '
 getCSSColors() + . 'width="' . round(99 / count($this->days[$j]->_currentCalendars)) . '%" ' + . 'valign="top">' + . $event->getLink($this->days[$j], true, $this->link(0, true)); + if ($showLocation) { + $row .= '
' . htmlspecialchars($event->getLocation()) . '
'; + } + $row .= '
 
'; + } + + $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 .= '' . $time . ''; + } else { + $row .= ' '; + } + + if (!count($this->_currentCalendars)) { + $row .= ' '; + } + 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 .= '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 .= '
' . htmlspecialchars($event->getTimeRange()) . '
'; + } + if ($showLocation) { + $row .= '
' . htmlspecialchars($event->getLocation()) . '
'; + } + $row .= ''; + } + } + } + + $diff = $this->days[$j]->_span[$cid] - $hspan; + if ($diff > 0) { + $row .= str_repeat(' ', $diff); + } + } + } + + $rows[] = array('row' => $row, 'slot' => '' . $time . ''); + } + + $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') + . ''; + } + + /** + * 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'; + } + +} diff --git a/kronolith/lib/View/WorkWeek.php b/kronolith/lib/View/WorkWeek.php new file mode 100644 index 000000000..672fccad5 --- /dev/null +++ b/kronolith/lib/View/WorkWeek.php @@ -0,0 +1,20 @@ + + * @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'; + } + +} diff --git a/kronolith/lib/View/Year.php b/kronolith/lib/View/Year.php new file mode 100644 index 000000000..fba4ffa1d --- /dev/null +++ b/kronolith/lib/View/Year.php @@ -0,0 +1,172 @@ + + * @author Jan Schneider + * @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 = ''; + for ($month = 1; $month <= 12; ++$month) { + $html .= ''; + if ($month % 3 == 0 && $month != 12) { + $html .= ''; + } + } + + echo $html . '
'; + + // 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 .= '

' . $mtitle . '

' . + ''; + if (!$prefs->getValue('week_start_monday')) { + $html .= ''; + } + $html .= '' . + '' . + '' . + '' . + '' . + ''; + if ($prefs->getValue('week_start_monday')) { + $html .= ''; + } + $html .= ''; + + $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 .= "\n"; + } + 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 = '' . Horde::linkTooltip($url, _("View Day"), '', '', '', $day_events) . $date->mday . ''; + } else { + /* No events, plain link to the day. */ + $cellday = Horde::linkTooltip($url, _("View Day")) . $date->mday . ''; + } + if ($date->isToday() && $date->month == $month) { + $style .= ' today'; + } + + $html .= ''; + ++$cell; + } + } + + $html .= '
' . _("Su"). '' . _("Mo") . '' . _("Tu") . '' . _("We") . '' . _("Th") . '' . _("Fr") . '' . _("Sa") . '' . _("Su") . '
' . + $cellday . '
'; + } + + function link($offset = 0, $full = false) + { + return Horde::applicationUrl(Horde_Util::addParameter('year.php', 'date', $this->year + $offset) . '0101', $full); + } + + function getName() + { + return 'Year'; + } + +} diff --git a/kronolith/lib/Views/Day.php b/kronolith/lib/Views/Day.php deleted file mode 100644 index 92791fedb..000000000 --- a/kronolith/lib/Views/Day.php +++ /dev/null @@ -1,485 +0,0 @@ - - * @author Jan Schneider - * @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 ''; - - 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')) . ''; - } else { - $newEventUrl = '' . _("All day") . ''; - } - - /* 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 .= ' '; - } 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 .= 'getCSSColors() - . 'width="' . round(90 / count($this->_currentCalendars)) . '%" ' - . 'valign="top" colspan="' . $this->_span[$cid] . '">' - . $event->getLink($this, true, $this->link(0, true)); - if ($showLocation) { - $row .= '
' . htmlspecialchars($event->getLocation()) . '
'; - } - $row .= ''; - } - } - require KRONOLITH_TEMPLATES . '/day/all_day.inc'; - $first_row = false; - } - - if ($first_row) { - $row .= ' '; - 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 .= ' '; - } - - 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 .= '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 .= '
' . htmlspecialchars($event->getTimeRange()) . '
'; - } - if ($showLocation) { - $row .= '
' . htmlspecialchars($event->getLocation()) . '
'; - } - $row .= ''; - } - } - - $diff = $this->_span[$cid] - $hspan; - if ($diff > 0) { - $row .= str_repeat(' ', $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')) . ''; - } else { - $newEventUrl = '' . $time . ''; - } - - $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') - . ''; - } - - /** - * 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); - } - -} diff --git a/kronolith/lib/Views/DeleteEvent.php b/kronolith/lib/Views/DeleteEvent.php deleted file mode 100644 index 6a7cbcf1d..000000000 --- a/kronolith/lib/Views/DeleteEvent.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @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 '

' . _("The requested event was not found.") . '

'; - 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 ''; - - 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'; - } - -} diff --git a/kronolith/lib/Views/EditEvent.php b/kronolith/lib/Views/EditEvent.php deleted file mode 100644 index ea48df665..000000000 --- a/kronolith/lib/Views/EditEvent.php +++ /dev/null @@ -1,131 +0,0 @@ - - * @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 '

' . _("The requested event was not found.") . '

'; - 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[] = ''; - } else { - if (!$this->event->isRemote()) { - $buttons[] = ''; - } - if ($this->event->isInitialized()) { - if (!$this->event->recurs() && - (!empty($conf['hooks']['permsdenied']) || - Kronolith::hasPermission('max_events') === true || - Kronolith::hasPermission('max_events') > Kronolith::countEvents())) { - $buttons[] = ''; - } - } - } - - 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 ''; - - 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'; - } - -} diff --git a/kronolith/lib/Views/Event.php b/kronolith/lib/Views/Event.php deleted file mode 100644 index 49cf7cc50..000000000 --- a/kronolith/lib/Views/Event.php +++ /dev/null @@ -1,122 +0,0 @@ - - * @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 '

' . _("The requested event was not found.") . '

'; - 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 ''; - - 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'; - } - -} diff --git a/kronolith/lib/Views/ExportEvent.php b/kronolith/lib/Views/ExportEvent.php deleted file mode 100644 index 7e46df20e..000000000 --- a/kronolith/lib/Views/ExportEvent.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @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; - } - -} diff --git a/kronolith/lib/Views/Month.php b/kronolith/lib/Views/Month.php deleted file mode 100644 index 6628300b8..000000000 --- a/kronolith/lib/Views/Month.php +++ /dev/null @@ -1,241 +0,0 @@ - - * @author Jan Schneider - * @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 .= ''; - } - - $showLocation = Kronolith::viewShowLocation(); - $showTime = Kronolith::viewShowTime(); - - foreach ($this->_currentCalendars as $id => $cal) { - if ($sidebyside) { - $html .= ''; - } - - $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 .= '' . htmlspecialchars($cal->get('name')) . ''; - } else { - $html .= "\n"; - } - } - 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 .= '
'; - - $url = Horde_Util::addParameter(Horde::applicationUrl('day.php'), - 'date', $date->dateString()); - $html .= '' . $date->mday . ''; - - 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', '+') . ''; - } - - 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) . ''; - } - - $html .= '
 
'; - - $date_stamp = $date->dateString(); - if (!empty($this->_events[$date_stamp])) { - foreach ($this->_events[$date_stamp] as $event) { - if (!$sidebyside || $event->getCalendar() == $id) { - $html .= '
getCSSColors() . '>' - . $event->getLink($date, true, $this->link(0, true)); - if ($showTime) { - $html .= '
' . htmlspecialchars($event->getTimeRange()) . '
'; - } - if ($showLocation) { - $html .= '
' . htmlspecialchars($event->getLocation()) . '
'; - } - $html .= '
'; - } - } - } - - $html .= "\n"; - ++$cell; - } - - if ($sidebyside) { - $html .= ''; - } - } - if (!$sidebyside && count($this->_currentCalendars)) { - $html .= ''; - } - - echo $html . ''; - } - - 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'; - } - -} diff --git a/kronolith/lib/Views/Week.php b/kronolith/lib/Views/Week.php deleted file mode 100644 index 23a57100d..000000000 --- a/kronolith/lib/Views/Week.php +++ /dev/null @@ -1,352 +0,0 @@ - - * @author Jan Schneider - * @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 ''; - - $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 .= '' . ($more_timeslots ? _("All day") : ' ') . '' . - ''; - if ($this->days[$j]->_all_day_maxrowspan > 0) { - for ($k = 0; $k < $this->days[$j]->_all_day_maxrowspan; ++$k) { - $row .= ''; - foreach ($this->days[$j]->_currentCalendars as $cid => $cal) { - if (count($this->days[$j]->_all_day_events[$cid]) === $k) { - $row .= ''; - } elseif (count($this->days[$j]->_all_day_events[$cid]) > $k) { - $event = $this->days[$j]->_all_day_events[$cid][$k]; - $row .= ''; - } - } - $row .= ''; - } - } else { - $row .= ''; - } - $row .= '
 getCSSColors() - . 'width="' . round(99 / count($this->days[$j]->_currentCalendars)) . '%" ' - . 'valign="top">' - . $event->getLink($this->days[$j], true, $this->link(0, true)); - if ($showLocation) { - $row .= '
' . htmlspecialchars($event->getLocation()) . '
'; - } - $row .= '
 
'; - } - - $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 .= '' . $time . ''; - } else { - $row .= ' '; - } - - if (!count($this->_currentCalendars)) { - $row .= ' '; - } - 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 .= '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 .= '
' . htmlspecialchars($event->getTimeRange()) . '
'; - } - if ($showLocation) { - $row .= '
' . htmlspecialchars($event->getLocation()) . '
'; - } - $row .= ''; - } - } - } - - $diff = $this->days[$j]->_span[$cid] - $hspan; - if ($diff > 0) { - $row .= str_repeat(' ', $diff); - } - } - } - - $rows[] = array('row' => $row, 'slot' => '' . $time . ''); - } - - $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') - . ''; - } - - /** - * 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'; - } - -} diff --git a/kronolith/lib/Views/WorkWeek.php b/kronolith/lib/Views/WorkWeek.php deleted file mode 100644 index 672fccad5..000000000 --- a/kronolith/lib/Views/WorkWeek.php +++ /dev/null @@ -1,20 +0,0 @@ - - * @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'; - } - -} diff --git a/kronolith/lib/Views/Year.php b/kronolith/lib/Views/Year.php deleted file mode 100644 index fba4ffa1d..000000000 --- a/kronolith/lib/Views/Year.php +++ /dev/null @@ -1,172 +0,0 @@ - - * @author Jan Schneider - * @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 = ''; - for ($month = 1; $month <= 12; ++$month) { - $html .= ''; - if ($month % 3 == 0 && $month != 12) { - $html .= ''; - } - } - - echo $html . '
'; - - // 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 .= '

' . $mtitle . '

' . - ''; - if (!$prefs->getValue('week_start_monday')) { - $html .= ''; - } - $html .= '' . - '' . - '' . - '' . - '' . - ''; - if ($prefs->getValue('week_start_monday')) { - $html .= ''; - } - $html .= ''; - - $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 .= "\n"; - } - 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 = '' . Horde::linkTooltip($url, _("View Day"), '', '', '', $day_events) . $date->mday . ''; - } else { - /* No events, plain link to the day. */ - $cellday = Horde::linkTooltip($url, _("View Day")) . $date->mday . ''; - } - if ($date->isToday() && $date->month == $month) { - $style .= ' today'; - } - - $html .= ''; - ++$cell; - } - } - - $html .= '
' . _("Su"). '' . _("Mo") . '' . _("Tu") . '' . _("We") . '' . _("Th") . '' . _("Fr") . '' . _("Sa") . '' . _("Su") . '
' . - $cellday . '
'; - } - - function link($offset = 0, $full = false) - { - return Horde::applicationUrl(Horde_Util::addParameter('year.php', 'date', $this->year + $offset) . '0101', $full); - } - - function getName() - { - return 'Year'; - } - -}