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'"