summaryrefslogtreecommitdiff
path: root/app/frontend/facades
diff options
context:
space:
mode:
Diffstat (limited to 'app/frontend/facades')
-rw-r--r--app/frontend/facades/CalendarFacade.php212
-rw-r--r--app/frontend/facades/EventFacade.php115
-rw-r--r--app/frontend/facades/Facade.php62
-rw-r--r--app/frontend/facades/UserFacade.php78
-rw-r--r--app/frontend/facades/config.xml10
5 files changed, 477 insertions, 0 deletions
diff --git a/app/frontend/facades/CalendarFacade.php b/app/frontend/facades/CalendarFacade.php
new file mode 100644
index 0000000..1f78594
--- /dev/null
+++ b/app/frontend/facades/CalendarFacade.php
@@ -0,0 +1,212 @@
+<?php
+
+Prado::using('Application.facades.Facade');
+Prado::using('Application.facades.EventFacade');
+Prado::using('Application.dto.CalendarDTO');
+Prado::using('Application.dto.CalendarGroupDTO');
+Prado::using('Application.dto.TimezoneDTO');
+Prado::using('Application.model.Calendar');
+Prado::using('Application.model.Category');
+Prado::using('Application.model.UserPreference');
+Prado::using('Application.user.DbUser');
+
+class CalendarFacade extends Facade {
+
+ private function _getCategoriesForCalendars(array $calendars) {
+ return Category::finder()->findAllByPks(
+ array_map(
+ function($calendar) {
+ return $calendar->CategoryID;
+ },
+ $calendars
+ )
+ );
+ }
+
+ private $_defaultPreference = NULL;
+ public function getDefaultPreference() {
+ if ($this->_defaultPreference === NULL) {
+ $this->_defaultPreference = Calendar::finder()->findAllByIsVisible(1);
+ }
+ return $this->_defaultPreference;
+ }
+
+ public function getCalendarPreference(DbUser $user) {
+ if ($user->IsGuest) {
+ return $this->getDefaultPreference();
+ } else {
+ return $user->DbRecord->Calendars;
+ }
+ }
+
+ public function getPreferenceList(DbUser $user) {
+ $calendars = $this->getCalendarPreference($user);
+ if ($calendars) {
+ $categories = array_map(
+ function($category) use($calendars) {
+ $dto = new CalendarGroupDTO();
+ $dto->loadRecord($category, $calendars);
+ return $dto;
+ },
+ $this->_getCategoriesForCalendars($calendars)
+ );
+ usort($categories, ['CalendarGroupDTO', '__compare']);
+ return $categories;
+ }
+ return [];
+ }
+
+ public function isCalendarPreferred(DbUser $user, $calendarID) {
+ return in_array(
+ $calendarID,
+ array_map(
+ function($calendar) {
+ return $calendar->UID;
+ },
+ $this->getCalendarPreference($user)
+ )
+ );
+ }
+
+ public function addToPreference(DbUser $user, $calendarID) {
+ if (!$user->IsGuest) {
+ $calendar = Calendar::finder()->findByPk($calendarID);
+ if ($calendar) {
+ $this->setPreferredCalendar($user->DbRecord, $calendar);
+ }
+ }
+ }
+
+ public function removeFromPreference(DbUser $user, $calendarID) {
+ if (!$user->IsGuest) {
+ $preferenceRecord = UserPreference::finder()->find(
+ '_user = ? AND _calendar = ?',
+ $user->DbRecord->ID,
+ $calendarID
+ );
+ if ($preferenceRecord) {
+ $preferenceRecord->delete();
+ }
+ }
+ }
+
+ public function setPreferredCalendar(User $user, Calendar $calendar) {
+ $preference = new UserPreference();
+ $preference->CalendarID = $calendar->UID;
+ $preference->UserID = $user->ID;
+ $preference->save();
+ }
+
+ public function setPreferredCalendars(User $user, array $calendars) {
+ //TODO: remove old preference, optionally
+ $transaction = $this->beginTransaction();
+ try {
+ foreach ($calendars as $calendar) {
+ $this->setPreferredCalendar($user, $calendar);
+ }
+ $transaction->commit();
+ } catch (Exception $e) {
+ $transaction->rollback();
+ throw $e;
+ }
+ }
+
+ public function getEventsForTimeframe(CalendarDTO $calendar,
+ DateTime $dateFrom,
+ DateTime $dateTo,
+ string $order = 'ASC') {
+ $calendar = Calendar::finder()->findAllByUID($calendar->ID);
+ if ($calendar) {
+ $events = EventFacade::getInstance()->getEventList(
+ $dateFrom->format('Y-m-d H:i:s'),
+ $dateTo->format('Y-m-d H:i:s'),
+ $calendar,
+ $order
+ );
+ return array_map(
+ function($event) use($calendar) {
+ $dto = new EventDTO();
+ $dto->loadRecord($event, $calendar);
+ return $dto;
+ },
+ $events
+ );
+ }
+ return [];
+ }
+
+ public function getAll() {
+ $records = Calendar::finder()->withCategory()->findAll('ORDER BY name ASC');
+ foreach ($records as $record) {
+ $this->_fillUrlCache($record);
+ }
+ return $records;
+ }
+
+ public function getCategories() {
+ $categories = array_map(
+ function($record) {
+ $dto = new CalendarGroupDTO();
+ $dto->loadRecord($record, []);
+ return $dto;
+ },
+ Category::finder()->findAll()
+ );
+ usort($categories, ['CalendarGroupDTO', '__compare']);
+ return $categories;
+ }
+
+ public function get($uid) {
+ $records = Calendar::finder()->withCategory()->findAllByPks($uid);
+ foreach ($records as $record) {
+ $this->_fillUrlCache($record);
+ }
+ return $records;
+ }
+
+ private $_urlCache = [];
+ private function _fillUrlCache(Calendar $record = NULL) {
+ if ($record && $record->CustomUrl
+ && !isset($this->_urlCache[$record->CustomUrl])) {
+ $dto = new CalendarDTO();
+ if ($record) {
+ $dto->loadRecord($record);
+ } else {
+ $dto = NULL;
+ }
+ return $this->_urlCache[$record->CustomUrl] = $dto;
+ }
+ }
+
+ public function resolveUrl(string $url = NULL) {
+ if ($url) {
+ if (isset($this->_urlCache[$url])) {
+ return $this->_urlCache[$url];
+ }
+ $record = Calendar::finder()->findByCustomUrl($url);
+ if ($record) {
+ return $this->_fillUrlCache($record);
+ }
+ }
+ return NULL;
+ }
+
+ public function getCalendarBoundaries($year, $month, TimezoneDTO $timezone) {
+ $firstDay = new DateTime(sprintf('%d-%02d', $year, $month),
+ new DateTimeZone($timezone->Name));
+ $firstDayAfter = clone $firstDay;
+ $firstDayAfter->modify('last day of this month')->modify('+1 day');
+ $firstDayOfTheWeek = $timezone->FirstDayOfTheWeek;
+ if ($firstDay->format('D') !== $firstDayOfTheWeek) {
+ $firstDay->modify('last ' . $firstDayOfTheWeek);
+ }
+ if ($firstDayAfter->format('D') !== $firstDayOfTheWeek) {
+ $firstDayAfter->modify('next ' . $firstDayOfTheWeek);
+ }
+ $firstDayAfter->modify('-1 day');
+ return [$firstDay, $firstDayAfter];
+ }
+
+}
+
+?>
diff --git a/app/frontend/facades/EventFacade.php b/app/frontend/facades/EventFacade.php
new file mode 100644
index 0000000..14f809d
--- /dev/null
+++ b/app/frontend/facades/EventFacade.php
@@ -0,0 +1,115 @@
+<?php
+
+Prado::using('Application.facades.Facade');
+Prado::using('Application.dto.EventDTO');
+Prado::using('Application.dto.TimezoneDTO');
+Prado::using('Application.dto.GridEventDTO');
+Prado::using('Application.dto.CalendarGridDTO');
+Prado::using('Application.model.Calendar');
+Prado::using('Application.facades.CalendarFacade');
+Prado::using('Application.user.DbUser');
+
+class EventFacade extends Facade {
+
+ public function getEventList(string $dateFrom=NULL, string $dateTo=NULL,
+ array $calendars=NULL, string $order='ASC') {
+ $calendarClause = '1=1';
+ if ($calendars) {
+ $calendarClause = sprintf(
+ '_calendar IN (%s)',
+ implode(
+ ',',
+ array_map(
+ function($calendar) {
+ return $this->quoteString($calendar->UID);
+ },
+ $calendars
+ )
+ )
+ );
+ }
+ return $this->fetchList(
+ 'getEvents',
+ [
+ 'date_from' => $dateFrom ?: '0000-00-00 00:00:00',
+ 'date_to' => $dateTo ?: '9999-99-99',
+ 'calendar_clause' => $calendarClause,
+ 'order_clause' => $order
+ ]
+ );
+ }
+
+ private function _compileEventObjects(array $events, array $calendars,
+ TimezoneDTO $tz,
+ string $class = 'Application.dto.EventDTO') {
+ return array_map(
+ function($event) use($calendars, $class, $tz) {
+ $dto = Prado::createComponent($class, $tz);
+ $dto->loadRecord($event, $calendars);
+ return $dto;
+ },
+ $events
+ );
+ }
+
+ public function getTimeframeListForUser(
+ DbUser $user,
+ DateTime $dateFrom, DateTime $dateTo,
+ string $returnClass = 'Application.dto.EventDTO') {
+ $calendars = CalendarFacade::getInstance()->getCalendarPreference($user);
+ if ($calendars) {
+ $events = $this->getEventList(
+ $dateFrom->format('Y-m-d H:i:s'),
+ $dateTo->format('Y-m-d H:i:s'),
+ $calendars
+ );
+ $calendars = $this->_getCalendarsForEvents($events);
+ return $this->_compileEventObjects(
+ $events, $calendars,
+ UserFacade::getInstance()->getTimezonePreference($user),
+ $returnClass);
+ }
+ return [];
+ }
+
+ public function getCalendarListForUser(DbUser $user,
+ $month, $year) {
+ if (!$year) {
+ $year = intval(date('Y'));
+ }
+ if (!$month) {
+ $month = intval(date('m'));
+ }
+ $timezone = $user
+ ? UserFacade::getInstance()->getTimezonePreference($user)
+ : new TimezoneDTO(date_default_timezone_get());
+ $timeframe = CalendarFacade::getInstance()->getCalendarBoundaries(
+ $year, $month, $timezone
+ );
+ return new CalendarGridDTO(
+ $this->getTimeframeListForUser(
+ $user,
+ $timeframe[0], $timeframe[1],
+ 'Application.dto.GridEventDTO'
+ ),
+ ...$timeframe
+ );
+ }
+
+ private function _getCalendarsForEvents(array $events) {
+ if ($events) {
+ return Calendar::finder()->findAllByPks(
+ array_map(
+ function($event) {
+ return $event->CalendarID;
+ },
+ $events
+ )
+ );
+ }
+ return [];
+ }
+
+}
+
+?>
diff --git a/app/frontend/facades/Facade.php b/app/frontend/facades/Facade.php
new file mode 100644
index 0000000..346024a
--- /dev/null
+++ b/app/frontend/facades/Facade.php
@@ -0,0 +1,62 @@
+<?php
+
+Prado::using('System.Data.SqlMap.TSqlMapGateway');
+
+class Facade {
+
+ protected static $_instances = [];
+
+ protected $_sqlMap;
+
+ protected function __construct() {
+ }
+
+ public function __sleep() {
+ $this->_sqlMap = NULL;
+ return array();
+ }
+
+ public static function getInstance() {
+ $className = get_called_class();
+ if (!isset(static::$_instances[$className])) {
+ static::$_instances[$className] = new static();
+ }
+ return static::$_instances[$className];
+ }
+
+ protected function getClient() {
+ if (!$this->_sqlMap) {
+ $this->_sqlMap = Prado::getApplication()->getModule('sqlmap')->Client;
+ }
+ return $this->_sqlMap;
+ }
+
+ protected function quoteString($string) {
+ return $this->getClient()->DbConnection->quoteString($string);
+ }
+
+ protected function fetch($sqlMap, $params) {
+ return $this->getClient()->queryForObject($sqlMap, $params);
+ }
+
+ protected function fetchList($sqlMap, $params) {
+ return $this->getClient()->queryForList($sqlMap, $params);
+ }
+
+ protected function fetchMap($sqlMap, $params, $key, $value=NULL) {
+ return $this->getClient()->queryForMap($sqlMap, $params, $key, $value);
+ }
+
+ protected function beginTransaction() {
+ return $this->getClient()->DbConnection->beginTransaction();
+ }
+
+ protected function raiseEvent($event, ...$params) {
+ return Prado::getApplication()->getModule('events')->raiseApplicationEvent(
+ $event, ...$params
+ );
+ }
+
+}
+
+?>
diff --git a/app/frontend/facades/UserFacade.php b/app/frontend/facades/UserFacade.php
new file mode 100644
index 0000000..1604a70
--- /dev/null
+++ b/app/frontend/facades/UserFacade.php
@@ -0,0 +1,78 @@
+<?php
+
+Prado::using('Application.facades.Facade');
+Prado::using('Application.user.DbUser');
+Prado::using('Application.model.User');
+Prado::using('Application.dto.TimezoneDTO');
+
+class UserFacade extends Facade {
+
+ public function findByLogin(string $login) {
+ return User::finder()->findByLogin($login);
+ }
+
+ public function checkForUsername(string $login) {
+ return !User::finder()->count('login = ?', $login);
+ }
+
+ public function registerUser(string $login, string $password, bool $admin) {
+ $transaction = $this->beginTransaction();
+ try {
+ $newUser = new User();
+ $newUser->Login = $login;
+ $newUser->Password = $this->generatePassword($password);
+ $newUser->IsAdmin = $admin;
+ $newUser->save();
+ $this->raiseEvent('UserRegistered', $newUser);
+ $transaction->commit();
+ return $newUser;
+ } catch (Exception $e) {
+ $transaction->rollback();
+ throw $e;
+ }
+ }
+
+ public function changePassword(DbUser $user, string $pass) {
+ if (!$user->IsGuest) {
+ $user->DbRecord->Password = $this->generatePassword($pass);
+ $user->DbRecord->save();
+ }
+ }
+
+ public function verifyUserPassword(string $password, DbUser $user) {
+ $dbPassword = $user->IsGuest ? '' : $user->DbRecord->Password;
+ return $this->verifyPassword($password, $dbPassword);
+ }
+
+ public function generatePassword(string $password) {
+ return password_hash($password, PASSWORD_DEFAULT);
+ }
+
+ public function verifyPassword(string $password, string $dbPassword) {
+ return password_verify($password, $dbPassword);
+ }
+
+ public function setTimezonePreference(DbUser $user, string $timezone) {
+ if ($user->IsGuest) {
+ throw new TInvalidDataException(
+ Prado::localize(
+ 'Timezone preference change impossible for guest user'
+ )
+ );
+ }
+ $user->DbRecord->Timezone = $timezone;
+ $user->DbRecord->save();
+ }
+
+ public function getTimezonePreference(DbUser $user) {
+ if (!$user->IsGuest) {
+ try {
+ return new TimezoneDTO($user->DbRecord->Timezone);
+ } catch(Exception $e) {}
+ }
+ return new TimezoneDTO(date_default_timezone_get());
+ }
+
+}
+
+?>
diff --git a/app/frontend/facades/config.xml b/app/frontend/facades/config.xml
new file mode 100644
index 0000000..8d5a298
--- /dev/null
+++ b/app/frontend/facades/config.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <modules>
+ <module id="sqlmap"
+ class="System.Data.SqlMap.TSqlMapConfig"
+ ConnectionID="db"
+ ConfigFile="Application.sqlmap.config"
+ EnableCache="true" />
+ </modules>
+</configuration>