Skip to content
Snippets Groups Projects
Commit 3788044e authored by Jan-Hendrik Willms's avatar Jan-Hendrik Willms
Browse files

calendar: set valid variable types and values and introduce some constants for that, fixes #4484

Closes #4484

Merge request studip/studip!3270
parent 9a3be241
No related branches found
No related tags found
No related merge requests found
...@@ -436,17 +436,25 @@ class Calendar_DateController extends AuthenticatedController ...@@ -436,17 +436,25 @@ class Calendar_DateController extends AuthenticatedController
//Store the repetition information: //Store the repetition information:
$this->date->clearRepetitionFields(); $this->date->clearRepetitionFields();
$this->date->repetition_type = Request::get('repetition_type', ''); $this->date->repetition_type = Request::get('repetition_type', CalendarDate::REPETITION_SINGLE);
if (!in_array($this->date->repetition_type, ['', 'DAILY', 'WEEKLY', 'WORKDAYS', 'MONTHLY', 'YEARLY'])) { 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.'); $this->form_errors[_('Wiederholung')] = _('Bitte wählen Sie ein gültiges Wiederholungsintervall aus.');
} } elseif ($this->date->repetition_type !== CalendarDate::REPETITION_SINGLE) {
if ($this->date->repetition_type !== '') {
$this->date->interval = ''; $this->date->interval = '';
if (in_array($this->date->repetition_type, ['DAILY', 'WEEKLY', 'MONTHLY', 'YEARLY'])) { if ($this->date->repetition_type !== 'WORKDAYS') {
$this->date->interval = Request::get('repetition_interval'); $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')); $dow = array_unique(Request::getArray('repetition_dow'));
foreach ($dow as $day) { foreach ($dow as $day) {
if ($day < 1 || $day > 7) { if ($day < 1 || $day > 7) {
...@@ -457,29 +465,29 @@ class Calendar_DateController extends AuthenticatedController ...@@ -457,29 +465,29 @@ class Calendar_DateController extends AuthenticatedController
} elseif ($this->date->repetition_type === 'WORKDAYS') { } elseif ($this->date->repetition_type === 'WORKDAYS') {
//Special case: The "WORKDAYS" repetition type is a shorthand type //Special case: The "WORKDAYS" repetition type is a shorthand type
//for a weekly repetition from Monday to Friday. //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->days = '12345';
$this->date->interval = '1'; $this->date->interval = 1;
} elseif ($this->date->repetition_type === 'MONTHLY') { } elseif ($this->date->repetition_type === CalendarDate::REPETITION_MONTHLY) {
$month_type = Request::get('repetition_month_type'); $month_type = Request::get('repetition_month_type');
if ($month_type === 'dom') { if ($month_type === 'dom') {
$this->date->offset = Request::get('repetition_dom'); $this->date->offset = Request::int('repetition_dom');
} elseif ($month_type === 'dow') { } elseif ($month_type === 'dow') {
$this->date->days = Request::get('repetition_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') { } elseif ($this->date->repetition_type === CalendarDate::REPETITION_YEARLY) {
$month = Request::get('repetition_month'); $month = Request::int('repetition_month');
if ($month < 1 || $month > 12) { if ($month < 1 || $month > 12) {
$this->form_errors[_('Monat')] = _('Bitte wählen Sie einen Monat zwischen Januar und Dezember aus.'); $this->form_errors[_('Monat')] = _('Bitte wählen Sie einen Monat zwischen Januar und Dezember aus.');
} }
$this->date->month = $month; $this->date->month = $month;
$month_type = Request::get('repetition_month_type'); $month_type = Request::get('repetition_month_type');
if ($month_type === 'dom') { if ($month_type === 'dom') {
$this->date->offset = Request::get('repetition_dom'); $this->date->offset = Request::int('repetition_dom');
} elseif ($month_type === 'dow') { } elseif ($month_type === 'dow') {
$this->date->days = Request::get('repetition_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 ...@@ -489,7 +497,7 @@ class Calendar_DateController extends AuthenticatedController
$end_date->setTime(23,59,59); $end_date->setTime(23,59,59);
$this->date->repetition_end = $end_date->getTimestamp(); $this->date->repetition_end = $end_date->getTimestamp();
} elseif ($end_type === 'end_count') { } 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 { } else {
//Repetition never ends: //Repetition never ends:
$this->date->repetition_end = CalendarDate::NEVER_ENDING; $this->date->repetition_end = CalendarDate::NEVER_ENDING;
......
<?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 ?>" <form class="default new-calendar-date-form" method="post" action="<?= $form_post_link ?>"
data-dialog="reload-on-close"> data-dialog="reload-on-close">
<?= CSRFProtection::tokenTag() ?> <?= CSRFProtection::tokenTag() ?>
......
...@@ -52,6 +52,12 @@ class CalendarDate extends SimpleORMap implements PrivacyObject ...@@ -52,6 +52,12 @@ class CalendarDate extends SimpleORMap implements PrivacyObject
*/ */
public const NEVER_ENDING = 2147483647; 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 = []) protected static function configure($config = [])
{ {
$config['db_table'] = 'calendar_dates'; $config['db_table'] = 'calendar_dates';
...@@ -103,10 +109,10 @@ class CalendarDate extends SimpleORMap implements PrivacyObject ...@@ -103,10 +109,10 @@ class CalendarDate extends SimpleORMap implements PrivacyObject
*/ */
public function getDefaultValue($field) public function getDefaultValue($field)
{ {
if ($field == 'begin') { if ($field === 'begin') {
return time(); return time();
} }
if ($field == 'end' && $this->content['begin']) { if ($field === 'end' && $this->content['begin']) {
return $this->content['begin'] + 3600; return $this->content['begin'] + 3600;
} }
return parent::getDefaultValue($field); return parent::getDefaultValue($field);
...@@ -305,19 +311,27 @@ class CalendarDate extends SimpleORMap implements PrivacyObject ...@@ -305,19 +311,27 @@ class CalendarDate extends SimpleORMap implements PrivacyObject
*/ */
public function calculateExpiration() 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. //No repetition. Nothing to do.
return; return;
} }
if ($this->number_of_dates > 1) { if ($this->number_of_dates > 1) {
//There is a certain amount of repetitions, so that the expiration date //There is a certain amount of repetitions, so that the expiration date
//has to be calculated by that. //has to be calculated by that.
$expiration = new DateTime(); $expiration = new DateTime();
$expiration->setTimestamp($this->begin); $expiration->setTimestamp($this->begin);
$interval_str = ''; $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); $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); $days_length = mb_strlen($this->days);
if ($days_length > 0) { if ($days_length > 0) {
$wday = $expiration->format('N'); $wday = $expiration->format('N');
...@@ -334,9 +348,9 @@ class CalendarDate extends SimpleORMap implements PrivacyObject ...@@ -334,9 +348,9 @@ class CalendarDate extends SimpleORMap implements PrivacyObject
} else { } else {
$interval_str = sprintf('P%dW', ($this->number_of_dates - 1) * $this->interval); $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); $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); $interval_str = sprintf('P%dY', ($this->number_of_dates - 1) * $this->interval);
} }
try { try {
...@@ -365,15 +379,15 @@ class CalendarDate extends SimpleORMap implements PrivacyObject ...@@ -365,15 +379,15 @@ class CalendarDate extends SimpleORMap implements PrivacyObject
*/ */
public function getRepetitionInterval() : ?DateInterval public function getRepetitionInterval() : ?DateInterval
{ {
if ($this->repetition_type === 'DAILY') { if ($this->repetition_type === self::REPETITION_DAILY) {
return new DateInterval(sprintf('P%uD', $this->interval)); return new DateInterval(sprintf('P%uD', $this->interval));
} elseif ($this->repetition_type === 'WORKDAYS') { } elseif ($this->repetition_type === 'WORKDAYS') {
return new DateInterval('P1W'); return new DateInterval('P1W');
} elseif ($this->repetition_type === 'WEEKLY') { } elseif ($this->repetition_type === self::REPETITION_WEEKLY) {
return new DateInterval(sprintf('P%uW', $this->interval)); 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)); 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)); return new DateInterval(sprintf('P%uY', $this->interval));
} }
//No repetition: no interval. //No repetition: no interval.
...@@ -387,13 +401,13 @@ class CalendarDate extends SimpleORMap implements PrivacyObject ...@@ -387,13 +401,13 @@ class CalendarDate extends SimpleORMap implements PrivacyObject
return null; return null;
} }
if ($this->repetition_type === 'MONTHLY') { if ($this->repetition_type === self::REPETITION_MONTHLY) {
if ($this->days_offset) { if ($this->days_offset) {
return new DateInterval(sprintf('P%1$uM%2$uD', $this->offset, $this->days_offset)); return new DateInterval(sprintf('P%1$uM%2$uD', $this->offset, $this->days_offset));
} else { } else {
return new DateInterval(sprintf('P%uM', $this->offset)); 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 new DateInterval(sprintf('P%uM', $this->offset));
} }
return null; return null;
...@@ -433,13 +447,13 @@ class CalendarDate extends SimpleORMap implements PrivacyObject ...@@ -433,13 +447,13 @@ class CalendarDate extends SimpleORMap implements PrivacyObject
*/ */
public function clearRepetitionFields() public function clearRepetitionFields()
{ {
$this->repetition_type = ''; $this->repetition_type = self::REPETITION_SINGLE;
$this->interval = ''; $this->interval = 0;
$this->offset = ''; $this->offset = 0;
$this->days = ''; $this->days = '';
$this->month = ''; $this->month = null;
$this->number_of_dates = '1'; $this->number_of_dates = 1;
$this->repetition_end = ''; $this->repetition_end = 0;
} }
public function getAccessAsString() : string public function getAccessAsString() : string
...@@ -461,9 +475,9 @@ class CalendarDate extends SimpleORMap implements PrivacyObject ...@@ -461,9 +475,9 @@ class CalendarDate extends SimpleORMap implements PrivacyObject
$repetition_string = ''; $repetition_string = '';
if ($this->repetition_type === 'SINGLE') { if ($this->repetition_type === self::REPETITION_SINGLE) {
$repetition_string = _('Keine Wiederholung'); $repetition_string = _('Keine Wiederholung');
} elseif ($this->repetition_type === 'DAILY') { } elseif ($this->repetition_type === self::REPETITION_DAILY) {
if ($this->interval > 0) { if ($this->interval > 0) {
if ($this->interval == '1') { if ($this->interval == '1') {
//Each day //Each day
...@@ -502,7 +516,7 @@ class CalendarDate extends SimpleORMap implements PrivacyObject ...@@ -502,7 +516,7 @@ class CalendarDate extends SimpleORMap implements PrivacyObject
} }
} }
} }
} elseif ($this->repetition_type === 'WEEKLY') { } elseif ($this->repetition_type === self::REPETITION_WEEKLY) {
$weekday_string = ''; $weekday_string = '';
if (strlen($this->days) > 1) { if (strlen($this->days) > 1) {
//Multiple days //Multiple days
...@@ -567,7 +581,7 @@ class CalendarDate extends SimpleORMap implements PrivacyObject ...@@ -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') { if ($this->interval == '1') {
//Each month //Each month
if ($this->days) { if ($this->days) {
...@@ -620,7 +634,7 @@ class CalendarDate extends SimpleORMap implements PrivacyObject ...@@ -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') { if ($this->interval == '1') {
//Each year //Each year
if ($this->days) { if ($this->days) {
......
...@@ -329,10 +329,10 @@ class CalendarDateAssignment extends SimpleORMap implements Event ...@@ -329,10 +329,10 @@ class CalendarDateAssignment extends SimpleORMap implements Event
$ts = $this->getNoonDate(); $ts = $this->getNoonDate();
$pos = 1; $pos = 1;
switch ($this->getRepetitionType()) { switch ($this->getRepetitionType()) {
case 'DAILY': case CalendarDate::REPETITION_DAILY:
$pos = $cal_date->diff($ts)->days % $this->calendar_date->interval; $pos = $cal_date->diff($ts)->days % $this->calendar_date->interval;
break; break;
case 'WEEKLY': case CalendarDate::REPETITION_WEEKLY:
$cal_ts = $cal_date->modify('monday this week noon'); $cal_ts = $cal_date->modify('monday this week noon');
if ($cal_date >= $this->getBegin()) { if ($cal_date >= $this->getBegin()) {
$pos = $cal_ts->diff($ts)->days % ($this->calendar_date->interval * 7); $pos = $cal_ts->diff($ts)->days % ($this->calendar_date->interval * 7);
...@@ -344,7 +344,7 @@ class CalendarDateAssignment extends SimpleORMap implements Event ...@@ -344,7 +344,7 @@ class CalendarDateAssignment extends SimpleORMap implements Event
} }
} }
break; break;
case 'MONTHLY': case CalendarDate::REPETITION_MONTHLY:
$cal_ts = $cal_date->modify('first day of this month noon'); $cal_ts = $cal_date->modify('first day of this month noon');
$diff = $cal_ts->diff($ts); $diff = $cal_ts->diff($ts);
$pos = ($diff->m + $diff->y * 12) % $this->calendar_date->interval; $pos = ($diff->m + $diff->y * 12) % $this->calendar_date->interval;
...@@ -361,7 +361,7 @@ class CalendarDateAssignment extends SimpleORMap implements Event ...@@ -361,7 +361,7 @@ class CalendarDateAssignment extends SimpleORMap implements Event
} }
} }
break; break;
case 'YEARLY': case CalendarDate::REPETITION_YEARLY:
$cal_ts = $cal_date->modify('first day of this year noon'); $cal_ts = $cal_date->modify('first day of this year noon');
$diff = $cal_ts->diff($ts); $diff = $cal_ts->diff($ts);
$pos = $diff->y % $this->calendar_date->interval; $pos = $diff->y % $this->calendar_date->interval;
...@@ -598,13 +598,13 @@ class CalendarDateAssignment extends SimpleORMap implements Event ...@@ -598,13 +598,13 @@ class CalendarDateAssignment extends SimpleORMap implements Event
{ {
$ts = DateTimeImmutable::createFromMutable($this->getBegin()); $ts = DateTimeImmutable::createFromMutable($this->getBegin());
switch ($this->calendar_date->repetition_type) { switch ($this->calendar_date->repetition_type) {
case 'DAILY': case CalendarDate::REPETITION_DAILY:
return $ts->modify('noon'); return $ts->modify('noon');
case 'WEEKLY': case CalendarDate::REPETITION_WEEKLY:
return $ts->modify('monday this week noon'); return $ts->modify('monday this week noon');
case 'MONTHLY': case CalendarDate::REPETITION_MONTHLY:
return $ts->modify('first day of this month noon'); return $ts->modify('first day of this month noon');
case 'YEARLY': case CalendarDate::REPETITION_YEARLY:
return $ts->modify('first day of this year noon'); return $ts->modify('first day of this year noon');
default: default:
return $ts; return $ts;
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<section> <section>
<label>{{ $gettext('Art der Wiederholung') }} <label>{{ $gettext('Art der Wiederholung') }}
<select :name="name + '_type'" v-model="repetition_type_value"> <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') }} {{ $gettext('Keine Wiederholung') }}
</option> </option>
<option value="DAILY" :selected="repetition_type_value === 'DAILY'"> <option value="DAILY" :selected="repetition_type_value === 'DAILY'">
...@@ -200,7 +200,7 @@ ...@@ -200,7 +200,7 @@
</label> </label>
</section> </section>
<section v-if="repetition_type_value"> <section v-if="repetition_type_value !== 'SINGLE'">
<label> <label>
{{ $gettext('Ende der Wiederholung') }} {{ $gettext('Ende der Wiederholung') }}
<select :name="name + '_rep_end_type'" <select :name="name + '_rep_end_type'"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment