diff --git a/app/controllers/calendar/date.php b/app/controllers/calendar/date.php index cb61a7e7ae7c9b3c7da70f5c7107e2e22d26a674..bd60e384ca0616b0d37b5abbfb0aabd4ac9f0d94 100644 --- a/app/controllers/calendar/date.php +++ b/app/controllers/calendar/date.php @@ -436,17 +436,25 @@ class Calendar_DateController extends AuthenticatedController //Store the repetition information: $this->date->clearRepetitionFields(); - $this->date->repetition_type = Request::get('repetition_type', ''); - if (!in_array($this->date->repetition_type, ['', 'DAILY', 'WEEKLY', 'WORKDAYS', 'MONTHLY', 'YEARLY'])) { + $this->date->repetition_type = Request::get('repetition_type', CalendarDate::REPETITION_SINGLE); + if ( + !in_array($this->date->repetition_type, [ + CalendarDate::REPETITION_SINGLE, + CalendarDate::REPETITION_DAILY, + CalendarDate::REPETITION_WEEKLY, + CalendarDate::REPETITION_MONTHLY, + CalendarDate::REPETITION_YEARLY, + 'WORKDAYS', + ]) + ) { $this->form_errors[_('Wiederholung')] = _('Bitte wählen Sie ein gültiges Wiederholungsintervall aus.'); - } - if ($this->date->repetition_type !== '') { + } elseif ($this->date->repetition_type !== CalendarDate::REPETITION_SINGLE) { $this->date->interval = ''; - if (in_array($this->date->repetition_type, ['DAILY', 'WEEKLY', 'MONTHLY', 'YEARLY'])) { - $this->date->interval = Request::get('repetition_interval'); + if ($this->date->repetition_type !== 'WORKDAYS') { + $this->date->interval = Request::int('repetition_interval'); } - if ($this->date->repetition_type === 'WEEKLY') { + if ($this->date->repetition_type === CalendarDate::REPETITION_WEEKLY) { $dow = array_unique(Request::getArray('repetition_dow')); foreach ($dow as $day) { if ($day < 1 || $day > 7) { @@ -457,29 +465,29 @@ class Calendar_DateController extends AuthenticatedController } elseif ($this->date->repetition_type === 'WORKDAYS') { //Special case: The "WORKDAYS" repetition type is a shorthand type //for a weekly repetition from Monday to Friday. - $this->date->repetition_type = 'WEEKLY'; + $this->date->repetition_type = CalendarDate::REPETITION_WEEKLY; $this->date->days = '12345'; - $this->date->interval = '1'; - } elseif ($this->date->repetition_type === 'MONTHLY') { + $this->date->interval = 1; + } elseif ($this->date->repetition_type === CalendarDate::REPETITION_MONTHLY) { $month_type = Request::get('repetition_month_type'); if ($month_type === 'dom') { - $this->date->offset = Request::get('repetition_dom'); + $this->date->offset = Request::int('repetition_dom'); } elseif ($month_type === 'dow') { $this->date->days = Request::get('repetition_dow'); - $this->date->offset = Request::get('repetition_dow_week'); + $this->date->offset = Request::int('repetition_dow_week'); } - } elseif ($this->date->repetition_type === 'YEARLY') { - $month = Request::get('repetition_month'); + } elseif ($this->date->repetition_type === CalendarDate::REPETITION_YEARLY) { + $month = Request::int('repetition_month'); if ($month < 1 || $month > 12) { $this->form_errors[_('Monat')] = _('Bitte wählen Sie einen Monat zwischen Januar und Dezember aus.'); } $this->date->month = $month; $month_type = Request::get('repetition_month_type'); if ($month_type === 'dom') { - $this->date->offset = Request::get('repetition_dom'); + $this->date->offset = Request::int('repetition_dom'); } elseif ($month_type === 'dow') { $this->date->days = Request::get('repetition_dow'); - $this->date->offset = Request::get('repetition_dow_week'); + $this->date->offset = Request::int('repetition_dow_week'); } } @@ -489,7 +497,7 @@ class Calendar_DateController extends AuthenticatedController $end_date->setTime(23,59,59); $this->date->repetition_end = $end_date->getTimestamp(); } elseif ($end_type === 'end_count') { - $this->date->number_of_dates = Request::get('repetition_number_of_dates'); + $this->date->number_of_dates = Request::int('repetition_number_of_dates'); } else { //Repetition never ends: $this->date->repetition_end = CalendarDate::NEVER_ENDING; diff --git a/app/views/calendar/date/_add_edit_form.php b/app/views/calendar/date/_add_edit_form.php index 4ececab1b592e9027894b3a76476b105c438d6b7..842464773d849dbe1247b931737b987062ee0217 100644 --- a/app/views/calendar/date/_add_edit_form.php +++ b/app/views/calendar/date/_add_edit_form.php @@ -1,3 +1,19 @@ +<?php +/** + * @var Calendar_DateController $controller + * @var string $form_post_link + * @var string|null $user_id + * @var string|null $group_id + * @var array $form_errors + * @var CalendarDate $date + * @var bool $all_day_event + * @var array<int, string> $category_options + * @var string[] $exceptions + * @var string $user_quick_search_type + * @var array $calendar_assignment_items + * @var string $owner_id + */ +?> <form class="default new-calendar-date-form" method="post" action="<?= $form_post_link ?>" data-dialog="reload-on-close"> <?= CSRFProtection::tokenTag() ?> diff --git a/lib/models/calendar/CalendarDate.php b/lib/models/calendar/CalendarDate.php index fc31d52f9122ea2ebb2ec0028ce77b3f036085d3..b5dad5105d0015c917f48af9cb18c5592468e257 100644 --- a/lib/models/calendar/CalendarDate.php +++ b/lib/models/calendar/CalendarDate.php @@ -52,6 +52,12 @@ class CalendarDate extends SimpleORMap implements PrivacyObject */ public const NEVER_ENDING = 2147483647; + public const REPETITION_SINGLE = 'SINGLE'; + public const REPETITION_DAILY = 'DAILY'; + public const REPETITION_WEEKLY = 'WEEKLY'; + public const REPETITION_MONTHLY = 'MONTHLY'; + public const REPETITION_YEARLY = 'YEARLY'; + protected static function configure($config = []) { $config['db_table'] = 'calendar_dates'; @@ -103,10 +109,10 @@ class CalendarDate extends SimpleORMap implements PrivacyObject */ public function getDefaultValue($field) { - if ($field == 'begin') { + if ($field === 'begin') { return time(); } - if ($field == 'end' && $this->content['begin']) { + if ($field === 'end' && $this->content['begin']) { return $this->content['begin'] + 3600; } return parent::getDefaultValue($field); @@ -305,19 +311,27 @@ class CalendarDate extends SimpleORMap implements PrivacyObject */ public function calculateExpiration() { - if (!in_array($this->repetition_type, ['DAILY', 'WEEKLY', 'MONTHLY', 'YEARLY'])) { + if ( + !in_array($this->repetition_type, [ + self::REPETITION_DAILY, + self::REPETITION_WEEKLY, + self::REPETITION_MONTHLY, + self::REPETITION_YEARLY, + ]) + ) { //No repetition. Nothing to do. return; } + if ($this->number_of_dates > 1) { //There is a certain amount of repetitions, so that the expiration date //has to be calculated by that. $expiration = new DateTime(); $expiration->setTimestamp($this->begin); $interval_str = ''; - if ($this->repetition_type === 'DAILY') { + if ($this->repetition_type === self::REPETITION_DAILY) { $interval_str = sprintf('P%dD', ((int) $this->number_of_dates - 1) * $this->interval); - } elseif ($this->repetition_type === 'WEEKLY') { + } elseif ($this->repetition_type === self::REPETITION_WEEKLY) { $days_length = mb_strlen($this->days); if ($days_length > 0) { $wday = $expiration->format('N'); @@ -334,9 +348,9 @@ class CalendarDate extends SimpleORMap implements PrivacyObject } else { $interval_str = sprintf('P%dW', ($this->number_of_dates - 1) * $this->interval); } - } elseif ($this->repetition_type === 'MONTHLY') { + } elseif ($this->repetition_type === self::REPETITION_MONTHLY) { $interval_str = sprintf('P%dM', ($this->number_of_dates - 1) * $this->interval); - } elseif ($this->repetition_type === 'YEARLY') { + } elseif ($this->repetition_type === self::REPETITION_YEARLY) { $interval_str = sprintf('P%dY', ($this->number_of_dates - 1) * $this->interval); } try { @@ -365,15 +379,15 @@ class CalendarDate extends SimpleORMap implements PrivacyObject */ public function getRepetitionInterval() : ?DateInterval { - if ($this->repetition_type === 'DAILY') { + if ($this->repetition_type === self::REPETITION_DAILY) { return new DateInterval(sprintf('P%uD', $this->interval)); } elseif ($this->repetition_type === 'WORKDAYS') { return new DateInterval('P1W'); - } elseif ($this->repetition_type === 'WEEKLY') { + } elseif ($this->repetition_type === self::REPETITION_WEEKLY) { return new DateInterval(sprintf('P%uW', $this->interval)); - } elseif ($this->repetition_type === 'MONTHLY') { + } elseif ($this->repetition_type === self::REPETITION_MONTHLY) { return new DateInterval(sprintf('P%uM', $this->interval)); - } elseif ($this->repetition_type === 'YEARLY') { + } elseif ($this->repetition_type === self::REPETITION_YEARLY) { return new DateInterval(sprintf('P%uY', $this->interval)); } //No repetition: no interval. @@ -387,13 +401,13 @@ class CalendarDate extends SimpleORMap implements PrivacyObject return null; } - if ($this->repetition_type === 'MONTHLY') { + if ($this->repetition_type === self::REPETITION_MONTHLY) { if ($this->days_offset) { return new DateInterval(sprintf('P%1$uM%2$uD', $this->offset, $this->days_offset)); } else { return new DateInterval(sprintf('P%uM', $this->offset)); } - } elseif ($this->repetition_type === 'YEARLY') { + } elseif ($this->repetition_type === self::REPETITION_YEARLY) { return new DateInterval(sprintf('P%uM', $this->offset)); } return null; @@ -433,13 +447,13 @@ class CalendarDate extends SimpleORMap implements PrivacyObject */ public function clearRepetitionFields() { - $this->repetition_type = ''; - $this->interval = ''; - $this->offset = ''; + $this->repetition_type = self::REPETITION_SINGLE; + $this->interval = 0; + $this->offset = 0; $this->days = ''; - $this->month = ''; - $this->number_of_dates = '1'; - $this->repetition_end = ''; + $this->month = null; + $this->number_of_dates = 1; + $this->repetition_end = 0; } public function getAccessAsString() : string @@ -461,9 +475,9 @@ class CalendarDate extends SimpleORMap implements PrivacyObject $repetition_string = ''; - if ($this->repetition_type === 'SINGLE') { + if ($this->repetition_type === self::REPETITION_SINGLE) { $repetition_string = _('Keine Wiederholung'); - } elseif ($this->repetition_type === 'DAILY') { + } elseif ($this->repetition_type === self::REPETITION_DAILY) { if ($this->interval > 0) { if ($this->interval == '1') { //Each day @@ -502,7 +516,7 @@ class CalendarDate extends SimpleORMap implements PrivacyObject } } } - } elseif ($this->repetition_type === 'WEEKLY') { + } elseif ($this->repetition_type === self::REPETITION_WEEKLY) { $weekday_string = ''; if (strlen($this->days) > 1) { //Multiple days @@ -567,7 +581,7 @@ class CalendarDate extends SimpleORMap implements PrivacyObject ); } } - } elseif ($this->repetition_type === 'MONTHLY') { + } elseif ($this->repetition_type === self::REPETITION_MONTHLY) { if ($this->interval == '1') { //Each month if ($this->days) { @@ -620,7 +634,7 @@ class CalendarDate extends SimpleORMap implements PrivacyObject ); } } - } elseif ($this->repetition_type === 'YEARLY') { + } elseif ($this->repetition_type === self::REPETITION_YEARLY) { if ($this->interval == '1') { //Each year if ($this->days) { diff --git a/lib/models/calendar/CalendarDateAssignment.php b/lib/models/calendar/CalendarDateAssignment.php index 53d54d86608ec284453c473e30ed58773a4baced..82bbab88678fee41ec42669a487e3a5f9b89fd4f 100644 --- a/lib/models/calendar/CalendarDateAssignment.php +++ b/lib/models/calendar/CalendarDateAssignment.php @@ -329,10 +329,10 @@ class CalendarDateAssignment extends SimpleORMap implements Event $ts = $this->getNoonDate(); $pos = 1; switch ($this->getRepetitionType()) { - case 'DAILY': + case CalendarDate::REPETITION_DAILY: $pos = $cal_date->diff($ts)->days % $this->calendar_date->interval; break; - case 'WEEKLY': + case CalendarDate::REPETITION_WEEKLY: $cal_ts = $cal_date->modify('monday this week noon'); if ($cal_date >= $this->getBegin()) { $pos = $cal_ts->diff($ts)->days % ($this->calendar_date->interval * 7); @@ -344,7 +344,7 @@ class CalendarDateAssignment extends SimpleORMap implements Event } } break; - case 'MONTHLY': + case CalendarDate::REPETITION_MONTHLY: $cal_ts = $cal_date->modify('first day of this month noon'); $diff = $cal_ts->diff($ts); $pos = ($diff->m + $diff->y * 12) % $this->calendar_date->interval; @@ -361,7 +361,7 @@ class CalendarDateAssignment extends SimpleORMap implements Event } } break; - case 'YEARLY': + case CalendarDate::REPETITION_YEARLY: $cal_ts = $cal_date->modify('first day of this year noon'); $diff = $cal_ts->diff($ts); $pos = $diff->y % $this->calendar_date->interval; @@ -598,13 +598,13 @@ class CalendarDateAssignment extends SimpleORMap implements Event { $ts = DateTimeImmutable::createFromMutable($this->getBegin()); switch ($this->calendar_date->repetition_type) { - case 'DAILY': + case CalendarDate::REPETITION_DAILY: return $ts->modify('noon'); - case 'WEEKLY': + case CalendarDate::REPETITION_WEEKLY: return $ts->modify('monday this week noon'); - case 'MONTHLY': + case CalendarDate::REPETITION_MONTHLY: return $ts->modify('first day of this month noon'); - case 'YEARLY': + case CalendarDate::REPETITION_YEARLY: return $ts->modify('first day of this year noon'); default: return $ts; diff --git a/resources/vue/components/form_inputs/RepetitionInput.vue b/resources/vue/components/form_inputs/RepetitionInput.vue index ef53ffb8cd2dd3963b3aced7bc72ba3fe684819b..55654fd23fa142723b106889076d2a58048e61ce 100644 --- a/resources/vue/components/form_inputs/RepetitionInput.vue +++ b/resources/vue/components/form_inputs/RepetitionInput.vue @@ -3,7 +3,7 @@ <section> <label>{{ $gettext('Art der Wiederholung') }} <select :name="name + '_type'" v-model="repetition_type_value"> - <option value="" :selected="!repetition_type_value"> + <option value="SINGLE" :selected="!repetition_type_value || repetition_type_value === 'SINGLE'"> {{ $gettext('Keine Wiederholung') }} </option> <option value="DAILY" :selected="repetition_type_value === 'DAILY'"> @@ -200,7 +200,7 @@ </label> </section> - <section v-if="repetition_type_value"> + <section v-if="repetition_type_value !== 'SINGLE'"> <label> {{ $gettext('Ende der Wiederholung') }} <select :name="name + '_rep_end_type'"