From 823d71ced9b4947b1a5a5ade7245d521ed490061 Mon Sep 17 00:00:00 2001 From: emkael Date: Tue, 7 Jun 2016 15:17:49 +0200 Subject: * renaming php directory --- app/frontend/application.xml | 30 ++ app/frontend/caches.xml | 6 + .../components/FileUploadSecureFileSize.php | 18 + .../components/FileUploadSecureFileType.php | 19 + .../components/FileUploadSecureMethods.php | 16 + app/frontend/components/FileUploadSecureOption.php | 17 + app/frontend/components/SafeActiveFileUpload.php | 13 + app/frontend/components/SafeFileUpload.php | 11 + app/frontend/controls/AddToFilter.php | 41 ++ app/frontend/controls/AddToFilter.tpl | 8 + app/frontend/controls/CalendarDetails.php | 7 + app/frontend/controls/CalendarDetails.tpl | 13 + app/frontend/controls/CalendarGrid.php | 59 +++ app/frontend/controls/CalendarGrid.tpl | 28 + app/frontend/controls/CalendarGroupFilter.php | 21 + app/frontend/controls/CalendarGroupFilter.tpl | 16 + app/frontend/controls/CalendarLabel.php | 13 + app/frontend/controls/CalendarLabel.tpl | 12 + app/frontend/controls/CalendarScaffold.php | 142 +++++ app/frontend/controls/CalendarScaffold.tpl | 81 +++ app/frontend/controls/CalendarSelection.php | 17 + app/frontend/controls/CalendarSelection.tpl | 8 + app/frontend/controls/EventList.php | 59 +++ app/frontend/controls/EventList.tpl | 6 + app/frontend/controls/EventRepeater.php | 25 + app/frontend/controls/EventRepeater.tpl | 12 + app/frontend/controls/HeaderMenu.php | 26 + app/frontend/controls/HeaderMenu.tpl | 36 ++ app/frontend/controls/LoginBox.php | 39 ++ app/frontend/controls/LoginBox.tpl | 33 ++ app/frontend/controls/PasswordChange.php | 44 ++ app/frontend/controls/PasswordChange.tpl | 59 +++ app/frontend/controls/RegistrationForm.php | 28 + app/frontend/controls/RegistrationForm.tpl | 66 +++ app/frontend/controls/TimezoneSelect.php | 58 +++ app/frontend/controls/TimezoneSelect.tpl | 5 + app/frontend/controls/UpcomingEvents.php | 33 ++ app/frontend/controls/UpcomingEvents.tpl | 5 + app/frontend/controls/UrlBasedCalendarControl.php | 40 ++ app/frontend/controls/UserSelection.php | 45 ++ app/frontend/controls/UserSelection.tpl | 29 ++ app/frontend/controls/config.xml | 6 + app/frontend/controls/scripts/AddToFilter.js | 5 + .../controls/scripts/CalendarGroupFilter.js | 29 ++ app/frontend/controls/scripts/CalendarLabel.js | 11 + app/frontend/controls/scripts/CalendarScaffold.js | 8 + app/frontend/controls/styles/CalendarGrid.css | 16 + app/frontend/controls/styles/CalendarScaffold.css | 11 + app/frontend/db/ActiveRecord.php | 69 +++ app/frontend/db/DBConnection.php | 28 + app/frontend/db/DBModule.php | 40 ++ app/frontend/db/DBTransaction.php | 53 ++ app/frontend/db/config.json | 1 + app/frontend/db/config.xml | 10 + app/frontend/dto/CalendarDTO.php | 31 ++ app/frontend/dto/CalendarGridDTO.php | 84 +++ app/frontend/dto/CalendarGridDayDTO.php | 28 + app/frontend/dto/CalendarGroupDTO.php | 44 ++ app/frontend/dto/EventDTO.php | 85 +++ app/frontend/dto/GridEventDTO.php | 28 + app/frontend/dto/TimezoneDTO.php | 46 ++ app/frontend/dto/weekdays.json | 1 + app/frontend/events/CalendarPreferenceEvents.php | 16 + app/frontend/events/EventModule.php | 53 ++ app/frontend/events/config.xml | 6 + app/frontend/facades/CalendarFacade.php | 212 ++++++++ app/frontend/facades/EventFacade.php | 115 +++++ app/frontend/facades/Facade.php | 62 +++ app/frontend/facades/UserFacade.php | 78 +++ app/frontend/facades/config.xml | 10 + app/frontend/i18n/config.xml | 14 + app/frontend/layouts/Layout.php | 11 + app/frontend/layouts/MainLayout.php | 9 + app/frontend/layouts/MainLayout.tpl | 22 + app/frontend/model/Calendar.php | 92 ++++ app/frontend/model/Category.php | 30 ++ app/frontend/model/Entry.php | 43 ++ app/frontend/model/User.php | 36 ++ app/frontend/model/UserPreference.php | 23 + app/frontend/model/config.xml | 9 + app/frontend/pages/Admin.page | 5 + app/frontend/pages/Calendar.page | 28 + app/frontend/pages/Home.page | 8 + app/frontend/pages/Login.page | 3 + app/frontend/pages/Profile.page | 21 + app/frontend/pages/Select.page | 8 + app/frontend/pages/Signup.page | 5 + app/frontend/pages/config.xml | 28 + app/frontend/resources | 1 + app/frontend/runtime | 1 + app/frontend/sqlmap/config.xml | 9 + app/frontend/sqlmap/events.xml | 11 + app/frontend/themes/default/preloader.gif | Bin 0 -> 7681 bytes app/frontend/url/UrlManager.php | 57 ++ app/frontend/url/config.xml | 44 ++ app/frontend/user/DbUser.php | 60 +++ app/frontend/user/config.xml | 9 + app/frontend/web/AssetManager.php | 11 + app/frontend/web/BaseUrlDerivedFromBasePath.php | 29 ++ app/frontend/web/ClientScriptManager.php | 572 +++++++++++++++++++++ app/frontend/web/FacadeTemplateControl.php | 27 + app/frontend/web/TemplateControl.php | 176 +++++++ app/frontend/web/ThemeManager.php | 11 + app/frontend/web/config.xml | 7 + app/php/application.xml | 30 -- app/php/caches.xml | 6 - app/php/components/FileUploadSecureFileSize.php | 18 - app/php/components/FileUploadSecureFileType.php | 19 - app/php/components/FileUploadSecureMethods.php | 16 - app/php/components/FileUploadSecureOption.php | 17 - app/php/components/SafeActiveFileUpload.php | 13 - app/php/components/SafeFileUpload.php | 11 - app/php/controls/AddToFilter.php | 41 -- app/php/controls/AddToFilter.tpl | 8 - app/php/controls/CalendarDetails.php | 7 - app/php/controls/CalendarDetails.tpl | 13 - app/php/controls/CalendarGrid.php | 59 --- app/php/controls/CalendarGrid.tpl | 28 - app/php/controls/CalendarGroupFilter.php | 21 - app/php/controls/CalendarGroupFilter.tpl | 16 - app/php/controls/CalendarLabel.php | 13 - app/php/controls/CalendarLabel.tpl | 12 - app/php/controls/CalendarScaffold.php | 142 ----- app/php/controls/CalendarScaffold.tpl | 81 --- app/php/controls/CalendarSelection.php | 17 - app/php/controls/CalendarSelection.tpl | 8 - app/php/controls/EventList.php | 59 --- app/php/controls/EventList.tpl | 6 - app/php/controls/EventRepeater.php | 25 - app/php/controls/EventRepeater.tpl | 12 - app/php/controls/HeaderMenu.php | 26 - app/php/controls/HeaderMenu.tpl | 36 -- app/php/controls/LoginBox.php | 39 -- app/php/controls/LoginBox.tpl | 33 -- app/php/controls/PasswordChange.php | 44 -- app/php/controls/PasswordChange.tpl | 59 --- app/php/controls/RegistrationForm.php | 28 - app/php/controls/RegistrationForm.tpl | 66 --- app/php/controls/TimezoneSelect.php | 58 --- app/php/controls/TimezoneSelect.tpl | 5 - app/php/controls/UpcomingEvents.php | 33 -- app/php/controls/UpcomingEvents.tpl | 5 - app/php/controls/UrlBasedCalendarControl.php | 40 -- app/php/controls/UserSelection.php | 45 -- app/php/controls/UserSelection.tpl | 29 -- app/php/controls/config.xml | 6 - app/php/controls/scripts/AddToFilter.js | 5 - app/php/controls/scripts/CalendarGroupFilter.js | 29 -- app/php/controls/scripts/CalendarLabel.js | 11 - app/php/controls/scripts/CalendarScaffold.js | 8 - app/php/controls/styles/CalendarGrid.css | 16 - app/php/controls/styles/CalendarScaffold.css | 11 - app/php/db/ActiveRecord.php | 69 --- app/php/db/DBConnection.php | 28 - app/php/db/DBModule.php | 40 -- app/php/db/DBTransaction.php | 53 -- app/php/db/config.json | 1 - app/php/db/config.xml | 10 - app/php/dto/CalendarDTO.php | 31 -- app/php/dto/CalendarGridDTO.php | 84 --- app/php/dto/CalendarGridDayDTO.php | 28 - app/php/dto/CalendarGroupDTO.php | 44 -- app/php/dto/EventDTO.php | 85 --- app/php/dto/GridEventDTO.php | 28 - app/php/dto/TimezoneDTO.php | 46 -- app/php/dto/weekdays.json | 1 - app/php/events/CalendarPreferenceEvents.php | 16 - app/php/events/EventModule.php | 53 -- app/php/events/config.xml | 6 - app/php/facades/CalendarFacade.php | 212 -------- app/php/facades/EventFacade.php | 115 ----- app/php/facades/Facade.php | 62 --- app/php/facades/UserFacade.php | 78 --- app/php/facades/config.xml | 10 - app/php/i18n/config.xml | 14 - app/php/layouts/Layout.php | 11 - app/php/layouts/MainLayout.php | 9 - app/php/layouts/MainLayout.tpl | 22 - app/php/model/Calendar.php | 92 ---- app/php/model/Category.php | 30 -- app/php/model/Entry.php | 43 -- app/php/model/User.php | 36 -- app/php/model/UserPreference.php | 23 - app/php/model/config.xml | 9 - app/php/pages/Admin.page | 5 - app/php/pages/Calendar.page | 28 - app/php/pages/Home.page | 8 - app/php/pages/Login.page | 3 - app/php/pages/Profile.page | 21 - app/php/pages/Select.page | 8 - app/php/pages/Signup.page | 5 - app/php/pages/config.xml | 28 - app/php/resources | 1 - app/php/runtime | 1 - app/php/sqlmap/config.xml | 9 - app/php/sqlmap/events.xml | 11 - app/php/themes/default/preloader.gif | Bin 7681 -> 0 bytes app/php/url/UrlManager.php | 57 -- app/php/url/config.xml | 44 -- app/php/user/DbUser.php | 60 --- app/php/user/config.xml | 9 - app/php/web/AssetManager.php | 11 - app/php/web/BaseUrlDerivedFromBasePath.php | 29 -- app/php/web/ClientScriptManager.php | 572 --------------------- app/php/web/FacadeTemplateControl.php | 27 - app/php/web/TemplateControl.php | 176 ------- app/php/web/ThemeManager.php | 11 - app/php/web/config.xml | 7 - 208 files changed, 3850 insertions(+), 3850 deletions(-) create mode 100644 app/frontend/application.xml create mode 100644 app/frontend/caches.xml create mode 100644 app/frontend/components/FileUploadSecureFileSize.php create mode 100644 app/frontend/components/FileUploadSecureFileType.php create mode 100644 app/frontend/components/FileUploadSecureMethods.php create mode 100644 app/frontend/components/FileUploadSecureOption.php create mode 100644 app/frontend/components/SafeActiveFileUpload.php create mode 100644 app/frontend/components/SafeFileUpload.php create mode 100644 app/frontend/controls/AddToFilter.php create mode 100644 app/frontend/controls/AddToFilter.tpl create mode 100644 app/frontend/controls/CalendarDetails.php create mode 100644 app/frontend/controls/CalendarDetails.tpl create mode 100644 app/frontend/controls/CalendarGrid.php create mode 100644 app/frontend/controls/CalendarGrid.tpl create mode 100644 app/frontend/controls/CalendarGroupFilter.php create mode 100644 app/frontend/controls/CalendarGroupFilter.tpl create mode 100644 app/frontend/controls/CalendarLabel.php create mode 100644 app/frontend/controls/CalendarLabel.tpl create mode 100644 app/frontend/controls/CalendarScaffold.php create mode 100644 app/frontend/controls/CalendarScaffold.tpl create mode 100644 app/frontend/controls/CalendarSelection.php create mode 100644 app/frontend/controls/CalendarSelection.tpl create mode 100644 app/frontend/controls/EventList.php create mode 100644 app/frontend/controls/EventList.tpl create mode 100644 app/frontend/controls/EventRepeater.php create mode 100644 app/frontend/controls/EventRepeater.tpl create mode 100644 app/frontend/controls/HeaderMenu.php create mode 100644 app/frontend/controls/HeaderMenu.tpl create mode 100644 app/frontend/controls/LoginBox.php create mode 100644 app/frontend/controls/LoginBox.tpl create mode 100644 app/frontend/controls/PasswordChange.php create mode 100644 app/frontend/controls/PasswordChange.tpl create mode 100644 app/frontend/controls/RegistrationForm.php create mode 100644 app/frontend/controls/RegistrationForm.tpl create mode 100644 app/frontend/controls/TimezoneSelect.php create mode 100644 app/frontend/controls/TimezoneSelect.tpl create mode 100644 app/frontend/controls/UpcomingEvents.php create mode 100644 app/frontend/controls/UpcomingEvents.tpl create mode 100644 app/frontend/controls/UrlBasedCalendarControl.php create mode 100644 app/frontend/controls/UserSelection.php create mode 100644 app/frontend/controls/UserSelection.tpl create mode 100644 app/frontend/controls/config.xml create mode 100644 app/frontend/controls/scripts/AddToFilter.js create mode 100644 app/frontend/controls/scripts/CalendarGroupFilter.js create mode 100644 app/frontend/controls/scripts/CalendarLabel.js create mode 100644 app/frontend/controls/scripts/CalendarScaffold.js create mode 100644 app/frontend/controls/styles/CalendarGrid.css create mode 100644 app/frontend/controls/styles/CalendarScaffold.css create mode 100644 app/frontend/db/ActiveRecord.php create mode 100644 app/frontend/db/DBConnection.php create mode 100644 app/frontend/db/DBModule.php create mode 100644 app/frontend/db/DBTransaction.php create mode 120000 app/frontend/db/config.json create mode 100644 app/frontend/db/config.xml create mode 100644 app/frontend/dto/CalendarDTO.php create mode 100644 app/frontend/dto/CalendarGridDTO.php create mode 100644 app/frontend/dto/CalendarGridDayDTO.php create mode 100644 app/frontend/dto/CalendarGroupDTO.php create mode 100644 app/frontend/dto/EventDTO.php create mode 100644 app/frontend/dto/GridEventDTO.php create mode 100644 app/frontend/dto/TimezoneDTO.php create mode 120000 app/frontend/dto/weekdays.json create mode 100644 app/frontend/events/CalendarPreferenceEvents.php create mode 100644 app/frontend/events/EventModule.php create mode 100644 app/frontend/events/config.xml create mode 100644 app/frontend/facades/CalendarFacade.php create mode 100644 app/frontend/facades/EventFacade.php create mode 100644 app/frontend/facades/Facade.php create mode 100644 app/frontend/facades/UserFacade.php create mode 100644 app/frontend/facades/config.xml create mode 100644 app/frontend/i18n/config.xml create mode 100644 app/frontend/layouts/Layout.php create mode 100644 app/frontend/layouts/MainLayout.php create mode 100644 app/frontend/layouts/MainLayout.tpl create mode 100644 app/frontend/model/Calendar.php create mode 100644 app/frontend/model/Category.php create mode 100644 app/frontend/model/Entry.php create mode 100644 app/frontend/model/User.php create mode 100644 app/frontend/model/UserPreference.php create mode 100644 app/frontend/model/config.xml create mode 100644 app/frontend/pages/Admin.page create mode 100644 app/frontend/pages/Calendar.page create mode 100644 app/frontend/pages/Home.page create mode 100644 app/frontend/pages/Login.page create mode 100644 app/frontend/pages/Profile.page create mode 100644 app/frontend/pages/Select.page create mode 100644 app/frontend/pages/Signup.page create mode 100644 app/frontend/pages/config.xml create mode 120000 app/frontend/resources create mode 120000 app/frontend/runtime create mode 100644 app/frontend/sqlmap/config.xml create mode 100644 app/frontend/sqlmap/events.xml create mode 100644 app/frontend/themes/default/preloader.gif create mode 100644 app/frontend/url/UrlManager.php create mode 100644 app/frontend/url/config.xml create mode 100644 app/frontend/user/DbUser.php create mode 100644 app/frontend/user/config.xml create mode 100644 app/frontend/web/AssetManager.php create mode 100644 app/frontend/web/BaseUrlDerivedFromBasePath.php create mode 100644 app/frontend/web/ClientScriptManager.php create mode 100644 app/frontend/web/FacadeTemplateControl.php create mode 100644 app/frontend/web/TemplateControl.php create mode 100644 app/frontend/web/ThemeManager.php create mode 100644 app/frontend/web/config.xml delete mode 100644 app/php/application.xml delete mode 100644 app/php/caches.xml delete mode 100644 app/php/components/FileUploadSecureFileSize.php delete mode 100644 app/php/components/FileUploadSecureFileType.php delete mode 100644 app/php/components/FileUploadSecureMethods.php delete mode 100644 app/php/components/FileUploadSecureOption.php delete mode 100644 app/php/components/SafeActiveFileUpload.php delete mode 100644 app/php/components/SafeFileUpload.php delete mode 100644 app/php/controls/AddToFilter.php delete mode 100644 app/php/controls/AddToFilter.tpl delete mode 100644 app/php/controls/CalendarDetails.php delete mode 100644 app/php/controls/CalendarDetails.tpl delete mode 100644 app/php/controls/CalendarGrid.php delete mode 100644 app/php/controls/CalendarGrid.tpl delete mode 100644 app/php/controls/CalendarGroupFilter.php delete mode 100644 app/php/controls/CalendarGroupFilter.tpl delete mode 100644 app/php/controls/CalendarLabel.php delete mode 100644 app/php/controls/CalendarLabel.tpl delete mode 100644 app/php/controls/CalendarScaffold.php delete mode 100644 app/php/controls/CalendarScaffold.tpl delete mode 100644 app/php/controls/CalendarSelection.php delete mode 100644 app/php/controls/CalendarSelection.tpl delete mode 100644 app/php/controls/EventList.php delete mode 100644 app/php/controls/EventList.tpl delete mode 100644 app/php/controls/EventRepeater.php delete mode 100644 app/php/controls/EventRepeater.tpl delete mode 100644 app/php/controls/HeaderMenu.php delete mode 100644 app/php/controls/HeaderMenu.tpl delete mode 100644 app/php/controls/LoginBox.php delete mode 100644 app/php/controls/LoginBox.tpl delete mode 100644 app/php/controls/PasswordChange.php delete mode 100644 app/php/controls/PasswordChange.tpl delete mode 100644 app/php/controls/RegistrationForm.php delete mode 100644 app/php/controls/RegistrationForm.tpl delete mode 100644 app/php/controls/TimezoneSelect.php delete mode 100644 app/php/controls/TimezoneSelect.tpl delete mode 100644 app/php/controls/UpcomingEvents.php delete mode 100644 app/php/controls/UpcomingEvents.tpl delete mode 100644 app/php/controls/UrlBasedCalendarControl.php delete mode 100644 app/php/controls/UserSelection.php delete mode 100644 app/php/controls/UserSelection.tpl delete mode 100644 app/php/controls/config.xml delete mode 100644 app/php/controls/scripts/AddToFilter.js delete mode 100644 app/php/controls/scripts/CalendarGroupFilter.js delete mode 100644 app/php/controls/scripts/CalendarLabel.js delete mode 100644 app/php/controls/scripts/CalendarScaffold.js delete mode 100644 app/php/controls/styles/CalendarGrid.css delete mode 100644 app/php/controls/styles/CalendarScaffold.css delete mode 100644 app/php/db/ActiveRecord.php delete mode 100644 app/php/db/DBConnection.php delete mode 100644 app/php/db/DBModule.php delete mode 100644 app/php/db/DBTransaction.php delete mode 120000 app/php/db/config.json delete mode 100644 app/php/db/config.xml delete mode 100644 app/php/dto/CalendarDTO.php delete mode 100644 app/php/dto/CalendarGridDTO.php delete mode 100644 app/php/dto/CalendarGridDayDTO.php delete mode 100644 app/php/dto/CalendarGroupDTO.php delete mode 100644 app/php/dto/EventDTO.php delete mode 100644 app/php/dto/GridEventDTO.php delete mode 100644 app/php/dto/TimezoneDTO.php delete mode 120000 app/php/dto/weekdays.json delete mode 100644 app/php/events/CalendarPreferenceEvents.php delete mode 100644 app/php/events/EventModule.php delete mode 100644 app/php/events/config.xml delete mode 100644 app/php/facades/CalendarFacade.php delete mode 100644 app/php/facades/EventFacade.php delete mode 100644 app/php/facades/Facade.php delete mode 100644 app/php/facades/UserFacade.php delete mode 100644 app/php/facades/config.xml delete mode 100644 app/php/i18n/config.xml delete mode 100644 app/php/layouts/Layout.php delete mode 100644 app/php/layouts/MainLayout.php delete mode 100644 app/php/layouts/MainLayout.tpl delete mode 100644 app/php/model/Calendar.php delete mode 100644 app/php/model/Category.php delete mode 100644 app/php/model/Entry.php delete mode 100644 app/php/model/User.php delete mode 100644 app/php/model/UserPreference.php delete mode 100644 app/php/model/config.xml delete mode 100644 app/php/pages/Admin.page delete mode 100644 app/php/pages/Calendar.page delete mode 100644 app/php/pages/Home.page delete mode 100644 app/php/pages/Login.page delete mode 100644 app/php/pages/Profile.page delete mode 100644 app/php/pages/Select.page delete mode 100644 app/php/pages/Signup.page delete mode 100644 app/php/pages/config.xml delete mode 120000 app/php/resources delete mode 120000 app/php/runtime delete mode 100644 app/php/sqlmap/config.xml delete mode 100644 app/php/sqlmap/events.xml delete mode 100644 app/php/themes/default/preloader.gif delete mode 100644 app/php/url/UrlManager.php delete mode 100644 app/php/url/config.xml delete mode 100644 app/php/user/DbUser.php delete mode 100644 app/php/user/config.xml delete mode 100644 app/php/web/AssetManager.php delete mode 100644 app/php/web/BaseUrlDerivedFromBasePath.php delete mode 100644 app/php/web/ClientScriptManager.php delete mode 100644 app/php/web/FacadeTemplateControl.php delete mode 100644 app/php/web/TemplateControl.php delete mode 100644 app/php/web/ThemeManager.php delete mode 100644 app/php/web/config.xml (limited to 'app') diff --git a/app/frontend/application.xml b/app/frontend/application.xml new file mode 100644 index 0000000..6937e53 --- /dev/null +++ b/app/frontend/application.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/frontend/caches.xml b/app/frontend/caches.xml new file mode 100644 index 0000000..8a88717 --- /dev/null +++ b/app/frontend/caches.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/frontend/components/FileUploadSecureFileSize.php b/app/frontend/components/FileUploadSecureFileSize.php new file mode 100644 index 0000000..1e60c9a --- /dev/null +++ b/app/frontend/components/FileUploadSecureFileSize.php @@ -0,0 +1,18 @@ +getIsSecure()) { + return filesize($this->getLocalName()); + } + return parent::getFileSize(); + } + +} + +?> diff --git a/app/frontend/components/FileUploadSecureFileType.php b/app/frontend/components/FileUploadSecureFileType.php new file mode 100644 index 0000000..ce16501 --- /dev/null +++ b/app/frontend/components/FileUploadSecureFileType.php @@ -0,0 +1,19 @@ +getIsSecure()) { + $fileInfo = new finfo(FILEINFO_MIME_TYPE); + return $fileInfo->file($this->getLocalName()); + } + return parent::getFileType(); + } + +} + +?> diff --git a/app/frontend/components/FileUploadSecureMethods.php b/app/frontend/components/FileUploadSecureMethods.php new file mode 100644 index 0000000..8a42240 --- /dev/null +++ b/app/frontend/components/FileUploadSecureMethods.php @@ -0,0 +1,16 @@ + diff --git a/app/frontend/components/FileUploadSecureOption.php b/app/frontend/components/FileUploadSecureOption.php new file mode 100644 index 0000000..3550e21 --- /dev/null +++ b/app/frontend/components/FileUploadSecureOption.php @@ -0,0 +1,17 @@ +_isSecure; + } + + public function setIsSecure($bool) { + $this->_isSecure = $bool; + } + +} + +?> diff --git a/app/frontend/components/SafeActiveFileUpload.php b/app/frontend/components/SafeActiveFileUpload.php new file mode 100644 index 0000000..69bffab --- /dev/null +++ b/app/frontend/components/SafeActiveFileUpload.php @@ -0,0 +1,13 @@ + diff --git a/app/frontend/components/SafeFileUpload.php b/app/frontend/components/SafeFileUpload.php new file mode 100644 index 0000000..a8cbcae --- /dev/null +++ b/app/frontend/components/SafeFileUpload.php @@ -0,0 +1,11 @@ + diff --git a/app/frontend/controls/AddToFilter.php b/app/frontend/controls/AddToFilter.php new file mode 100644 index 0000000..9146f3b --- /dev/null +++ b/app/frontend/controls/AddToFilter.php @@ -0,0 +1,41 @@ +setViewState('Description', TPropertyValue::ensureString($val)); + } + + public function getDescription() { + return $this->getViewState('Description'); + } + + public function setUserPreference($sender, $param) { + $user = $this->getUserToManage(); + if ($user && !$user->IsGuest) { + if ($sender->Checked) { + $this->getFacade()->addToPreference($user, $this->getCalendar()->ID); + } else { + $this->getFacade()->removeFromPreference($user, $this->getCalendar()->ID); + } + $this->Page->CallbackClient->jQuery($this->Box, 'removeAttr', 'disabled'); + } + } + + public function getUserToManage() { + return $this->getControlState('user'); + } + + public function setUserToManage($user) { + $this->setControlState('user', $user); + } + + public function getPradoScriptDependencies() { + return ['jquery']; + } + +} + +?> diff --git a/app/frontend/controls/AddToFilter.tpl b/app/frontend/controls/AddToFilter.tpl new file mode 100644 index 0000000..a202aa7 --- /dev/null +++ b/app/frontend/controls/AddToFilter.tpl @@ -0,0 +1,8 @@ + + <%= !$this->UserToManage->IsGuest %> + <%= $this->Facade->isCalendarPreferred($this->UserToManage, $this->getCalendar()->ID) %> + <%= $this->UserToManage->IsGuest ? Prado::localize('log in to manage your selections') : '' %> + + + <%= $this->getDescription() %> + diff --git a/app/frontend/controls/CalendarDetails.php b/app/frontend/controls/CalendarDetails.php new file mode 100644 index 0000000..95ee563 --- /dev/null +++ b/app/frontend/controls/CalendarDetails.php @@ -0,0 +1,7 @@ + diff --git a/app/frontend/controls/CalendarDetails.tpl b/app/frontend/controls/CalendarDetails.tpl new file mode 100644 index 0000000..2fd755c --- /dev/null +++ b/app/frontend/controls/CalendarDetails.tpl @@ -0,0 +1,13 @@ + + <%= $this->getCalendar()->Name %> + + + <%= $this->getCalendar()->Image %> + + + <%[ Source website ]%> + <%= $this->getCalendar()->Website %> + +

+ <%[ Last updated: ]%> <%= $this->getCalendar()->LastUpdated %> +

diff --git a/app/frontend/controls/CalendarGrid.php b/app/frontend/controls/CalendarGrid.php new file mode 100644 index 0000000..4ebfacd --- /dev/null +++ b/app/frontend/controls/CalendarGrid.php @@ -0,0 +1,59 @@ +setControlState('Month', $month); + } + + public function getMonth() { + return $this->getControlState('Month'); + } + + public function setYear($year) { + $this->setControlState('Year', $year); + } + + public function getYear() { + return $this->getControlState('Year'); + } + + public function setUserToDisplay(DbUser $user) { + $this->setControlState('User', $user); + } + + public function getUserToDisplay() { + return $this->getControlState('User'); + } + + private function _getGrid() { + return $this->getFacade()->getCalendarListForUser( + $this->UserToDisplay, + $this->Month, + $this->Year + ); + } + + public function onPreRender($param) { + parent::onPreRender($param); + $this->Weeks->DataSource = $this->_getGrid()->Weeks; + $this->Weeks->dataBind(); + } + + public function weekDataBind($sender, $param) { + $param->Item->Days->DataSource = $param->Item->Data; + $param->Item->Days->dataBind(); + } + + public function dayDataBind($sender, $param) { + $param->Item->Events->DataSource = $param->Item->Data->Events; + $param->Item->Events->dataBind(); + } + +} + +?> diff --git a/app/frontend/controls/CalendarGrid.tpl b/app/frontend/controls/CalendarGrid.tpl new file mode 100644 index 0000000..2b3ada8 --- /dev/null +++ b/app/frontend/controls/CalendarGrid.tpl @@ -0,0 +1,28 @@ + + +
+ + +
+ <%# $this->Data->Date %> + + + + + + gridEvent <%# $this->Parent->Parent->Data->Date == $this->Data->DateFrom ? 'beginDate' : '' %> <%# $this->Parent->Parent->Data->Date == $this->Data->DateTo ? 'endDate' : '' %> + <%# $this->Data->Name %> + + + +
 
+
+
+
+
+
+
+
+
+
+
diff --git a/app/frontend/controls/CalendarGroupFilter.php b/app/frontend/controls/CalendarGroupFilter.php new file mode 100644 index 0000000..6f19bcd --- /dev/null +++ b/app/frontend/controls/CalendarGroupFilter.php @@ -0,0 +1,21 @@ +Categories->DataSource = $this->Facade->getCategories(); + $this->Categories->dataBind(); + } + + public function getPradoScriptDependencies() { + return ['jquery']; + } + +} + +?> diff --git a/app/frontend/controls/CalendarGroupFilter.tpl b/app/frontend/controls/CalendarGroupFilter.tpl new file mode 100644 index 0000000..ac82465 --- /dev/null +++ b/app/frontend/controls/CalendarGroupFilter.tpl @@ -0,0 +1,16 @@ + + +
+ <%[ All ]%> + +
+
+ +
+ <%# $this->Data->Name %> + + <%# $this->Data->ID %> + +
+
+
diff --git a/app/frontend/controls/CalendarLabel.php b/app/frontend/controls/CalendarLabel.php new file mode 100644 index 0000000..667e847 --- /dev/null +++ b/app/frontend/controls/CalendarLabel.php @@ -0,0 +1,13 @@ + diff --git a/app/frontend/controls/CalendarLabel.tpl b/app/frontend/controls/CalendarLabel.tpl new file mode 100644 index 0000000..69e0147 --- /dev/null +++ b/app/frontend/controls/CalendarLabel.tpl @@ -0,0 +1,12 @@ + + <%= $this->Calendar->GroupID %> + + <%= $this->Service->constructUrl('Calendar', ['calendar' => $this->Calendar->Url]) %> + <%= $this->Calendar->Name %> + + + <%= $this->Facade %> + <%= $this->Calendar->Url %> + <%= $this->User %> + + diff --git a/app/frontend/controls/CalendarScaffold.php b/app/frontend/controls/CalendarScaffold.php new file mode 100644 index 0000000..7f15a32 --- /dev/null +++ b/app/frontend/controls/CalendarScaffold.php @@ -0,0 +1,142 @@ +Page->IsPostBack && !$this->Page->IsCallBack) { + $this->_rebindData(); + } + } + + private function _rebindCalendars(array $calendars) { + $this->Calendars->DataSource = $calendars; + $this->Calendars->dataBind(); + } + + private function _rebindCategoryList(array $categories) { + foreach ($this->Calendars->Columns as $column) { + if ($column->ID === 'Category' + && $column instanceof TActiveDropDownListColumn) { + $column->ListDataSource = $categories; + } + } + } + + private function _rebindData(bool $refresh = FALSE) { + $this->_rebindCategoryList( + $this->_getCategories() + ); + $this->_rebindCalendars( + $this->_getCalendars($refresh) + ); + } + + private function _getCalendars(bool $refresh = FALSE) { + if ($refresh) { + $this->clearViewState('Calendars'); + } + $calendars = $this->getViewState( + 'Calendars', + $this->getFacade()->getAll() + ); + $this->setViewState('Calendars', $calendars); + return $calendars; + } + + private function _getCategories() { + $categories = $this->getViewState( + 'Categories', + $this->getFacade()->getCategories() + ); + $this->setViewState('Categories', $categories); + return $categories; + } + + public function editRow($sender, $param) { + $this->Calendars->EditItemIndex = $param->Item->ItemIndex; + $this->_rebindData(); + } + + private function _compileSaveData(TDataGridItem $item) { + return [ + 'CategoryID' => $item->Category->DropDownList->SelectedValue, + 'Visible' => $item->Visible->CheckBox->Checked, + 'CustomName' => $item->CustomName->TextBox->SafeText, + 'CustomUrl' => $item->CustomUrl->TextBox->SafeText, + 'CustomImage' => $item->CustomImage->Value->SafeText + ]; + } + + public function saveRow($sender, $param) { + $calendar = $this->getFacade()->get( + $sender->DataKeys[$param->Item->ItemIndex] + ); + if ($calendar) { + foreach ($calendar as $c) { + $c->saveData($this->_compileSaveData($param->Item)); + } + } else { + throw new TInvalidDataValueException( + Prado::localize('Calendar not found') + ); + } + $this->Calendars->EditItemIndex = -1; + $this->_rebindData(TRUE); + } + + public function cancelRowEdit($sender, $param) { + $this->Calendars->EditItemIndex = -1; + $this->_rebindData(); + } + + public function toggleDefaultState($sender, $param) { + $calendar = $this->getFacade()->get($sender->CustomData); + if ($calendar) { + $calendar[0]->Visible = $sender->Checked; + $calendar[0]->save(); + $this->_rebindData(TRUE); + } + } + + public function uploadRowFile($sender, $param) { + $fileType = $sender->getFileType(); + if (preg_match('/^image\//', $fileType)) { + $calendar = $this->getFacade()->get($sender->CustomData); + if ($calendar) { + $targetFile = $calendar[0]->getCustomImagePath( + $sender->getLocalName(), + $fileType + ); + if ($sender->saveAs($targetFile)) { + $sender->NamingContainer->CustomImage->Value->Text = basename( + $targetFile + ); + } + } else { + throw new TInvalidDataValueException( + Prado::localize('Calendar not found') + ); + } + } else { + throw new TInvalidDataTypeException( + Prado::localize('Invalid file type') + ); + } + } + + protected function getPradoScriptDependencies() { + return ['jquery']; + } + +} + +?> diff --git a/app/frontend/controls/CalendarScaffold.tpl b/app/frontend/controls/CalendarScaffold.tpl new file mode 100644 index 0000000..6a22bc2 --- /dev/null +++ b/app/frontend/controls/CalendarScaffold.tpl @@ -0,0 +1,81 @@ + + + + <%[ Calendar ]%> + + + <%[ WWW ]%> + <%[ [www] ]%> + + + <%[ ICS ]%> + <%[ [ics] ]%> + + + <%[ Category ]%> + + + <%[ Default ]%> + + + <%# $this->Parent->Data->Visible %> + <%# $this->Parent->Data->UID %> + + + + + <%# $this->Parent->Data->Visible %> + + + + + <%[ Custom name ]%> + + + <%[ URL ]%> + + + <%[ Image ]%> + + + <%# $this->Parent->Data->CustomImageUrl %> + + + + + <%# $this->Parent->Data->CustomImage %> +
+ + <%# $this->Parent->Data->UID %> + +
+
+ + <%[ Edit ]%> + <%[ Save ]%> + <%[ Cancel ]%> + +
+
diff --git a/app/frontend/controls/CalendarSelection.php b/app/frontend/controls/CalendarSelection.php new file mode 100644 index 0000000..e53aa36 --- /dev/null +++ b/app/frontend/controls/CalendarSelection.php @@ -0,0 +1,17 @@ +Page->IsCallBack) { + $this->Calendars->DataSource = $this->Facade->getAll(); + $this->Calendars->dataBind(); + } + } + +} + +?> diff --git a/app/frontend/controls/CalendarSelection.tpl b/app/frontend/controls/CalendarSelection.tpl new file mode 100644 index 0000000..d6bdd83 --- /dev/null +++ b/app/frontend/controls/CalendarSelection.tpl @@ -0,0 +1,8 @@ + + + + <%# $this->SourceTemplateControl->Facade %> + <%# $this->Data->CustomUrl %> + + + diff --git a/app/frontend/controls/EventList.php b/app/frontend/controls/EventList.php new file mode 100644 index 0000000..d40e000 --- /dev/null +++ b/app/frontend/controls/EventList.php @@ -0,0 +1,59 @@ + $date]) + ); + } + $this->setViewState($key, $datetime); + } + + public function setDateFrom($date) { + $this->_setDate('DateFrom', $date); + } + + public function getDateFrom() { + return $this->getViewState('DateFrom'); + } + + public function setDateTo($date) { + $this->_setDate('DateTo', $date); + } + + public function getDateTo() { + return $this->getViewState('DateTo'); + } + + public function setHeaderText($text) { + $this->setViewState('HeaderText', TPropertyValue::ensureString($text)); + } + + public function getHeaderText() { + return $this->getViewState('HeaderText'); + } + + public function setReverse($value) { + $this->setViewState('Reverse', TPropertyValue::ensureBoolean($value)); + } + + public function getReverse() { + return $this->getViewState('Reverse'); + } + + public function getEvents() { + return $this->getFacade()->getEventsForTimeframe( + $this->getCalendar(), + $this->getDateFrom() ?: new DateTime('0000-00-00'), + $this->getDateTo() ?: new DateTime('9999-99-99'), + $this->getReverse() ? 'DESC' : 'ASC' + ); + } + +} + +?> diff --git a/app/frontend/controls/EventList.tpl b/app/frontend/controls/EventList.tpl new file mode 100644 index 0000000..5881ce7 --- /dev/null +++ b/app/frontend/controls/EventList.tpl @@ -0,0 +1,6 @@ + + <%= $this->getHeaderText() %> + + + <%= $this->getEvents() %> + diff --git a/app/frontend/controls/EventRepeater.php b/app/frontend/controls/EventRepeater.php new file mode 100644 index 0000000..4fb2812 --- /dev/null +++ b/app/frontend/controls/EventRepeater.php @@ -0,0 +1,25 @@ +Events->DataSource = $events; + $this->Events->dataBind(); + } + + public function setCalendarLinkVisible($value) { + $this->setViewState( + 'CalendarLinkVisible', + TPropertyValue::ensureBoolean($value) + ); + } + + public function getCalendarLinkVisible() { + return $this->getViewState('CalendarLinkVisible', TRUE); + } + +} + +?> diff --git a/app/frontend/controls/EventRepeater.tpl b/app/frontend/controls/EventRepeater.tpl new file mode 100644 index 0000000..69aaabf --- /dev/null +++ b/app/frontend/controls/EventRepeater.tpl @@ -0,0 +1,12 @@ + + + <%# $this->Data->DateString %> + <%# $this->Data->Name %> + + <%# $this->SourceTemplateControl->CalendarLinkVisible %> + (<%# $this->Data->Calendar->Name %>) + <%# $this->Service->constructUrl('Calendar', ['calendar' => $this->Data->Calendar->Url]) %> + +
+
+
diff --git a/app/frontend/controls/HeaderMenu.php b/app/frontend/controls/HeaderMenu.php new file mode 100644 index 0000000..2488629 --- /dev/null +++ b/app/frontend/controls/HeaderMenu.php @@ -0,0 +1,26 @@ +Application->getModule('auth'); + $authModule->setReturnUrl($this->Request->RequestUri); + $this->Response->redirect( + $this->Service->ConstructUrl($authModule->LoginPage) + ); + } + + public function logoutUser($sender, $param) { + $this->Application->getModule('auth')->logout(); + $this->Response->redirect( + $this->Service->ConstructUrl(NULL) + ); + } + +} + +?> diff --git a/app/frontend/controls/HeaderMenu.tpl b/app/frontend/controls/HeaderMenu.tpl new file mode 100644 index 0000000..a760588 --- /dev/null +++ b/app/frontend/controls/HeaderMenu.tpl @@ -0,0 +1,36 @@ + diff --git a/app/frontend/controls/LoginBox.php b/app/frontend/controls/LoginBox.php new file mode 100644 index 0000000..1136a79 --- /dev/null +++ b/app/frontend/controls/LoginBox.php @@ -0,0 +1,39 @@ +Page->IsPostBack && !$this->User->IsGuest) { + $this->_afterLoginRedirect(); + } + } + + private function _afterLoginRedirect() { + $authModule = $this->Application->getModule('auth'); + $redirUrl = $authModule->ReturnUrl; + if (!$redirUrl + || $redirUrl == $this->Service->constructUrl($authModule->LoginPage)) { + $redirUrl = $this->Service->constructUrl(NULL); + } + $this->Response->redirect($redirUrl); + } + + public function loginUser($sender, $param) { + if ($this->Page->IsValid) { + $this->_afterLoginRedirect(); + } + } + + public function validatePassword($sender, $param) { + $param->IsValid = $this->Application->getModule('auth')->login( + $this->Login->Text, + $this->Password->Text + ); + } + +} + +?> diff --git a/app/frontend/controls/LoginBox.tpl b/app/frontend/controls/LoginBox.tpl new file mode 100644 index 0000000..070ab86 --- /dev/null +++ b/app/frontend/controls/LoginBox.tpl @@ -0,0 +1,33 @@ +<%[ Username: ]%> + + + <%[ Username cannot be empty ]%> + +
+<%[ Password: ]%> + + + <%[ Password cannot be empty ]%> + + + <%[ Username and password don't match ]%> + +
+ + <%[ Login ]%> + diff --git a/app/frontend/controls/PasswordChange.php b/app/frontend/controls/PasswordChange.php new file mode 100644 index 0000000..45ce656 --- /dev/null +++ b/app/frontend/controls/PasswordChange.php @@ -0,0 +1,44 @@ +getControlState('user'); + } + + public function setUserToChange(DbUser $user) { + if ($user->IsGuest && !$this->Page->IsCallBack) { + throw new TInvalidDataValueException( + Prado::localize( + 'Password change impossible for guest user' + ) + ); + } + $this->setControlState('user', $user); + } + + public function checkPassword($sender, $param) { + $param->IsValid = $this->getFacade()->verifyUserPassword( + $this->Password->Text, $this->UserToChange + ); + } + + public function changePassword($sender, $param) { + $this->SuccessMessage->Visible = FALSE; + if ($this->Page->IsValid) { + $this->getFacade()->changePassword( + $this->UserToChange, + $this->NewPassword->Text + ); + $this->SuccessMessage->Visible = TRUE; + } + } + +} + +?> diff --git a/app/frontend/controls/PasswordChange.tpl b/app/frontend/controls/PasswordChange.tpl new file mode 100644 index 0000000..4eb9a8e --- /dev/null +++ b/app/frontend/controls/PasswordChange.tpl @@ -0,0 +1,59 @@ +<%[ Change password ]%>
+<%[ Current password: ]%> + + + <%[ Current password cannot be empty ]%> + + + <%[ Password is incorrect ]%> + +
+<%[ New password: ]%> + + + <%[ New password cannot be empty ]%> + +
+<%[ Repeat password: ]%> + + + <%[ New password cannot be empty ]%> + + + <%[ Passwords don't match ]%> + +
+ + <%[ Change password ]%> + + + <%[ Your password has been changed ]%> + diff --git a/app/frontend/controls/RegistrationForm.php b/app/frontend/controls/RegistrationForm.php new file mode 100644 index 0000000..46494e3 --- /dev/null +++ b/app/frontend/controls/RegistrationForm.php @@ -0,0 +1,28 @@ +IsValid = $this->getFacade()->checkForUsername($this->Login->SafeText); + } + + public function registerUser($sender, $param) { + if ($this->Page->IsValid) { + $this->getFacade()->registerUser( + $this->Login->SafeText, + $this->Password->Text, + $this->Admin->Checked + ); + $this->Response->redirect( + $this->Service->constructUrl(NULL) + ); + } + } + +} + +?> diff --git a/app/frontend/controls/RegistrationForm.tpl b/app/frontend/controls/RegistrationForm.tpl new file mode 100644 index 0000000..9defe54 --- /dev/null +++ b/app/frontend/controls/RegistrationForm.tpl @@ -0,0 +1,66 @@ +<%[ Username: ]%> + + + <%[ Username cannot be empty ]%> + + + <%[ Username must contain 6-255 characters, all Latin alphanumeric or underscore ]%> + + + <%[ Username already exists ]%> + +
+<%[ Password: ]%> + + + <%[ Password cannot be empty ]%> + +
+<%[ Repeat password: ]%> + + + <%[ Password cannot be empty ]%> + + + <%[ Passwords don't match ]%> + +
+<%[ Admin: ]%> + +
+ + <%[ Create ]%> + + diff --git a/app/frontend/controls/TimezoneSelect.php b/app/frontend/controls/TimezoneSelect.php new file mode 100644 index 0000000..25af453 --- /dev/null +++ b/app/frontend/controls/TimezoneSelect.php @@ -0,0 +1,58 @@ +getControlState('user'); + } + + public function setUserToChange(DbUser $user) { + if ($user->IsGuest && !$this->Page->IsCallBack) { + throw new TInvalidDataValueException( + Prado::localize( + 'Timezone preference change impossible for guest user' + ) + ); + } + $this->setControlState('user', $user); + } + + public function onPreRender($param) { + parent::onPreRender($param); + $this->Timezones->DataSource = $this->_getTimezones(); + $this->Timezones->DataValueField = 'Name'; + $this->Timezones->DataTextField = 'Label'; + $this->Timezones->dataBind(); + $this->Timezones->setSelectedValue( + $this->getFacade()->getTimezonePreference($this->UserToChange)->Name + ); + } + + public function saveTimezone($sender, $param) { + $this->getFacade()->setTimezonePreference( + $this->UserToChange, + $this->Timezones->SelectedValue + ); + } + + private function _getTimezones() { + $timezones = array_map( + function($tz) { + return new TimezoneDTO($tz); + }, + DateTimeZone::listIdentifiers() + ); + usort($timezones, ['TimezoneDTO', '__compare']); + return $timezones; + } + +} + +?> diff --git a/app/frontend/controls/TimezoneSelect.tpl b/app/frontend/controls/TimezoneSelect.tpl new file mode 100644 index 0000000..ee703d6 --- /dev/null +++ b/app/frontend/controls/TimezoneSelect.tpl @@ -0,0 +1,5 @@ + + + <%[ Save timezone ]%> + diff --git a/app/frontend/controls/UpcomingEvents.php b/app/frontend/controls/UpcomingEvents.php new file mode 100644 index 0000000..27fc723 --- /dev/null +++ b/app/frontend/controls/UpcomingEvents.php @@ -0,0 +1,33 @@ +getControlState('user'); + } + + public function setUserToDisplay(DbUser $user) { + $this->setControlState('user', $user); + } + + public function getEvents() { + return $this->_getEventsForUser($this->UserToDisplay); + } + + private function _getEventsForUser(DbUser $user) { + $utc = new DateTimeZone('UTC'); + $dateFrom = new DateTime('now', $utc); + $dateTo = new DateTime('+7 days', $utc); + return $this->getFacade()->getTimeframeListForUser( + $user, + $dateFrom, $dateTo + ); + } + +} + +?> diff --git a/app/frontend/controls/UpcomingEvents.tpl b/app/frontend/controls/UpcomingEvents.tpl new file mode 100644 index 0000000..ac5f60c --- /dev/null +++ b/app/frontend/controls/UpcomingEvents.tpl @@ -0,0 +1,5 @@ +<%[ Upcoming events: ]%> +
+ + <%= $this->getEvents() %> + diff --git a/app/frontend/controls/UrlBasedCalendarControl.php b/app/frontend/controls/UrlBasedCalendarControl.php new file mode 100644 index 0000000..a5be82e --- /dev/null +++ b/app/frontend/controls/UrlBasedCalendarControl.php @@ -0,0 +1,40 @@ +getFacade()->resolveUrl($url); + if ($calendar) { + $this->setControlState('Calendar', $calendar); + return; + } + } + if ($this->getRaiseException()) { + throw new THttpException( + 404, + Prado::localize('Page not found') + ); + } else { + $this->Visible = FALSE; + } + } + + public function getCalendar() { + return $this->getControlState('Calendar'); + } + + public function setRaiseException($value) { + $this->setControlState('RaiseException', TPropertyValue::ensureBoolean($value)); + } + + public function getRaiseException() { + return $this->getControlState('RaiseException', FALSE); + } + +} + +?> diff --git a/app/frontend/controls/UserSelection.php b/app/frontend/controls/UserSelection.php new file mode 100644 index 0000000..233f0bf --- /dev/null +++ b/app/frontend/controls/UserSelection.php @@ -0,0 +1,45 @@ +getControlState('user'); + } + + public function setUserToDisplay(DbUser $user = NULL) { + $this->setControlState('user', $user); + } + + public function onPreRender($param) { + parent::onPreRender($param); + $this->Categories->setDataSource( + $this->_getUserSelection($this->UserToDisplay) + ); + $this->Categories->dataBind(); + } + + public function categoryDataBind($sender, $param) { + $param->Item->Calendars->setDataSource($param->Item->Data->Calendars); + $param->Item->Calendars->dataBind(); + } + + public function removeFromSelection($sender, $param) { + if (!$this->UserToDisplay->IsGuest) { + return $this->getFacade()->removeFromPreference( + $this->UserToDisplay, + $param->CommandParameter + ); + } + } + + private function _getUserSelection(DbUser $user) { + return $this->getFacade()->getPreferenceList($user); + } + +} + +?> diff --git a/app/frontend/controls/UserSelection.tpl b/app/frontend/controls/UserSelection.tpl new file mode 100644 index 0000000..8d20365 --- /dev/null +++ b/app/frontend/controls/UserSelection.tpl @@ -0,0 +1,29 @@ +<%[ Selected calendars: ]%> +
+ + + <%# $this->Data->Name %>
+ + + + <%# $this->Data->ID %> + <%# !$this->SourceTemplateControl->UserToDisplay->IsGuest %> + + <%# $this->Data->Name %> + + <%[ (details) ]%> + <%# $this->Service->constructUrl('Calendar', ['calendar' => $this->Data->Url]) %> + + + <%# $this->Data->Website %> + +
+
+
+
+
+
diff --git a/app/frontend/controls/config.xml b/app/frontend/controls/config.xml new file mode 100644 index 0000000..61d7e5b --- /dev/null +++ b/app/frontend/controls/config.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/frontend/controls/scripts/AddToFilter.js b/app/frontend/controls/scripts/AddToFilter.js new file mode 100644 index 0000000..e6d7b39 --- /dev/null +++ b/app/frontend/controls/scripts/AddToFilter.js @@ -0,0 +1,5 @@ +$(document).on('ready', function() { + $('input.addToFilterBox').on('change', function() { + $(this).attr('disabled', true); + }); +}); diff --git a/app/frontend/controls/scripts/CalendarGroupFilter.js b/app/frontend/controls/scripts/CalendarGroupFilter.js new file mode 100644 index 0000000..e6c1d73 --- /dev/null +++ b/app/frontend/controls/scripts/CalendarGroupFilter.js @@ -0,0 +1,29 @@ +$(document).on('ready', function() { + var selectBoxes = $('.selectGroup input.box'); + var selectAllBox = $('.selectAllGroups input.box'); + selectBoxes.on('change', function() { + var groups = []; + var allSelected = true; + $('.selectGroup input.box').each(function() { + var box = $(this); + if (box.is(':checked')) { + groups.push(box.val()); + } else { + allSelected = false; + } + }); + if (allSelected) { + selectAllBox.prop('checked', true); + } else { + selectAllBox.removeAttr('checked'); + } + $(document).trigger('Application.calendarGroupFilterChanged', {groups: groups}); + }); + selectAllBox.on('change', function() { + if ($(this).is(':checked')) { + selectBoxes.prop('checked', true).trigger('change'); + } else { + selectBoxes.removeAttr('checked').trigger('change'); + } + }); +}); diff --git a/app/frontend/controls/scripts/CalendarLabel.js b/app/frontend/controls/scripts/CalendarLabel.js new file mode 100644 index 0000000..8193e56 --- /dev/null +++ b/app/frontend/controls/scripts/CalendarLabel.js @@ -0,0 +1,11 @@ +$(document).on('Application.calendarGroupFilterChanged', function(event, args) { + var selectedGroups = args.groups || []; + $('.calendar').each(function() { + var label = $(this); + if (selectedGroups.indexOf(label.attr('data-group')) >= 0) { + label.show(); + } else { + label.hide(); + } + }); +}); diff --git a/app/frontend/controls/scripts/CalendarScaffold.js b/app/frontend/controls/scripts/CalendarScaffold.js new file mode 100644 index 0000000..d4b8ec5 --- /dev/null +++ b/app/frontend/controls/scripts/CalendarScaffold.js @@ -0,0 +1,8 @@ +$('body').on( + 'click', + 'main .calendarScaffold tbody a[href^="javascript:;//"], main .calendarScaffold tbody input.visibilityToggle', + function(e) { + var loader = $('
').addClass('calendarScaffoldLoader'); + $('main .calendarScaffold div[id$="_Container"]').append(loader); + } +); diff --git a/app/frontend/controls/styles/CalendarGrid.css b/app/frontend/controls/styles/CalendarGrid.css new file mode 100644 index 0000000..4710993 --- /dev/null +++ b/app/frontend/controls/styles/CalendarGrid.css @@ -0,0 +1,16 @@ +div.gridWeek { + clear: both; + display: flex; + flex-flow: row nowrap; +} +div.gridDay { + width: 14%; + min-height: 8em; + flex: 1 1 auto; +} +div.gridEvent, div.gridItem { height: 1.5em; padding: 0.3em 0.5em; margin: 0.1em 0; } +div.gridEvent { overflow: hidden; white-space: nowrap; background: #ddd } +div.gridEvent.beginDate { border-top-left-radius: 1.5em; + border-bottom-left-radius: 1.5em } +div.gridEvent.endDate { border-top-right-radius: 1.5em; + border-bottom-right-radius: 1.5em } diff --git a/app/frontend/controls/styles/CalendarScaffold.css b/app/frontend/controls/styles/CalendarScaffold.css new file mode 100644 index 0000000..071f672 --- /dev/null +++ b/app/frontend/controls/styles/CalendarScaffold.css @@ -0,0 +1,11 @@ +.calendarScaffold { + position: relative; +} +.calendarScaffold .calendarScaffoldLoader { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: url(preloader.gif) no-repeat center 5% rgba(255,255,255,0.8); +} diff --git a/app/frontend/db/ActiveRecord.php b/app/frontend/db/ActiveRecord.php new file mode 100644 index 0000000..1176767 --- /dev/null +++ b/app/frontend/db/ActiveRecord.php @@ -0,0 +1,69 @@ + 2) { + $method .= $parameter[2]; + } + } + } + } + } + return $method; + } + + public function __get($name) { + $name = $this->_getMappedPropertyName($name); + if (property_exists($this, $name)) { + return $this->$name; + } + return parent::__get($name); + } + + public function __set($name, $value) { + $name = $this->_getMappedPropertyName($name); + if (property_exists($this, $name)) { + return $this->$name = $value; + } + return parent::__set($name, $value); + } + + public function __call($method, $args) { + return parent::__call($this->_getMappedMethodName($method), $args); + } + +} + +?> diff --git a/app/frontend/db/DBConnection.php b/app/frontend/db/DBConnection.php new file mode 100644 index 0000000..92ab0fb --- /dev/null +++ b/app/frontend/db/DBConnection.php @@ -0,0 +1,28 @@ +_transaction->getActive()) { + $this->_transaction = NULL; + } + return $this->_transaction; + } + + public function beginTransaction() { + if ($this->_transaction && $this->_transaction->getActive()) { + $this->_transaction->beginNestedTransaction(); + } + else { + $this->_transaction = parent::beginTransaction(); + } + return $this->_transaction; + } + +} + +?> diff --git a/app/frontend/db/DBModule.php b/app/frontend/db/DBModule.php new file mode 100644 index 0000000..462b6f6 --- /dev/null +++ b/app/frontend/db/DBModule.php @@ -0,0 +1,40 @@ +getAttributes() as $attr => $val) { + $newXML->setAttribute($attr, $val); + } + $dbXML = new TXmlElement('database'); + $config = json_decode(file_get_contents( + Prado::getPathOfNamespace($this->_config, '.json') + )); + if (isset($config->cset)) { + $dbXML->setAttribute('Charset', $config->cset); + } + $dbXML->setAttribute('Username', $config->user); + $dbXML->setAttribute('Password', $config->pass); + $dbXML->setAttribute( + 'ConnectionString', + sprintf( + '%s:host=%s;dbname=%s', + $config->type, $config->host, $config->name + ) + ); + $newXML->Elements[] = $dbXML; + parent::init($newXML); + } + + public function setConfig($config) { + $this->_config = TPropertyValue::ensureString($config); + } + +} + +?> diff --git a/app/frontend/db/DBTransaction.php b/app/frontend/db/DBTransaction.php new file mode 100644 index 0000000..b176453 --- /dev/null +++ b/app/frontend/db/DBTransaction.php @@ -0,0 +1,53 @@ +getActive()) { + $this->_nestedCount++; + } + } + + public function commit() { + if ($this->_rolledBack) { + $childTransaction = (bool)($this->_nestedCount); + $this->rollback(); + if (!$childTransaction) { + throw new TDbException('Nested transaction was rolled back, unable to commit.'); + } + } + else { + if ($this->_nestedCount) { + $this->_nestedCount--; + } + else { + parent::commit(); + } + } + } + + public function rollback() { + if (!$this->getActive()) { + $this->_nestedCount = 0; + return; + } + if ($this->_nestedCount) { + $this->_rolledBack = TRUE; + $this->_nestedCount--; + } + else { + parent::rollback(); + $this->_nestedCount = 0; + $this->_rolledBack = FALSE; + } + } + +} + +?> diff --git a/app/frontend/db/config.json b/app/frontend/db/config.json new file mode 120000 index 0000000..89a492f --- /dev/null +++ b/app/frontend/db/config.json @@ -0,0 +1 @@ +../../../config/db.json \ No newline at end of file diff --git a/app/frontend/db/config.xml b/app/frontend/db/config.xml new file mode 100644 index 0000000..3210593 --- /dev/null +++ b/app/frontend/db/config.xml @@ -0,0 +1,10 @@ + + + + + + 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 @@ +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 @@ +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 @@ +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 @@ +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 @@ +_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 @@ +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 @@ +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 diff --git a/app/frontend/events/CalendarPreferenceEvents.php b/app/frontend/events/CalendarPreferenceEvents.php new file mode 100644 index 0000000..76fa071 --- /dev/null +++ b/app/frontend/events/CalendarPreferenceEvents.php @@ -0,0 +1,16 @@ +setPreferredCalendars($user, $facade->getDefaultPreference()); + } + +} + +?> diff --git a/app/frontend/events/EventModule.php b/app/frontend/events/EventModule.php new file mode 100644 index 0000000..6474523 --- /dev/null +++ b/app/frontend/events/EventModule.php @@ -0,0 +1,53 @@ +getMethods() as $method) { + if (is_a($method->class, get_class(), TRUE)) { + $eventPattern = []; + if (preg_match('/^on(.*)/', $method->name, $eventPattern)) { + $this->_registerEventHandler( + $eventPattern[1], + $method->getClosure($this) + ); + } + } + } + if (get_class() === get_called_class()) { + $directory = dirname(__FILE__); + foreach (scandir($directory) as $dirEntry) { + $classNameMatch = []; + if (preg_match('/(.*)\.php$/', $dirEntry, $classNameMatch)) { + $className = $classNameMatch[1]; + include_once($directory . DIRECTORY_SEPARATOR . $dirEntry); + if ($className != get_class() + && is_a($className, get_class(), TRUE)) { + $class = new $className(); + $class->init(NULL); + } + } + } + } + } + + protected static $_handlers = []; + private function _registerEventHandler($event, $handler) { + if (!isset(self::$_handlers[$event])) { + self::$_handlers[$event] = []; + } + self::$_handlers[$event][] = $handler; + } + + public function raiseApplicationEvent($event, ...$params) { + if (isset(self::$_handlers[$event])) { + foreach (self::$_handlers[$event] as $handler) { + call_user_func_array($handler, $params); + } + } + } + +} + +?> diff --git a/app/frontend/events/config.xml b/app/frontend/events/config.xml new file mode 100644 index 0000000..d1c1e3f --- /dev/null +++ b/app/frontend/events/config.xml @@ -0,0 +1,6 @@ + + + + + + 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 @@ +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 @@ +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 @@ +_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 @@ +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 @@ + + + + + + diff --git a/app/frontend/i18n/config.xml b/app/frontend/i18n/config.xml new file mode 100644 index 0000000..c80b46d --- /dev/null +++ b/app/frontend/i18n/config.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + diff --git a/app/frontend/layouts/Layout.php b/app/frontend/layouts/Layout.php new file mode 100644 index 0000000..324c69f --- /dev/null +++ b/app/frontend/layouts/Layout.php @@ -0,0 +1,11 @@ +ViewID->Value ?: md5(mt_rand()); + } + +} + +?> diff --git a/app/frontend/layouts/MainLayout.php b/app/frontend/layouts/MainLayout.php new file mode 100644 index 0000000..5843952 --- /dev/null +++ b/app/frontend/layouts/MainLayout.php @@ -0,0 +1,9 @@ + diff --git a/app/frontend/layouts/MainLayout.tpl b/app/frontend/layouts/MainLayout.tpl new file mode 100644 index 0000000..0deb816 --- /dev/null +++ b/app/frontend/layouts/MainLayout.tpl @@ -0,0 +1,22 @@ + + + + + <com:TContentPlaceHolder ID="Title" /> + + + +
+ +
+
+ +
+
+
+ + <%= $this->generateViewID() %> + +
+ + diff --git a/app/frontend/model/Calendar.php b/app/frontend/model/Calendar.php new file mode 100644 index 0000000..b49bf92 --- /dev/null +++ b/app/frontend/model/Calendar.php @@ -0,0 +1,92 @@ + 'UID', + 'url' => 'Url', + 'name' => 'Name', + 'website' => 'Website', + 'visible' => 'Visible', + 'last_updated' => 'LastUpdated', + 'custom_name' => 'CustomName', + 'custom_image' => 'CustomImage', + 'custom_url' => 'CustomUrl', + '_category' => 'CategoryID' + ]; + + public static $RELATIONS = [ + 'Entries' => [self::HAS_MANY, 'Entry', '_calendar'], + 'Category' => [self::BELONGS_TO, 'Category', '_category'] + ]; + + public static function finder($className=__CLASS__) { + return parent::finder($className); + } + + const CUSTOM_IMAGE_PATH = 'resources/images/calendars'; + + public function getCustomImageUrl() { + if ($this->CustomImage) { + if (!preg_match('#^//#', $this->CustomImage)) { + return Prado::getApplication()->getAssetManager()->publishFilePath( + implode( + DIRECTORY_SEPARATOR, + [ + Prado::getApplication()->getBasePath(), + self::CUSTOM_IMAGE_PATH, + $this->CustomImage + ] + ), + TRUE + ); + } + return $this->CustomImage; + } + } + + public function getCustomImagePath($forFile = NULL, $type = '') { + $pathParts = [ + Prado::getApplication()->getBasePath(), + self::CUSTOM_IMAGE_PATH + ]; + if ($forFile) { + $pathParts[] = $this->_getCustomImageHash($forFile, $type); + } + return implode(DIRECTORY_SEPARATOR, $pathParts); + } + + private function _getCustomImageHash($file, $type) { + $hash = md5($file . md5_file($file) . filemtime($file)); + if ($type) { + $hash .= '.' . preg_replace('#^image/#', '', $type); + } + return $hash; + } + + public function saveData($data) { + $this->copyFrom($data); + return $this->save(); + } + +} + +?> diff --git a/app/frontend/model/Category.php b/app/frontend/model/Category.php new file mode 100644 index 0000000..87b97b6 --- /dev/null +++ b/app/frontend/model/Category.php @@ -0,0 +1,30 @@ + 'ID', + 'name' => 'Name', + 'priority' => 'Priority' + ]; + + public static $RELATIONS = [ + 'Calendars' => [self::HAS_MANY, 'Calendar', '_category'] + ]; + + public static function finder($className=__CLASS__) { + return parent::finder($className); + } + +} + +?> diff --git a/app/frontend/model/Entry.php b/app/frontend/model/Entry.php new file mode 100644 index 0000000..4b93f04 --- /dev/null +++ b/app/frontend/model/Entry.php @@ -0,0 +1,43 @@ + 'ID', + 'uid' => 'UID', + 'begin_date' => 'BeginDate', + 'end_date' => 'EndDate', + 'all_day' => 'AllDay', + 'name' => 'Name', + 'location' => 'Location', + 'last_modified' => 'LastModified', + '_calendar' => 'CalendarID' + ]; + + public static $RELATIONS = [ + 'Calendar' => [self::BELONGS_TO, 'Calendar', '_calendar'] + ]; + + public static function finder($className=__CLASS__) { + return parent::finder($className); + } + +} + +?> diff --git a/app/frontend/model/User.php b/app/frontend/model/User.php new file mode 100644 index 0000000..d431183 --- /dev/null +++ b/app/frontend/model/User.php @@ -0,0 +1,36 @@ + 'ID', + 'login' => 'Login', + 'password' => 'Password', + 'is_admin' => 'IsAdmin', + 'timezone' => 'Timezone', + 'last_login' => 'LastLogin' + ]; + + public static $RELATIONS = [ + 'Calendars' => [self::MANY_TO_MANY, 'Calendar', 'user_selections'] + ]; + + public static function finder($className=__CLASS__) { + return parent::finder($className); + } + +} + +?> diff --git a/app/frontend/model/UserPreference.php b/app/frontend/model/UserPreference.php new file mode 100644 index 0000000..90fa221 --- /dev/null +++ b/app/frontend/model/UserPreference.php @@ -0,0 +1,23 @@ + 'UserID', + '_calendar' => 'CalendarID' + ]; + + public static function finder($className=__CLASS__) { + return parent::finder($className); + } + +} + +?> diff --git a/app/frontend/model/config.xml b/app/frontend/model/config.xml new file mode 100644 index 0000000..a729150 --- /dev/null +++ b/app/frontend/model/config.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/app/frontend/pages/Admin.page b/app/frontend/pages/Admin.page new file mode 100644 index 0000000..b130583 --- /dev/null +++ b/app/frontend/pages/Admin.page @@ -0,0 +1,5 @@ + + + <%= CalendarFacade::getInstance() %> + + diff --git a/app/frontend/pages/Calendar.page b/app/frontend/pages/Calendar.page new file mode 100644 index 0000000..f414dae --- /dev/null +++ b/app/frontend/pages/Calendar.page @@ -0,0 +1,28 @@ + + + <%= CalendarFacade::getInstance() %> + <%= $this->Request->itemAt('calendar') %> + + + <%= CalendarFacade::getInstance() %> + <%= $this->getUser() %> + <%= $this->Request->itemAt('calendar') %> + + <%[ calendar visible in current filter selection ]%> + + + + <%= CalendarFacade::getInstance() %> + <%= $this->Request->itemAt('calendar') %> + + <%[ Upcoming events in the calendar: ]%> + + + + <%= CalendarFacade::getInstance() %> + <%= $this->Request->itemAt('calendar') %> + + <%[ Past events in the calendar: ]%> + + + diff --git a/app/frontend/pages/Home.page b/app/frontend/pages/Home.page new file mode 100644 index 0000000..fb60066 --- /dev/null +++ b/app/frontend/pages/Home.page @@ -0,0 +1,8 @@ + + + <%= EventFacade::getInstance() %> + <%= $this->Request->itemAt('month') %> + <%= $this->Request->itemAt('year') %> + <%= $this->User %> + + diff --git a/app/frontend/pages/Login.page b/app/frontend/pages/Login.page new file mode 100644 index 0000000..15bc93e --- /dev/null +++ b/app/frontend/pages/Login.page @@ -0,0 +1,3 @@ + + + diff --git a/app/frontend/pages/Profile.page b/app/frontend/pages/Profile.page new file mode 100644 index 0000000..163d3fa --- /dev/null +++ b/app/frontend/pages/Profile.page @@ -0,0 +1,21 @@ + + + <%= UserFacade::getInstance() %> + <%= $this->User %> + +
+ + <%= UserFacade::getInstance() %> + <%= $this->User %> + +
+ + <%= $this->User %> + <%= CalendarFacade::getInstance() %> + +
+ + <%= $this->User %> + <%= EventFacade::getInstance() %> + +
diff --git a/app/frontend/pages/Select.page b/app/frontend/pages/Select.page new file mode 100644 index 0000000..5e1f232 --- /dev/null +++ b/app/frontend/pages/Select.page @@ -0,0 +1,8 @@ + + + <%= CalendarFacade::getInstance() %> + + + <%= CalendarFacade::getInstance() %> + + diff --git a/app/frontend/pages/Signup.page b/app/frontend/pages/Signup.page new file mode 100644 index 0000000..834b7cf --- /dev/null +++ b/app/frontend/pages/Signup.page @@ -0,0 +1,5 @@ + + + <%= UserFacade::getInstance() %> + + diff --git a/app/frontend/pages/config.xml b/app/frontend/pages/config.xml new file mode 100644 index 0000000..305651e --- /dev/null +++ b/app/frontend/pages/config.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/app/frontend/resources b/app/frontend/resources new file mode 120000 index 0000000..bc76415 --- /dev/null +++ b/app/frontend/resources @@ -0,0 +1 @@ +../../resources \ No newline at end of file diff --git a/app/frontend/runtime b/app/frontend/runtime new file mode 120000 index 0000000..2cee2e0 --- /dev/null +++ b/app/frontend/runtime @@ -0,0 +1 @@ +../../cache/prado \ No newline at end of file diff --git a/app/frontend/sqlmap/config.xml b/app/frontend/sqlmap/config.xml new file mode 100644 index 0000000..101e1b7 --- /dev/null +++ b/app/frontend/sqlmap/config.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/app/frontend/sqlmap/events.xml b/app/frontend/sqlmap/events.xml new file mode 100644 index 0000000..030a773 --- /dev/null +++ b/app/frontend/sqlmap/events.xml @@ -0,0 +1,11 @@ + + + + diff --git a/app/frontend/themes/default/preloader.gif b/app/frontend/themes/default/preloader.gif new file mode 100644 index 0000000..6505467 Binary files /dev/null and b/app/frontend/themes/default/preloader.gif differ diff --git a/app/frontend/url/UrlManager.php b/app/frontend/url/UrlManager.php new file mode 100644 index 0000000..a33d98e --- /dev/null +++ b/app/frontend/url/UrlManager.php @@ -0,0 +1,57 @@ +_convertServiceParam($serviceParam), + preg_replace('#^/' . $serviceID . '#', '', $url) + ), + '/' + ) . '/'; + } + + public function parseUrl() { + $params = parent::parseUrl(); + if ($this->MatchingPattern) { + $serviceID = $this->MatchingPattern->ServiceID; + if (isset($params[$serviceID])) { + $params[$serviceID] = $this->_parseServiceParam($params[$serviceID]); + } + } + return $params; + } + + /** + * Convert service param from camelCase to hyphenated-form. + **/ + private function _convertServiceParam($param) { + return implode( + '-', + array_map('mb_strtolower', array_filter(preg_split('/(?=[A-Z])/', $param))) + ); + } + + /** + * Convert service param from hyphenated-form to camelCase. + **/ + private function _parseServiceParam($param) { + return implode( + '', + array_map('ucfirst', explode('-', $param)) + ); + } +} + +?> diff --git a/app/frontend/url/config.xml b/app/frontend/url/config.xml new file mode 100644 index 0000000..b072b2d --- /dev/null +++ b/app/frontend/url/config.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/frontend/user/DbUser.php b/app/frontend/user/DbUser.php new file mode 100644 index 0000000..d636e8b --- /dev/null +++ b/app/frontend/user/DbUser.php @@ -0,0 +1,60 @@ +_record = $record; + } + + public function getDbRecord() { + if (!$this->_record) { + $this->_record = UserFacade::getInstance()->findByLogin($this->Name); + } + return $this->_record; + } + + public function createUser($username) { + $dbUser = UserFacade::getInstance()->findByLogin($username); + if (!$dbUser) { + return NULL; + } + $user = new DbUser($this->Manager); + $user->setDbRecord($dbUser); + $user->Name = $dbUser->Login; + if ($dbUser->IsAdmin) { + $user->Roles = 'Admin'; + } + $user->IsGuest = FALSE; + return $user; + } + + public function validateUser($login, $password) { + $user = UserFacade::getInstance()->findByLogin($login); + $dbPassword = $user ? $user->Password : ''; + if (UserFacade::getInstance()->verifyPassword($password, $dbPassword) + && $user) { + $user->LastLogin = date('Y-m-d H:i:s'); + $user->save(); + return TRUE; + } else { + return FALSE; + } + } + + public function __call($name, $args) { + $match = []; + if (preg_match('/^getIs(.+)$/', $name, $match)) { + return $this->isInRole($match[1]); + } + throw new Exception('Unimplemented CustomDbUser method'); + } + +} + +?> diff --git a/app/frontend/user/config.xml b/app/frontend/user/config.xml new file mode 100644 index 0000000..80027e5 --- /dev/null +++ b/app/frontend/user/config.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/app/frontend/web/AssetManager.php b/app/frontend/web/AssetManager.php new file mode 100644 index 0000000..2677585 --- /dev/null +++ b/app/frontend/web/AssetManager.php @@ -0,0 +1,11 @@ + diff --git a/app/frontend/web/BaseUrlDerivedFromBasePath.php b/app/frontend/web/BaseUrlDerivedFromBasePath.php new file mode 100644 index 0000000..2da277f --- /dev/null +++ b/app/frontend/web/BaseUrlDerivedFromBasePath.php @@ -0,0 +1,29 @@ +BaseUrl === NULL && $this->BasePath !== NULL) { + $appWebPath = preg_replace( + '#' . $this->Application->Request->ApplicationUrl . '$#', + '', + $this->Application->Request->ApplicationFilePath + ); + $appBaseUrl = preg_replace( + '#^' . $appWebPath . '#', + '', + dirname($this->Application->Request->ApplicationFilePath) + ); + $this->BaseUrl = $appBaseUrl + . preg_replace( + '#^' . Prado::getPathOfNamespace('Web') . '#', + '', + $this->BasePath + ); + } + parent::init($config); + } + +} + +?> diff --git a/app/frontend/web/ClientScriptManager.php b/app/frontend/web/ClientScriptManager.php new file mode 100644 index 0000000..223c6e2 --- /dev/null +++ b/app/frontend/web/ClientScriptManager.php @@ -0,0 +1,572 @@ +_page = $page; + parent::__construct($page); + } + + // Base path of the entire application + private function _getBasePath() { + return Prado::getPathOfNamespace('Web'); + } + + // Translate URLs to filesystem paths, index return array by URLs + private function _getBasePaths(array $urls) { + $basePath = $this->_getBasePath(); + return array_combine( + $urls, + array_map( + function($path) use($basePath) { + return $basePath . DIRECTORY_SEPARATOR . $path; + }, + $urls + ) + ); + } + + // Base cache path, suffixed with subdirectory, create on demand + private function _getCachePath(string $subdir = 'assets') { + $cachePath = $this->Application->RuntimePath + . DIRECTORY_SEPARATOR + . $subdir; + if (!is_dir($cachePath)) { + if (file_exists($cachePath)) { + throw new TIOException( + sprintf( + 'Client script manager cache path "%s" exists and is not a directory', + $cachePath + ) + ); + } else { + mkdir($cachePath); + } + } + return $cachePath; + } + + // Cache path for a file of specified type + private function _getCacheFilePath($path, $type) { + return $this->_getCachePath($type) + . DIRECTORY_SEPARATOR + . $path; + } + + // Cache key for specific file set, including current theme + private function _getFileCollectionCacheKey(array $files) { + sort($files); + if ($this->_page->Theme) { + $files[] = $this->_page->Theme->Name; + } + return md5(implode(PHP_EOL, $files)); + } + + // Last modification time of a file set + private function _getFileCollectionMTime(array $files) { + return max(array_map('filemtime', $files)); + } + + // Storage (application cache) key for list of rendered assets of specified type + // Rendered[ASSET_TYPE].[VIEW_ID] (VIEW_ID as rendered in Layout hidden field) + private function _getRenderedAssetsStoreKey($type) { + $template = $this->_page->Master; + if (!$template instanceof Layout) { + throw new TNotSupportedException( + 'Compiled assets may only be used within Layout master class controls' + ); + } + return sprintf('Rendered%s.%s', $type, $template->generateViewID()); + } + + // Shorthand for JS assets cache key + private function _getRenderedScriptsStoreKey() { + return $this->_getRenderedAssetsStoreKey('Scripts'); + } + + // Shorthand for CSS assets cache key + private function _getRenderedSheetsStoreKey() { + return $this->_getRenderedAssetsStoreKey('Sheets'); + } + + // Application (primary) cache module, required to keep track of assets rendered on current page + private function _getCache() { + $cache = $this->Application->Cache; + if (!$cache) { + throw new TNotSupportedException( + 'Compiled assets require cache to be configured' + ); + } + return $cache; + } + + // Check cache file validity, comparing to source file set + private function _isCacheValid($cacheFile, array $paths) { + return file_exists($cacheFile) + && (filemtime($cacheFile) >= $this->_getFileCollectionMTime($paths)); + } + + // Determine whether specific URL points to a local asset (i.e. existing on the filesystem) + private function _isFileLocal($file) { + $basePath = $this->_getBasePath(); + return file_exists($basePath . DIRECTORY_SEPARATOR . $file); + } + + // Filter URL set to leave only local assets + private function _determineLocalFiles($files) { + return array_filter( + $files, [$this, '_isFileLocal'] + ); + } + + // Scripts - internal methods + + private $_renderedScriptsInitialized = FALSE; + + // Retrieve scripts already rendered on current page from application cache, + // maintaining the state over callbacks + private function _getRenderedScripts() { + $sessionKey = $this->_getRenderedScriptsStoreKey(); + if ($this->_page->IsCallBack || $this->_renderedScriptsInitialized) { + return $this->_getCache()->get($sessionKey) ?: []; + } else { + $this->_getCache()->delete($sessionKey); + $this->_renderedScriptsInitialized = TRUE; + return []; + } + } + + // Store information on rendered scripts in application cache + private function _appendRenderedScripts(array $newScripts, $compiledFileKey) { + $scripts = $this->_getRenderedScripts(); + if (!isset($scripts[$compiledFileKey])) { + $scripts[$compiledFileKey] = []; + } + $scripts[$compiledFileKey] = array_unique( + array_merge( + $scripts[$compiledFileKey], + $newScripts + ) + ); + $this->_getCache()->set( + $this->_getRenderedScriptsStoreKey(), + $scripts + ); + } + + // Compress JS file and return its content + private function _getCompressedScript($path) { + return trim(TJavaScript::JSMin( + file_get_contents($path) + )); + } + + // Join multiple script files into single asset, mark all of them as rendered in parent + private function _compileScriptFiles(array $files) { + foreach ($files as $file) { + $this->markScriptFileAsRendered($file); + } + $paths = $this->_getBasePaths($files); + $cacheFile = $this->_getCacheFilePath( + $this->_getFileCollectionCacheKey($paths) . '.js', + 'scripts' + ); + $this->_appendRenderedScripts($files, $cacheFile); + if (!$this->_isCacheValid($cacheFile, $paths)) { + $scriptContent = implode( + PHP_EOL, + array_map( + [$this, '_getCompressedScript'], + $paths + ) + ); + file_put_contents($cacheFile, $scriptContent); + } + return $this->Application->AssetManager->publishFilePath($cacheFile); + } + + // Write output tag for a single, compiled JS asset, consisting of multiple local assets + private function _renderLocalScriptFiles(THtmlWriter $writer, array $localFiles) { + if ($localFiles) { + $assetPath = $this->_compileScriptFiles($localFiles); + $writer->write(TJavascript::renderScriptFile($assetPath)); + } + } + + // Keep track of external JS scripts rendered on the page + private function _renderExternalScriptFiles(THtmlWriter $writer, array $externalFiles) { + if ($externalFiles) { + foreach ($externalFiles as $file) { + $this->markScriptFileAsRendered($file); + $this->_appendRenderedScripts([$file], $file); + } + parent::renderScriptFiles($writer, $externalFiles); + } + } + + // Determine actual asset URL that a source JS file was rendered as (after compilation/compression) + // FALSE means script wasn't rendered at all (i.e. was just registered in current callback) + private function _getRenderedScriptUrl($registeredScript) { + $renderedScripts = $this->_getRenderedScripts(); + foreach ($renderedScripts as $compiledFile => $scripts) { + if (in_array($registeredScript, $scripts)) { + if (file_exists($compiledFile)) { + return $this->Application->AssetManager->getPublishedUrl( + $compiledFile + ); + } else { + return $registeredScript; + } + } + } + return FALSE; + } + + // Scripts - public interface overrides + + // In application modes "higher" than Debug, compile JS assets to as few files as possible + public function renderScriptFiles($writer, Array $files) { + if ($this->getApplication()->getMode() !== TApplicationMode::Debug) { + if ($files) { + $localFiles = $this->_determineLocalFiles($files); + $this->_renderLocalScriptFiles($writer, $localFiles); + $externalFiles = array_diff($files, $localFiles); + $this->_renderExternalScriptFiles($writer, $externalFiles); + } + } else { + parent::renderScriptFiles($writer, $files); + } + } + + // When above compilation occurs, list of JS URLs a callback requires + // significantly deviates from parent implementation. + // Also, new scripts that have been registered in current callback may need compiling, too. + public function getScriptUrls() { + if ($this->getApplication()->getMode() !== TApplicationMode::Debug) { + $registeredScripts = array_unique( + array_merge( + $this->_scripts, $this->_headScripts + ) + ); + $scriptUrls = []; + $newScripts = []; + foreach ($registeredScripts as $registeredScript) { + $renderedScriptUrl = $this->_getRenderedScriptUrl($registeredScript); + if ($renderedScriptUrl) { + $scriptUrls[] = $renderedScriptUrl; + } else { + $newScripts[] = $registeredScript; + } + } + $newLocalScripts = $this->_determineLocalFiles($newScripts); + $newRemoteScripts = array_diff($newScripts, $newLocalScripts); + if ($newLocalScripts) { + $scriptUrls[] = $this->_compileScriptFiles($newLocalScripts); + } + $scriptUrls = array_values( + array_unique(array_merge($scriptUrls, $newRemoteScripts)) + ); + return $scriptUrls; + } + return parent::getScriptUrls(); + } + + private $_scripts = []; + private $_headScripts = []; + + // Keep track of what we're registering + public function registerScriptFile($key, $file) { + $this->_scripts[$key] = $file; + return parent::registerScriptFile($key, $file); + } + + // Keep track of what we're registering + public function registerHeadScriptFile($key, $file) { + $this->_headScripts[$key] = $file; + return parent::registerHeadScriptFile($key, $file); + } + + // Stylesheets - internal methods + + private $_renderedSheetsInitialized = FALSE; + + // Retrieve stylesheets already rendered on current page from application cache, + // maintaining the state over callbacks + private function _getRenderedSheets() { + $sessionKey = $this->_getRenderedSheetsStoreKey(); + if ($this->_page->IsCallBack || $this->_renderedSheetsInitialized) { + return $this->_getCache()->get($sessionKey) ?: []; + } else { + $this->_getCache()->delete($sessionKey); + $this->_renderedSheetsInitialized = TRUE; + return []; + } + } + + // Store information on rendered stylesheets in application cache + private function _appendRenderedSheets(array $newSheets, $compiledFileKey) { + $sheets = $this->_getRenderedSheets(); + if (!isset($sheets[$compiledFileKey])) { + $sheets[$compiledFileKey] = []; + } + $sheets[$compiledFileKey] = array_merge( + $sheets[$compiledFileKey], + $newSheets + ); + $this->_getCache()->set( + $this->_getRenderedSheetsStoreKey(), + $sheets + ); + } + + // Resolve all "url(FILE)" CSS directives pointing + // to relative resources to specified path + private function _fixStyleSheetPaths($content, $originalUrl) { + $originalDir = dirname($originalUrl . '.'); + return preg_replace_callback( + '/url\s*\([\'"]?(.*?)[\'"]?\)/', + function($matches) use($originalDir) { + $url = parse_url($matches[1]); + // ignore absolute URLs and paths + if (isset($url['scheme']) + || isset($url['host']) + || $url['path'][0] == '/') { + return $matches[0]; + } + // resolve relative paths + return str_replace( + $matches[1], + $originalDir . '/' . $matches[1], + $matches[0] + ); + }, + $content + ); + } + + // Compress CSS file and return its content + private function _getCompressedSheet($origPath, $path) { + Prado::using('Lib.cssmin.CssMin'); + return trim(CssMin::minify( + $this->_fixStyleSheetPaths( + file_get_contents($path), + $origPath + ) + )); + } + + // Join multiple stylesheet files into single asset + private function _compileSheetFiles(array $files) { + $paths = $this->_getBasePaths( + array_map('reset', $files) + ); + // determine if file was registered as a themed sheet + $correctedPaths = []; + foreach ($paths as $url => $path) { + $correctedPaths[ + in_array($url, $this->_themeStyles) && $this->_page->Theme + ? $this->_page->Theme->BaseUrl . DIRECTORY_SEPARATOR + : $url + ] = $path; + } + $cacheFile = $this->_getCacheFilePath( + $this->_getFileCollectionCacheKey($paths) . '.css', + 'styles' + ); + $this->_appendRenderedSheets($files, $cacheFile); + if (!$this->_isCacheValid($cacheFile, $paths)) { + $styleContent = implode( + PHP_EOL, + array_map( + [$this, '_getCompressedSheet'], + array_keys($correctedPaths), + $correctedPaths + ) + ); + file_put_contents($cacheFile, $styleContent); + } + return $this->Application->AssetManager->publishFilePath($cacheFile); + } + + // Filter only local stylesheet file entries + private function _determineLocalSheetFiles(array $files) { + $basePath = $this->_getBasePath(); + return array_filter( + $files, + function($file) use($basePath) { + return file_exists($basePath . DIRECTORY_SEPARATOR . $file[0]); + } + ); + } + + // Write HTML markup for CSS stylesheet + private function _renderSheetFileTag(THtmlWriter $writer, $href, $media) { + $writer->addAttribute('rel', 'stylesheet'); + $writer->addAttribute('type', 'text/css'); + $writer->addAttribute('media', $media); + $writer->addAttribute('href', $href); + $writer->renderBeginTag('link'); + $writer->write(PHP_EOL); + } + + // Group registered local CSS assets by media query string and render markup for compiled sheets + private function _renderLocalSheetFiles(THtmlWriter $writer, array $localFiles) { + if ($localFiles) { + $fileTypes = []; + foreach ($localFiles as $file) { + $type = $file[1] ?: 'all'; + if (!isset($fileTypes[$type])) { + $fileTypes[$type] = []; + } + $fileTypes[$type][] = $file; + } + foreach ($fileTypes as $type => $files) { + $assetPath = $this->_compileSheetFiles($files); + $this->_renderSheetFileTag($writer, $assetPath, $type); + } + } + } + + // Render markup for external stylesheets + private function _renderExternalSheetFiles(THtmlWriter $writer, array $externalFiles) { + if ($externalFiles) { + foreach ($externalFiles as $file) { + $this->_appendRenderedSheets([$file], $file[0]); + $this->_renderSheetFileTag($writer, $file[0], $file[1] ?: 'all'); + } + } + } + + // Determine actual asset URL that a source CSS file was rendered as (after compilation/compression) + // FALSE means sheet wasn't rendered at all (i.e. was just registered in current callback) + // Media query types can easily be ignored in a callback request, only URLs matter + private function _getRenderedSheetUrl($registeredSheet) { + $renderedSheets = $this->_getRenderedSheets(); + foreach ($renderedSheets as $compiledFile => $sheets) { + foreach ($sheets as $sheet) { + if ($registeredSheet[0] == $sheet[0]) { + if (file_exists($compiledFile)) { + return $this->Application->AssetManager->getPublishedUrl( + $compiledFile + ); + } else { + return $registeredSheet[0]; + } + } + } + } + return FALSE; + } + + // Stylesheets - public interface overrides + + // In application modes "higher" than Debug, compile CSS assets to as few files as possible + public function renderStyleSheetFiles($writer) { + if ($this->getApplication()->getMode() !== TApplicationMode::Debug) { + $files = $this->_styles; + if ($files) { + $localFiles = $this->_determineLocalSheetFiles($files); + $this->_renderLocalSheetFiles($writer, $localFiles); + $externalFiles = array_diff_key($files, $localFiles); + $this->_renderExternalSheetFiles($writer, $externalFiles); + } + } else { + parent::renderStyleSheetFiles($writer); + } + } + + // When above compilation occurs, list of CSS URLs a callback requires + // significantly deviates from parent implementation. + // New stylesheets may need compiling, as well. + public function getStyleSheetUrls() { + if ($this->getApplication()->getMode() !== TApplicationMode::Debug) { + $registeredSheets = $this->_styles; + $sheetUrls = []; + $newSheets = []; + foreach ($registeredSheets as $registeredSheet) { + $renderedSheetUrl = $this->_getRenderedSheetUrl( + $registeredSheet + ); + if ($renderedSheetUrl) { + $sheetUrls[] = $renderedSheetUrl; + } else { + $newSheets[] = $registeredSheet; + } + } + $newLocalSheets = $this->_determineLocalSheetFiles($newSheets); + $newLocalUrls = array_map('reset', $newLocalSheets); + $newRemoteSheets = array_filter( + $newSheets, + function($sheet) use($newLocalUrls) { + return !in_array($sheet[0], $newLocalUrls); + } + ); + $newRemoteUrls = array_map('reset', $newRemoteSheets); + if ($newLocalSheets) { + $sheetUrls[] = $this->_compileSheetFiles($newLocalSheets); + } + $sheetUrls = array_values( + array_unique(array_merge($sheetUrls, $newRemoteUrls)) + ); + return $sheetUrls; + } + // And even in Debug mode, theme sheets before fixing paths + // might also have been published via assets manager, + // so we have to discard these from parent list. + return array_diff( + parent::getStyleSheetUrls(), + $this->_fixedStyleFiles + ); + } + + private $_styles = []; + + // Keep track of what we're registering + public function registerStyleSheetFile($key, $file, $media = '') { + $this->_styles[$key] = [$file, $media]; + return parent::registerStyleSheetFile($key, $file, $media ?: 'all'); + } + + private $_themeStyles = []; + private $_fixedStyleFiles = []; + + // New method, automatically corrects URLs within stylesheet to current page theme + // when sheets are not compiled (when they are, it's done on compilation anyways). + // Such files are rewritten (not in place, though) and registered so that they don't show up + // within published assets returned from asset manager, as they don't end up in the markup. + public function registerThemeStyleSheetFile($key, $file, $media = '') { + if ($this->getApplication()->getMode() !== TApplicationMode::Debug) { + $this->_themeStyles[$key] = $file; + } else { + if ($this->_isFileLocal($file) && $this->_page->Theme) { + $tempFile = $this->_getCacheFilePath( + $this->_getFileCollectionCacheKey([ + $this->_getBasePath() + . DIRECTORY_SEPARATOR + . $file + ]) + . '.' . basename($file), + $this->_page->Theme->Name + ); + file_put_contents( + $tempFile, + $this->_fixStyleSheetPaths( + file_get_contents( + $this->_getBasePath() . DIRECTORY_SEPARATOR . $file + ), + $this->_page->Theme->BaseUrl . DIRECTORY_SEPARATOR + ) + ); + $this->_fixedStyleFiles[] = $file; + $file = $this->Application->AssetManager->publishFilePath($tempFile); + } + } + return $this->registerStyleSheetFile($key, $file, $media ?: 'all'); + } + +} + +?> diff --git a/app/frontend/web/FacadeTemplateControl.php b/app/frontend/web/FacadeTemplateControl.php new file mode 100644 index 0000000..05d148c --- /dev/null +++ b/app/frontend/web/FacadeTemplateControl.php @@ -0,0 +1,27 @@ +setControlState('Facade', $facade); + } + + public function getFacade() { + return $this->getControlState('Facade'); + } + + public function onPreRender($param) { + parent::onPreRender($param); + if (!$this->getFacade()) { + throw new TInvalidDataValueException( + 'FacadeTemplateControl requires a Facade instance' + ); + } + } + +} + +?> diff --git a/app/frontend/web/TemplateControl.php b/app/frontend/web/TemplateControl.php new file mode 100644 index 0000000..aa95d75 --- /dev/null +++ b/app/frontend/web/TemplateControl.php @@ -0,0 +1,176 @@ +_getControlScriptPath(get_class($this)); + if (file_exists($scriptFile)) { + $this->_registerScriptFile($scriptFile); + } + $styleFile = $this->_getControlStylePath(get_class($this)); + if (file_exists($styleFile)) { + $this->_registerStyleFile($styleFile); + } + } + + protected function getExternalScriptDependencies() { + return []; + } + + protected function getLibScriptDependencies() { + return []; + } + + protected function getPradoScriptDependencies() { + return []; + } + + protected function getControlScriptDependencies() { + return []; + } + + protected function getExternalStyleDependencies() { + return []; + } + + protected function getLibStyleDependencies() { + return []; + } + + protected function getControlStyleDependencies() { + return []; + } + + private function _getControlScriptPath($className) { + return Prado::getPathOfNamespace('Application.controls.scripts') + . DIRECTORY_SEPARATOR + . $className + . '.js'; + } + + private function _getControlStylePath($className) { + return Prado::getPathOfNamespace('Application.controls.styles') + . DIRECTORY_SEPARATOR + . $className + . '.css'; + } + + private function _getLibPath($identifier, $extension = '') { + return Prado::getPathOfNamespace('Lib') + . DIRECTORY_SEPARATOR + . $identifier + . $extension; + } + + private function _registerScriptFile($scriptFile) { + $this->_registerExternalScriptDependencies( + $this->getExternalScriptDependencies() + ); + $this->_registerLibScriptDependencies( + $this->getLibScriptDependencies() + ); + $this->_registerPradoScriptDependencies( + $this->getPradoScriptDependencies() + ); + $this->_registerControlScriptDependencies( + $this->getControlScriptDependencies() + ); + $this->Page->ClientScript->registerScriptFile( + 'TemplateControl.' . get_class($this), + $this->Application->AssetManager->publishFilePath($scriptFile) + ); + } + + private function _registerExternalScriptDependencies(array $dependencies) { + foreach ($dependencies as $dependency) { + $this->Page->ClientScript->registerHeadScriptFile( + $dependency, $dependency + ); + } + } + + private function _registerLibScriptDependencies(array $dependencies) { + foreach ($dependencies as $dependency) { + $this->Page->ClientScript->registerScriptFile( + 'LibScript.' . $dependency, + $this->Application->AssetManager->publishFilePath( + $this->_getLibPath($dependency, '.js') + ) + ); + } + } + + private function _registerPradoScriptDependencies(array $dependencies) { + foreach ($dependencies as $dependency) { + $this->Page->ClientScript->registerPradoScript($dependency); + } + } + + private function _registerControlScriptDependencies(array $dependencies) { + foreach ($dependencies as $dependency) { + $this->Page->ClientScript->registerScriptFile( + 'TemplateControl.' . $dependency, + $this->Application->AssetManager->publishFilePath( + $this->_getControlScriptPath($dependency) + ) + ); + } + } + + private function _registerStyleFile($styleFile) { + $this->_registerExternalStyleDependencies( + $this->getExternalStyleDependencies() + ); + $this->_registerLibStyleDependencies( + $this->getLibStyleDependencies() + ); + $this->_registerControlStyleDependencies( + $this->getControlStyleDependencies() + ); + if (method_exists($this->Page->ClientScript, 'registerThemeStyleSheetFile')) { + $this->Page->ClientScript->registerThemeStyleSheetFile( + 'TemplateControl.' . get_class($this), + $this->Application->AssetManager->publishFilePath($styleFile) + ); + } else { + $this->Page->ClientScript->registerStyleSheetFile( + 'TemplateControl.' . get_class($this), + $this->Application->AssetManager->publishFilePath($styleFile) + ); + } + } + + private function _registerExternalStyleDependencies(array $dependencies) { + foreach ($dependencies as $dependency) { + $this->Page->ClientScript->registerStyleSheetFile( + $dependency, $dependency + ); + } + } + + private function _registerLibStyleDependencies(array $dependencies) { + foreach ($dependencies as $dependency) { + $this->Page->ClientScript->registerStyleSheetFile( + 'LibStyle.' . $dependency, + $this->Application->AssetManager->publishFilePath( + $this->_getLibPath($dependency, '.css') + ) + ); + } + } + + private function _registerControlStyleDependencies(array $dependencies) { + foreach ($dependencies as $dependency) { + $this->Page->ClientScript->registerStyleSheetFile( + 'TemplateControl.' . $dependency, + $this->Application->AssetManager->publishFilePath( + $this->_getControlStylePath($dependency) + ) + ); + } + } + +} + +?> diff --git a/app/frontend/web/ThemeManager.php b/app/frontend/web/ThemeManager.php new file mode 100644 index 0000000..9dcae76 --- /dev/null +++ b/app/frontend/web/ThemeManager.php @@ -0,0 +1,11 @@ + diff --git a/app/frontend/web/config.xml b/app/frontend/web/config.xml new file mode 100644 index 0000000..49bbcc6 --- /dev/null +++ b/app/frontend/web/config.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/php/application.xml b/app/php/application.xml deleted file mode 100644 index 6937e53..0000000 --- a/app/php/application.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/php/caches.xml b/app/php/caches.xml deleted file mode 100644 index 8a88717..0000000 --- a/app/php/caches.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/app/php/components/FileUploadSecureFileSize.php b/app/php/components/FileUploadSecureFileSize.php deleted file mode 100644 index 1e60c9a..0000000 --- a/app/php/components/FileUploadSecureFileSize.php +++ /dev/null @@ -1,18 +0,0 @@ -getIsSecure()) { - return filesize($this->getLocalName()); - } - return parent::getFileSize(); - } - -} - -?> diff --git a/app/php/components/FileUploadSecureFileType.php b/app/php/components/FileUploadSecureFileType.php deleted file mode 100644 index ce16501..0000000 --- a/app/php/components/FileUploadSecureFileType.php +++ /dev/null @@ -1,19 +0,0 @@ -getIsSecure()) { - $fileInfo = new finfo(FILEINFO_MIME_TYPE); - return $fileInfo->file($this->getLocalName()); - } - return parent::getFileType(); - } - -} - -?> diff --git a/app/php/components/FileUploadSecureMethods.php b/app/php/components/FileUploadSecureMethods.php deleted file mode 100644 index 8a42240..0000000 --- a/app/php/components/FileUploadSecureMethods.php +++ /dev/null @@ -1,16 +0,0 @@ - diff --git a/app/php/components/FileUploadSecureOption.php b/app/php/components/FileUploadSecureOption.php deleted file mode 100644 index 3550e21..0000000 --- a/app/php/components/FileUploadSecureOption.php +++ /dev/null @@ -1,17 +0,0 @@ -_isSecure; - } - - public function setIsSecure($bool) { - $this->_isSecure = $bool; - } - -} - -?> diff --git a/app/php/components/SafeActiveFileUpload.php b/app/php/components/SafeActiveFileUpload.php deleted file mode 100644 index 69bffab..0000000 --- a/app/php/components/SafeActiveFileUpload.php +++ /dev/null @@ -1,13 +0,0 @@ - diff --git a/app/php/components/SafeFileUpload.php b/app/php/components/SafeFileUpload.php deleted file mode 100644 index a8cbcae..0000000 --- a/app/php/components/SafeFileUpload.php +++ /dev/null @@ -1,11 +0,0 @@ - diff --git a/app/php/controls/AddToFilter.php b/app/php/controls/AddToFilter.php deleted file mode 100644 index 9146f3b..0000000 --- a/app/php/controls/AddToFilter.php +++ /dev/null @@ -1,41 +0,0 @@ -setViewState('Description', TPropertyValue::ensureString($val)); - } - - public function getDescription() { - return $this->getViewState('Description'); - } - - public function setUserPreference($sender, $param) { - $user = $this->getUserToManage(); - if ($user && !$user->IsGuest) { - if ($sender->Checked) { - $this->getFacade()->addToPreference($user, $this->getCalendar()->ID); - } else { - $this->getFacade()->removeFromPreference($user, $this->getCalendar()->ID); - } - $this->Page->CallbackClient->jQuery($this->Box, 'removeAttr', 'disabled'); - } - } - - public function getUserToManage() { - return $this->getControlState('user'); - } - - public function setUserToManage($user) { - $this->setControlState('user', $user); - } - - public function getPradoScriptDependencies() { - return ['jquery']; - } - -} - -?> diff --git a/app/php/controls/AddToFilter.tpl b/app/php/controls/AddToFilter.tpl deleted file mode 100644 index a202aa7..0000000 --- a/app/php/controls/AddToFilter.tpl +++ /dev/null @@ -1,8 +0,0 @@ - - <%= !$this->UserToManage->IsGuest %> - <%= $this->Facade->isCalendarPreferred($this->UserToManage, $this->getCalendar()->ID) %> - <%= $this->UserToManage->IsGuest ? Prado::localize('log in to manage your selections') : '' %> - - - <%= $this->getDescription() %> - diff --git a/app/php/controls/CalendarDetails.php b/app/php/controls/CalendarDetails.php deleted file mode 100644 index 95ee563..0000000 --- a/app/php/controls/CalendarDetails.php +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/app/php/controls/CalendarDetails.tpl b/app/php/controls/CalendarDetails.tpl deleted file mode 100644 index 2fd755c..0000000 --- a/app/php/controls/CalendarDetails.tpl +++ /dev/null @@ -1,13 +0,0 @@ - - <%= $this->getCalendar()->Name %> - - - <%= $this->getCalendar()->Image %> - - - <%[ Source website ]%> - <%= $this->getCalendar()->Website %> - -

- <%[ Last updated: ]%> <%= $this->getCalendar()->LastUpdated %> -

diff --git a/app/php/controls/CalendarGrid.php b/app/php/controls/CalendarGrid.php deleted file mode 100644 index 4ebfacd..0000000 --- a/app/php/controls/CalendarGrid.php +++ /dev/null @@ -1,59 +0,0 @@ -setControlState('Month', $month); - } - - public function getMonth() { - return $this->getControlState('Month'); - } - - public function setYear($year) { - $this->setControlState('Year', $year); - } - - public function getYear() { - return $this->getControlState('Year'); - } - - public function setUserToDisplay(DbUser $user) { - $this->setControlState('User', $user); - } - - public function getUserToDisplay() { - return $this->getControlState('User'); - } - - private function _getGrid() { - return $this->getFacade()->getCalendarListForUser( - $this->UserToDisplay, - $this->Month, - $this->Year - ); - } - - public function onPreRender($param) { - parent::onPreRender($param); - $this->Weeks->DataSource = $this->_getGrid()->Weeks; - $this->Weeks->dataBind(); - } - - public function weekDataBind($sender, $param) { - $param->Item->Days->DataSource = $param->Item->Data; - $param->Item->Days->dataBind(); - } - - public function dayDataBind($sender, $param) { - $param->Item->Events->DataSource = $param->Item->Data->Events; - $param->Item->Events->dataBind(); - } - -} - -?> diff --git a/app/php/controls/CalendarGrid.tpl b/app/php/controls/CalendarGrid.tpl deleted file mode 100644 index 2b3ada8..0000000 --- a/app/php/controls/CalendarGrid.tpl +++ /dev/null @@ -1,28 +0,0 @@ - - -
- - -
- <%# $this->Data->Date %> - - - - - - gridEvent <%# $this->Parent->Parent->Data->Date == $this->Data->DateFrom ? 'beginDate' : '' %> <%# $this->Parent->Parent->Data->Date == $this->Data->DateTo ? 'endDate' : '' %> - <%# $this->Data->Name %> - - - -
 
-
-
-
-
-
-
-
-
-
-
diff --git a/app/php/controls/CalendarGroupFilter.php b/app/php/controls/CalendarGroupFilter.php deleted file mode 100644 index 6f19bcd..0000000 --- a/app/php/controls/CalendarGroupFilter.php +++ /dev/null @@ -1,21 +0,0 @@ -Categories->DataSource = $this->Facade->getCategories(); - $this->Categories->dataBind(); - } - - public function getPradoScriptDependencies() { - return ['jquery']; - } - -} - -?> diff --git a/app/php/controls/CalendarGroupFilter.tpl b/app/php/controls/CalendarGroupFilter.tpl deleted file mode 100644 index ac82465..0000000 --- a/app/php/controls/CalendarGroupFilter.tpl +++ /dev/null @@ -1,16 +0,0 @@ - - -
- <%[ All ]%> - -
-
- -
- <%# $this->Data->Name %> - - <%# $this->Data->ID %> - -
-
-
diff --git a/app/php/controls/CalendarLabel.php b/app/php/controls/CalendarLabel.php deleted file mode 100644 index 667e847..0000000 --- a/app/php/controls/CalendarLabel.php +++ /dev/null @@ -1,13 +0,0 @@ - diff --git a/app/php/controls/CalendarLabel.tpl b/app/php/controls/CalendarLabel.tpl deleted file mode 100644 index 69e0147..0000000 --- a/app/php/controls/CalendarLabel.tpl +++ /dev/null @@ -1,12 +0,0 @@ - - <%= $this->Calendar->GroupID %> - - <%= $this->Service->constructUrl('Calendar', ['calendar' => $this->Calendar->Url]) %> - <%= $this->Calendar->Name %> - - - <%= $this->Facade %> - <%= $this->Calendar->Url %> - <%= $this->User %> - - diff --git a/app/php/controls/CalendarScaffold.php b/app/php/controls/CalendarScaffold.php deleted file mode 100644 index 7f15a32..0000000 --- a/app/php/controls/CalendarScaffold.php +++ /dev/null @@ -1,142 +0,0 @@ -Page->IsPostBack && !$this->Page->IsCallBack) { - $this->_rebindData(); - } - } - - private function _rebindCalendars(array $calendars) { - $this->Calendars->DataSource = $calendars; - $this->Calendars->dataBind(); - } - - private function _rebindCategoryList(array $categories) { - foreach ($this->Calendars->Columns as $column) { - if ($column->ID === 'Category' - && $column instanceof TActiveDropDownListColumn) { - $column->ListDataSource = $categories; - } - } - } - - private function _rebindData(bool $refresh = FALSE) { - $this->_rebindCategoryList( - $this->_getCategories() - ); - $this->_rebindCalendars( - $this->_getCalendars($refresh) - ); - } - - private function _getCalendars(bool $refresh = FALSE) { - if ($refresh) { - $this->clearViewState('Calendars'); - } - $calendars = $this->getViewState( - 'Calendars', - $this->getFacade()->getAll() - ); - $this->setViewState('Calendars', $calendars); - return $calendars; - } - - private function _getCategories() { - $categories = $this->getViewState( - 'Categories', - $this->getFacade()->getCategories() - ); - $this->setViewState('Categories', $categories); - return $categories; - } - - public function editRow($sender, $param) { - $this->Calendars->EditItemIndex = $param->Item->ItemIndex; - $this->_rebindData(); - } - - private function _compileSaveData(TDataGridItem $item) { - return [ - 'CategoryID' => $item->Category->DropDownList->SelectedValue, - 'Visible' => $item->Visible->CheckBox->Checked, - 'CustomName' => $item->CustomName->TextBox->SafeText, - 'CustomUrl' => $item->CustomUrl->TextBox->SafeText, - 'CustomImage' => $item->CustomImage->Value->SafeText - ]; - } - - public function saveRow($sender, $param) { - $calendar = $this->getFacade()->get( - $sender->DataKeys[$param->Item->ItemIndex] - ); - if ($calendar) { - foreach ($calendar as $c) { - $c->saveData($this->_compileSaveData($param->Item)); - } - } else { - throw new TInvalidDataValueException( - Prado::localize('Calendar not found') - ); - } - $this->Calendars->EditItemIndex = -1; - $this->_rebindData(TRUE); - } - - public function cancelRowEdit($sender, $param) { - $this->Calendars->EditItemIndex = -1; - $this->_rebindData(); - } - - public function toggleDefaultState($sender, $param) { - $calendar = $this->getFacade()->get($sender->CustomData); - if ($calendar) { - $calendar[0]->Visible = $sender->Checked; - $calendar[0]->save(); - $this->_rebindData(TRUE); - } - } - - public function uploadRowFile($sender, $param) { - $fileType = $sender->getFileType(); - if (preg_match('/^image\//', $fileType)) { - $calendar = $this->getFacade()->get($sender->CustomData); - if ($calendar) { - $targetFile = $calendar[0]->getCustomImagePath( - $sender->getLocalName(), - $fileType - ); - if ($sender->saveAs($targetFile)) { - $sender->NamingContainer->CustomImage->Value->Text = basename( - $targetFile - ); - } - } else { - throw new TInvalidDataValueException( - Prado::localize('Calendar not found') - ); - } - } else { - throw new TInvalidDataTypeException( - Prado::localize('Invalid file type') - ); - } - } - - protected function getPradoScriptDependencies() { - return ['jquery']; - } - -} - -?> diff --git a/app/php/controls/CalendarScaffold.tpl b/app/php/controls/CalendarScaffold.tpl deleted file mode 100644 index 6a22bc2..0000000 --- a/app/php/controls/CalendarScaffold.tpl +++ /dev/null @@ -1,81 +0,0 @@ - - - - <%[ Calendar ]%> - - - <%[ WWW ]%> - <%[ [www] ]%> - - - <%[ ICS ]%> - <%[ [ics] ]%> - - - <%[ Category ]%> - - - <%[ Default ]%> - - - <%# $this->Parent->Data->Visible %> - <%# $this->Parent->Data->UID %> - - - - - <%# $this->Parent->Data->Visible %> - - - - - <%[ Custom name ]%> - - - <%[ URL ]%> - - - <%[ Image ]%> - - - <%# $this->Parent->Data->CustomImageUrl %> - - - - - <%# $this->Parent->Data->CustomImage %> -
- - <%# $this->Parent->Data->UID %> - -
-
- - <%[ Edit ]%> - <%[ Save ]%> - <%[ Cancel ]%> - -
-
diff --git a/app/php/controls/CalendarSelection.php b/app/php/controls/CalendarSelection.php deleted file mode 100644 index e53aa36..0000000 --- a/app/php/controls/CalendarSelection.php +++ /dev/null @@ -1,17 +0,0 @@ -Page->IsCallBack) { - $this->Calendars->DataSource = $this->Facade->getAll(); - $this->Calendars->dataBind(); - } - } - -} - -?> diff --git a/app/php/controls/CalendarSelection.tpl b/app/php/controls/CalendarSelection.tpl deleted file mode 100644 index d6bdd83..0000000 --- a/app/php/controls/CalendarSelection.tpl +++ /dev/null @@ -1,8 +0,0 @@ - - - - <%# $this->SourceTemplateControl->Facade %> - <%# $this->Data->CustomUrl %> - - - diff --git a/app/php/controls/EventList.php b/app/php/controls/EventList.php deleted file mode 100644 index d40e000..0000000 --- a/app/php/controls/EventList.php +++ /dev/null @@ -1,59 +0,0 @@ - $date]) - ); - } - $this->setViewState($key, $datetime); - } - - public function setDateFrom($date) { - $this->_setDate('DateFrom', $date); - } - - public function getDateFrom() { - return $this->getViewState('DateFrom'); - } - - public function setDateTo($date) { - $this->_setDate('DateTo', $date); - } - - public function getDateTo() { - return $this->getViewState('DateTo'); - } - - public function setHeaderText($text) { - $this->setViewState('HeaderText', TPropertyValue::ensureString($text)); - } - - public function getHeaderText() { - return $this->getViewState('HeaderText'); - } - - public function setReverse($value) { - $this->setViewState('Reverse', TPropertyValue::ensureBoolean($value)); - } - - public function getReverse() { - return $this->getViewState('Reverse'); - } - - public function getEvents() { - return $this->getFacade()->getEventsForTimeframe( - $this->getCalendar(), - $this->getDateFrom() ?: new DateTime('0000-00-00'), - $this->getDateTo() ?: new DateTime('9999-99-99'), - $this->getReverse() ? 'DESC' : 'ASC' - ); - } - -} - -?> diff --git a/app/php/controls/EventList.tpl b/app/php/controls/EventList.tpl deleted file mode 100644 index 5881ce7..0000000 --- a/app/php/controls/EventList.tpl +++ /dev/null @@ -1,6 +0,0 @@ - - <%= $this->getHeaderText() %> - - - <%= $this->getEvents() %> - diff --git a/app/php/controls/EventRepeater.php b/app/php/controls/EventRepeater.php deleted file mode 100644 index 4fb2812..0000000 --- a/app/php/controls/EventRepeater.php +++ /dev/null @@ -1,25 +0,0 @@ -Events->DataSource = $events; - $this->Events->dataBind(); - } - - public function setCalendarLinkVisible($value) { - $this->setViewState( - 'CalendarLinkVisible', - TPropertyValue::ensureBoolean($value) - ); - } - - public function getCalendarLinkVisible() { - return $this->getViewState('CalendarLinkVisible', TRUE); - } - -} - -?> diff --git a/app/php/controls/EventRepeater.tpl b/app/php/controls/EventRepeater.tpl deleted file mode 100644 index 69aaabf..0000000 --- a/app/php/controls/EventRepeater.tpl +++ /dev/null @@ -1,12 +0,0 @@ - - - <%# $this->Data->DateString %> - <%# $this->Data->Name %> - - <%# $this->SourceTemplateControl->CalendarLinkVisible %> - (<%# $this->Data->Calendar->Name %>) - <%# $this->Service->constructUrl('Calendar', ['calendar' => $this->Data->Calendar->Url]) %> - -
-
-
diff --git a/app/php/controls/HeaderMenu.php b/app/php/controls/HeaderMenu.php deleted file mode 100644 index 2488629..0000000 --- a/app/php/controls/HeaderMenu.php +++ /dev/null @@ -1,26 +0,0 @@ -Application->getModule('auth'); - $authModule->setReturnUrl($this->Request->RequestUri); - $this->Response->redirect( - $this->Service->ConstructUrl($authModule->LoginPage) - ); - } - - public function logoutUser($sender, $param) { - $this->Application->getModule('auth')->logout(); - $this->Response->redirect( - $this->Service->ConstructUrl(NULL) - ); - } - -} - -?> diff --git a/app/php/controls/HeaderMenu.tpl b/app/php/controls/HeaderMenu.tpl deleted file mode 100644 index a760588..0000000 --- a/app/php/controls/HeaderMenu.tpl +++ /dev/null @@ -1,36 +0,0 @@ - diff --git a/app/php/controls/LoginBox.php b/app/php/controls/LoginBox.php deleted file mode 100644 index 1136a79..0000000 --- a/app/php/controls/LoginBox.php +++ /dev/null @@ -1,39 +0,0 @@ -Page->IsPostBack && !$this->User->IsGuest) { - $this->_afterLoginRedirect(); - } - } - - private function _afterLoginRedirect() { - $authModule = $this->Application->getModule('auth'); - $redirUrl = $authModule->ReturnUrl; - if (!$redirUrl - || $redirUrl == $this->Service->constructUrl($authModule->LoginPage)) { - $redirUrl = $this->Service->constructUrl(NULL); - } - $this->Response->redirect($redirUrl); - } - - public function loginUser($sender, $param) { - if ($this->Page->IsValid) { - $this->_afterLoginRedirect(); - } - } - - public function validatePassword($sender, $param) { - $param->IsValid = $this->Application->getModule('auth')->login( - $this->Login->Text, - $this->Password->Text - ); - } - -} - -?> diff --git a/app/php/controls/LoginBox.tpl b/app/php/controls/LoginBox.tpl deleted file mode 100644 index 070ab86..0000000 --- a/app/php/controls/LoginBox.tpl +++ /dev/null @@ -1,33 +0,0 @@ -<%[ Username: ]%> - - - <%[ Username cannot be empty ]%> - -
-<%[ Password: ]%> - - - <%[ Password cannot be empty ]%> - - - <%[ Username and password don't match ]%> - -
- - <%[ Login ]%> - diff --git a/app/php/controls/PasswordChange.php b/app/php/controls/PasswordChange.php deleted file mode 100644 index 45ce656..0000000 --- a/app/php/controls/PasswordChange.php +++ /dev/null @@ -1,44 +0,0 @@ -getControlState('user'); - } - - public function setUserToChange(DbUser $user) { - if ($user->IsGuest && !$this->Page->IsCallBack) { - throw new TInvalidDataValueException( - Prado::localize( - 'Password change impossible for guest user' - ) - ); - } - $this->setControlState('user', $user); - } - - public function checkPassword($sender, $param) { - $param->IsValid = $this->getFacade()->verifyUserPassword( - $this->Password->Text, $this->UserToChange - ); - } - - public function changePassword($sender, $param) { - $this->SuccessMessage->Visible = FALSE; - if ($this->Page->IsValid) { - $this->getFacade()->changePassword( - $this->UserToChange, - $this->NewPassword->Text - ); - $this->SuccessMessage->Visible = TRUE; - } - } - -} - -?> diff --git a/app/php/controls/PasswordChange.tpl b/app/php/controls/PasswordChange.tpl deleted file mode 100644 index 4eb9a8e..0000000 --- a/app/php/controls/PasswordChange.tpl +++ /dev/null @@ -1,59 +0,0 @@ -<%[ Change password ]%>
-<%[ Current password: ]%> - - - <%[ Current password cannot be empty ]%> - - - <%[ Password is incorrect ]%> - -
-<%[ New password: ]%> - - - <%[ New password cannot be empty ]%> - -
-<%[ Repeat password: ]%> - - - <%[ New password cannot be empty ]%> - - - <%[ Passwords don't match ]%> - -
- - <%[ Change password ]%> - - - <%[ Your password has been changed ]%> - diff --git a/app/php/controls/RegistrationForm.php b/app/php/controls/RegistrationForm.php deleted file mode 100644 index 46494e3..0000000 --- a/app/php/controls/RegistrationForm.php +++ /dev/null @@ -1,28 +0,0 @@ -IsValid = $this->getFacade()->checkForUsername($this->Login->SafeText); - } - - public function registerUser($sender, $param) { - if ($this->Page->IsValid) { - $this->getFacade()->registerUser( - $this->Login->SafeText, - $this->Password->Text, - $this->Admin->Checked - ); - $this->Response->redirect( - $this->Service->constructUrl(NULL) - ); - } - } - -} - -?> diff --git a/app/php/controls/RegistrationForm.tpl b/app/php/controls/RegistrationForm.tpl deleted file mode 100644 index 9defe54..0000000 --- a/app/php/controls/RegistrationForm.tpl +++ /dev/null @@ -1,66 +0,0 @@ -<%[ Username: ]%> - - - <%[ Username cannot be empty ]%> - - - <%[ Username must contain 6-255 characters, all Latin alphanumeric or underscore ]%> - - - <%[ Username already exists ]%> - -
-<%[ Password: ]%> - - - <%[ Password cannot be empty ]%> - -
-<%[ Repeat password: ]%> - - - <%[ Password cannot be empty ]%> - - - <%[ Passwords don't match ]%> - -
-<%[ Admin: ]%> - -
- - <%[ Create ]%> - - diff --git a/app/php/controls/TimezoneSelect.php b/app/php/controls/TimezoneSelect.php deleted file mode 100644 index 25af453..0000000 --- a/app/php/controls/TimezoneSelect.php +++ /dev/null @@ -1,58 +0,0 @@ -getControlState('user'); - } - - public function setUserToChange(DbUser $user) { - if ($user->IsGuest && !$this->Page->IsCallBack) { - throw new TInvalidDataValueException( - Prado::localize( - 'Timezone preference change impossible for guest user' - ) - ); - } - $this->setControlState('user', $user); - } - - public function onPreRender($param) { - parent::onPreRender($param); - $this->Timezones->DataSource = $this->_getTimezones(); - $this->Timezones->DataValueField = 'Name'; - $this->Timezones->DataTextField = 'Label'; - $this->Timezones->dataBind(); - $this->Timezones->setSelectedValue( - $this->getFacade()->getTimezonePreference($this->UserToChange)->Name - ); - } - - public function saveTimezone($sender, $param) { - $this->getFacade()->setTimezonePreference( - $this->UserToChange, - $this->Timezones->SelectedValue - ); - } - - private function _getTimezones() { - $timezones = array_map( - function($tz) { - return new TimezoneDTO($tz); - }, - DateTimeZone::listIdentifiers() - ); - usort($timezones, ['TimezoneDTO', '__compare']); - return $timezones; - } - -} - -?> diff --git a/app/php/controls/TimezoneSelect.tpl b/app/php/controls/TimezoneSelect.tpl deleted file mode 100644 index ee703d6..0000000 --- a/app/php/controls/TimezoneSelect.tpl +++ /dev/null @@ -1,5 +0,0 @@ - - - <%[ Save timezone ]%> - diff --git a/app/php/controls/UpcomingEvents.php b/app/php/controls/UpcomingEvents.php deleted file mode 100644 index 27fc723..0000000 --- a/app/php/controls/UpcomingEvents.php +++ /dev/null @@ -1,33 +0,0 @@ -getControlState('user'); - } - - public function setUserToDisplay(DbUser $user) { - $this->setControlState('user', $user); - } - - public function getEvents() { - return $this->_getEventsForUser($this->UserToDisplay); - } - - private function _getEventsForUser(DbUser $user) { - $utc = new DateTimeZone('UTC'); - $dateFrom = new DateTime('now', $utc); - $dateTo = new DateTime('+7 days', $utc); - return $this->getFacade()->getTimeframeListForUser( - $user, - $dateFrom, $dateTo - ); - } - -} - -?> diff --git a/app/php/controls/UpcomingEvents.tpl b/app/php/controls/UpcomingEvents.tpl deleted file mode 100644 index ac5f60c..0000000 --- a/app/php/controls/UpcomingEvents.tpl +++ /dev/null @@ -1,5 +0,0 @@ -<%[ Upcoming events: ]%> -
- - <%= $this->getEvents() %> - diff --git a/app/php/controls/UrlBasedCalendarControl.php b/app/php/controls/UrlBasedCalendarControl.php deleted file mode 100644 index a5be82e..0000000 --- a/app/php/controls/UrlBasedCalendarControl.php +++ /dev/null @@ -1,40 +0,0 @@ -getFacade()->resolveUrl($url); - if ($calendar) { - $this->setControlState('Calendar', $calendar); - return; - } - } - if ($this->getRaiseException()) { - throw new THttpException( - 404, - Prado::localize('Page not found') - ); - } else { - $this->Visible = FALSE; - } - } - - public function getCalendar() { - return $this->getControlState('Calendar'); - } - - public function setRaiseException($value) { - $this->setControlState('RaiseException', TPropertyValue::ensureBoolean($value)); - } - - public function getRaiseException() { - return $this->getControlState('RaiseException', FALSE); - } - -} - -?> diff --git a/app/php/controls/UserSelection.php b/app/php/controls/UserSelection.php deleted file mode 100644 index 233f0bf..0000000 --- a/app/php/controls/UserSelection.php +++ /dev/null @@ -1,45 +0,0 @@ -getControlState('user'); - } - - public function setUserToDisplay(DbUser $user = NULL) { - $this->setControlState('user', $user); - } - - public function onPreRender($param) { - parent::onPreRender($param); - $this->Categories->setDataSource( - $this->_getUserSelection($this->UserToDisplay) - ); - $this->Categories->dataBind(); - } - - public function categoryDataBind($sender, $param) { - $param->Item->Calendars->setDataSource($param->Item->Data->Calendars); - $param->Item->Calendars->dataBind(); - } - - public function removeFromSelection($sender, $param) { - if (!$this->UserToDisplay->IsGuest) { - return $this->getFacade()->removeFromPreference( - $this->UserToDisplay, - $param->CommandParameter - ); - } - } - - private function _getUserSelection(DbUser $user) { - return $this->getFacade()->getPreferenceList($user); - } - -} - -?> diff --git a/app/php/controls/UserSelection.tpl b/app/php/controls/UserSelection.tpl deleted file mode 100644 index 8d20365..0000000 --- a/app/php/controls/UserSelection.tpl +++ /dev/null @@ -1,29 +0,0 @@ -<%[ Selected calendars: ]%> -
- - - <%# $this->Data->Name %>
- - - - <%# $this->Data->ID %> - <%# !$this->SourceTemplateControl->UserToDisplay->IsGuest %> - - <%# $this->Data->Name %> - - <%[ (details) ]%> - <%# $this->Service->constructUrl('Calendar', ['calendar' => $this->Data->Url]) %> - - - <%# $this->Data->Website %> - -
-
-
-
-
-
diff --git a/app/php/controls/config.xml b/app/php/controls/config.xml deleted file mode 100644 index 61d7e5b..0000000 --- a/app/php/controls/config.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/app/php/controls/scripts/AddToFilter.js b/app/php/controls/scripts/AddToFilter.js deleted file mode 100644 index e6d7b39..0000000 --- a/app/php/controls/scripts/AddToFilter.js +++ /dev/null @@ -1,5 +0,0 @@ -$(document).on('ready', function() { - $('input.addToFilterBox').on('change', function() { - $(this).attr('disabled', true); - }); -}); diff --git a/app/php/controls/scripts/CalendarGroupFilter.js b/app/php/controls/scripts/CalendarGroupFilter.js deleted file mode 100644 index e6c1d73..0000000 --- a/app/php/controls/scripts/CalendarGroupFilter.js +++ /dev/null @@ -1,29 +0,0 @@ -$(document).on('ready', function() { - var selectBoxes = $('.selectGroup input.box'); - var selectAllBox = $('.selectAllGroups input.box'); - selectBoxes.on('change', function() { - var groups = []; - var allSelected = true; - $('.selectGroup input.box').each(function() { - var box = $(this); - if (box.is(':checked')) { - groups.push(box.val()); - } else { - allSelected = false; - } - }); - if (allSelected) { - selectAllBox.prop('checked', true); - } else { - selectAllBox.removeAttr('checked'); - } - $(document).trigger('Application.calendarGroupFilterChanged', {groups: groups}); - }); - selectAllBox.on('change', function() { - if ($(this).is(':checked')) { - selectBoxes.prop('checked', true).trigger('change'); - } else { - selectBoxes.removeAttr('checked').trigger('change'); - } - }); -}); diff --git a/app/php/controls/scripts/CalendarLabel.js b/app/php/controls/scripts/CalendarLabel.js deleted file mode 100644 index 8193e56..0000000 --- a/app/php/controls/scripts/CalendarLabel.js +++ /dev/null @@ -1,11 +0,0 @@ -$(document).on('Application.calendarGroupFilterChanged', function(event, args) { - var selectedGroups = args.groups || []; - $('.calendar').each(function() { - var label = $(this); - if (selectedGroups.indexOf(label.attr('data-group')) >= 0) { - label.show(); - } else { - label.hide(); - } - }); -}); diff --git a/app/php/controls/scripts/CalendarScaffold.js b/app/php/controls/scripts/CalendarScaffold.js deleted file mode 100644 index d4b8ec5..0000000 --- a/app/php/controls/scripts/CalendarScaffold.js +++ /dev/null @@ -1,8 +0,0 @@ -$('body').on( - 'click', - 'main .calendarScaffold tbody a[href^="javascript:;//"], main .calendarScaffold tbody input.visibilityToggle', - function(e) { - var loader = $('
').addClass('calendarScaffoldLoader'); - $('main .calendarScaffold div[id$="_Container"]').append(loader); - } -); diff --git a/app/php/controls/styles/CalendarGrid.css b/app/php/controls/styles/CalendarGrid.css deleted file mode 100644 index 4710993..0000000 --- a/app/php/controls/styles/CalendarGrid.css +++ /dev/null @@ -1,16 +0,0 @@ -div.gridWeek { - clear: both; - display: flex; - flex-flow: row nowrap; -} -div.gridDay { - width: 14%; - min-height: 8em; - flex: 1 1 auto; -} -div.gridEvent, div.gridItem { height: 1.5em; padding: 0.3em 0.5em; margin: 0.1em 0; } -div.gridEvent { overflow: hidden; white-space: nowrap; background: #ddd } -div.gridEvent.beginDate { border-top-left-radius: 1.5em; - border-bottom-left-radius: 1.5em } -div.gridEvent.endDate { border-top-right-radius: 1.5em; - border-bottom-right-radius: 1.5em } diff --git a/app/php/controls/styles/CalendarScaffold.css b/app/php/controls/styles/CalendarScaffold.css deleted file mode 100644 index 071f672..0000000 --- a/app/php/controls/styles/CalendarScaffold.css +++ /dev/null @@ -1,11 +0,0 @@ -.calendarScaffold { - position: relative; -} -.calendarScaffold .calendarScaffoldLoader { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: url(preloader.gif) no-repeat center 5% rgba(255,255,255,0.8); -} diff --git a/app/php/db/ActiveRecord.php b/app/php/db/ActiveRecord.php deleted file mode 100644 index 1176767..0000000 --- a/app/php/db/ActiveRecord.php +++ /dev/null @@ -1,69 +0,0 @@ - 2) { - $method .= $parameter[2]; - } - } - } - } - } - return $method; - } - - public function __get($name) { - $name = $this->_getMappedPropertyName($name); - if (property_exists($this, $name)) { - return $this->$name; - } - return parent::__get($name); - } - - public function __set($name, $value) { - $name = $this->_getMappedPropertyName($name); - if (property_exists($this, $name)) { - return $this->$name = $value; - } - return parent::__set($name, $value); - } - - public function __call($method, $args) { - return parent::__call($this->_getMappedMethodName($method), $args); - } - -} - -?> diff --git a/app/php/db/DBConnection.php b/app/php/db/DBConnection.php deleted file mode 100644 index 92ab0fb..0000000 --- a/app/php/db/DBConnection.php +++ /dev/null @@ -1,28 +0,0 @@ -_transaction->getActive()) { - $this->_transaction = NULL; - } - return $this->_transaction; - } - - public function beginTransaction() { - if ($this->_transaction && $this->_transaction->getActive()) { - $this->_transaction->beginNestedTransaction(); - } - else { - $this->_transaction = parent::beginTransaction(); - } - return $this->_transaction; - } - -} - -?> diff --git a/app/php/db/DBModule.php b/app/php/db/DBModule.php deleted file mode 100644 index 462b6f6..0000000 --- a/app/php/db/DBModule.php +++ /dev/null @@ -1,40 +0,0 @@ -getAttributes() as $attr => $val) { - $newXML->setAttribute($attr, $val); - } - $dbXML = new TXmlElement('database'); - $config = json_decode(file_get_contents( - Prado::getPathOfNamespace($this->_config, '.json') - )); - if (isset($config->cset)) { - $dbXML->setAttribute('Charset', $config->cset); - } - $dbXML->setAttribute('Username', $config->user); - $dbXML->setAttribute('Password', $config->pass); - $dbXML->setAttribute( - 'ConnectionString', - sprintf( - '%s:host=%s;dbname=%s', - $config->type, $config->host, $config->name - ) - ); - $newXML->Elements[] = $dbXML; - parent::init($newXML); - } - - public function setConfig($config) { - $this->_config = TPropertyValue::ensureString($config); - } - -} - -?> diff --git a/app/php/db/DBTransaction.php b/app/php/db/DBTransaction.php deleted file mode 100644 index b176453..0000000 --- a/app/php/db/DBTransaction.php +++ /dev/null @@ -1,53 +0,0 @@ -getActive()) { - $this->_nestedCount++; - } - } - - public function commit() { - if ($this->_rolledBack) { - $childTransaction = (bool)($this->_nestedCount); - $this->rollback(); - if (!$childTransaction) { - throw new TDbException('Nested transaction was rolled back, unable to commit.'); - } - } - else { - if ($this->_nestedCount) { - $this->_nestedCount--; - } - else { - parent::commit(); - } - } - } - - public function rollback() { - if (!$this->getActive()) { - $this->_nestedCount = 0; - return; - } - if ($this->_nestedCount) { - $this->_rolledBack = TRUE; - $this->_nestedCount--; - } - else { - parent::rollback(); - $this->_nestedCount = 0; - $this->_rolledBack = FALSE; - } - } - -} - -?> diff --git a/app/php/db/config.json b/app/php/db/config.json deleted file mode 120000 index 89a492f..0000000 --- a/app/php/db/config.json +++ /dev/null @@ -1 +0,0 @@ -../../../config/db.json \ No newline at end of file diff --git a/app/php/db/config.xml b/app/php/db/config.xml deleted file mode 100644 index 3210593..0000000 --- a/app/php/db/config.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/app/php/dto/CalendarDTO.php b/app/php/dto/CalendarDTO.php deleted file mode 100644 index 4468941..0000000 --- a/app/php/dto/CalendarDTO.php +++ /dev/null @@ -1,31 +0,0 @@ -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/php/dto/CalendarGridDTO.php b/app/php/dto/CalendarGridDTO.php deleted file mode 100644 index f5d91a5..0000000 --- a/app/php/dto/CalendarGridDTO.php +++ /dev/null @@ -1,84 +0,0 @@ -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/php/dto/CalendarGridDayDTO.php b/app/php/dto/CalendarGridDayDTO.php deleted file mode 100644 index ba65eb9..0000000 --- a/app/php/dto/CalendarGridDayDTO.php +++ /dev/null @@ -1,28 +0,0 @@ -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/php/dto/CalendarGroupDTO.php b/app/php/dto/CalendarGroupDTO.php deleted file mode 100644 index 7b64c6e..0000000 --- a/app/php/dto/CalendarGroupDTO.php +++ /dev/null @@ -1,44 +0,0 @@ -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/php/dto/EventDTO.php b/app/php/dto/EventDTO.php deleted file mode 100644 index 8f5cdf5..0000000 --- a/app/php/dto/EventDTO.php +++ /dev/null @@ -1,85 +0,0 @@ -_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/php/dto/GridEventDTO.php b/app/php/dto/GridEventDTO.php deleted file mode 100644 index 0d2bb37..0000000 --- a/app/php/dto/GridEventDTO.php +++ /dev/null @@ -1,28 +0,0 @@ -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/php/dto/TimezoneDTO.php b/app/php/dto/TimezoneDTO.php deleted file mode 100644 index e4078e6..0000000 --- a/app/php/dto/TimezoneDTO.php +++ /dev/null @@ -1,46 +0,0 @@ -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/php/dto/weekdays.json b/app/php/dto/weekdays.json deleted file mode 120000 index 325c801..0000000 --- a/app/php/dto/weekdays.json +++ /dev/null @@ -1 +0,0 @@ -../../../config/weekdays.json \ No newline at end of file diff --git a/app/php/events/CalendarPreferenceEvents.php b/app/php/events/CalendarPreferenceEvents.php deleted file mode 100644 index 76fa071..0000000 --- a/app/php/events/CalendarPreferenceEvents.php +++ /dev/null @@ -1,16 +0,0 @@ -setPreferredCalendars($user, $facade->getDefaultPreference()); - } - -} - -?> diff --git a/app/php/events/EventModule.php b/app/php/events/EventModule.php deleted file mode 100644 index 6474523..0000000 --- a/app/php/events/EventModule.php +++ /dev/null @@ -1,53 +0,0 @@ -getMethods() as $method) { - if (is_a($method->class, get_class(), TRUE)) { - $eventPattern = []; - if (preg_match('/^on(.*)/', $method->name, $eventPattern)) { - $this->_registerEventHandler( - $eventPattern[1], - $method->getClosure($this) - ); - } - } - } - if (get_class() === get_called_class()) { - $directory = dirname(__FILE__); - foreach (scandir($directory) as $dirEntry) { - $classNameMatch = []; - if (preg_match('/(.*)\.php$/', $dirEntry, $classNameMatch)) { - $className = $classNameMatch[1]; - include_once($directory . DIRECTORY_SEPARATOR . $dirEntry); - if ($className != get_class() - && is_a($className, get_class(), TRUE)) { - $class = new $className(); - $class->init(NULL); - } - } - } - } - } - - protected static $_handlers = []; - private function _registerEventHandler($event, $handler) { - if (!isset(self::$_handlers[$event])) { - self::$_handlers[$event] = []; - } - self::$_handlers[$event][] = $handler; - } - - public function raiseApplicationEvent($event, ...$params) { - if (isset(self::$_handlers[$event])) { - foreach (self::$_handlers[$event] as $handler) { - call_user_func_array($handler, $params); - } - } - } - -} - -?> diff --git a/app/php/events/config.xml b/app/php/events/config.xml deleted file mode 100644 index d1c1e3f..0000000 --- a/app/php/events/config.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/app/php/facades/CalendarFacade.php b/app/php/facades/CalendarFacade.php deleted file mode 100644 index 1f78594..0000000 --- a/app/php/facades/CalendarFacade.php +++ /dev/null @@ -1,212 +0,0 @@ -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/php/facades/EventFacade.php b/app/php/facades/EventFacade.php deleted file mode 100644 index 14f809d..0000000 --- a/app/php/facades/EventFacade.php +++ /dev/null @@ -1,115 +0,0 @@ -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/php/facades/Facade.php b/app/php/facades/Facade.php deleted file mode 100644 index 346024a..0000000 --- a/app/php/facades/Facade.php +++ /dev/null @@ -1,62 +0,0 @@ -_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/php/facades/UserFacade.php b/app/php/facades/UserFacade.php deleted file mode 100644 index 1604a70..0000000 --- a/app/php/facades/UserFacade.php +++ /dev/null @@ -1,78 +0,0 @@ -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/php/facades/config.xml b/app/php/facades/config.xml deleted file mode 100644 index 8d5a298..0000000 --- a/app/php/facades/config.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/app/php/i18n/config.xml b/app/php/i18n/config.xml deleted file mode 100644 index c80b46d..0000000 --- a/app/php/i18n/config.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - diff --git a/app/php/layouts/Layout.php b/app/php/layouts/Layout.php deleted file mode 100644 index 324c69f..0000000 --- a/app/php/layouts/Layout.php +++ /dev/null @@ -1,11 +0,0 @@ -ViewID->Value ?: md5(mt_rand()); - } - -} - -?> diff --git a/app/php/layouts/MainLayout.php b/app/php/layouts/MainLayout.php deleted file mode 100644 index 5843952..0000000 --- a/app/php/layouts/MainLayout.php +++ /dev/null @@ -1,9 +0,0 @@ - diff --git a/app/php/layouts/MainLayout.tpl b/app/php/layouts/MainLayout.tpl deleted file mode 100644 index 0deb816..0000000 --- a/app/php/layouts/MainLayout.tpl +++ /dev/null @@ -1,22 +0,0 @@ - - - - - <com:TContentPlaceHolder ID="Title" /> - - - -
- -
-
- -
-
-
- - <%= $this->generateViewID() %> - -
- - diff --git a/app/php/model/Calendar.php b/app/php/model/Calendar.php deleted file mode 100644 index b49bf92..0000000 --- a/app/php/model/Calendar.php +++ /dev/null @@ -1,92 +0,0 @@ - 'UID', - 'url' => 'Url', - 'name' => 'Name', - 'website' => 'Website', - 'visible' => 'Visible', - 'last_updated' => 'LastUpdated', - 'custom_name' => 'CustomName', - 'custom_image' => 'CustomImage', - 'custom_url' => 'CustomUrl', - '_category' => 'CategoryID' - ]; - - public static $RELATIONS = [ - 'Entries' => [self::HAS_MANY, 'Entry', '_calendar'], - 'Category' => [self::BELONGS_TO, 'Category', '_category'] - ]; - - public static function finder($className=__CLASS__) { - return parent::finder($className); - } - - const CUSTOM_IMAGE_PATH = 'resources/images/calendars'; - - public function getCustomImageUrl() { - if ($this->CustomImage) { - if (!preg_match('#^//#', $this->CustomImage)) { - return Prado::getApplication()->getAssetManager()->publishFilePath( - implode( - DIRECTORY_SEPARATOR, - [ - Prado::getApplication()->getBasePath(), - self::CUSTOM_IMAGE_PATH, - $this->CustomImage - ] - ), - TRUE - ); - } - return $this->CustomImage; - } - } - - public function getCustomImagePath($forFile = NULL, $type = '') { - $pathParts = [ - Prado::getApplication()->getBasePath(), - self::CUSTOM_IMAGE_PATH - ]; - if ($forFile) { - $pathParts[] = $this->_getCustomImageHash($forFile, $type); - } - return implode(DIRECTORY_SEPARATOR, $pathParts); - } - - private function _getCustomImageHash($file, $type) { - $hash = md5($file . md5_file($file) . filemtime($file)); - if ($type) { - $hash .= '.' . preg_replace('#^image/#', '', $type); - } - return $hash; - } - - public function saveData($data) { - $this->copyFrom($data); - return $this->save(); - } - -} - -?> diff --git a/app/php/model/Category.php b/app/php/model/Category.php deleted file mode 100644 index 87b97b6..0000000 --- a/app/php/model/Category.php +++ /dev/null @@ -1,30 +0,0 @@ - 'ID', - 'name' => 'Name', - 'priority' => 'Priority' - ]; - - public static $RELATIONS = [ - 'Calendars' => [self::HAS_MANY, 'Calendar', '_category'] - ]; - - public static function finder($className=__CLASS__) { - return parent::finder($className); - } - -} - -?> diff --git a/app/php/model/Entry.php b/app/php/model/Entry.php deleted file mode 100644 index 4b93f04..0000000 --- a/app/php/model/Entry.php +++ /dev/null @@ -1,43 +0,0 @@ - 'ID', - 'uid' => 'UID', - 'begin_date' => 'BeginDate', - 'end_date' => 'EndDate', - 'all_day' => 'AllDay', - 'name' => 'Name', - 'location' => 'Location', - 'last_modified' => 'LastModified', - '_calendar' => 'CalendarID' - ]; - - public static $RELATIONS = [ - 'Calendar' => [self::BELONGS_TO, 'Calendar', '_calendar'] - ]; - - public static function finder($className=__CLASS__) { - return parent::finder($className); - } - -} - -?> diff --git a/app/php/model/User.php b/app/php/model/User.php deleted file mode 100644 index d431183..0000000 --- a/app/php/model/User.php +++ /dev/null @@ -1,36 +0,0 @@ - 'ID', - 'login' => 'Login', - 'password' => 'Password', - 'is_admin' => 'IsAdmin', - 'timezone' => 'Timezone', - 'last_login' => 'LastLogin' - ]; - - public static $RELATIONS = [ - 'Calendars' => [self::MANY_TO_MANY, 'Calendar', 'user_selections'] - ]; - - public static function finder($className=__CLASS__) { - return parent::finder($className); - } - -} - -?> diff --git a/app/php/model/UserPreference.php b/app/php/model/UserPreference.php deleted file mode 100644 index 90fa221..0000000 --- a/app/php/model/UserPreference.php +++ /dev/null @@ -1,23 +0,0 @@ - 'UserID', - '_calendar' => 'CalendarID' - ]; - - public static function finder($className=__CLASS__) { - return parent::finder($className); - } - -} - -?> diff --git a/app/php/model/config.xml b/app/php/model/config.xml deleted file mode 100644 index a729150..0000000 --- a/app/php/model/config.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - diff --git a/app/php/pages/Admin.page b/app/php/pages/Admin.page deleted file mode 100644 index b130583..0000000 --- a/app/php/pages/Admin.page +++ /dev/null @@ -1,5 +0,0 @@ - - - <%= CalendarFacade::getInstance() %> - - diff --git a/app/php/pages/Calendar.page b/app/php/pages/Calendar.page deleted file mode 100644 index f414dae..0000000 --- a/app/php/pages/Calendar.page +++ /dev/null @@ -1,28 +0,0 @@ - - - <%= CalendarFacade::getInstance() %> - <%= $this->Request->itemAt('calendar') %> - - - <%= CalendarFacade::getInstance() %> - <%= $this->getUser() %> - <%= $this->Request->itemAt('calendar') %> - - <%[ calendar visible in current filter selection ]%> - - - - <%= CalendarFacade::getInstance() %> - <%= $this->Request->itemAt('calendar') %> - - <%[ Upcoming events in the calendar: ]%> - - - - <%= CalendarFacade::getInstance() %> - <%= $this->Request->itemAt('calendar') %> - - <%[ Past events in the calendar: ]%> - - - diff --git a/app/php/pages/Home.page b/app/php/pages/Home.page deleted file mode 100644 index fb60066..0000000 --- a/app/php/pages/Home.page +++ /dev/null @@ -1,8 +0,0 @@ - - - <%= EventFacade::getInstance() %> - <%= $this->Request->itemAt('month') %> - <%= $this->Request->itemAt('year') %> - <%= $this->User %> - - diff --git a/app/php/pages/Login.page b/app/php/pages/Login.page deleted file mode 100644 index 15bc93e..0000000 --- a/app/php/pages/Login.page +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/app/php/pages/Profile.page b/app/php/pages/Profile.page deleted file mode 100644 index 163d3fa..0000000 --- a/app/php/pages/Profile.page +++ /dev/null @@ -1,21 +0,0 @@ - - - <%= UserFacade::getInstance() %> - <%= $this->User %> - -
- - <%= UserFacade::getInstance() %> - <%= $this->User %> - -
- - <%= $this->User %> - <%= CalendarFacade::getInstance() %> - -
- - <%= $this->User %> - <%= EventFacade::getInstance() %> - -
diff --git a/app/php/pages/Select.page b/app/php/pages/Select.page deleted file mode 100644 index 5e1f232..0000000 --- a/app/php/pages/Select.page +++ /dev/null @@ -1,8 +0,0 @@ - - - <%= CalendarFacade::getInstance() %> - - - <%= CalendarFacade::getInstance() %> - - diff --git a/app/php/pages/Signup.page b/app/php/pages/Signup.page deleted file mode 100644 index 834b7cf..0000000 --- a/app/php/pages/Signup.page +++ /dev/null @@ -1,5 +0,0 @@ - - - <%= UserFacade::getInstance() %> - - diff --git a/app/php/pages/config.xml b/app/php/pages/config.xml deleted file mode 100644 index 305651e..0000000 --- a/app/php/pages/config.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/app/php/resources b/app/php/resources deleted file mode 120000 index bc76415..0000000 --- a/app/php/resources +++ /dev/null @@ -1 +0,0 @@ -../../resources \ No newline at end of file diff --git a/app/php/runtime b/app/php/runtime deleted file mode 120000 index 2cee2e0..0000000 --- a/app/php/runtime +++ /dev/null @@ -1 +0,0 @@ -../../cache/prado \ No newline at end of file diff --git a/app/php/sqlmap/config.xml b/app/php/sqlmap/config.xml deleted file mode 100644 index 101e1b7..0000000 --- a/app/php/sqlmap/config.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/app/php/sqlmap/events.xml b/app/php/sqlmap/events.xml deleted file mode 100644 index 030a773..0000000 --- a/app/php/sqlmap/events.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - diff --git a/app/php/themes/default/preloader.gif b/app/php/themes/default/preloader.gif deleted file mode 100644 index 6505467..0000000 Binary files a/app/php/themes/default/preloader.gif and /dev/null differ diff --git a/app/php/url/UrlManager.php b/app/php/url/UrlManager.php deleted file mode 100644 index a33d98e..0000000 --- a/app/php/url/UrlManager.php +++ /dev/null @@ -1,57 +0,0 @@ -_convertServiceParam($serviceParam), - preg_replace('#^/' . $serviceID . '#', '', $url) - ), - '/' - ) . '/'; - } - - public function parseUrl() { - $params = parent::parseUrl(); - if ($this->MatchingPattern) { - $serviceID = $this->MatchingPattern->ServiceID; - if (isset($params[$serviceID])) { - $params[$serviceID] = $this->_parseServiceParam($params[$serviceID]); - } - } - return $params; - } - - /** - * Convert service param from camelCase to hyphenated-form. - **/ - private function _convertServiceParam($param) { - return implode( - '-', - array_map('mb_strtolower', array_filter(preg_split('/(?=[A-Z])/', $param))) - ); - } - - /** - * Convert service param from hyphenated-form to camelCase. - **/ - private function _parseServiceParam($param) { - return implode( - '', - array_map('ucfirst', explode('-', $param)) - ); - } -} - -?> diff --git a/app/php/url/config.xml b/app/php/url/config.xml deleted file mode 100644 index b072b2d..0000000 --- a/app/php/url/config.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/app/php/user/DbUser.php b/app/php/user/DbUser.php deleted file mode 100644 index d636e8b..0000000 --- a/app/php/user/DbUser.php +++ /dev/null @@ -1,60 +0,0 @@ -_record = $record; - } - - public function getDbRecord() { - if (!$this->_record) { - $this->_record = UserFacade::getInstance()->findByLogin($this->Name); - } - return $this->_record; - } - - public function createUser($username) { - $dbUser = UserFacade::getInstance()->findByLogin($username); - if (!$dbUser) { - return NULL; - } - $user = new DbUser($this->Manager); - $user->setDbRecord($dbUser); - $user->Name = $dbUser->Login; - if ($dbUser->IsAdmin) { - $user->Roles = 'Admin'; - } - $user->IsGuest = FALSE; - return $user; - } - - public function validateUser($login, $password) { - $user = UserFacade::getInstance()->findByLogin($login); - $dbPassword = $user ? $user->Password : ''; - if (UserFacade::getInstance()->verifyPassword($password, $dbPassword) - && $user) { - $user->LastLogin = date('Y-m-d H:i:s'); - $user->save(); - return TRUE; - } else { - return FALSE; - } - } - - public function __call($name, $args) { - $match = []; - if (preg_match('/^getIs(.+)$/', $name, $match)) { - return $this->isInRole($match[1]); - } - throw new Exception('Unimplemented CustomDbUser method'); - } - -} - -?> diff --git a/app/php/user/config.xml b/app/php/user/config.xml deleted file mode 100644 index 80027e5..0000000 --- a/app/php/user/config.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - diff --git a/app/php/web/AssetManager.php b/app/php/web/AssetManager.php deleted file mode 100644 index 2677585..0000000 --- a/app/php/web/AssetManager.php +++ /dev/null @@ -1,11 +0,0 @@ - diff --git a/app/php/web/BaseUrlDerivedFromBasePath.php b/app/php/web/BaseUrlDerivedFromBasePath.php deleted file mode 100644 index 2da277f..0000000 --- a/app/php/web/BaseUrlDerivedFromBasePath.php +++ /dev/null @@ -1,29 +0,0 @@ -BaseUrl === NULL && $this->BasePath !== NULL) { - $appWebPath = preg_replace( - '#' . $this->Application->Request->ApplicationUrl . '$#', - '', - $this->Application->Request->ApplicationFilePath - ); - $appBaseUrl = preg_replace( - '#^' . $appWebPath . '#', - '', - dirname($this->Application->Request->ApplicationFilePath) - ); - $this->BaseUrl = $appBaseUrl - . preg_replace( - '#^' . Prado::getPathOfNamespace('Web') . '#', - '', - $this->BasePath - ); - } - parent::init($config); - } - -} - -?> diff --git a/app/php/web/ClientScriptManager.php b/app/php/web/ClientScriptManager.php deleted file mode 100644 index 223c6e2..0000000 --- a/app/php/web/ClientScriptManager.php +++ /dev/null @@ -1,572 +0,0 @@ -_page = $page; - parent::__construct($page); - } - - // Base path of the entire application - private function _getBasePath() { - return Prado::getPathOfNamespace('Web'); - } - - // Translate URLs to filesystem paths, index return array by URLs - private function _getBasePaths(array $urls) { - $basePath = $this->_getBasePath(); - return array_combine( - $urls, - array_map( - function($path) use($basePath) { - return $basePath . DIRECTORY_SEPARATOR . $path; - }, - $urls - ) - ); - } - - // Base cache path, suffixed with subdirectory, create on demand - private function _getCachePath(string $subdir = 'assets') { - $cachePath = $this->Application->RuntimePath - . DIRECTORY_SEPARATOR - . $subdir; - if (!is_dir($cachePath)) { - if (file_exists($cachePath)) { - throw new TIOException( - sprintf( - 'Client script manager cache path "%s" exists and is not a directory', - $cachePath - ) - ); - } else { - mkdir($cachePath); - } - } - return $cachePath; - } - - // Cache path for a file of specified type - private function _getCacheFilePath($path, $type) { - return $this->_getCachePath($type) - . DIRECTORY_SEPARATOR - . $path; - } - - // Cache key for specific file set, including current theme - private function _getFileCollectionCacheKey(array $files) { - sort($files); - if ($this->_page->Theme) { - $files[] = $this->_page->Theme->Name; - } - return md5(implode(PHP_EOL, $files)); - } - - // Last modification time of a file set - private function _getFileCollectionMTime(array $files) { - return max(array_map('filemtime', $files)); - } - - // Storage (application cache) key for list of rendered assets of specified type - // Rendered[ASSET_TYPE].[VIEW_ID] (VIEW_ID as rendered in Layout hidden field) - private function _getRenderedAssetsStoreKey($type) { - $template = $this->_page->Master; - if (!$template instanceof Layout) { - throw new TNotSupportedException( - 'Compiled assets may only be used within Layout master class controls' - ); - } - return sprintf('Rendered%s.%s', $type, $template->generateViewID()); - } - - // Shorthand for JS assets cache key - private function _getRenderedScriptsStoreKey() { - return $this->_getRenderedAssetsStoreKey('Scripts'); - } - - // Shorthand for CSS assets cache key - private function _getRenderedSheetsStoreKey() { - return $this->_getRenderedAssetsStoreKey('Sheets'); - } - - // Application (primary) cache module, required to keep track of assets rendered on current page - private function _getCache() { - $cache = $this->Application->Cache; - if (!$cache) { - throw new TNotSupportedException( - 'Compiled assets require cache to be configured' - ); - } - return $cache; - } - - // Check cache file validity, comparing to source file set - private function _isCacheValid($cacheFile, array $paths) { - return file_exists($cacheFile) - && (filemtime($cacheFile) >= $this->_getFileCollectionMTime($paths)); - } - - // Determine whether specific URL points to a local asset (i.e. existing on the filesystem) - private function _isFileLocal($file) { - $basePath = $this->_getBasePath(); - return file_exists($basePath . DIRECTORY_SEPARATOR . $file); - } - - // Filter URL set to leave only local assets - private function _determineLocalFiles($files) { - return array_filter( - $files, [$this, '_isFileLocal'] - ); - } - - // Scripts - internal methods - - private $_renderedScriptsInitialized = FALSE; - - // Retrieve scripts already rendered on current page from application cache, - // maintaining the state over callbacks - private function _getRenderedScripts() { - $sessionKey = $this->_getRenderedScriptsStoreKey(); - if ($this->_page->IsCallBack || $this->_renderedScriptsInitialized) { - return $this->_getCache()->get($sessionKey) ?: []; - } else { - $this->_getCache()->delete($sessionKey); - $this->_renderedScriptsInitialized = TRUE; - return []; - } - } - - // Store information on rendered scripts in application cache - private function _appendRenderedScripts(array $newScripts, $compiledFileKey) { - $scripts = $this->_getRenderedScripts(); - if (!isset($scripts[$compiledFileKey])) { - $scripts[$compiledFileKey] = []; - } - $scripts[$compiledFileKey] = array_unique( - array_merge( - $scripts[$compiledFileKey], - $newScripts - ) - ); - $this->_getCache()->set( - $this->_getRenderedScriptsStoreKey(), - $scripts - ); - } - - // Compress JS file and return its content - private function _getCompressedScript($path) { - return trim(TJavaScript::JSMin( - file_get_contents($path) - )); - } - - // Join multiple script files into single asset, mark all of them as rendered in parent - private function _compileScriptFiles(array $files) { - foreach ($files as $file) { - $this->markScriptFileAsRendered($file); - } - $paths = $this->_getBasePaths($files); - $cacheFile = $this->_getCacheFilePath( - $this->_getFileCollectionCacheKey($paths) . '.js', - 'scripts' - ); - $this->_appendRenderedScripts($files, $cacheFile); - if (!$this->_isCacheValid($cacheFile, $paths)) { - $scriptContent = implode( - PHP_EOL, - array_map( - [$this, '_getCompressedScript'], - $paths - ) - ); - file_put_contents($cacheFile, $scriptContent); - } - return $this->Application->AssetManager->publishFilePath($cacheFile); - } - - // Write output tag for a single, compiled JS asset, consisting of multiple local assets - private function _renderLocalScriptFiles(THtmlWriter $writer, array $localFiles) { - if ($localFiles) { - $assetPath = $this->_compileScriptFiles($localFiles); - $writer->write(TJavascript::renderScriptFile($assetPath)); - } - } - - // Keep track of external JS scripts rendered on the page - private function _renderExternalScriptFiles(THtmlWriter $writer, array $externalFiles) { - if ($externalFiles) { - foreach ($externalFiles as $file) { - $this->markScriptFileAsRendered($file); - $this->_appendRenderedScripts([$file], $file); - } - parent::renderScriptFiles($writer, $externalFiles); - } - } - - // Determine actual asset URL that a source JS file was rendered as (after compilation/compression) - // FALSE means script wasn't rendered at all (i.e. was just registered in current callback) - private function _getRenderedScriptUrl($registeredScript) { - $renderedScripts = $this->_getRenderedScripts(); - foreach ($renderedScripts as $compiledFile => $scripts) { - if (in_array($registeredScript, $scripts)) { - if (file_exists($compiledFile)) { - return $this->Application->AssetManager->getPublishedUrl( - $compiledFile - ); - } else { - return $registeredScript; - } - } - } - return FALSE; - } - - // Scripts - public interface overrides - - // In application modes "higher" than Debug, compile JS assets to as few files as possible - public function renderScriptFiles($writer, Array $files) { - if ($this->getApplication()->getMode() !== TApplicationMode::Debug) { - if ($files) { - $localFiles = $this->_determineLocalFiles($files); - $this->_renderLocalScriptFiles($writer, $localFiles); - $externalFiles = array_diff($files, $localFiles); - $this->_renderExternalScriptFiles($writer, $externalFiles); - } - } else { - parent::renderScriptFiles($writer, $files); - } - } - - // When above compilation occurs, list of JS URLs a callback requires - // significantly deviates from parent implementation. - // Also, new scripts that have been registered in current callback may need compiling, too. - public function getScriptUrls() { - if ($this->getApplication()->getMode() !== TApplicationMode::Debug) { - $registeredScripts = array_unique( - array_merge( - $this->_scripts, $this->_headScripts - ) - ); - $scriptUrls = []; - $newScripts = []; - foreach ($registeredScripts as $registeredScript) { - $renderedScriptUrl = $this->_getRenderedScriptUrl($registeredScript); - if ($renderedScriptUrl) { - $scriptUrls[] = $renderedScriptUrl; - } else { - $newScripts[] = $registeredScript; - } - } - $newLocalScripts = $this->_determineLocalFiles($newScripts); - $newRemoteScripts = array_diff($newScripts, $newLocalScripts); - if ($newLocalScripts) { - $scriptUrls[] = $this->_compileScriptFiles($newLocalScripts); - } - $scriptUrls = array_values( - array_unique(array_merge($scriptUrls, $newRemoteScripts)) - ); - return $scriptUrls; - } - return parent::getScriptUrls(); - } - - private $_scripts = []; - private $_headScripts = []; - - // Keep track of what we're registering - public function registerScriptFile($key, $file) { - $this->_scripts[$key] = $file; - return parent::registerScriptFile($key, $file); - } - - // Keep track of what we're registering - public function registerHeadScriptFile($key, $file) { - $this->_headScripts[$key] = $file; - return parent::registerHeadScriptFile($key, $file); - } - - // Stylesheets - internal methods - - private $_renderedSheetsInitialized = FALSE; - - // Retrieve stylesheets already rendered on current page from application cache, - // maintaining the state over callbacks - private function _getRenderedSheets() { - $sessionKey = $this->_getRenderedSheetsStoreKey(); - if ($this->_page->IsCallBack || $this->_renderedSheetsInitialized) { - return $this->_getCache()->get($sessionKey) ?: []; - } else { - $this->_getCache()->delete($sessionKey); - $this->_renderedSheetsInitialized = TRUE; - return []; - } - } - - // Store information on rendered stylesheets in application cache - private function _appendRenderedSheets(array $newSheets, $compiledFileKey) { - $sheets = $this->_getRenderedSheets(); - if (!isset($sheets[$compiledFileKey])) { - $sheets[$compiledFileKey] = []; - } - $sheets[$compiledFileKey] = array_merge( - $sheets[$compiledFileKey], - $newSheets - ); - $this->_getCache()->set( - $this->_getRenderedSheetsStoreKey(), - $sheets - ); - } - - // Resolve all "url(FILE)" CSS directives pointing - // to relative resources to specified path - private function _fixStyleSheetPaths($content, $originalUrl) { - $originalDir = dirname($originalUrl . '.'); - return preg_replace_callback( - '/url\s*\([\'"]?(.*?)[\'"]?\)/', - function($matches) use($originalDir) { - $url = parse_url($matches[1]); - // ignore absolute URLs and paths - if (isset($url['scheme']) - || isset($url['host']) - || $url['path'][0] == '/') { - return $matches[0]; - } - // resolve relative paths - return str_replace( - $matches[1], - $originalDir . '/' . $matches[1], - $matches[0] - ); - }, - $content - ); - } - - // Compress CSS file and return its content - private function _getCompressedSheet($origPath, $path) { - Prado::using('Lib.cssmin.CssMin'); - return trim(CssMin::minify( - $this->_fixStyleSheetPaths( - file_get_contents($path), - $origPath - ) - )); - } - - // Join multiple stylesheet files into single asset - private function _compileSheetFiles(array $files) { - $paths = $this->_getBasePaths( - array_map('reset', $files) - ); - // determine if file was registered as a themed sheet - $correctedPaths = []; - foreach ($paths as $url => $path) { - $correctedPaths[ - in_array($url, $this->_themeStyles) && $this->_page->Theme - ? $this->_page->Theme->BaseUrl . DIRECTORY_SEPARATOR - : $url - ] = $path; - } - $cacheFile = $this->_getCacheFilePath( - $this->_getFileCollectionCacheKey($paths) . '.css', - 'styles' - ); - $this->_appendRenderedSheets($files, $cacheFile); - if (!$this->_isCacheValid($cacheFile, $paths)) { - $styleContent = implode( - PHP_EOL, - array_map( - [$this, '_getCompressedSheet'], - array_keys($correctedPaths), - $correctedPaths - ) - ); - file_put_contents($cacheFile, $styleContent); - } - return $this->Application->AssetManager->publishFilePath($cacheFile); - } - - // Filter only local stylesheet file entries - private function _determineLocalSheetFiles(array $files) { - $basePath = $this->_getBasePath(); - return array_filter( - $files, - function($file) use($basePath) { - return file_exists($basePath . DIRECTORY_SEPARATOR . $file[0]); - } - ); - } - - // Write HTML markup for CSS stylesheet - private function _renderSheetFileTag(THtmlWriter $writer, $href, $media) { - $writer->addAttribute('rel', 'stylesheet'); - $writer->addAttribute('type', 'text/css'); - $writer->addAttribute('media', $media); - $writer->addAttribute('href', $href); - $writer->renderBeginTag('link'); - $writer->write(PHP_EOL); - } - - // Group registered local CSS assets by media query string and render markup for compiled sheets - private function _renderLocalSheetFiles(THtmlWriter $writer, array $localFiles) { - if ($localFiles) { - $fileTypes = []; - foreach ($localFiles as $file) { - $type = $file[1] ?: 'all'; - if (!isset($fileTypes[$type])) { - $fileTypes[$type] = []; - } - $fileTypes[$type][] = $file; - } - foreach ($fileTypes as $type => $files) { - $assetPath = $this->_compileSheetFiles($files); - $this->_renderSheetFileTag($writer, $assetPath, $type); - } - } - } - - // Render markup for external stylesheets - private function _renderExternalSheetFiles(THtmlWriter $writer, array $externalFiles) { - if ($externalFiles) { - foreach ($externalFiles as $file) { - $this->_appendRenderedSheets([$file], $file[0]); - $this->_renderSheetFileTag($writer, $file[0], $file[1] ?: 'all'); - } - } - } - - // Determine actual asset URL that a source CSS file was rendered as (after compilation/compression) - // FALSE means sheet wasn't rendered at all (i.e. was just registered in current callback) - // Media query types can easily be ignored in a callback request, only URLs matter - private function _getRenderedSheetUrl($registeredSheet) { - $renderedSheets = $this->_getRenderedSheets(); - foreach ($renderedSheets as $compiledFile => $sheets) { - foreach ($sheets as $sheet) { - if ($registeredSheet[0] == $sheet[0]) { - if (file_exists($compiledFile)) { - return $this->Application->AssetManager->getPublishedUrl( - $compiledFile - ); - } else { - return $registeredSheet[0]; - } - } - } - } - return FALSE; - } - - // Stylesheets - public interface overrides - - // In application modes "higher" than Debug, compile CSS assets to as few files as possible - public function renderStyleSheetFiles($writer) { - if ($this->getApplication()->getMode() !== TApplicationMode::Debug) { - $files = $this->_styles; - if ($files) { - $localFiles = $this->_determineLocalSheetFiles($files); - $this->_renderLocalSheetFiles($writer, $localFiles); - $externalFiles = array_diff_key($files, $localFiles); - $this->_renderExternalSheetFiles($writer, $externalFiles); - } - } else { - parent::renderStyleSheetFiles($writer); - } - } - - // When above compilation occurs, list of CSS URLs a callback requires - // significantly deviates from parent implementation. - // New stylesheets may need compiling, as well. - public function getStyleSheetUrls() { - if ($this->getApplication()->getMode() !== TApplicationMode::Debug) { - $registeredSheets = $this->_styles; - $sheetUrls = []; - $newSheets = []; - foreach ($registeredSheets as $registeredSheet) { - $renderedSheetUrl = $this->_getRenderedSheetUrl( - $registeredSheet - ); - if ($renderedSheetUrl) { - $sheetUrls[] = $renderedSheetUrl; - } else { - $newSheets[] = $registeredSheet; - } - } - $newLocalSheets = $this->_determineLocalSheetFiles($newSheets); - $newLocalUrls = array_map('reset', $newLocalSheets); - $newRemoteSheets = array_filter( - $newSheets, - function($sheet) use($newLocalUrls) { - return !in_array($sheet[0], $newLocalUrls); - } - ); - $newRemoteUrls = array_map('reset', $newRemoteSheets); - if ($newLocalSheets) { - $sheetUrls[] = $this->_compileSheetFiles($newLocalSheets); - } - $sheetUrls = array_values( - array_unique(array_merge($sheetUrls, $newRemoteUrls)) - ); - return $sheetUrls; - } - // And even in Debug mode, theme sheets before fixing paths - // might also have been published via assets manager, - // so we have to discard these from parent list. - return array_diff( - parent::getStyleSheetUrls(), - $this->_fixedStyleFiles - ); - } - - private $_styles = []; - - // Keep track of what we're registering - public function registerStyleSheetFile($key, $file, $media = '') { - $this->_styles[$key] = [$file, $media]; - return parent::registerStyleSheetFile($key, $file, $media ?: 'all'); - } - - private $_themeStyles = []; - private $_fixedStyleFiles = []; - - // New method, automatically corrects URLs within stylesheet to current page theme - // when sheets are not compiled (when they are, it's done on compilation anyways). - // Such files are rewritten (not in place, though) and registered so that they don't show up - // within published assets returned from asset manager, as they don't end up in the markup. - public function registerThemeStyleSheetFile($key, $file, $media = '') { - if ($this->getApplication()->getMode() !== TApplicationMode::Debug) { - $this->_themeStyles[$key] = $file; - } else { - if ($this->_isFileLocal($file) && $this->_page->Theme) { - $tempFile = $this->_getCacheFilePath( - $this->_getFileCollectionCacheKey([ - $this->_getBasePath() - . DIRECTORY_SEPARATOR - . $file - ]) - . '.' . basename($file), - $this->_page->Theme->Name - ); - file_put_contents( - $tempFile, - $this->_fixStyleSheetPaths( - file_get_contents( - $this->_getBasePath() . DIRECTORY_SEPARATOR . $file - ), - $this->_page->Theme->BaseUrl . DIRECTORY_SEPARATOR - ) - ); - $this->_fixedStyleFiles[] = $file; - $file = $this->Application->AssetManager->publishFilePath($tempFile); - } - } - return $this->registerStyleSheetFile($key, $file, $media ?: 'all'); - } - -} - -?> diff --git a/app/php/web/FacadeTemplateControl.php b/app/php/web/FacadeTemplateControl.php deleted file mode 100644 index 05d148c..0000000 --- a/app/php/web/FacadeTemplateControl.php +++ /dev/null @@ -1,27 +0,0 @@ -setControlState('Facade', $facade); - } - - public function getFacade() { - return $this->getControlState('Facade'); - } - - public function onPreRender($param) { - parent::onPreRender($param); - if (!$this->getFacade()) { - throw new TInvalidDataValueException( - 'FacadeTemplateControl requires a Facade instance' - ); - } - } - -} - -?> diff --git a/app/php/web/TemplateControl.php b/app/php/web/TemplateControl.php deleted file mode 100644 index aa95d75..0000000 --- a/app/php/web/TemplateControl.php +++ /dev/null @@ -1,176 +0,0 @@ -_getControlScriptPath(get_class($this)); - if (file_exists($scriptFile)) { - $this->_registerScriptFile($scriptFile); - } - $styleFile = $this->_getControlStylePath(get_class($this)); - if (file_exists($styleFile)) { - $this->_registerStyleFile($styleFile); - } - } - - protected function getExternalScriptDependencies() { - return []; - } - - protected function getLibScriptDependencies() { - return []; - } - - protected function getPradoScriptDependencies() { - return []; - } - - protected function getControlScriptDependencies() { - return []; - } - - protected function getExternalStyleDependencies() { - return []; - } - - protected function getLibStyleDependencies() { - return []; - } - - protected function getControlStyleDependencies() { - return []; - } - - private function _getControlScriptPath($className) { - return Prado::getPathOfNamespace('Application.controls.scripts') - . DIRECTORY_SEPARATOR - . $className - . '.js'; - } - - private function _getControlStylePath($className) { - return Prado::getPathOfNamespace('Application.controls.styles') - . DIRECTORY_SEPARATOR - . $className - . '.css'; - } - - private function _getLibPath($identifier, $extension = '') { - return Prado::getPathOfNamespace('Lib') - . DIRECTORY_SEPARATOR - . $identifier - . $extension; - } - - private function _registerScriptFile($scriptFile) { - $this->_registerExternalScriptDependencies( - $this->getExternalScriptDependencies() - ); - $this->_registerLibScriptDependencies( - $this->getLibScriptDependencies() - ); - $this->_registerPradoScriptDependencies( - $this->getPradoScriptDependencies() - ); - $this->_registerControlScriptDependencies( - $this->getControlScriptDependencies() - ); - $this->Page->ClientScript->registerScriptFile( - 'TemplateControl.' . get_class($this), - $this->Application->AssetManager->publishFilePath($scriptFile) - ); - } - - private function _registerExternalScriptDependencies(array $dependencies) { - foreach ($dependencies as $dependency) { - $this->Page->ClientScript->registerHeadScriptFile( - $dependency, $dependency - ); - } - } - - private function _registerLibScriptDependencies(array $dependencies) { - foreach ($dependencies as $dependency) { - $this->Page->ClientScript->registerScriptFile( - 'LibScript.' . $dependency, - $this->Application->AssetManager->publishFilePath( - $this->_getLibPath($dependency, '.js') - ) - ); - } - } - - private function _registerPradoScriptDependencies(array $dependencies) { - foreach ($dependencies as $dependency) { - $this->Page->ClientScript->registerPradoScript($dependency); - } - } - - private function _registerControlScriptDependencies(array $dependencies) { - foreach ($dependencies as $dependency) { - $this->Page->ClientScript->registerScriptFile( - 'TemplateControl.' . $dependency, - $this->Application->AssetManager->publishFilePath( - $this->_getControlScriptPath($dependency) - ) - ); - } - } - - private function _registerStyleFile($styleFile) { - $this->_registerExternalStyleDependencies( - $this->getExternalStyleDependencies() - ); - $this->_registerLibStyleDependencies( - $this->getLibStyleDependencies() - ); - $this->_registerControlStyleDependencies( - $this->getControlStyleDependencies() - ); - if (method_exists($this->Page->ClientScript, 'registerThemeStyleSheetFile')) { - $this->Page->ClientScript->registerThemeStyleSheetFile( - 'TemplateControl.' . get_class($this), - $this->Application->AssetManager->publishFilePath($styleFile) - ); - } else { - $this->Page->ClientScript->registerStyleSheetFile( - 'TemplateControl.' . get_class($this), - $this->Application->AssetManager->publishFilePath($styleFile) - ); - } - } - - private function _registerExternalStyleDependencies(array $dependencies) { - foreach ($dependencies as $dependency) { - $this->Page->ClientScript->registerStyleSheetFile( - $dependency, $dependency - ); - } - } - - private function _registerLibStyleDependencies(array $dependencies) { - foreach ($dependencies as $dependency) { - $this->Page->ClientScript->registerStyleSheetFile( - 'LibStyle.' . $dependency, - $this->Application->AssetManager->publishFilePath( - $this->_getLibPath($dependency, '.css') - ) - ); - } - } - - private function _registerControlStyleDependencies(array $dependencies) { - foreach ($dependencies as $dependency) { - $this->Page->ClientScript->registerStyleSheetFile( - 'TemplateControl.' . $dependency, - $this->Application->AssetManager->publishFilePath( - $this->_getControlStylePath($dependency) - ) - ); - } - } - -} - -?> diff --git a/app/php/web/ThemeManager.php b/app/php/web/ThemeManager.php deleted file mode 100644 index 9dcae76..0000000 --- a/app/php/web/ThemeManager.php +++ /dev/null @@ -1,11 +0,0 @@ - diff --git a/app/php/web/config.xml b/app/php/web/config.xml deleted file mode 100644 index 49bbcc6..0000000 --- a/app/php/web/config.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - -- cgit v1.2.3