Version: current

      1 <?php
      2 /**
      3  * Страница событий (мероприятий)
      4  *
      5  * @author menedem
      6  *
      7  * @package event
      8  */
      9 class EventHolder extends Page {
     10
     11     static $db = array(
     12         'EventsPerPage' => 'Int',
     13         'SortType' => 'Int', // Сортировка, 1 - По дате в прямом порядке(по-умолчанию), 2 - По дате в обратном порядке
     14     );
     15
     16     static $defaults = array(
     17         'AutoChild' => 0,
     18         'SortType' => 1,
     19     );
     20
     21     static $allowed_children = array ('Event');
     22     static $subpage_children = 'Event';
     23
     24     function getSQLSort() {
     25         switch ($this->SortType) {
     26             case 1:
     27                 return "EventDate ASC";
     28             case 2:
     29                 return "EventDate DESC";
     30             default:
     31                 return "EventDate ASC";
     32         }
     33     }
     34
     35     static function getMonths() {
     36         $months = new DataObjectSet();
     37         $i = 0;
     38         foreach (array('Non', 'Jan','Feb','Mar','Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec') as $month) {
     39             $months->push(new ArrayData(array(
     40                 'Number' => $i,
     41                 'Title' => _t('EventHolder.MonthLong_'.$month, $month),
     42                 'ShortTitle' => _t('EventHolder.MonthShort_'.$month, $month)
     43             )));
     44             $i++;
     45         }
     46         return $months;
     47     }
     48
     49     static function getWeekDays() {
     50         $days = new DataObjectSet();
     51         foreach (array('Mon', 'Tue','Wen','Thu','Fri', 'Sat', 'Sun') as $day) {
     52             $days->push(new ArrayData(array(
     53                 'Title' => _t('EventHolder.WeekdayLong_'.$day, $day),
     54                 'ShortTitle' => _t('EventHolder.WeekdayShort_'.$day, $day),
     55                 'Weekend' => false,
     56                 'WorkdayOrWeekend' => 'workday'
     57             )));
     58         }
     59
     60         $sat = $days->items[5];
     61         $sat->WorkdayOrWeekend = 'weekend';
     62         $sat->Weekend = true;
     63
     64         $sun = $days->items[6];
     65         $sun->WorkdayOrWeekend = 'weekend';
     66         $sun->Weekend = true;
     67
     68         $days->replace($days->items[5], $sat);
     69         $days->replace($days->items[6], $sun);
     70
     71         return $days;
     72     }
     73
     74      /**
     75      * Возвращает предыдущую и следующую даты относительно заданной + наименования месяцов
     76      *
     77      * @param int $year
     78      * @param int $month
     79      *
     80      * @return DataObject
     81      */
     82     static function getMonthLinks($year, $month) {
     83         $navLinks = new DataObject();
     84
     85         $months = self::getMonths();
     86
     87         $nextMonth = $month + 1;
     88         $prevMonth = $month - 1;
     89         $nextYear = $year;
     90         if ($nextMonth > 12) {
     91             $nextMonth = 1;
     92             $nextYear = $year + 1;
     93         }
     94         $prevYear = $year;
     95         if ($prevMonth < 1) {
     96             $prevMonth = 12;
     97             $prevYear = $year - 1;
     98         }
     99         $nextMonth = substr('0' . $nextMonth, -2, 2);
    100         $prevMonth = substr('0' . $prevMonth, -2, 2);
    101
    102         $navLinks->nextYear = $nextYear;
    103         $navLinks->nextMonth = $nextMonth;
    104
    105         $navLinks->prevYear = $prevYear;
    106         $navLinks->prevMonth = $prevMonth;
    107
    108         $navLinks->prevTitle = $months->items[(int)$prevMonth]->Title;
    109         $navLinks->currentTitle = $months->items[(int)$month]->Title;
    110         $navLinks->nextTitle = $months->items[(int)$nextMonth]->Title;
    111
    112         return $navLinks;
    113
    114     }
    115
    116     public function getCMSFields() {
    117         $fields = parent::getCMSFields();
    118         $fields->addFieldToTab('Root.Content.Main', new TextField('EventsPerPage', $this->fieldLabel('EventsPerPage')));
    119
    120          $fields->addFieldToTab('Root.Content.Main',
    121                 new OptionsetField('SortType', $this->fieldLabel('SortType'), array(
    122                     1 => _t('NewsHolder.TYPE_SORT_ASC', "ASC"),
    123                     2 => _t('NewsHolder.TYPE_SORT_DESC', "DESC"),
    124                 ))
    125         );
    126
    127         $fields->addFieldToTab('Root.Content', new Tab('tabSubPages', _t('EventHolder.Events', 'Events')), 'Metadata');
    128
    129         $subClass = self::$subpage_children;
    130         $sp = new SubpageListField('Subpages', $this, $subClass, 'EventDate DESC');
    131         $sp->Sortable = false;
    132
    133         $url = '<a href=\"admin/show/$ID\">$value</a>';
    134
    135         $sp->setFieldFormatting(array_combine(array_keys(singleton($subClass)->summaryFields()), array_fill(0, count(singleton($subClass)->summaryFields()), $url)));
    136         $fields->addFieldToTab('Root.Content.tabSubPages', $sp);
    137
    138         return $fields;
    139     }
    140
    141
    142      /**
    143      * Возвращает недели календаря по году и месяцу
    144      *
    145      * @param int $year
    146      * @param int $month
    147      *
    148      * @return DataObjectSet
    149      */
    150     public function getWeeks($year, $month) {
    151
    152         $days = new DataObjectSet();
    153         $weeks = new DataObjectSet();
    154         $day_of_week = date("N", mktime(0,0,0,$month,1,$year));
    155         $days_of_month = date("t", strtotime($year."-".$month."-01"));
    156         $week_count = ((int) ceil(($day_of_week - 1 + $days_of_month) / 7));
    157         $days_count = $week_count * 7;
    158         $first_week = true;
    159         $last_week = false;
    160
    161         $months = self::getMonths();
    162
    163         for ($i = 1; $i <= $days_count; $i++) {
    164             $number = $i - $day_of_week + 1;
    165             if ($number <= 0) {
    166                 $number = date("t", strtotime($year."-".($month - 1)."-01")) + $number;
    167                 $right_month = $month - 1;
    168                 if ($right_month == 0) {
    169                     $right_month = 12;
    170                     $right_year = $year - 1;
    171                 } else {
    172                     $right_year = $year;
    173                 }
    174             } elseif ($number > $days_of_month) {
    175                 $number = $number - $days_of_month;
    176                 $right_month = $month + 1;
    177                 if ($right_month == 13) {
    178                     $right_month = 1;
    179                     $right_year = $year + 1;
    180                 } else {
    181                     $right_year = $year;
    182                 }
    183             } else {
    184                 $right_month = $month;
    185                 $right_year = $year;
    186             }
    187
    188             $newWeek = false;
    189             if ($i % 7 == 0) {
    190                 $newWeek = true;
    191                 $week_count--;
    192             }
    193
    194             $currentMonth = true;
    195             if ($month != $right_month) {
    196                 $currentMonth = false;
    197             }
    198
    199             $currentDay = false;
    200             if ($right_year == date('Y') && $right_month == date('m') && $number == date('d')) {
    201                 $currentDay = true;
    202             }
    203
    204             $rightDate = sprintf('%04d%02d%02d', $right_year, $right_month, $number);
    205
    206             $dateObject = new Date();
    207             $dateObject->setValue(sprintf('%04d-%02d-%02d', $right_year, $right_month, $number));
    208
    209             // !!! $dateObject->weekday() > 4 (0=Mon, ..., 6=Sat)
    210             $weekend  = (date('N', strtotime($rightDate)) >= 6);
    211
    212             $dayEventsCount = 0;
    213             if ($dayEvents = Event::get_events($rightDate, $rightDate, $this->ID)) {
    214                 $dayEventsCount = $dayEvents->Count();
    215             }
    216
    217             $days->push(new ArrayData(array(
    218                 'Date' => $dateObject,
    219                 'Title' => $months->items[(int)$right_month]->Title,
    220                 'EventCount' => $dayEventsCount,
    221                 'EventsLink' => $this->Link('/index/' . $rightDate),
    222                 'HasEvents' => ($dayEvents) ? 'hasEvents' : '',
    223                 'NewWeek' => $newWeek,
    224                 'Weekend' => $weekend,
    225                 'WorkdayOrWeekend' => ($weekend) ? 'weekend' : 'workday',
    226                 'isCurrent' => $currentDay,
    227                 'isSection' => $currentMonth,
    228                 'LinkOrCurrent' => ($currentDay) ? 'current' : 'link',
    229                 'LinkOrSection' => ($currentMonth) ? 'section' : 'link',
    230                 'LinkingMode' => ($currentDay) ? 'current' : ($currentMonth) ? 'section' : 'link'
    231
    232             )));
    233
    234             if ($newWeek) {
    235                 $weeks->push(new ArrayData(array(
    236                     'First' => $first_week,
    237                     'Last' => $last_week,
    238                     'Days' => $days
    239                 )));
    240                 $days = new DataObjectSet();
    241                 $first_week = false;
    242                 if ($week_count == 1) {
    243                     $last_week = true;
    244                 }
    245             }
    246         }
    247         return $weeks;
    248     }
    249
    250     /**
    251      * Возвращает календарь по году и месяцу со всеми необходимыми данными
    252      *
    253      * @param string $date
    254      *
    255      * @return DataObjectSet
    256      */
    257
    258     function getCalendar($date = '') {
    259         $month = date('m');
    260         $year = date('Y');
    261         if (strlen($date) >= 6) {
    262             $year = substr($date, 0, 4);
    263             $month = substr($date, 4, 2);
    264             if ((int)$year == 0 || (int)$month == 0) {
    265                 $month = date('m');
    266                 $year = date('Y');
    267             }
    268         }
    269         $navLinks = self::getMonthLinks($year, $month);
    270
    271         return $this->customise(array(
    272             'Weeks' => $this->getWeeks($year, $month),
    273             'WeekDays' => self::getWeekDays(),
    274             'PrevMonth' => array(
    275                                 'Year' => $navLinks->prevYear,
    276                                 'Month' => $navLinks->prevMonth,
    277                                 'Title' => $navLinks->prevTitle,
    278                                 'CalendarLink' => $this->Link('ShowCalendar') . '/' . $navLinks->prevYear.$navLinks->prevMonth,
    279                                 'EventsLink' => $this->URLSegment . '/index/' .  $navLinks->prevYear.$navLinks->prevMonth
    280             ),
    281             'CurrentMonth' => array(
    282                             'Year' => $year,
    283                             'Month' => $month,
    284                             'Title' => $navLinks->currentTitle,
    285                             'CalendarLink' => $this->Link('ShowCalendar') . '/' . $year.$month,
    286                             'EventsLink' => $this->URLSegment . '/index/' .  $year.$month,
    287             ),
    288             'NextMonth' => array(
    289                                 'Year' => $navLinks->nextYear,
    290                                 'Month' => $navLinks->nextMonth,
    291                                 'Title' => $navLinks->nextTitle,
    292                                 'CalendarLink' => $this->Link('ShowCalendar') . '/' . $navLinks->nextYear.$navLinks->nextMonth,
    293                                 'EventsLink' => $this->URLSegment . '/index/' .  $navLinks->nextYear.$navLinks->nextMonth
    294             )
    295
    296         ));
    297     }
    298
    299 }
    300
    301 class EventHolder_Controller extends Page_Controller {
    302     function index() {
    303         $startDate = $this->request->param('ID');
    304         $endDate = $this->request->param('OtherID');
    305
    306         //Приводим входные даты к формату /yyyymmdd/yyyymmdd
    307         $startDate = Event::parseDate($startDate);
    308         $endDate = Event::parseDate($endDate);
    309         if ($startDate->year == '0') {
    310             $startDate->year = date('Y');
    311             $endDate->year = date('Y');
    312         }
    313         if ($startDate->month == '0') {
    314             $startDate->month = date('m');
    315             $endDate->month = date('m');
    316             $endDate->day = date('t', strtotime($startDate->year."-".$startDate->month."-01"));
    317         }
    318         if ($startDate->day == '0') {
    319             $startDate->day = '01';
    320         }
    321         if (!$endDate->full_date) {
    322             if ($startDate->full_date) {
    323                 $endDate = $startDate;
    324                 $endDate->full_date = false;
    325             } else {
    326                 $endDate->year = ($endDate->year == '0') ? $startDate->year : $endDate->year;
    327                 $endDate->month = ($endDate->month == '0') ? $startDate->month : $endDate->month;
    328                 $endDate->day = ($endDate->day == '0') ? date('t', strtotime($endDate->year."-".$endDate->month."-01")) : $endDate->day;
    329             }
    330         }
    331         if (!$startDate->full_date || !$endDate->full_date) {
    332             Director::redirect($this->URLSegment . '/index/' . $startDate->year.$startDate->month.$startDate->day . '/' . $endDate->year.$endDate->month.$endDate->day);
    333         }
    334         $eventHolderID = $this->ID;
    335         $rs = Event::get_events($startDate->year.$startDate->month.$startDate->day, $endDate->year.$endDate->month.$endDate->day, $eventHolderID);
    336
    337         $start = 0;
    338         if (isset($_GET['start'])) {
    339             $start = (int)$_GET['start'];
    340         }
    341
    342         if ($rs) {
    343             $totalCount = $rs->Count();
    344             $rs->setPageLength($totalCount);
    345
    346             if ($count = $this->EventsPerPage) {
    347                 $rs = $rs->getRange($start, $count);
    348                 $rs->setPageLimits($start, $count, $totalCount);
    349             }
    350         }
    351         return $this->render(array("Events" => $rs));
    352     }
    353
    354     function FilterForm() {
    355         $startDate = $this->request->param('ID');
    356         $startDate = Event::parseDate($startDate);
    357
    358         $endDate = $this->request->param('OtherID');
    359         $endDate = Event::parseDate($endDate);
    360
    361         $fields = new FieldSet(
    362             new DateField('StartDate',_t('EventHolder.StartDate','StartDate'), $startDate->day . '.' . $startDate->month . '.' . $startDate->year),
    363             new DateField('EndDate',_t('EventHolder.EndDate','EndDate'), $endDate->day . '.' . $endDate->month . '.' . $endDate->year )
    364         );
    365         $actions = new FieldSet(new FormAction('doFilter',_t('EventHolder.Filter','Filter')));
    366         $filterForm = new Form($this, "FilterForm", $fields, $actions);
    367         $filterForm->disableSecurityToken();
    368         return $filterForm;
    369     }
    370
    371     function doFilter($data, $form) {
    372         $link = $this->URLSegment . '/index/';
    373         $startDate = '';
    374         if (isset($data['StartDate']) && strlen($data['StartDate']) == 10) {
    375             $tmp = explode('.', $data['StartDate']);
    376             $startDate = $tmp[2].$tmp[1].$tmp[0];
    377             $link .= $startDate;
    378         }
    379         $endDate = '';
    380         if (isset($data['EndDate']) && strlen($data['EndDate']) == 10) {
    381             $tmp = explode('.', $data['EndDate']);
    382             $endDate = $tmp[2].$tmp[1].$tmp[0];
    383             $link .= '/' . $endDate;
    384         }
    385         Director::redirect($link);
    386     }
    387
    388     function ShowCalendar() {
    389         $date = $this->request->param('ID');
    390         $rs = $this->getCalendar($date);
    391         return $rs->renderWith('EventCalendarWidget');
    392     }
    393
    394     function SelectDateForm() {
    395         $date = $this->request->param('ID');
    396         $date = Event::parseDate($date);
    397         $monthMap = array();
    398         $months = EventHolder::getMonths();
    399         foreach($months as $month) {
    400             if ((int)$month->Number) {
    401                 $number = ($month->Number < 10) ? "0{$month->Number}" : $month->Number;
    402                 $monthMap[$number] = $month->Title;
    403             }
    404         }
    405
    406         $yearsMap = array();
    407         if ($allEvents = Event::get_events(null, null, $this->ID)) {
    408             $allEvents->sort('EventDate');
    409             $firstYear = date('Y', strtotime($allEvents->First()->EventDate));
    410             $lastYear = date('Y', strtotime($allEvents->Last()->EventDate));
    411             for($i = $firstYear; $i <= $lastYear; $i++) {
    412                 $yearsMap[$i] = $i;
    413             }
    414         } else {
    415             $yearsMap[date('Y')] = date('Y');
    416         }
    417
    418         $fields = new FieldSet();
    419         $fields->push(new DropdownField('Month',_t('EventHolder.FilterMonth','FilterMonth'), $monthMap, $date->month));
    420         $fields->push(new DropdownField('Year',_t('EventHolder.FilterYear','FilterYear'), $yearsMap, $date->year));
    421
    422         $actions = new FieldSet(new FormAction('doSelectDate',_t('EventHolder.SelectDate','Select Date')));
    423         $filterForm = new Form($this, "SelectDateForm", $fields, $actions);
    424         $filterForm->disableSecurityToken();
    425         return $filterForm;
    426     }
    427
    428     function doSelectDate($data) {
    429         $link = $this->Link("index");
    430         if (isset($data['Year']) && ($year = (int)$data['Year'])) {
    431             $link = $this->Link("index/{$year}");
    432             if (isset($data['Month']) && ((int)$data['Month'])) {
    433                 $month = Convert::raw2sql($data['Month']);
    434                 $link = $this->Link("index/{$year}{$month}");
    435             }
    436         }
    437         return $this->redirect($link);
    438
    439
    440     }
    441 }
    442
    443

[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. -