Source of file YearCalendarPage.php
Size: 12,405 Bytes - Last Modified: 2021-12-23T10:04:07+00:00
/var/www/docs.ssmods.com/process/src/code/pages/YearCalendarPage.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490 | <?php /** * Class YearCalendarPage * */ class YearCalendarPage extends Page { /** * Current month * * @var string */ protected $month; /** * Current year * * @var string */ protected $year; /** * Current archive * * @var string */ protected $archive; /** * @inheritdoc */ private static $db = [ 'Template' => 'Enum("YearCalendar, EventList", "YearCalendar")', ]; /** * @inheritdoc */ private static $many_many = [ 'Tags' => 'YearCalendarItemTag', ]; /** * Flag: are the front-end scripts loaded * * @var bool */ protected static $frontendLoaded = false; /** * @inheritdoc */ public function getCMSFields() { $fields = parent::getCMSFields(); $fields->removeByName([ 'Tags', ]); $fields->insertBefore( 'Content', TagField::create( 'Tags', _t('YearCalendar.Tags', 'Tags'), YearCalendarItemTag::get(), $this->Tags() ) ->setCanCreate(false) ->setShouldLazyLoad(true) ); $fields->insertAfter( 'Tags', DropdownField::create( 'Template', _t('YearCalendarPage.db_Template', 'Template'), $this->dbObject('Template') ->enumValues(), $this->Template ) ); $this->extend('modifyCMSFields', $fields); return $fields; } /** * Retrieve all YearCalendarItems as a calendar * * @return \ArrayData */ public function YearCalendarItems() { $start = new DateTimeHelper(sprintf('%1$s-%2$s-01', $this->year, $this->month)); $start->setTimeToDayStart(); $end = clone $start; $end->modify('last day of this month'); $end->setTimeToDayEnd(); $items = YearCalendarItem::get() ->whereAny( [ '"YearCalendarItem"."From" < ? AND "YearCalendarItem"."To" > ?' => [$start->getSqlDateTime(), $start->getSqlDateTime()], '"YearCalendarItem"."To" > ? AND "YearCalendarItem"."From" < ?' => [$end->getSqlDateTime(), $end->getSqlDateTime()], '"YearCalendarItem"."To" >= ? AND "YearCalendarItem"."From" <= ?' => [$start->getSqlDateTime(), $end->getSqlDateTime()], ] ); // if we have Tags, filter items by them if ($this->Tags() ->Count() ) { $items = $items->filter([ 'Tags.ID' => $this->Tags() ->map('ID', 'ID') ->toArray(), ]); } $calendar = Calendar::create($start, $end, $items); if (!static::$frontendLoaded) { Requirements::customScript(sprintf(" var year = %1\$s; var month = %2\$s; ", $calendar->Year, $calendar->Month->Numeric)); static::$frontendLoaded = true; } return $calendar; } /** * Retrieve all YearCalendarItems in a list * * @return mixed */ public function YearCalendarList() { if ($this->archive) { $start = new DateTimeHelper(sprintf('%1$s-01-01', $this->archive)); $end = new DateTimeHelper(sprintf('%1$s-12-31', $this->archive)); $start->setTimeToDayStart(); $end->setTimeToDayEnd(); $where = [ '"YearCalendarItem"."From" < ? AND "YearCalendarItem"."To" > ?' => [$start->getSqlDateTime(), $start->getSqlDateTime()], '"YearCalendarItem"."To" > ? AND "YearCalendarItem"."From" < ?' => [$end->getSqlDateTime(), $end->getSqlDateTime()], '"YearCalendarItem"."To" >= ? AND "YearCalendarItem"."From" <= ?' => [$start->getSqlDateTime(), $end->getSqlDateTime()], ]; } else { $start = new DateTimeHelper(); $start->setTimeToDayStart(); $where = [ '"YearCalendarItem"."To" >= ?' => [$start->getSqlDateTime()], ]; } $items = YearCalendarItem::get() ->whereAny($where); // if we have Tags, filter items by them if ($this->Tags() ->Count() ) { $items = $items->filter([ 'Tags.ID' => $this->Tags() ->map('ID', 'ID') ->toArray(), ]); } return EventList::create($items->Sort('From', 'asc')); } /** * Retrieve everything marked as a holiday * * @return mixed */ public function Holidays() { $start = new DateTimeHelper(sprintf('%1$s-01-01', $this->year)); $start->setTimeToDayStart(); $end = new DateTimeHelper(sprintf('%1$s-12-31', $this->year)); $end->setTimeToDayEnd(); $items = YearCalendarItem::get() ->leftJoin('YearCalendarItem_Tags', 'YearCalendarItem.ID = YearCalendarItem_Tags.YearCalendarItemID') ->leftJoin('YearCalendarItemTag', 'YearCalendarItem_Tags.YearCalendarItemTagID = YearCalendarItemTag.ID') ->filter(['YearCalendarItemTag.URLSegment' => 'vakantie']) ->whereAny([ '"YearCalendarItem"."To" >= ? AND "YearCalendarItem"."To" <= ?' => [$start->getSqlDateTime(), $end->getSqlDateTime()], '"YearCalendarItem"."From" >= ?' => [$start->getSqlDateTime()], ]); return $items; } /** * Set the current date * * @param string $month * @param $year */ public function setDate($month, $year) { $this->month = $month; $this->year = $year; } /** * Set the current archive * * @param string $archive */ public function setArchive($archive) { $this->archive = $archive; } /** * Retrieve the current archive * * @return string */ public function getArchive() { return $this->archive; } } /** * Class CalendarPage_Controller * */ class YearCalendarPage_Controller extends Page_Controller { /** * @inheritdoc */ private static $allowed_actions = [ 'ical', 'year', ]; /** * @inheritdoc */ public function init() { parent::init(); $month = $this->getRequest() ->getVar('month') ?: date('m'); $year = $this->getRequest() ->getVar('year') ?: date('Y'); $this->data() ->setDate($month, $year); } /** * index action * * @return mixed */ public function index() { return $this->renderWith($this->templates()); } /** * year action * * @return mixed */ public function year() { $this->data() ->setArchive( $this->getRequest() ->param('ID') ); return $this->renderWith($this->templates('EventList')); } /** * ical action * * @return \SS_HTTPResponse */ public function ical() { if ($id = $this->getRequest() ->param('ID') ) { return $this->itemIcal($id); } return $this->pageIcal(); } /** * Generate an ical response for a single item * * @param int $id * * @return \SS_HTTPResponse */ protected function itemIcal($id) { $agenda = YearCalendarItem::get() ->filter(['ID' => $id]); $filter = URLSegmentFilter::create(); $title = $filter->filter($agenda->First()->Title); $object = $agenda->First(); $this->extend('updateItemIcalTitle', $title, $object); return $this->generateIcal($agenda, $title); } /** * Generate an ical response for this page * * @return \SS_HTTPResponse */ protected function pageIcal() { $now = new DateTimeHelper(); $agenda = YearCalendarItem::get() ->filterAny([ 'From:GreaterThanOrEqual' => $now->getSqlDateTime(), 'To:GreaterThanOrEqual' => $now->getSqlDateTime(), ]); // if we have Tags, filter items by them if ($this->Tags() ->Count() ) { $agenda = $agenda->filter([ 'Tags.ID' => $this->Tags() ->map('ID', 'ID'), ]); } $filter = URLSegmentFilter::create(); $title = $filter->filter($this->data()->Title); $object = $this->data(); $this->extend('updatePageIcalTitle', $title, $object); return $this->generateIcal($agenda, $title); } /** * Generate an ical response * * @param DataList $agenda * @param string $filename * * @return \SS_HTTPResponse */ protected function generateIcal(DataList $agenda, $filename = 'calendar') { $ical = new Sabre\VObject\Component\VCalendar([ 'PRODID' => 'JaarKalender', 'X-WR-CALNAME' => SiteConfig::current_site_config()->Title . ' Jaarkalender', ]); /** @var Agenda $item */ foreach ($agenda as $item) { $event = $ical->createComponent('VEVENT'); $ical->add($event); $event->SUMMARY = $item->Title; $event->UID = sprintf('%1$s-%2$s@%3$s', singleton('SiteTree')->generateURLSegment($item->Title), $item->ID, $_SERVER['SERVER_NAME']); $event->DTSTAMP = $item->FromDateTime() ->setTimezone(new DateTimeZone("UTC")) ->format('Ymd\THis\Z'); $event->DTSTART = $item->FromDateTime() ->setTimezone(new DateTimeZone("UTC")) ->format('Ymd\THis\Z'); $event->DTEND = $item->ToDateTime() ->setTimezone(new DateTimeZone("UTC")) ->format('Ymd\THis\Z'); } return SS_HTTPRequest::send_file($ical->serialize(), sprintf('%1$s.ics', $filename), 'text/calendar; charset=utf-8'); } /** * Retrieve tags belonging to this Page * * @return \DataList */ public function Tags() { /** @var DataList $tags */ $tags = $this->data() ->Tags() ->Count() ? $this->data() ->Tags() : YearCalendarItemTag::get(); /** @var YearCalendarItemTag $object */ $tags = $tags->filterByCallback(function ($object) { return $object->Items() ->Count(); }); $this->extend('updateTags', $tags); return $tags; } /** * Create a dropdown field * * @return DropdownField */ public function ArchiveDropdown() { Requirements::customScript(sprintf(" var link = '%1\$s' ", $this->Link())); return DropdownField::create( 'Year', null, $this->Years(), $this->data() ->getArchive() ) ->setEmptyString('Upcoming') ->addExtraClass('archive'); } /** * Collect the years for which we have items * * @return array */ protected function Years() { $value = []; foreach ( (new SQLSelect())->setFrom('YearCalendarItem as yci') ->setSelect('DISTINCT(DATE_FORMAT(yci.From, \'%Y\')) as Year') ->execute() as $row ) { array_push($value, $row['Year']); } sort($value); $value = array_combine($value, $value); $this->extend('updateYears', $value); return $value; } /** * Retrieve the templates we're using to render * * @return array */ protected function templates($template = null) { if (is_null($template)) { $template = $this->data()->Template; } return [ sprintf('%1$sPage', $template), 'Page', ]; } } |