From 3187844aa3c1ae301b1b11edcce621866d13ec0c Mon Sep 17 00:00:00 2001 From: Kelsey Martens Date: Mon, 19 Mar 2018 16:18:17 -0500 Subject: [PATCH] v2.0.0-beta.5 --- CHANGELOG.md | 12 +++ composer.json | 2 +- src/Calendar.php | 30 ++++-- src/Controllers/EventsApiController.php | 2 +- src/Controllers/EventsController.php | 95 ++++++++++++++++--- src/Elements/Db/EventQuery.php | 60 +++++++++--- src/Elements/Event.php | 29 ++++++ src/FieldTypes/EventFieldType.php | 48 ++++++++++ src/Resources/css/src/event-edit.css | 2 +- src/Resources/js/src/widget/agenda.js | 2 +- src/Services/EventsService.php | 9 +- src/templates/_widgets/agenda/body.html | 2 +- .../_widgets/upcoming-events/body.html | 2 +- src/templates/events/_edit.html | 20 ++-- src/translations/{de.php => de/calendar.php} | 0 .../{en.php => en-US/calendar.php} | 0 src/translations/{lv.php => lv/calendar.php} | 0 src/translations/{nl.php => nl/calendar.php} | 0 18 files changed, 263 insertions(+), 52 deletions(-) create mode 100644 src/FieldTypes/EventFieldType.php rename src/translations/{de.php => de/calendar.php} (100%) rename src/translations/{en.php => en-US/calendar.php} (100%) rename src/translations/{lv.php => lv/calendar.php} (100%) rename src/translations/{nl.php => nl/calendar.php} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39b625e..7089ab8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Solspace Freeform Changelog +## 2.0.0-beta.5 - 2018-03-19 +### Fixed +- Added Live Preview functionality back. +- Added Calendar 1.x to 2.x (Craft 2.x to 3.x) migration path. +- Fixed a bug where the Calendar Event fieldtype was not available. +- Fixed a bug where the Agenda widget would visually allow you to drag and drop events (locked now). +- Fixed a bug where the Agenda widget would not correctly display all day and multi-day events. +- Fixed some deprecation errors with dashboard widgets. +- Fixed a bug where Quick Creating events with title format option was not working correctly. +- Fixed a bug where Events function wasn't correctly including multi-day events. +- Fixed a bug where translations were not being loaded. + ## 2.0.0-beta.4 - 2018-03-15 ### Fixed - Added back all Calendar widgets. diff --git a/composer.json b/composer.json index c062db8..3a709ee 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "solspace/craft3-calendar", "description": "The most powerful event management plugin for Craft.", - "version": "2.0.0-beta.4", + "version": "2.0.0-beta.5", "type": "craft-plugin", "minimum-stability": "dev", "authors": [ diff --git a/src/Calendar.php b/src/Calendar.php index fea4d36..bc5b8ff 100644 --- a/src/Calendar.php +++ b/src/Calendar.php @@ -7,6 +7,7 @@ use craft\events\RegisterUrlRulesEvent; use craft\events\RegisterUserPermissionsEvent; use craft\services\Dashboard; +use craft\services\Fields; use craft\services\UserPermissions; use craft\web\twig\variables\CraftVariable; use craft\web\UrlManager; @@ -17,6 +18,7 @@ use Solspace\Calendar\Controllers\EventsController; use Solspace\Calendar\Controllers\SettingsController; use Solspace\Calendar\Controllers\ViewController; +use Solspace\Calendar\FieldTypes\EventFieldType; use Solspace\Calendar\Models\CalendarModel; use Solspace\Calendar\Models\CalendarSiteSettingsModel; use Solspace\Calendar\Models\SettingsModel; @@ -98,15 +100,17 @@ public function init() { parent::init(); - $this->controllerMap = [ - 'api' => ApiController::class, - 'codepack' => CodePackController::class, - 'calendars' => CalendarsController::class, - 'events-api' => EventsApiController::class, - 'events' => EventsController::class, - 'settings' => SettingsController::class, - 'view' => ViewController::class, - ]; + if (!\Craft::$app->request->isConsoleRequest) { + $this->controllerMap = [ + 'api' => ApiController::class, + 'codepack' => CodePackController::class, + 'calendars' => CalendarsController::class, + 'events-api' => EventsApiController::class, + 'events' => EventsController::class, + 'settings' => SettingsController::class, + 'view' => ViewController::class, + ]; + } $this->setComponents( [ @@ -147,6 +151,14 @@ function (RegisterComponentTypesEvent $event) { } ); + Event::on( + Fields::class, + Fields::EVENT_REGISTER_FIELD_TYPES, + function (RegisterComponentTypesEvent $event) { + $event->types[] = EventFieldType::class; + } + ); + // craft()->on('i18n.onAddLocale', [craft()->calendar_events, 'addLocaleHandler']); // craft()->on('i18n.onAddLocale', [craft()->calendar_calendars, 'addLocaleHandler']); diff --git a/src/Controllers/EventsApiController.php b/src/Controllers/EventsApiController.php index 78df86e..fff6adc 100644 --- a/src/Controllers/EventsApiController.php +++ b/src/Controllers/EventsApiController.php @@ -218,7 +218,7 @@ public function actionCreate(): Response $event->endDate = $endDate; $event->allDay = $isAllDay; - if (Calendar::getInstance()->events->saveEvent($event, false)) { + if (Calendar::getInstance()->events->saveEvent($event, false, true)) { return $this->asJson(['event' => $event]); } diff --git a/src/Controllers/EventsController.php b/src/Controllers/EventsController.php index 97a9913..0bfdb80 100644 --- a/src/Controllers/EventsController.php +++ b/src/Controllers/EventsController.php @@ -13,6 +13,8 @@ use Solspace\Calendar\Library\DateHelper; use Solspace\Calendar\Library\Exceptions\EventException; use Solspace\Calendar\Library\RecurrenceHelper; +use Solspace\Calendar\Models\ExceptionModel; +use Solspace\Calendar\Models\SelectDateModel; use Solspace\Calendar\Resources\Bundles\EventEditBundle; use yii\helpers\FormatConverter; use yii\web\HttpException; @@ -344,7 +346,7 @@ private function renderEditForm(Event $event, string $title): Response $showPreviewButton = false; if (!\Craft::$app->getRequest()->isMobileBrowser(true) && $this->getCalendarService()->isEventTemplateValid($calendar, $event->siteId)) { $this->getView()->registerJs('Craft.LivePreview.init(' . Json::encode([ - 'fields' => '#title-field, #fields > div > div > .field, #fields > div > .field', + 'fields' => '#title-field, #fields .calendar-event-wrapper > .field, #fields > .field > .field', 'extraFields' => '#settings', 'previewUrl' => $event->getUrl(), 'previewAction' => 'calendar/events/preview', @@ -453,25 +455,92 @@ private function getEventModel(): Event */ private function populateEventModel(Event $event) { - // Set the entry attributes, defaulting to the existing values for whatever is missing from the post data - $event->slug = \Craft::$app->getRequest()->getBodyParam('slug', $event->slug); - $event->enabled = (bool) \Craft::$app->getRequest()->getBodyParam('enabled', $event->enabled); - $event->enabledForSite = (bool) \Craft::$app->getRequest()->getBodyParam('enabledForSite', $event->enabledForSite); - $event->title = \Craft::$app->getRequest()->getBodyParam('title', $event->title); + $request = \Craft::$app->request; - // Prevent the last entry type's field layout from being used - $event->fieldLayoutId = null; + $eventId = $event->id; + $values = $request->getBodyParam(self::EVENT_FIELD_NAME); + if (null === $values) { + throw new HttpException('No event data posted'); + } - $fieldsLocation = \Craft::$app->getRequest()->getParam('fieldsLocation', 'fields'); + $event->slug = $request->getBodyParam('slug', $event->slug); + $event->enabled = (bool) $request->getBodyParam('enabled', $event->enabled); + $event->enabledForSite = (bool) $request->getBodyParam('enabledForSite', $event->enabledForSite); + $event->title = $request->getBodyParam('title', $event->title); + + $event->fieldLayoutId = null; + $fieldsLocation = $request->getParam('fieldsLocation', 'fields'); $event->setFieldValuesFromRequest($fieldsLocation); - // Author $authorId = \Craft::$app->getRequest()->getBodyParam('author', ($event->authorId ?: \Craft::$app->getUser()->getIdentity()->id)); - if (is_array($authorId)) { - $authorId = $authorId[0] ?? null; + if (\is_array($authorId)) { + $authorId = $authorId[0] ?? null; + $event->authorId = $authorId; } - $event->authorId = $authorId; + $event->enabled = (bool) $request->post('enabled', $event->enabled); + + if (isset($values['calendarId'])) { + $event->calendarId = $values['calendarId']; + } + + $isCalendarPublic = Calendar::getInstance()->calendars->isCalendarPublic($event->getCalendar()); + + $isNewAndPublic = !$event->id && !$isCalendarPublic; + if ($eventId || $isNewAndPublic) { + CalendarPermissionHelper::requireCalendarEditPermissions($event->getCalendar()); + } + + if (isset($values['startDate'])) { + $event->startDate = new Carbon($values['startDate']['date'] . ' ' . $values['startDate']['time'], DateHelper::UTC); + } + + if (isset($values['endDate'])) { + $event->endDate = new Carbon($values['endDate']['date'] . ' ' . $values['endDate']['time'], DateHelper::UTC); + } + + if (isset($values['allDay'])) { + $event->allDay = (bool) $values['allDay']; + } + + if ($event->allDay && $event->startDate && $event->endDate) { + $event->startDate->setTime(0, 0, 0); + $event->endDate->setTime(23, 59, 59); + } + + $startDate = $event->getStartDate(); + $endDate = $event->getEndDate(); + + if ($startDate && $endDate && $startDate->eq($endDate)) { + $endDate = $endDate->addHour(); + $event->endDate->setTime( + $endDate->hour, + $endDate->minute, + $endDate->second + ); + } + + $this->handleRepeatRules($event, $values); + + if (isset($values['exceptions'])) { + foreach ($values['exceptions'] as $date) { + $exception = new ExceptionModel(); + $exception->eventId = $event->id; + $exception->date = new Carbon($date, DateHelper::UTC); + + $event->addException($exception); + } + } + + if (isset($values['selectDates'])) { + foreach ($values['selectDates'] as $date) { + $selectDate = new SelectDateModel(); + $selectDate->eventId = $event->id; + $selectDate->date = new Carbon($date, DateHelper::UTC); + + $event->addSelectDate($selectDate); + } + } } /** diff --git a/src/Elements/Db/EventQuery.php b/src/Elements/Db/EventQuery.php index 33dc12e..1890cf8 100644 --- a/src/Elements/Db/EventQuery.php +++ b/src/Elements/Db/EventQuery.php @@ -17,7 +17,7 @@ use Solspace\Commons\Helpers\PermissionHelper; use yii\db\Connection; -class EventQuery extends ElementQuery +class EventQuery extends ElementQuery implements \Countable { const FORMAT_MONTH = 'Ym'; const FORMAT_WEEK = 'YW'; @@ -279,7 +279,7 @@ public function count($q = '*', $db = null): int $this->all($db); if (null === $this->totalCount) { - $this->totalCount = \count($this->events); + $this->totalCount = \count($this->events ?? []); } return $this->totalCount; @@ -295,7 +295,8 @@ public function all($db = null): array $configHash = $this->getConfigStateHash(); // Nasty elements index hack - if (\Craft::$app->request->post('context') === 'index') { + $context = \Craft::$app->request->post('context'); + if (\in_array($context, ['index', 'modal'], true)) { $this->loadOccurrences = false; } @@ -430,12 +431,28 @@ public function getEventsByHour(Carbon $date): array */ protected function beforePrepare(): bool { - $table = Event::TABLE_STD; - $calendarTable = CalendarRecord::TABLE; + $table = Event::TABLE_STD; + $calendarTable = CalendarRecord::TABLE; // join in the products table $this->joinElementTable($table); - $this->join = [['INNER JOIN', $calendarTable, "$calendarTable.id = $table.calendarId"]]; + $hasCalendarsJoined = false; + + if (!empty($this->join)) { + foreach ($this->join as $join) { + if ($join[1] === $calendarTable) { + $hasCalendarsJoined = true; + } + } + } + + if (!$hasCalendarsJoined) { + if (null === $this->join) { + $this->join = []; + } + + $this->join[] = ['INNER JOIN', $calendarTable, "$calendarTable.id = $table.calendarId"]; + } // select the price column $this->query->select( @@ -490,17 +507,34 @@ protected function beforePrepare(): bool if ($this->rangeStart) { $rangeStartString = $this->extractDateAsFormattedString($this->rangeStart); + $this->subQuery->andWhere( - "($table.rrule IS NULL AND $table.startDate >= :rangeStart) OR ($table.rrule IS NOT NULL)", - ['rangeStart' => $rangeStartString] + "($table.rrule IS NULL AND $table.endDate >= :rangeStart) + OR ($table.rrule IS NOT NULL AND $table.until IS NOT NULL AND $table.until >= :rangeStart) + OR ($table.rrule IS NOT NULL AND $table.until IS NULL) + OR ($table.freq = :freq)", + [ + 'rangeStart' => $rangeStartString, + 'freq' => RecurrenceHelper::SELECT_DATES, + ] ); } if ($this->rangeEnd) { - $rangeEndString = $this->extractDateAsFormattedString($this->rangeEnd); + $rangeEnd = $this->rangeEnd->copy(); + + if ($rangeEnd->format('His') === '000000') { + $rangeEnd->setTime(23, 59, 59); + } + + $rangeEndString = $this->extractDateAsFormattedString($rangeEnd); + $this->subQuery->andWhere( - "$table.endDate <= :rangeEnd", - ['rangeEnd' => $rangeEndString] + "$table.startDate <= :rangeEnd OR $table.freq = :freq", + [ + 'rangeEnd' => $rangeEndString, + 'freq' => RecurrenceHelper::SELECT_DATES, + ] ); } @@ -859,6 +893,10 @@ private function orderEvents(array &$events) $modifier = $this->getSortModifier(); $orderBy = $this->getOrderByField() ?? 'startDate'; + if (false !== strpos($orderBy, '.')) { + $orderBy = 'startDate'; + } + usort( $events, function (Event $eventA, Event $eventB) use ($modifier, $orderBy) { diff --git a/src/Elements/Event.php b/src/Elements/Event.php index 56bbc38..15d65e3 100644 --- a/src/Elements/Event.php +++ b/src/Elements/Event.php @@ -470,6 +470,19 @@ public function getExceptions(): array return $this->exceptions; } + /** + * @param ExceptionModel $exceptionModel + * + * @return $this + */ + public function addException(ExceptionModel $exceptionModel): Event + { + $this->getExceptions(); + $this->exceptions[] = $exceptionModel; + + return $this; + } + /** * @return array */ @@ -542,6 +555,22 @@ public function getSelectDatesAsString($format = 'Y-m-d'): array return $formattedDatesList; } + /** + * @param SelectDateModel $selectDateModel + * + * @return $this + */ + public function addSelectDate(SelectDateModel $selectDateModel): Event + { + $this->getSelectDates(); + $this->selectDatesCache[] = $selectDateModel; + usort($this->selectDatesCache, function (SelectDateModel $a, SelectDateModel $b) { + return $a->date <=> $b->date; + }); + + return $this; + } + /** * @return bool */ diff --git a/src/FieldTypes/EventFieldType.php b/src/FieldTypes/EventFieldType.php new file mode 100644 index 0000000..595332c --- /dev/null +++ b/src/FieldTypes/EventFieldType.php @@ -0,0 +1,48 @@ +setLoadOccurrences(false); + } + + return $query; + } +} \ No newline at end of file diff --git a/src/Resources/css/src/event-edit.css b/src/Resources/css/src/event-edit.css index f89e175..b81d8a1 100644 --- a/src/Resources/css/src/event-edit.css +++ b/src/Resources/css/src/event-edit.css @@ -1 +1 @@ -.recurrence-choices-specific>li:after{content:"";display:table;clear:both}body.ltr #locales{padding:0 0 0 24px}body.rtl #locales{padding:0 24px 0 0}#locales li{position:relative}body.ltr #locales li{padding:7px 45px 7px 0}body.rtl #locales li{padding:7px 0 7px 45px}#locales li+li{border-top:1px solid rgba(115,127,140,0.15)}#locales li.sel{color:#8f98a3;cursor:default}#locales li.sel:before{font-size:11px;color:#8f98a3 !important;font-family:'Craft';speak:none;-webkit-font-feature-settings:"liga", "dlig";-moz-font-feature-settings:"liga=1, dlig=1";-moz-font-feature-settings:"liga", "dlig";-ms-font-feature-settings:"liga", "dlig";-o-font-feature-settings:"liga", "dlig";font-feature-settings:"liga", "dlig";text-rendering:optimizeLegibility;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;direction:ltr;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;text-align:center;font-style:normal;vertical-align:middle;word-wrap:normal !important;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;content:'check'}body.ltr #locales li.sel:before{float:left}body.rtl #locales li.sel:before{float:right}body.ltr #locales li.sel:before{margin:3px 0 0 -16px}body.rtl #locales li.sel:before{margin:3px -16px 0 0}#locales li a{color:#29323d}#locales li a:hover{color:#0d78f2;cursor:pointer}#locales li .lightswitch{position:absolute;top:50%;margin-top:-9px}body.ltr #locales li .lightswitch{right:9px}body.rtl #locales li .lightswitch{left:9px}#locales li .status{display:block;position:absolute;top:50%;margin:-5px 0 0}body.ltr #locales li .status{right:16px}body.rtl #locales li .status{left:16px}#settings .select,#settings .select select{width:100%}.recurrence-choices-specific>li:after{content:"";display:table;clear:both}.ui-timepicker-with-duration .ui-timepicker-list{width:14em}.ui-datepicker-calendar .ui-datepicker-unselectable>span{display:block;width:26px;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;line-height:26px;text-align:center;color:#cdcdcd}.cal-grid:after{content:'';display:table;clear:both}.cal-grid *[class^="cal-row-"]{display:block;float:left}.cal-grid .cal-row-1{width:8.33333%}.cal-grid .cal-row-2{width:16.66667%}.cal-grid .cal-row-3{width:25%}.cal-grid .cal-row-4{width:33.33333%}.cal-grid .cal-row-5{width:41.66667%}.cal-grid .cal-row-6{width:50%}.cal-grid .cal-row-7{width:58.33333%}.cal-grid .cal-row-8{width:66.66667%}.cal-grid .cal-row-9{width:75%}.cal-grid .cal-row-10{width:83.33333%}.cal-grid .cal-row-11{width:91.66667%}ul.cal-group{margin:auto -10px}ul.cal-group:after{content:'';display:table;clear:both}ul.cal-group>li{display:block;float:left;margin:0 10px}ul.cal-group>li.side-label{margin-top:20px}ul.cal-group>li.side-label .field:after{content:'';display:table;clear:both}ul.cal-group>li.side-label .field .heading{float:left;margin:6px 10px 0 0}ul.cal-group>li.side-label .field .input{float:left}ul.cal-group>li.side-label.radio-group .field .input:after{content:'';display:table;clear:both}ul.cal-group>li.side-label.radio-group .field .input>div{float:left;margin:5px 0 0 0}ul.cal-group>li.side-label.radio-group .field .input>div:first-child{margin-right:25px}.event-interval .heading label{font-weight:normal}.event-all-day .input{margin-top:8px}.cal-date-row{width:230px;-webkit-transition:width 0.3s ease-out;-moz-transition:width 0.3s ease-out;-ms-transition:width 0.3s ease-out;-o-transition:width 0.3s ease-out;transition:width 0.3s ease-out}.cal-date-row.short{width:105px}.recurrence-switch{position:relative}.recurrence-switch .recurrence-choices{position:absolute;top:0;left:70px;-webkit-transition:all 0.2s ease-out;-moz-transition:all 0.2s ease-out;-ms-transition:all 0.2s ease-out;-o-transition:all 0.2s ease-out;transition:all 0.2s ease-out}.recurrence-switch .recurrence-choices.no-show{left:200px;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=” $value * 100 “)";filter:alpha(opacity=0);zoom:1;pointer-events:none}.until-switch{position:relative}.until-switch .cal-group{position:absolute;top:6px;left:130px;-webkit-transition:all 0.2s ease-out;-moz-transition:all 0.2s ease-out;-ms-transition:all 0.2s ease-out;-o-transition:all 0.2s ease-out;transition:all 0.2s ease-out}.until-switch .cal-group li.until-count{display:none}.until-switch .cal-group li.until-count:after{content:'';display:table;clear:both}.until-switch .cal-group li.until-count>*{float:left}.until-switch .cal-group li.until-count>label{margin:6px 0 0 10px}.until-switch .cal-group.no-show{left:200px;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=” $value * 100 “)";filter:alpha(opacity=0);zoom:1;pointer-events:none}.recurrence-choices-specific>li{display:none}.recurrence-choices-specific>li>*{display:block;float:left}.recurrence-choices-specific>li>label{margin:7px 10px 0 0}.recurrence-choices-specific>li>label.spaced{margin:7px 30px 0 0}.recurrence-choices-specific>li>.field{margin:0}.recurrence-wrapper{display:none}.recurrence-block{-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;padding:15px 15px 8px;background:#F9F9F9}.recurrence-block div.checkbox-group:after{content:'';display:table;clear:both}.recurrence-block div.checkbox-group>div{float:left;margin:0 7px 7px 0}.recurrence-block div.checkbox-group>div input[type=checkbox]{display:none}.recurrence-block div.checkbox-group>div input[type=checkbox]+label{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;display:block;width:25px;height:25px;white-space:nowrap;padding:4px 0 0 !important;background:#fff;text-align:center;-webkit-transition:all 0.3s ease-out;-moz-transition:all 0.3s ease-out;-ms-transition:all 0.3s ease-out;-o-transition:all 0.3s ease-out;transition:all 0.3s ease-out}.recurrence-block div.checkbox-group>div input[type=checkbox]+label:before{display:none}.recurrence-block div.checkbox-group>div input[type=checkbox]+label:hover{background-color:#e6e6e6}.recurrence-block div.checkbox-group>div input[type=checkbox]:checked+label{color:#FFFFFF;background-color:#727F8B}.recurrence-block div.checkbox-group>div input[type=checkbox]:checked+label:hover{background-color:#5b656f}.recurrence-block div.checkbox-group.month-days{max-width:530px}.recurrence-block .months{width:330px}.recurrence-block .months .checkbox-group{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}.recurrence-block .months .checkbox-group>div{-ms-flex:0 0 30%;flex:0 0 30%}.recurrence-block .months .checkbox-group>div label{width:auto !important}ul.date-list>li{position:relative;background:#F9F9F9;padding:5px 10px 5px 30px}ul.date-list>li:first-child{padding-top:10px;-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;background-clip:padding-box}ul.date-list>li:first-child>a{top:10px}ul.date-list>li:last-child{padding-bottom:10px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px;-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;background-clip:padding-box}ul.date-list>li>a{position:absolute;top:5px;left:10px;display:block;width:13px;height:20px;color:#CCCCCC;-webkit-transition:color 0.2s ease-out;-moz-transition:color 0.2s ease-out;-ms-transition:color 0.2s ease-out;-o-transition:color 0.2s ease-out;transition:color 0.2s ease-out}ul.date-list>li>a:hover{color:#da5a47;text-decoration:none}ul.date-list>li>a:before{content:'remove';font-family:Craft, sans-serif}.select-dates-wrapper{display:none} +.recurrence-choices-specific>li:after{content:"";display:table;clear:both}body.ltr #locales{padding:0 0 0 24px}body.rtl #locales{padding:0 24px 0 0}#locales li{position:relative}body.ltr #locales li{padding:7px 45px 7px 0}body.rtl #locales li{padding:7px 0 7px 45px}#locales li+li{border-top:1px solid rgba(115,127,140,0.15)}#locales li.sel{color:#8f98a3;cursor:default}#locales li.sel:before{font-size:11px;color:#8f98a3 !important;font-family:'Craft';speak:none;-webkit-font-feature-settings:"liga", "dlig";-moz-font-feature-settings:"liga=1, dlig=1";-moz-font-feature-settings:"liga", "dlig";-ms-font-feature-settings:"liga", "dlig";-o-font-feature-settings:"liga", "dlig";font-feature-settings:"liga", "dlig";text-rendering:optimizeLegibility;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;direction:ltr;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;text-align:center;font-style:normal;vertical-align:middle;word-wrap:normal !important;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;content:'check'}body.ltr #locales li.sel:before{float:left}body.rtl #locales li.sel:before{float:right}body.ltr #locales li.sel:before{margin:3px 0 0 -16px}body.rtl #locales li.sel:before{margin:3px -16px 0 0}#locales li a{color:#29323d}#locales li a:hover{color:#0d78f2;cursor:pointer}#locales li .lightswitch{position:absolute;top:50%;margin-top:-9px}body.ltr #locales li .lightswitch{right:9px}body.rtl #locales li .lightswitch{left:9px}#locales li .status{display:block;position:absolute;top:50%;margin:-5px 0 0}body.ltr #locales li .status{right:16px}body.rtl #locales li .status{left:16px}#settings .select,#settings .select select{width:100%}.recurrence-choices-specific>li:after{content:"";display:table;clear:both}.ui-timepicker-with-duration .ui-timepicker-list{width:14em}.ui-datepicker-calendar .ui-datepicker-unselectable>span{display:block;width:26px;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;line-height:26px;text-align:center;color:#cdcdcd}.cal-grid:after{content:'';display:table;clear:both}.cal-grid *[class^="cal-row-"]{display:block;float:left}.cal-grid .cal-row-1{width:8.33333%}.cal-grid .cal-row-2{width:16.66667%}.cal-grid .cal-row-3{width:25%}.cal-grid .cal-row-4{width:33.33333%}.cal-grid .cal-row-5{width:41.66667%}.cal-grid .cal-row-6{width:50%}.cal-grid .cal-row-7{width:58.33333%}.cal-grid .cal-row-8{width:66.66667%}.cal-grid .cal-row-9{width:75%}.cal-grid .cal-row-10{width:83.33333%}.cal-grid .cal-row-11{width:91.66667%}ul.cal-group{margin:auto -10px}ul.cal-group:after{content:'';display:table;clear:both}ul.cal-group>li{display:block;float:left;margin:0 10px}ul.cal-group>li.side-label{margin-top:20px}ul.cal-group>li.side-label .field:after{content:'';display:table;clear:both}ul.cal-group>li.side-label .field .heading{float:left;margin:6px 10px 0 0}ul.cal-group>li.side-label .field .input{float:left}ul.cal-group>li.side-label.radio-group .field .input:after{content:'';display:table;clear:both}ul.cal-group>li.side-label.radio-group .field .input>div{float:left;margin:5px 0 0 0}ul.cal-group>li.side-label.radio-group .field .input>div:first-child{margin-right:25px}.event-interval .heading label{font-weight:normal}.event-all-day .input{margin-top:8px}.cal-date-row{width:230px;-webkit-transition:width 0.3s ease-out;-moz-transition:width 0.3s ease-out;-ms-transition:width 0.3s ease-out;-o-transition:width 0.3s ease-out;transition:width 0.3s ease-out}.cal-date-row.short{width:105px}.recurrence-switch{position:relative}.recurrence-switch .recurrence-choices{position:absolute;top:0;left:70px;-webkit-transition:all 0.2s ease-out;-moz-transition:all 0.2s ease-out;-ms-transition:all 0.2s ease-out;-o-transition:all 0.2s ease-out;transition:all 0.2s ease-out}.recurrence-switch .recurrence-choices.no-show{left:200px;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=” $value * 100 “)";filter:alpha(opacity=0);zoom:1;pointer-events:none}.until-switch{position:relative}.until-switch .cal-group{position:absolute;top:6px;left:130px;-webkit-transition:all 0.2s ease-out;-moz-transition:all 0.2s ease-out;-ms-transition:all 0.2s ease-out;-o-transition:all 0.2s ease-out;transition:all 0.2s ease-out}.until-switch .cal-group li.until-count{display:none}.until-switch .cal-group li.until-count:after{content:'';display:table;clear:both}.until-switch .cal-group li.until-count>*{float:left}.until-switch .cal-group li.until-count>label{margin:6px 0 0 10px}.until-switch .cal-group.no-show{left:200px;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=” $value * 100 “)";filter:alpha(opacity=0);zoom:1;pointer-events:none}.recurrence-choices-specific>li{display:none}.recurrence-choices-specific>li>*{display:block;float:left}.recurrence-choices-specific>li>label{margin:7px 10px 0 0}.recurrence-choices-specific>li>label.spaced{margin:7px 30px 0 0}.recurrence-choices-specific>li>.field{margin:0}.recurrence-wrapper{display:none}.recurrence-block{-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;padding:15px 15px 8px;background:#F9F9F9}.recurrence-block div.checkbox-group:after{content:'';display:table;clear:both}.recurrence-block div.checkbox-group>div{float:left;margin:0 7px 7px 0}.recurrence-block div.checkbox-group>div input[type=checkbox]{display:none}.recurrence-block div.checkbox-group>div input[type=checkbox]+label{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;display:block;width:25px;height:25px;white-space:nowrap;padding:4px 0 0 !important;background:#fff;text-align:center;-webkit-transition:all 0.3s ease-out;-moz-transition:all 0.3s ease-out;-ms-transition:all 0.3s ease-out;-o-transition:all 0.3s ease-out;transition:all 0.3s ease-out}.recurrence-block div.checkbox-group>div input[type=checkbox]+label:before{display:none}.recurrence-block div.checkbox-group>div input[type=checkbox]+label:hover{background-color:#e6e6e6}.recurrence-block div.checkbox-group>div input[type=checkbox]:checked+label{color:#FFFFFF;background-color:#727F8B}.recurrence-block div.checkbox-group>div input[type=checkbox]:checked+label:hover{background-color:#5b656f}.recurrence-block div.checkbox-group.month-days{max-width:530px}.recurrence-block .months{width:330px}.recurrence-block .months .checkbox-group{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}.recurrence-block .months .checkbox-group>div{-ms-flex:0 0 30%;flex:0 0 30%}.recurrence-block .months .checkbox-group>div label{width:auto !important}ul.date-list>li{position:relative;background:#F9F9F9;padding:5px 10px 5px 30px}ul.date-list>li:first-child{padding-top:10px;-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;background-clip:padding-box}ul.date-list>li:first-child>a{top:10px}ul.date-list>li:last-child{padding-bottom:10px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px;-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;background-clip:padding-box}ul.date-list>li>a{position:absolute;top:5px;left:10px;display:block;width:13px;height:20px;color:#CCCCCC;-webkit-transition:color 0.2s ease-out;-moz-transition:color 0.2s ease-out;-ms-transition:color 0.2s ease-out;-o-transition:color 0.2s ease-out;transition:color 0.2s ease-out}ul.date-list>li>a:hover{color:#da5a47;text-decoration:none}ul.date-list>li>a:before{content:'remove';font-family:Craft, sans-serif}.select-dates-wrapper{display:none}.ui-datepicker{z-index:102 !important} diff --git a/src/Resources/js/src/widget/agenda.js b/src/Resources/js/src/widget/agenda.js index 1ddacad..5401b4b 100644 --- a/src/Resources/js/src/widget/agenda.js +++ b/src/Resources/js/src/widget/agenda.js @@ -1 +1 @@ -"use strict";function _defineProperty(e,a,t){return a in e?Object.defineProperty(e,a,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[a]=t,e}function initiateAgenda(e){var a=e,t=e.data(),n=t.overlapThreshold,r=t.locale,l=t.firstDayOfWeek;a.fullCalendar({defaultView:a.data("view"),nextDayThreshold:"0"+n+":00:01",fixedWeekCount:!1,eventLimit:3,lang:r,views:viewSpecificOptions,firstDay:l,height:500,scrollTime:moment().format("HH:mm:ss"),eventClick:eventClick,eventRender:function(e,a){if(e.allDay&&a.addClass("fc-event-all-day"),e.end){if(e.multiDay||e.allDay)a.addClass("fc-event-multi-day");else{a.addClass("fc-event-single-day");var t=$("").addClass("fc-color-icon").css("background-color",e.backgroundColor).css("border-color",e.borderColor);$(".fc-content",a).prepend(t)}e.enabled||a.addClass("fc-event-disabled"),a.addClass("fc-color-"+e.textColor)}},events:function(e,t,n,r){$.ajax({url:Craft.getCpUrl("calendar/month"),data:_defineProperty({rangeStart:e.toISOString(),rangeEnd:t.toISOString(),nonEditable:!0,calendars:a.data("calendars")},Craft.csrfTokenName,Craft.csrfTokenValue),type:"post",dataType:"json",success:function(e){r(e)}})},customButtons:{refresh:{text:Craft.t("calendar","Refresh"),click:function(){a.fullCalendar("refetchEvents")}}},header:{right:"prev,today,next",left:"title"}})}var viewSpecificOptions={week:{columnFormat:"ddd D",timeFormat:"LT",slotLabelFormat:"LT"},day:{columnFormat:"",timeFormat:"LT",slotLabelFormat:"LT"}}; \ No newline at end of file +"use strict";function _defineProperty(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function initiateAgenda(e){var t=e,r=e.data(),a=r.overlapThreshold,n=r.locale,o=r.firstDayOfWeek;t.fullCalendar({defaultView:t.data("view"),nextDayThreshold:"0"+a+":00:01",fixedWeekCount:!1,eventLimit:3,lang:n,views:viewSpecificOptions,firstDay:o,height:500,scrollTime:moment().format("HH:mm:ss"),eventClick:eventClick,eventRender:function(e,t){if(e.allDay&&t.addClass("fc-event-all-day"),e.end){if(e.multiDay||e.allDay)t.addClass("fc-event-multi-day");else{t.addClass("fc-event-single-day");var r=$("").addClass("fc-color-icon").css("background-color",e.backgroundColor).css("border-color",e.borderColor);$(".fc-content",t).prepend(r)}e.enabled||t.addClass("fc-event-disabled"),t.addClass("fc-color-"+e.textColor)}},events:function(e,r,a,n){$.ajax({url:Craft.getCpUrl("calendar/month"),data:_defineProperty({rangeStart:e.toISOString(),rangeEnd:r.toISOString(),nonEditable:!0,calendars:t.data("calendars")},Craft.csrfTokenName,Craft.csrfTokenValue),type:"post",dataType:"json",success:function(e){var t=!0,r=!1,a=void 0;try{for(var o,l=e.entries()[Symbol.iterator]();!(t=(o=l.next()).done);t=!0){var i=_slicedToArray(o.value,2),d=i[0],c=i[1];c.allDay&&(e[d].end=moment(c.end).add(2,"s").utc().format()),e[d].editable=!1}}catch(s){r=!0,a=s}finally{try{!t&&l["return"]&&l["return"]()}finally{if(r)throw a}}n(e)}})},customButtons:{refresh:{text:Craft.t("calendar","Refresh"),click:function(){t.fullCalendar("refetchEvents")}}},header:{right:"prev,today,next",left:"title"}})}var _slicedToArray=function(){function e(e,t){var r=[],a=!0,n=!1,o=void 0;try{for(var l,i=e[Symbol.iterator]();!(a=(l=i.next()).done)&&(r.push(l.value),!t||r.length!==t);a=!0);}catch(d){n=!0,o=d}finally{try{!a&&i["return"]&&i["return"]()}finally{if(n)throw o}}return r}return function(t,r){if(Array.isArray(t))return t;if(Symbol.iterator in Object(t))return e(t,r);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),viewSpecificOptions={week:{columnFormat:"ddd D",timeFormat:"LT",slotLabelFormat:"LT"},day:{columnFormat:"",timeFormat:"LT",slotLabelFormat:"LT"}}; \ No newline at end of file diff --git a/src/Services/EventsService.php b/src/Services/EventsService.php index 3649b2d..15ba8eb 100644 --- a/src/Services/EventsService.php +++ b/src/Services/EventsService.php @@ -189,15 +189,18 @@ public function getAllEventCount(): int * @param Event $event * @param bool|null $validateContent * + * @param bool $bypassTitleGenerator + * * @return bool - * @throws \Exception * @throws \Throwable + * @throws \yii\base\Exception + * @throws \yii\db\Exception */ - public function saveEvent(Event $event, bool $validateContent = true): bool + public function saveEvent(Event $event, bool $validateContent = true, bool $bypassTitleGenerator = false): bool { $isNewEvent = !$event->id; - if (!$event->getCalendar()->hasTitleField) { + if (!$bypassTitleGenerator && !$event->getCalendar()->hasTitleField) { $event->title = \Craft::$app->view->renderObjectTemplate($event->getCalendar()->titleFormat, $event); } diff --git a/src/templates/_widgets/agenda/body.html b/src/templates/_widgets/agenda/body.html index 769758f..2e65097 100644 --- a/src/templates/_widgets/agenda/body.html +++ b/src/templates/_widgets/agenda/body.html @@ -4,7 +4,7 @@ id="calendar-agenda-{{ ID }}" data-view="{{ settings.view }}" data-calendars="{{ settings.calendars|join(',') }}" - data-time-format="{{ craft.i18n.timepickerJsFormat }}" + data-time-format="{{ craft.app.locale.getTimeFormat('short', 'php') }}" data-locale="{{ locale }}" data-overlap-threshold="{{ craft.calendar.settings.overlapThreshold }}" data-first-day-of-week="{{ currentUser is defined and currentUser ? currentUser.getPreference('weekStartDay') : craft.config.general.defaultWeekStartDay }}" diff --git a/src/templates/_widgets/upcoming-events/body.html b/src/templates/_widgets/upcoming-events/body.html index db1787a..e1dd22b 100644 --- a/src/templates/_widgets/upcoming-events/body.html +++ b/src/templates/_widgets/upcoming-events/body.html @@ -10,7 +10,7 @@ - {% for event in events %} + {% for event in events.all %}
{% if settings.calendars|length > 1 or settings.calendars == "*" %} diff --git a/src/templates/events/_edit.html b/src/templates/events/_edit.html index e8a1092..7885330 100644 --- a/src/templates/events/_edit.html +++ b/src/templates/events/_edit.html @@ -22,16 +22,16 @@ {% block header %} {{ block('pageTitle') }} {{ block('contextMenu') }} - {#
#} - {#{% if showPreviewBtn or shareUrl is defined %}#} - {#{% if showPreviewBtn %}#} - {#
{{ "Live Preview"|t('app') }}
#} - {#{% endif %}#} - {#{% if shareUrl is defined %}#} - {##} - {#{% endif %}#} - {#
#} - {#{% endif %}#} +
+ {% if showPreviewBtn or shareUrl is defined %} + {% if showPreviewBtn %} +
{{ "Live Preview"|t('app') }}
+ {% endif %} + {% if shareUrl is defined %} + + {% endif %} +
+ {% endif %} {{ block('actionButton') }} {% endblock %} diff --git a/src/translations/de.php b/src/translations/de/calendar.php similarity index 100% rename from src/translations/de.php rename to src/translations/de/calendar.php diff --git a/src/translations/en.php b/src/translations/en-US/calendar.php similarity index 100% rename from src/translations/en.php rename to src/translations/en-US/calendar.php diff --git a/src/translations/lv.php b/src/translations/lv/calendar.php similarity index 100% rename from src/translations/lv.php rename to src/translations/lv/calendar.php diff --git a/src/translations/nl.php b/src/translations/nl/calendar.php similarity index 100% rename from src/translations/nl.php rename to src/translations/nl/calendar.php