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
//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;
......
<?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() ?>
......
......@@ -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) {
......
......@@ -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;
......
......@@ -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'"
......
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