Allow autoloading of Kronolith_View classes.
authorJan Schneider <jan@horde.org>
Wed, 29 Jul 2009 07:40:41 +0000 (09:40 +0200)
committerJan Schneider <jan@horde.org>
Wed, 29 Jul 2009 16:53:25 +0000 (18:53 +0200)
19 files changed:
kronolith/lib/Kronolith.php
kronolith/lib/View/Day.php [new file with mode: 0644]
kronolith/lib/View/DeleteEvent.php [new file with mode: 0644]
kronolith/lib/View/EditEvent.php [new file with mode: 0644]
kronolith/lib/View/Event.php [new file with mode: 0644]
kronolith/lib/View/ExportEvent.php [new file with mode: 0644]
kronolith/lib/View/Month.php [new file with mode: 0644]
kronolith/lib/View/Week.php [new file with mode: 0644]
kronolith/lib/View/WorkWeek.php [new file with mode: 0644]
kronolith/lib/View/Year.php [new file with mode: 0644]
kronolith/lib/Views/Day.php [deleted file]
kronolith/lib/Views/DeleteEvent.php [deleted file]
kronolith/lib/Views/EditEvent.php [deleted file]
kronolith/lib/Views/Event.php [deleted file]
kronolith/lib/Views/ExportEvent.php [deleted file]
kronolith/lib/Views/Month.php [deleted file]
kronolith/lib/Views/Week.php [deleted file]
kronolith/lib/Views/WorkWeek.php [deleted file]
kronolith/lib/Views/Year.php [deleted file]

index 964cb40..eecebff 100644 (file)
@@ -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 (file)
index 0000000..92791fe
--- /dev/null
@@ -0,0 +1,485 @@
+<?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] . '">&nbsp;</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%">&nbsp;</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>&nbsp;</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>&nbsp;</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);
+    }
+
+}
diff --git a/kronolith/lib/View/DeleteEvent.php b/kronolith/lib/View/DeleteEvent.php
new file mode 100644 (file)
index 0000000..9624707
--- /dev/null
@@ -0,0 +1,79 @@
+<?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';
+    }
+
+}
diff --git a/kronolith/lib/View/EditEvent.php b/kronolith/lib/View/EditEvent.php
new file mode 100644 (file)
index 0000000..0c6c6fd
--- /dev/null
@@ -0,0 +1,129 @@
+<?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';
+    }
+
+}
diff --git a/kronolith/lib/View/Event.php b/kronolith/lib/View/Event.php
new file mode 100644 (file)
index 0000000..cebe7df
--- /dev/null
@@ -0,0 +1,120 @@
+<?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';
+    }
+
+}
diff --git a/kronolith/lib/View/ExportEvent.php b/kronolith/lib/View/ExportEvent.php
new file mode 100644 (file)
index 0000000..7e46df2
--- /dev/null
@@ -0,0 +1,40 @@
+<?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;
+    }
+
+}
diff --git a/kronolith/lib/View/Month.php b/kronolith/lib/View/Month.php
new file mode 100644 (file)
index 0000000..6628300
--- /dev/null
@@ -0,0 +1,241 @@
+<?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">&nbsp;</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';
+    }
+
+}
diff --git a/kronolith/lib/View/Week.php b/kronolith/lib/View/Week.php
new file mode 100644 (file)
index 0000000..23a5710
--- /dev/null
@@ -0,0 +1,352 @@
+<?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") : '&nbsp;') . '</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)) . '%">&nbsp;</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) . '">&nbsp;</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>&nbsp;</td>';
+                }
+
+                if (!count($this->_currentCalendars)) {
+                    $row .= '<td>&nbsp;</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>&nbsp;</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';
+    }
+
+}
diff --git a/kronolith/lib/View/WorkWeek.php b/kronolith/lib/View/WorkWeek.php
new file mode 100644 (file)
index 0000000..672fcca
--- /dev/null
@@ -0,0 +1,20 @@
+<?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';
+    }
+
+}
diff --git a/kronolith/lib/View/Year.php b/kronolith/lib/View/Year.php
new file mode 100644 (file)
index 0000000..fba4ffa
--- /dev/null
@@ -0,0 +1,172 @@
+<?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 = '&nbsp;';
+                    } 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';
+    }
+
+}
diff --git a/kronolith/lib/Views/Day.php b/kronolith/lib/Views/Day.php
deleted file mode 100644 (file)
index 92791fe..0000000
+++ /dev/null
@@ -1,485 +0,0 @@
-<?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] . '">&nbsp;</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%">&nbsp;</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>&nbsp;</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>&nbsp;</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);
-    }
-
-}
diff --git a/kronolith/lib/Views/DeleteEvent.php b/kronolith/lib/Views/DeleteEvent.php
deleted file mode 100644 (file)
index 6a7cbcf..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-<?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';
-    }
-
-}
diff --git a/kronolith/lib/Views/EditEvent.php b/kronolith/lib/Views/EditEvent.php
deleted file mode 100644 (file)
index ea48df6..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-<?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';
-    }
-
-}
diff --git a/kronolith/lib/Views/Event.php b/kronolith/lib/Views/Event.php
deleted file mode 100644 (file)
index 49cf7cc..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-<?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';
-    }
-
-}
diff --git a/kronolith/lib/Views/ExportEvent.php b/kronolith/lib/Views/ExportEvent.php
deleted file mode 100644 (file)
index 7e46df2..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-<?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;
-    }
-
-}
diff --git a/kronolith/lib/Views/Month.php b/kronolith/lib/Views/Month.php
deleted file mode 100644 (file)
index 6628300..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-<?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">&nbsp;</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';
-    }
-
-}
diff --git a/kronolith/lib/Views/Week.php b/kronolith/lib/Views/Week.php
deleted file mode 100644 (file)
index 23a5710..0000000
+++ /dev/null
@@ -1,352 +0,0 @@
-<?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") : '&nbsp;') . '</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)) . '%">&nbsp;</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) . '">&nbsp;</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>&nbsp;</td>';
-                }
-
-                if (!count($this->_currentCalendars)) {
-                    $row .= '<td>&nbsp;</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>&nbsp;</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';
-    }
-
-}
diff --git a/kronolith/lib/Views/WorkWeek.php b/kronolith/lib/Views/WorkWeek.php
deleted file mode 100644 (file)
index 672fcca..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-<?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';
-    }
-
-}
diff --git a/kronolith/lib/Views/Year.php b/kronolith/lib/Views/Year.php
deleted file mode 100644 (file)
index fba4ffa..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-<?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 = '&nbsp;';
-                    } 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';
-    }
-
-}