1 <?php
2
3 class CalendarWidget extends ViewableData {
4
5 function __construct($controller, sfDate $start_date = null, $end_date = null, $default_view = false) {
6 if ($start_date === null)
7 $start_date = new sfDate();
8 if ($end_date === null || !$end_date instanceof sfDate)
9 $end_date = $start_date;
10
11 $range_start = $default_view ? "null" : "'" . $start_date->format('Y-m-d') . "'";
12 $range_end = $default_view ? "null" : "'" . $end_date->format('Y-m-d') . "'";
13 $month_view = "'" . ($start_date->format('m') - 1) . "'";
14 $year_view = "'" . $start_date->format('Y') . "'";
15
16 Requirements::customScript("
17 var controller_url_segment = '" . $controller->AbsoluteLink() . "';
18 var current_url_segment = '" . Controller::curr()->Link() . "';
19 var start_date = $range_start;
20 var end_date = $range_end;
21 var month_view = $month_view;
22 var year_view = $year_view;
23 ");
24
25 $file = _t('CalendarWidget.LOCALEFILE', 'date_en.js');
26
27 Requirements::javascript("calendar_base/javascript/locale/$file");
28 }
29
30 public function forTemplate() {
31 return $this->renderWith('CalendarWidget');
32 }
33
34 }
35
36 class MonthNavigator extends ViewableData {
37
38 public function __construct($controller, sfDate $start_date = null) {
39 if ($start_date === null)
40 $start_date = new sfDate();
41 Requirements::customScript("
42 var controller_url_segment = '" . $controller->Link() . "';
43 var current_url_segment = '" . Controller::curr()->Link() . "';
44 ");
45
46 $start = new sfDate($start_date->firstDayOfMonth()->dump());
47 $end = new sfDate($start_date->firstDayOfMonth()->dump());
48
49 $start->subtractMonth(6);
50 $end->addMonth(6);
51
52 $map = array();
53 while ($start->get() < $end->get()) {
54 $map[$start->format('Y-m')] = CalendarUtil::i18n_date("%B %Y", $start->get());
55 $start->addMonth();
56 }
57 unset($start, $end);
58
59 $this->Dropdown = new DropdownField('MonthNavigator', null, $map, $start_date->reset()->format('Y-m'));
60 }
61
62 public function forTemplate() {
63 return $this->renderWith('MonthNavigator');
64 }
65
66 }
67
68 class LiveCalendarWidget extends ViewableData {
69
70 protected $calendar;
71 protected $calendar_class;
72 protected $start_date;
73 protected $end_date;
74 protected $default_view;
75 protected $anchor_start;
76 protected $anchor_end;
77 protected $date_counter;
78 protected ;
79 protected $startDayOfMonth;
80 protected $lastDateOfMonth;
81 protected $rows;
82
83 public function __construct(Calendar $calendar, $start_date = null, $end_date = null, $default_view = false) {
84 $this->calendar = $calendar->hasMethod('getModel') ? $calendar->getModel() : $calendar;
85 $this->calendar_class = $calendar->class;
86 $this->default_view = $default_view;
87 if (is_string($start_date))
88 $this->start_date = new sfDate($start_date);
89 else if ($start_date instanceof sfDate)
90 $this->start_date = new sfDate($start_date->get());
91 else
92 $this->start_date = new sfDate();
93 $this->date_counter = new sfDate($this->start_date->get());
94 if (!Director::is_ajax())
95 $this->anchor_start = new sfDate($this->start_date->get());
96
97 if (is_string($end_date))
98 $this->end_date = new sfDate($end_date);
99 else if ($end_date instanceof sfDate)
100 $this->end_date = $end_date;
101 else
102 $this->end_date = new sfDate();
103 if (!Director::is_ajax())
104 $this->anchor_end = new sfDate($this->end_date->get());
105
106 $this->date_counter->firstDayOfMonth();
107 $this->calendarHeader = CalendarUtil::i18n_date('%B', $this->date_counter->get()) . " " . $this->date_counter->retrieve(sfTime::YEAR);
108 $this->startDayOfMonth = $this->date_counter->firstDayOfMonth()->format('N');
109 $this->lastDateOfMonth = $this->date_counter->finalDayOfMonth()->format('j');
110 $this->rows = ceil(($this->startDayOfMonth + $this->lastDateOfMonth) / 7);
111 }
112
113 public function setAnchorStart($date) {
114 $this->anchor_start = new sfDate(CalendarUtil::getDateFromString($date));
115 }
116
117 public function setAnchorEnd($date) {
118 $this->anchor_end = new sfDate(CalendarUtil::getDateFromString($date));
119 }
120
121 public function Link($action = null) {
122 if ($action === null)
123 $action = "";
124 return Director::baseURL() . "LiveCalendarWidget_Controller" . "/$action";
125 }
126
127 public function ShowMonthLink($month) {
128 $default_view = $this->default_view ? "1" : "0";
129 if ($this->anchor_start && $this->anchor_end) {
130 return $this->Link('show') . "/" . $month . "/" . $this->anchor_start->format('Ymd') . "/" . $this->anchor_end->format('Ymd') . "/" . $this->calendar->class . "/" . $this->calendar->ID . "/" . $default_view;
131 }
132 }
133
134 protected function getQuickMonthLink() {
135 $d = new sfDate();
136 return $this->calendar->AbsoluteLink() . "view/" . $d->firstDayOfMonth()->format('Ym');
137 }
138
139 protected function getQuickWeekLink() {
140 $d = new sfDate();
141 return $this->calendar->AbsoluteLink() . "view/" . $d->firstDayOfWeek()->format('Ymd') . "/" . $d->finalDayOfWeek()->format('Ymd');
142 }
143
144 protected function getQuickWeekendLink() {
145 $d = new sfDate();
146
147 if ($d->format('N') == 7)
148 $d->previousDay();
149
150 else if ($d->format('N') < 6)
151 $d->nextDay(sfTime::FRIDAY);
152
153 return $this->calendar->AbsoluteLink() . "view/" . $d->format('Ymd') . "/" . $d->addDay(2)->format('Ymd');
154 }
155
156 protected function getEventsFor($start, $end) {
157 $events = $this->calendar->Events(null, $start, $end);
158 $map = array();
159 if ($events) {
160 foreach ($events as $event) {
161 if ($event->EndDate && $event->EndDate != $event->StartDate) {
162 $current_event = new sfDate($event->StartDate);
163 while ($current_event->date() != $event->EndDate) {
164 $map[] = $current_event->date();
165 $current_event->addDay();
166 }
167 $map[] = $event->EndDate;
168 }
169 else
170 $map[] = $event->StartDate;
171 }
172 }
173 return $map;
174 }
175
176 protected function getWeeks() {
177 $weeks = new DataObjectSet();
178 $today = new sfDate();
179 $today->clearTime();
180 $this->date_counter->firstDayOfMonth()->firstDayOfWeek();
181 $view_start = new sfDate($this->date_counter->get());
182 $view_end = new sfDate($view_start->addDay($this->rows * 7)->subtractDay()->get());
183 $view_start->reset();
184 $this->start_date->reset();
185 $event_map = $this->getEventsFor($view_start, $view_end);
186
187 for ($i = 0; $i < $this->rows; $i++) {
188 $days = new DataObjectSet();
189 $week_range_start = $this->date_counter->format('Ymd');
190 for ($j = 0; $j < 7; $j++) {
191 $current_day = "";
192 if (!$this->default_view) {
193 if ($this->date_counter && $this->anchor_start && $this->anchor_end && ($this->date_counter->get() >= $this->anchor_start->get()) && ($this->date_counter->get() <= $this->anchor_end->get()))
194 $current_day = "currentDay";
195 }
196 $days->push(new ArrayData(array(
197 'Today' => $this->date_counter->get() == $today->get() ? "calendarToday" : "",
198 'OutOfMonth' => $this->date_counter->format('m') != $this->start_date->format('m') ? "calendarOutOfMonth" : "",
199 'CurrentDay' => $current_day,
200 'HasEvent' => in_array($this->date_counter->date(), $event_map) ? "hasEvent" : "",
201 'ShowDayLink' => $this->calendar->Link('view') . "/" . $this->date_counter->format('Ymd'),
202 'Events' => ($this->calendar->hasMethod('Events')) ? $this->calendar->Events(null, $this->date_counter->get(), $this->date_counter->get()) : null,
203 'Number' => $this->date_counter->format('d')
204 )));
205 $this->date_counter->addDay();
206 }
207 $week_range_end = $this->date_counter->subtractDay()->format('Ymd');
208 $this->date_counter->addDay();
209 $weeks->push(new ArrayData(array(
210 'Days' => $days,
211 'ShowWeekLink' => $this->calendar->Link('view') . "/" . $week_range_start . "/" . $week_range_end
212 )));
213 }
214 return $weeks;
215 }
216
217 protected function getNavigationOptions() {
218 $options = new DataObjectSet();
219 $counter = new sfDate($this->start_date->get());
220 $counter->subtractMonth(6);
221 for ($i = 0; $i < 12; $i++) {
222 $options->push(new ArrayData(array(
223 'Link' => $this->ShowMonthLink($counter->format('Ym')),
224 'Selected' => $this->start_date->format('Ym') == $counter->format('Ym') ? 'selected="selected"' : '',
225 'Month' => CalendarUtil::i18n_date('%B, %Y', $counter->get())
226 )));
227 $counter->addMonth();
228 }
229 unset($counter);
230 return $options;
231 }
232
233 public function forTemplate() {
234 return $this->customise(array(
235 'Weeks' => $this->getWeeks(),
236 'NavigationOptions' => $this->getNavigationOptions(),
237 'CurrentMonthLink' => $this->calendar->Link('view') . "/" . $this->start_date->format('Y-m'),
238 'PrevMonthLink' => $this->ShowMonthLink($this->start_date->subtractMonth()->format('Ym')),
239 'NextMonthLink' => $this->ShowMonthLink($this->start_date->addMonth(2)->format('Ym')),
240 'QuickMonthLink' => $this->getQuickMonthLink(),
241 'QuickWeekLink' => $this->getQuickWeekLink(),
242 'QuickWeekendLink' => $this->getQuickWeekendLink(),
243 'CalendarHeader' => $this->calendarHeader,
244 'Ajax' => Director::is_ajax(),
245 'Sun' => CalendarUtil::i18n_date('%a', $this->date_counter->previousDay(sfTIME::SUNDAY)->get()),
246 'Mon' => CalendarUtil::i18n_date('%a', $this->date_counter->addDay()->get()),
247 'Tue' => CalendarUtil::i18n_date('%a', $this->date_counter->addDay()->get()),
248 'Wed' => CalendarUtil::i18n_date('%a', $this->date_counter->addDay()->get()),
249 'Thu' => CalendarUtil::i18n_date('%a', $this->date_counter->addDay()->get()),
250 'Fri' => CalendarUtil::i18n_date('%a', $this->date_counter->addDay()->get()),
251 'Sat' => CalendarUtil::i18n_date('%a', $this->date_counter->addDay()->get())
252 ))->renderWith('LiveCalendarWidget');
253 }
254
255 }
256
257 class LiveCalendarWidget_Controller extends Controller {
258
259 static $url_handlers = array(
260 'show/$CurrentMonth/$AnchorStart/$AnchorEnd/$CalendarClass/$CalendarID/$DefaultView' => 'handleShow'
261 );
262
263 public function handleShow($request) {
264 $calendar = DataObject::get_by_id($request->param('CalendarClass'), $request->param('CalendarID'));
265 if ($calendar) {
266 $default_view = $request->param('DefaultView') == "1";
267 $c = new LiveCalendarWidget(
268 $calendar,
269 new sfDate(CalendarUtil::getDateFromString($request->param('CurrentMonth'))),
270 null,
271 $default_view
272 );
273 $c->setAnchorStart($request->param('AnchorStart'));
274 $c->setAnchorEnd($request->param('AnchorEnd'));
275 echo $c->forTemplate();
276 }
277 else
278 return false;
279 }
280
281 }
282 ?>
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the
Silverstripe Forums to ask development related questions.
-