diff options
Diffstat (limited to 'app/frontend/facades')
-rw-r--r-- | app/frontend/facades/CalendarFacade.php | 212 | ||||
-rw-r--r-- | app/frontend/facades/EventFacade.php | 115 | ||||
-rw-r--r-- | app/frontend/facades/Facade.php | 62 | ||||
-rw-r--r-- | app/frontend/facades/UserFacade.php | 78 | ||||
-rw-r--r-- | app/frontend/facades/config.xml | 10 |
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> |