Version: current

      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 $calendarHeader;
     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         // Saturday? Dial back to Friday
    147         if ($d->format('N') == 7)
    148             $d->previousDay();
    149         // Before Friday? Advance. Otherwise, it's Friday, so leave it alone.
    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. -