summaryrefslogtreecommitdiff
path: root/app/frontend/dto
diff options
context:
space:
mode:
Diffstat (limited to 'app/frontend/dto')
-rw-r--r--app/frontend/dto/CalendarDTO.php31
-rw-r--r--app/frontend/dto/CalendarGridDTO.php84
-rw-r--r--app/frontend/dto/CalendarGridDayDTO.php28
-rw-r--r--app/frontend/dto/CalendarGroupDTO.php44
-rw-r--r--app/frontend/dto/EventDTO.php85
-rw-r--r--app/frontend/dto/GridEventDTO.php28
-rw-r--r--app/frontend/dto/TimezoneDTO.php46
l---------app/frontend/dto/weekdays.json1
8 files changed, 347 insertions, 0 deletions
diff --git a/app/frontend/dto/CalendarDTO.php b/app/frontend/dto/CalendarDTO.php
new file mode 100644
index 0000000..4468941
--- /dev/null
+++ b/app/frontend/dto/CalendarDTO.php
@@ -0,0 +1,31 @@
+<?php
+
+Prado::using('Application.model.Calendar');
+
+class CalendarDTO {
+
+ public $ID;
+ public $Name;
+ public $Website;
+ public $Image;
+ public $Url;
+ public $LastUpdated;
+ public $GroupID;
+
+ public function loadRecord(Calendar $calendarRecord) {
+ $this->ID = $calendarRecord->UID;
+ $this->Name = $calendarRecord->CustomName ?: $calendarRecord->Name;
+ $this->Website = $calendarRecord->Website;
+ $this->Image = $calendarRecord->CustomImageUrl;
+ $this->Url = $calendarRecord->CustomUrl;
+ $this->LastUpdated = $calendarRecord->LastUpdated;
+ $this->GroupID = $calendarRecord->CategoryID;
+ }
+
+ public static function __compare(CalendarDTO $cal1, CalendarDTO $cal2) {
+ return strcmp($cal1->Name, $cal2->Name);
+ }
+
+}
+
+?>
diff --git a/app/frontend/dto/CalendarGridDTO.php b/app/frontend/dto/CalendarGridDTO.php
new file mode 100644
index 0000000..f5d91a5
--- /dev/null
+++ b/app/frontend/dto/CalendarGridDTO.php
@@ -0,0 +1,84 @@
+<?php
+
+Prado::using('Application.dto.CalendarGridDayDTO');
+Prado::using('Application.dto.GridEventDTO');
+
+class CalendarGridDTO {
+
+ public $DateFrom;
+ public $DateTo;
+ public $Weeks = [];
+
+ public function __construct($events, DateTime $dateFrom, DateTime $dateTo) {
+ $this->DateFrom = DateTimeImmutable::createFromMutable($dateFrom);
+ $this->DateTo = DateTimeImmutable::createFromMutable($dateTo);
+ $date = $this->DateFrom;
+ $days = [];
+ $previousDay = NULL;
+ while ($date <= $this->DateTo) {
+ $day = $this->_getGridDay($date, $events, $previousDay);
+ $days[] = $day;
+ $previousDay = $day;
+ $date = $date->modify('+1 day');
+ }
+ $this->Weeks = array_chunk($days, 7);
+ }
+
+ private function _getContinuedEventGridPositions(
+ CalendarGridDayDTO $day,
+ CalendarGridDayDTO $previousDay = NULL) {
+ $eventPositions = [];
+ if ($previousDay) {
+ foreach ($day->Events as $event) {
+ if (in_array($event, $previousDay->Events)) {
+ $eventPositions[] = $event->GridPosition;
+ }
+ }
+ }
+ return $eventPositions;
+ }
+
+ private function _alignEvents(array $eventPositions, array $events) {
+ $previousCount = count($eventPositions);
+ foreach ($events as $event) {
+ if ($event->GridPosition === NULL) {
+ $event->GridPosition = min(
+ array_diff(
+ range(0, count($events) + $previousCount),
+ $eventPositions
+ )
+ );
+ $eventPositions[] = $event->GridPosition;
+ }
+ }
+ usort($events, ['GridEventDTO', '__compare']);
+ return $events;
+ }
+
+ private function _fillEventGrid(array $events) {
+ $previousEvent = -1;
+ foreach ($events as $event) {
+ $eventStep = $event->GridPosition - $previousEvent;
+ if ($eventStep > 1) {
+ array_splice(
+ $events, $previousEvent + 1, 0, array_fill(0, $eventStep - 1, NULL)
+ );
+ }
+ $previousEvent = $event->GridPosition;
+ }
+ return $events;
+ }
+
+ private function _getGridDay(DateTimeImmutable $date,
+ array $events,
+ CalendarGridDayDTO $previousDay = NULL) {
+ $day = new CalendarGridDayDTO($date, $events);
+ $eventPositions = $this->_getContinuedEventGridPositions($day, $previousDay);
+ $day->Events = $this->_alignEvents($eventPositions, $day->Events);
+ $day->Events = $this->_fillEventGrid($day->Events);
+ return $day;
+ }
+
+}
+
+?>
diff --git a/app/frontend/dto/CalendarGridDayDTO.php b/app/frontend/dto/CalendarGridDayDTO.php
new file mode 100644
index 0000000..ba65eb9
--- /dev/null
+++ b/app/frontend/dto/CalendarGridDayDTO.php
@@ -0,0 +1,28 @@
+<?php
+
+Prado::using('Application.dto.EventDTO');
+Prado::using('Application.dto.GridEventDTO');
+
+class CalendarGridDayDTO {
+
+ public $Date;
+ public $Events;
+
+ public function __construct(DateTimeImmutable $date, array $events) {
+ $this->Date = $date->format('Y-m-d');
+ $this->Events = array_filter($events, [$this, '_checkEventDate']);
+ // initial sort (date and calendar name)
+ // events are going to be re-sorted after assigning grid priorities
+ usort($this->Events, ['EventDTO', '__compare']);
+ }
+
+ private function _checkEventDate(GridEventDTO $event) {
+ if (!$this->Date) {
+ return FALSE;
+ }
+ return ($this->Date >= $event->DateFrom) && ($this->Date <= $event->DateTo);
+ }
+
+}
+
+?>
diff --git a/app/frontend/dto/CalendarGroupDTO.php b/app/frontend/dto/CalendarGroupDTO.php
new file mode 100644
index 0000000..7b64c6e
--- /dev/null
+++ b/app/frontend/dto/CalendarGroupDTO.php
@@ -0,0 +1,44 @@
+<?php
+
+Prado::using('Application.model.Category');
+Prado::using('Application.dto.CalendarDTO');
+
+class CalendarGroupDTO {
+
+ public $Name;
+ public $ID;
+ public $Priority;
+ public $Calendars = [];
+
+ public function loadRecord(Category $categoryRecord, array $calendars) {
+ $this->Name = $categoryRecord->Name;
+ $this->ID = $categoryRecord->ID;
+ $this->Priority = $categoryRecord->Priority;
+ $this->Calendars = array_map(
+ function($calendarRecord) {
+ $dto = new CalendarDTO();
+ $dto->loadRecord($calendarRecord);
+ return $dto;
+ },
+ array_filter(
+ $calendars,
+ function($calendarRecord) use($categoryRecord) {
+ return $categoryRecord->ID == $calendarRecord->CategoryID;
+ }
+ )
+ );
+ usort($this->Calendars, ['CalendarDTO', '__compare']);
+ }
+
+ public static function __compare(CalendarGroupDTO $cat1,
+ CalendarGroupDTO $cat2) {
+ $cmp = ($cat1->Priority ?: PHP_MAX_INT) - ($cat2->Priority ?: PHP_MAX_INT);
+ if ($cmp !== 0) {
+ return $cmp;
+ }
+ return strcmp($cat1->Name, $cat2->Name);
+ }
+
+}
+
+?>
diff --git a/app/frontend/dto/EventDTO.php b/app/frontend/dto/EventDTO.php
new file mode 100644
index 0000000..8f5cdf5
--- /dev/null
+++ b/app/frontend/dto/EventDTO.php
@@ -0,0 +1,85 @@
+<?php
+
+Prado::using('Application.model.Entry');
+Prado::using('Application.dto.CalendarDTO');
+Prado::using('Application.facades.UserFacade');
+
+class EventDTO {
+
+ public $DateString;
+ public $Name;
+ public $Location;
+ public $Calendar;
+
+ private $_utc;
+ private $_targetTZ;
+
+ public function __construct(TimezoneDTO $tz = NULL) {
+ $this->_utc = new DateTimeZone('UTC');
+ $this->_targetTZ = new DateTimeZone(
+ $tz
+ ? $tz->Name
+ : UserFacade::getInstance()->getTimezonePreference(
+ Prado::getApplication()->getUser()
+ )->Name
+ );
+ }
+
+ private $_beginDate;
+ protected function getBeginDate(Entry $event) {
+ if (!$this->_beginDate) {
+ $this->_beginDate = new DateTime($event->BeginDate, $this->_utc);
+ }
+ return $this->_beginDate;
+ }
+
+ private $_endDate;
+ protected function getEndDate(Entry $event) {
+ if (!$this->_endDate) {
+ $this->_endDate = new DateTime($event->EndDate, $this->_utc);
+ if ($event->AllDay) {
+ $this->_endDate = $this->_endDate->modify('-1 day');
+ }
+ }
+ return $this->_endDate;
+ }
+
+ public function loadRecord(Entry $event, array $calendars) {
+ $this->Name = $event->Name;
+ $this->Location = $event->Location;
+
+ if ($event->AllDay) {
+ $this->DateString = $this->getBeginDate($event)->format('Y-m-d');
+ if ($this->getBeginDate($event) != $this->getEndDate($event)) {
+ $this->DateString .= sprintf(
+ ' - %s',
+ $this->getEndDate($event)->format('Y-m-d')
+ );
+ }
+ } else {
+ $beginDate = $this->getBeginDate($event)->setTimezone($this->_targetTZ);
+ $this->DateString = $beginDate->format('Y-m-d H:i');
+ }
+
+ $calendars = array_filter(
+ $calendars,
+ function ($calendar) use($event) {
+ return $calendar->UID == $event->CalendarID;
+ }
+ );
+ $this->Calendar = new CalendarDTO();
+ $this->Calendar->loadRecord(
+ $calendars ? array_values($calendars)[0] : $event->Calendar
+ );
+ }
+
+ public static function __compare(EventDTO $ev1, EventDTO $ev2) {
+ if ($ev1->DateString === $ev2->DateString) {
+ return strcmp($ev1->Calendar->Name, $ev2->Calendar->Name);
+ }
+ return strcmp($ev1->DateString, $ev2->DateString);
+ }
+
+}
+
+?>
diff --git a/app/frontend/dto/GridEventDTO.php b/app/frontend/dto/GridEventDTO.php
new file mode 100644
index 0000000..0d2bb37
--- /dev/null
+++ b/app/frontend/dto/GridEventDTO.php
@@ -0,0 +1,28 @@
+<?php
+
+Prado::using('Application.dto.EventDTO');
+
+class GridEventDTO extends EventDTO {
+
+ public $DateFrom;
+ public $DateTo;
+ public $AllDay;
+ public $GridPosition;
+
+ public function loadRecord(Entry $event, array $calendars) {
+ parent::loadRecord($event, $calendars);
+ $this->AllDay = TPropertyValue::ensureBoolean($event->AllDay);
+ $this->DateFrom = $this->getBeginDate($event)->format('Y-m-d');
+ $this->DateTo = $this->getEndDate($event)->format('Y-m-d');
+ }
+
+ public static function __compare(EventDTO $ev1, EventDTO $ev2) {
+ if ($ev1->GridPosition === NULL || $ev2->GridPosition === NULL) {
+ return parent::__compare($ev1, $ev2);
+ }
+ return $ev1->GridPosition - $ev2->GridPosition;
+ }
+
+}
+
+?>
diff --git a/app/frontend/dto/TimezoneDTO.php b/app/frontend/dto/TimezoneDTO.php
new file mode 100644
index 0000000..e4078e6
--- /dev/null
+++ b/app/frontend/dto/TimezoneDTO.php
@@ -0,0 +1,46 @@
+<?php
+
+class TimezoneDTO {
+
+ public $Label;
+ public $Name;
+ public $Offset;
+ public $OffsetHours;
+ public $OffsetMinutes;
+ public $Location;
+ public $FirstDayOfTheWeek;
+
+ public function __construct(string $name) {
+ $tz = new DateTimeZone($name);
+ $this->Name = $tz->getName();
+ $this->Offset = $tz->getOffset(new DateTime());
+ $this->OffsetHours = $this->Offset / 3600;
+ $this->OffsetMinutes = $this->Offset % 3600 / 60;
+ $this->Location = $tz->getLocation()['country_code'];
+ $this->FirstDayOfTheWeek = $this->_getFirstDayOfTheWeek();
+ $this->Label = sprintf('UTC%+03d:%02d %s', $this->OffsetHours, $this->OffsetMinutes, $this->Name);
+ }
+
+ private function _getFirstDayOfTheWeek() {
+ $dayMapping = json_decode(
+ file_get_contents(
+ Prado::getPathOfNamespace('Application.dto.weekdays', '.json')
+ ),
+ TRUE
+ );
+ if ($this->Location && isset($dayMapping[$this->Location])) {
+ return ucfirst($dayMapping[$this->Location]);
+ }
+ return ucfirst($dayMapping['001']);
+ }
+
+
+
+ public static function __compare(TimezoneDTO $tz1, TimezoneDTO $tz2) {
+ $diff = $tz1->Offset - $tz2->Offset;
+ return ($diff == 0) ? strcmp($tz1->Name, $tz2->Name) : $diff;
+ }
+
+}
+
+?>
diff --git a/app/frontend/dto/weekdays.json b/app/frontend/dto/weekdays.json
new file mode 120000
index 0000000..325c801
--- /dev/null
+++ b/app/frontend/dto/weekdays.json
@@ -0,0 +1 @@
+../../../config/weekdays.json \ No newline at end of file