1<?php
2/**
3 * Display a mini month view of calendar items.
4 */
5class Kronolith_Block_Month extends Horde_Core_Block
6{
7    /**
8     */
9    public function __construct($app, $params = array())
10    {
11        parent::__construct($app, $params);
12
13        $this->_name = _("This Month");
14    }
15
16    /**
17     */
18    protected function _params()
19    {
20        $params = array(
21            'calendar' => array(
22                'name' => _("Calendar"),
23                'type' => 'enum',
24                'default' => '__all'
25            )
26        );
27
28        $params['calendar']['values']['__all'] = _("All Visible");
29        foreach (Kronolith::listCalendars(Horde_Perms::SHOW, true) as $id => $cal) {
30            $params['calendar']['values'][$id] = $cal->name();
31        }
32
33        return $params;
34    }
35
36    /**
37     */
38    protected function _title()
39    {
40        $title = _("All Calendars");
41        $url = Horde::url($GLOBALS['registry']->getInitialPage(), true);
42        if (isset($this->_params['calendar']) &&
43            $this->_params['calendar'] != '__all') {
44            $calendars = Kronolith::listCalendars();
45            if (isset($calendars[$this->_params['calendar']])) {
46                $title = htmlspecialchars($calendars[$this->_params['calendar']]->name());
47            } else {
48                $title = _("Calendar not found");
49            }
50            $url->add('display_cal', $this->_params['calendar']);
51        }
52        $date = new Horde_Date(time());
53
54        return $title . ', ' . $url->link() . $date->strftime('%B, %Y') . '</a>';
55    }
56
57    /**
58     */
59    protected function _content()
60    {
61        global $prefs;
62
63        if (isset($this->_params['calendar']) &&
64            $this->_params['calendar'] != '__all') {
65            $calendars = Kronolith::listCalendars();
66            if (!isset($calendars[$this->_params['calendar']])) {
67                return _("Calendar not found");
68            }
69            if (!$calendars[$this->_params['calendar']]->hasPermission(Horde_Perms::READ)) {
70                return _("Permission Denied");
71            }
72        }
73
74        $year = date('Y');
75        $month = date('m');
76        $startday = new Horde_Date(array('mday' => 1,
77                                         'month' => $month,
78                                         'year' => $year));
79        $startday = $startday->dayOfWeek();
80        $daysInView = Date_Calc::weeksInMonth($month, $year) * 7;
81        if (!$prefs->getValue('week_start_monday')) {
82            $startOfView = 1 - $startday;
83
84            // We may need to adjust the number of days in the view if
85            // we're starting weeks on Sunday.
86            if ($startday == Horde_Date::DATE_SUNDAY) {
87                $daysInView -= 7;
88            }
89            $endday = new Horde_Date(array('mday' => Horde_Date_Utils::daysInMonth($month, $year),
90                                           'month' => $month,
91                                           'year' => $year));
92            $endday = $endday->dayOfWeek();
93            if ($endday == Horde_Date::DATE_SUNDAY) {
94                $daysInView += 7;
95            }
96        } else {
97            if ($startday == Horde_Date::DATE_SUNDAY) {
98                $startOfView = -5;
99            } else {
100                $startOfView = 2 - $startday;
101            }
102        }
103
104        $startDate = new Horde_Date(array('year' => $year, 'month' => $month, 'mday' => $startOfView));
105        $endDate = new Horde_Date(array('year' => $year, 'month' => $month, 'mday' => $startOfView + $daysInView,
106                                        'hour' => 23, 'min' => 59, 'sec' => 59));
107
108        /* Table start. and current month indicator. */
109        $html = '<table cellspacing="1" class="monthgrid" width="100%"><tr>';
110
111        /* Set up the weekdays. */
112        $weekdays = array(_("Mo"), _("Tu"), _("We"), _("Th"), _("Fr"), _("Sa"));
113        if (!$prefs->getValue('week_start_monday')) {
114            array_unshift($weekdays, _("Su"));
115        } else {
116            $weekdays[] = _("Su");
117        }
118        foreach ($weekdays as $weekday) {
119            $html .= '<th class="item">' . $weekday . '</th>';
120        }
121
122        try {
123            if (isset($this->_params['calendar']) &&
124                $this->_params['calendar'] != '__all') {
125                list($type, $calendar) = explode('_', $this->_params['calendar'], 2);
126                $driver = Kronolith::getDriver($type, $calendar);
127                $all_events = $driver->listEvents($startDate, $endDate, array(
128                    'show_recurrence' => true));
129            } else {
130                $all_events = Kronolith::listEvents($startDate, $endDate, $GLOBALS['calendar_manager']->get(Kronolith::DISPLAY_CALENDARS));
131            }
132        } catch (Exception $e) {
133            return '<em>' . $e->getMessage() . '</em>';
134        }
135
136        $weekday = 0;
137        $week = -1;
138        for ($day = $startOfView; $day < $startOfView + $daysInView; ++$day) {
139            if ($weekday == 7) {
140                $weekday = 0;
141            }
142            if ($weekday == 0) {
143                ++$week;
144                $html .= '</tr><tr>';
145            }
146
147            $date_ob = new Kronolith_Day($month, $day, $year);
148            if ($date_ob->isToday()) {
149                $td_class = 'kronolith-today';
150            } elseif ($date_ob->month != $month) {
151                $td_class = 'kronolith-othermonth';
152            } elseif ($date_ob->dayOfWeek() == 0 || $date_ob->dayOfWeek() == 6) {
153                $td_class = 'kronolith-weekend';
154            } else {
155                $td_class = '';
156            }
157            $html .= '<td align="center" class="' . $td_class . '">';
158
159            /* Set up the link to the day view. */
160            $url = Horde::url('day.php', true)
161                ->add('date', $date_ob->dateString());
162            if (isset($this->_params['calendar']) &&
163                $this->_params['calendar'] != '__all') {
164                $url->add('display_cal', $this->_params['calendar']);
165            }
166
167            $date_stamp = $date_ob->dateString();
168            if (empty($all_events[$date_stamp])) {
169                /* No events, plain link to the day. */
170                $cell = Horde::linkTooltip($url, _("View Day")) . $date_ob->mday . '</a>';
171            } else {
172                /* There are events; create a cell with tooltip to
173                 * list them. */
174                $day_events = '';
175                foreach ($all_events[$date_stamp] as $event) {
176                    if ($event->isAllDay()) {
177                        $day_events .= _("All day");
178                    } else {
179                        $day_events .= $event->start->strftime($prefs->getValue('twentyFour') ? '%R' : '%I:%M%p') . '-' . $event->end->strftime($prefs->getValue('twentyFour') ? '%R' : '%I:%M%p');
180                    }
181                    $location = $event->getLocation();
182                    $day_events .= ':'
183                        . ($location ? ' (' . htmlspecialchars($location) . ')' : '')
184                        . ' ' . $event->getTitle() . "\n";
185                }
186                $cell = Horde::linkTooltip($url, _("View Day"), '', '', '', $day_events) . $date_ob->mday . '</a>';
187            }
188
189            /* Bold the cell if there are events. */
190            if (!empty($all_events[$date_stamp])) {
191                $cell = '<strong>' . $cell . '</strong>';
192            }
193
194            $html .= $cell . '</td>';
195            ++$weekday;
196        }
197
198        return $html . '</tr></table>';
199    }
200
201}
202