diff options
| author | Moritz Strohm <strohm@data-quest.de> | 2024-01-29 15:16:24 +0000 |
|---|---|---|
| committer | Moritz Strohm <strohm@data-quest.de> | 2024-01-29 15:16:24 +0000 |
| commit | 7c1df847d94d3956bc763b94b73cebfe108dc9a1 (patch) | |
| tree | e18e003bff65c5bf0748c644d6cd3d235cb1feca /app/controllers/calendar/date.php | |
| parent | da0110d5e85279123e8dde392cb4c926397238bf (diff) | |
StEP 01354, closes #1354
Closes #1354
Merge request studip/studip!2116
Diffstat (limited to 'app/controllers/calendar/date.php')
| -rw-r--r-- | app/controllers/calendar/date.php | 828 |
1 files changed, 828 insertions, 0 deletions
diff --git a/app/controllers/calendar/date.php b/app/controllers/calendar/date.php new file mode 100644 index 0000000..32cf99c --- /dev/null +++ b/app/controllers/calendar/date.php @@ -0,0 +1,828 @@ +<?php + +class Calendar_DateController extends AuthenticatedController +{ + protected function getCategoryOptions() + { + if (empty($GLOBALS['PERS_TERMIN_KAT'])) { + return []; + } + $options = []; + foreach ($GLOBALS['PERS_TERMIN_KAT'] as $key => $data) { + $options[$key] = $data['name']; + } + if (!array_key_exists(255, $options)) { + $options[255] = _('Sonstige'); + } + return $options; + } + + protected function getCalendarOwner($range_and_id) + { + $range = ''; + $range_id = ''; + $range_and_id = explode('_', $range_and_id ?? []); + if (!empty($range_and_id[1])) { + $range = $range_and_id[0]; + $range_id = $range_and_id[1]; + } + if (!$range) { + //Show the personal calendar of the current user: + $range = 'user'; + $range_id = $GLOBALS['user']->id; + } + + $owner = null; + if (!$range_id) { + //Assume a user calendar. $range contains the user-ID. + $owner = User::getCalendarOwner($range); + } else { + if ($range === 'user') { + $owner = User::getCalendarOwner($range_id); + } elseif ($range === 'course') { + $owner = Course::getCalendarOwner($range_id); + } + } + + if (!$owner || !$owner->isCalendarReadable()) { + throw new AccessDeniedException(_('Sie dürfen diesen Kalender nicht sehen!')); + } + return $owner; + } + + /** + * A helper method to determine whether the current user may write the date. + * + * @return Studip\Calendar\Owner[] The owners in which the current user may add a date. + */ + protected function getCalendarOwnersWithWriteAccess(?CalendarDate $date, ?Studip\Calendar\Owner $owner) : array + { + $result = []; + if ($owner instanceof Course) { + //For course calendars, only the course can be the owner. + $result[$owner->id] = $owner; + return $result; + } + if ($date) { + foreach ($date->calendars as $calendar) { + if ($calendar->user) { + $result[$calendar->user->id] = $calendar->user; + } elseif ($calendar->course) { + $result[$calendar->course->id] = $calendar->course; + } + } + } else { + if ($group_id = Request::get('group_id')) { + $group = ContactGroup::find($group_id); + if ($group) { + foreach ($group->items as $item) { + if ($item->user && $item->user->isCalendarWritable()) { + $result[$item->user_id] = $item->user; + } + } + } + } elseif ($user_id = Request::get('user_id', $GLOBALS['user']->id)) { + $user = User::find($user_id); + if ($user && $user->isCalendarWritable()) { + $result[$user->id] = $user; + } + } + if ($other_calendar_ids = Request::getArray('other_calendar_ids')) { + foreach ($other_calendar_ids as $other_calendar_id) { + $user = User::find($other_calendar_id); + if ($user && $user->isCalendarWritable()) { + $result[$user->id] = $user; + } + } + } + } + return $result; + } + + public function index_action($date_id) + { + $this->date = CalendarDate::find($date_id); + if (!$this->date) { + PageLayout::postError(_('Der angegebene Termin wurde nicht gefunden.')); + return; + } + if (!$this->date->isVisible($GLOBALS['user']->id)) { + throw new AccessDeniedException(); + } + PageLayout::setTitle( + sprintf( + _('%1$s (am %2$s von %3$s bis %4$s Uhr)'), + $this->date->title, + date('d.m.Y', $this->date->begin), + date('H:i', $this->date->begin), + date('H:i', $this->date->end) + ) + ); + $this->selected_date = ''; + if ($this->date->repetition_type) { + $this->selected_date = Request::get('selected_date'); + } + $this->calendar_assignments = CalendarDateAssignment::findBySql( + "INNER JOIN `auth_user_md5` + ON `calendar_date_assignments`.`range_id` = `auth_user_md5`.`user_id` + WHERE + `calendar_date_id` = :calendar_date_id", + ['calendar_date_id' => $this->date->id] + ); + $this->participation_message = null; + $this->user_participation_status = ''; + $this->all_assignments_writable = false; + $this->is_group_date = count($this->calendar_assignments) > 1; + + if ($this->calendar_assignments) { + $writable_assignment_c = 0; + $more_than_one_assignment = count($this->calendar_assignments) > 1; + //Find the calendar assignment of the user and set the participation message + //according to the participation status. + foreach ($this->calendar_assignments as $index => $assignment) { + if ($assignment->range_id === $GLOBALS['user']->id && $this->is_group_date) { + $this->user_participation_status = $assignment->participation; + if ($assignment->participation === 'ACCEPTED') { + $this->participation_message = MessageBox::info(_('Sie nehmen am Termin teil.')); + } elseif ($assignment->participation === 'DECLINED') { + $this->participation_message = MessageBox::info(_('Sie nehmen nicht am Termin teil.')); + } elseif ($assignment->participation === 'ACKNOWLEDGED') { + $this->participation_message = MessageBox::info(_('Sie haben den Termin zur Kenntnis genommen.')); + } else { + $this->participation_message = MessageBox::info(_('Sie haben keine Angaben zur Teilnahme gemacht.')); + } + if ($more_than_one_assignment) { + $writable_assignment_c++; + } else { + //We don't need the users own assignment in the list of assignments + //when there is only one assignment to the users own calendar. + unset($this->calendar_assignments[$index]); + + } + } else { + if ($assignment->isWritable($GLOBALS['user']->id)) { + $writable_assignment_c++; + } + } + } + + $this->all_assignments_writable = $writable_assignment_c === count($this->calendar_assignments); + + //Order all calendar assignments by type and name: + uasort($this->calendar_assignments, function ($a, $b) { + $compare_name = ($a->course instanceof Course && $b->course instanceof Course) + || ($a->user instanceof User && $b->user instanceof User); + if ($compare_name) { + $a_name = ''; + if ($a->course instanceof Course) { + $a_name = $a->course->getFullname(); + } elseif ($a->user instanceof User) { + $a_name = $a->user->getFullName(); + } + $b_name = ''; + if ($b->course instanceof Course) { + $b_name = $b->course->getFullname(); + } elseif ($b->user instanceof User) { + $b_name = $b->user->getFullName(); + } + if ($a_name < $b_name) { + return -1; + } elseif ($a_name > $b_name) { + return 1; + } else { + return 0; + } + } else { + //Compare types. + $a_is_course = $a->course instanceof Course; + if ($a_is_course) { + return -1; + } else { + //$b is a course: + return 1; + } + } + }); + } + } + + public function add_action($range_and_id = '') + { + PageLayout::setTitle(_('Termin anlegen')); + + $owner = $this->getCalendarOwner($range_and_id); + + $this->date = new CalendarDate(); + if (Request::submitted('begin') && Request::submitted('end')) { + $this->date->begin = Request::get('begin'); + $this->date->end = Request::get('end'); + $this->date->repetition_end = $this->date->end; + } else { + $time = new DateTime(); + $time = $time->add(new DateInterval('PT1H')); + $time->setTime(intval($time->format('H')), 0, 0); + $this->date->begin = $time->getTimestamp(); + $time = $time->add(new DateInterval('PT30M')); + $this->date->end = $time->getTimestamp(); + $this->date->repetition_end = $this->date->end; + } + if ($owner instanceof Course) { + $this->form_post_link = $this->link_for('calendar/date/add/course_' . $owner->id); + } else { + //Personal calendar or group calendar + $this->form_post_link = $this->link_for('calendar/date/add'); + } + $this->handleForm('add', $owner); + } + + public function edit_action($date_id) + { + PageLayout::setTitle(_('Termin bearbeiten')); + + $this->date = CalendarDate::find($date_id); + if (!$this->date) { + throw new Exception(_('Der Termin wurde nicht gefunden!')); + } + //Set the repetition end date to the end of the date in case it isn't set: + if (!$this->date->repetition_end) { + $this->date->repetition_end = $this->date->end; + } + + $this->form_post_link = $this->link_for('calendar/date/edit/' . $this->date->id); + $this->handleForm(); + } + + protected function handleForm($mode = 'edit', $owner = null) + { + $this->form_errors = []; + $this->calendar_assignment_items = []; + + $this->writable_calendars = $this->getCalendarOwnersWithWriteAccess($mode === 'edit' ? $this->date : null, $owner); + if (!$this->writable_calendars) { + throw new AccessDeniedException(); + } + $this->user_id = Request::get('user_id', $owner->id ?? ''); + $this->group_id = ''; + if (!$owner) { + $this->group_id = Request::get('group_id'); + } + $this->owner_id = $owner ? $owner->id : ''; + + $this->category_options = $this->getCategoryOptions(); + $this->exceptions = []; + + if (!$owner || !($owner instanceof Course)) { + $this->user_quick_search_type = null; + $this->multi_person_search = null; + if (Config::get()->CALENDAR_GROUP_ENABLE) { + if (Config::get()->CALENDAR_GRANT_ALL_INSERT) { + $this->user_quick_search_type = new StandardSearch('user_id'); + } else { + //Only get those users where the current user has + //write access to the calendar. + $this->user_quick_search_type = new SQLSearch( + "SELECT + `auth_user_md5`.`user_id`, " + . $GLOBALS['_fullname_sql']['full'] . " AS fullname + FROM `auth_user_md5` + INNER JOIN `contact` + ON `auth_user_md5`.`user_id` = `contact`.`owner_id` + INNER JOIN `user_info` + ON `user_info`.`user_id` = `auth_user_md5`.`user_id` + WHERE + `auth_user_md5`.`user_id` <> " . DBManager::get()->quote($GLOBALS['user']->id) . " + AND `contact`.`user_id` = " . DBManager::get()->quote($GLOBALS['user']->id) . " + AND `contact`.`calendar_permissions` = 'WRITE' + AND ( + `auth_user_md5`.`username` LIKE :input + OR CONCAT(`auth_user_md5`.`Vorname`, ' ', `auth_user_md5`.`Nachname`) LIKE :input + OR CONCAT(`auth_user_md5`.`Nachname`, ' ', `auth_user_md5`.`Vorname`) LIKE :input + OR `auth_user_md5`.`Nachname` LIKE :input + OR " . $GLOBALS['_fullname_sql']['full'] . " LIKE :input + ) + GROUP BY `auth_user_md5`.`user_id` + ORDER BY fullname ASC", + _('Person suchen'), + 'user_id' + ); + } + } + } + + if ($this->date->isNew()) { + if (!($owner instanceof Course)) { + //Assign the date to the calendar of the current user by default: + $user = User::findCurrent(); + if ($user) { + $this->calendar_assignment_items[] = [ + 'value' => $user->id, + 'name' => $user->getFullName(), + 'deletable' => true + ]; + } + } + } else { + $exceptions = CalendarDateException::findBySql( + 'calendar_date_id = :date_id ORDER BY `date` ASC', + ['date_id' => $this->date->id] + ); + foreach ($exceptions as $exception) { + $this->exceptions[] = $exception->date; + } + + $calendars_assignments = CalendarDateAssignment::findByCalendar_date_id($this->date->id); + foreach ($calendars_assignments as $assignment) { + $range_avatar = $assignment->getRangeAvatar(); + $this->calendar_assignment_items[] = [ + 'value' => $assignment->range_id, + 'name' => $assignment->getRangeName(), + 'deletable' => true + ]; + } + } + + $this->all_day_event = false; + if ($mode === 'add' && Request::get('all_day') === '1') { + $this->all_day_event = true; + } else { + $begin = new DateTime(); + $begin->setTimestamp(intval($this->date->begin)); + $end = new DateTime(); + $end->setTimestamp(intval($this->date->end)); + $duration = $end->diff($begin); + if ($duration->h === 23 && $duration->i === 59 && $duration->s === 59 && $begin->format('H:i:s') === '00:00:00') { + //The event starts at midnight and ends on 23:59:59. It is an all-day event. + $this->all_day_event = true; + } + } + + if (!Request::isPost()) { + return; + } + if (Request::submitted('save')) { + CSRFProtection::verifyUnsafeRequest(); + + if ($this->date->isNew()) { + $this->date->author_id = $GLOBALS['user']->id; + } + $this->date->editor_id = $GLOBALS['user']->id; + + $begin = Request::getDateTime('begin', 'd.m.Y H:i'); + $end = Request::getDateTime('end', 'd.m.Y H:i'); + if (Request::get('all_day') === '1') { + $this->all_day_event = true; + $begin->setTime(0,0,0); + $end = clone $begin; + $end->setTime(23,59,59); + } + $this->date->begin = $begin->getTimestamp(); + $this->date->end = $end->getTimestamp(); + if (!$this->date->begin) { + $this->form_errors[_('Beginn')] = _('Bitte geben Sie einen Startzeitpunkt ein.'); + } + if (!$this->date->end && !$this->all_day_event) { + $this->form_errors[_('Ende')] = _('Bitte geben Sie einen Endzeitpunkt ein.'); + } + if ($this->date->begin && $this->date->end && ($this->date->end < $this->date->begin)) { + $this->form_errors[_('Ende')] = _('Der Startzeitpunkt darf nicht nach dem Endzeitpunkt liegen!'); + } + + $this->date->title = Request::get('title'); + if (!$this->date->title) { + $this->form_errors[_('Titel')] = _('Bitte geben Sie einen Titel ein.'); + } + + $this->date->access = Request::get('access'); + if (!in_array($this->date->access, ['PUBLIC', 'CONFIDENTIAL', 'PRIVATE'])) { + $this->form_errors[_('Zugriff')] = _('Bitte wählen Sie einen Zugriffstyp aus.'); + } + + $this->date->description = Request::get('description'); + + $this->date->category = Request::get('category'); + if (!in_array($this->date->category, array_keys($this->category_options))) { + $this->form_errors[_('Kategorie')] = _('Bitte wählen Sie eine gültige Kategorie aus.'); + } + + $this->date->user_category = Request::get('user_category'); + + $this->date->location = Request::get('location'); + + //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->form_errors[_('Wiederholung')] = _('Bitte wählen Sie ein gültiges Wiederholungsintervall aus.'); + } + if ($this->date->repetition_type !== '') { + $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 === 'WEEKLY') { + $dow = array_unique(Request::getArray('repetition_dow')); + foreach ($dow as $day) { + if ($day < 1 || $day > 7) { + $this->form_errors[_('Wiederholung an bestimmtem Wochentag')] = _('Bitte wählen Sie einen Wochentag zwischen Montag und Sonntag aus.'); + } + } + $this->date->days = implode('', $dow); + } 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->days = '12345'; + $this->date->interval = '1'; + } elseif ($this->date->repetition_type === 'MONTHLY') { + $month_type = Request::get('repetition_month_type'); + if ($month_type === 'dom') { + $this->date->offset = Request::get('repetition_dom'); + } elseif ($month_type === 'dow') { + $this->date->days = Request::get('repetition_dow'); + $this->date->offset = Request::get('repetition_dow_week'); + } + } elseif ($this->date->repetition_type === 'YEARLY') { + $month = Request::get('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'); + } elseif ($month_type === 'dow') { + $this->date->days = Request::get('repetition_dow'); + $this->date->offset = Request::get('repetition_dow_week'); + } + } + + $end_type = Request::get('repetition_rep_end_type'); + if ($end_type === 'end_date') { + $end_date = Request::getDateTime('repetition_rep_end_date', 'd.m.Y'); + $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'); + } else { + //Repetition never ends: + $this->date->repetition_end = CalendarDate::NEVER_ENDING; + } + } + + $assigned_calendar_ids = Request::getArray('assigned_calendar_ids'); + if (!$assigned_calendar_ids || (count($assigned_calendar_ids) === 0)) { + $this->form_errors[_('Teilnehmende Personen')] = _('Der Termin ist keinem Kalender zugewiesen!'); + } + + if ($this->form_errors) { + return; + } + + $stored = false; + if ($this->date->isDirty()) { + $stored = $this->date->store(); + } else { + $stored = true; + } + if (!$stored) { + PageLayout::postError( + _('Beim Speichern des Termins ist ein Fehler aufgetreten.') + ); + return; + } + + //Assign the calendar date to all writable calendars. + + //Check the assigned calendar-IDs first if they are valid: + $valid_assigned_calendar_ids = []; + if (($owner instanceof Course)) { + //Set the course as calendar: + $allowed_calendar_ids = [$owner->id]; + } else { + //Assign the date to the calendars of all the selected users: + $allowed_calendar_ids = [$GLOBALS['user']->id]; + if (Config::get()->CALENDAR_GROUP_ENABLE) { + $allowed_calendar_results = $this->user_quick_search_type->getResults('%%%%'); + foreach ($allowed_calendar_results as $result) { + $allowed_calendar_ids[] = $result[0]; + } + } + } + + foreach ($assigned_calendar_ids as $assigned_calendar_id) { + if (Course::exists($assigned_calendar_id) || User::exists($assigned_calendar_id)) { + //Valid ID of an existing calendar (range-ID). + if (in_array($assigned_calendar_id, $allowed_calendar_ids)) { + //The calendar is writable. + $valid_assigned_calendar_ids[] = $assigned_calendar_id; + } + } + } + if (count($valid_assigned_calendar_ids) < 1) { + PageLayout::postError( + _('Die Zuweisungen des Termins zu Kalendern sind ungültig!') + ); + return; + } + + //Remove the date from all user calendars that aren't in the array of writable calendars. + CalendarDateAssignment::deleteBySQL( + '`range_id` NOT IN ( :owner_ids ) AND `calendar_date_id` = :calendar_date_id', + ['owner_ids' => $allowed_calendar_ids, 'calendar_date_id' => $this->date->id] + ); + + //Now add the date to all selected calendars: + foreach($valid_assigned_calendar_ids as $assigned_calendar_id) { + $assignment = CalendarDateAssignment::findOneBySql( + 'range_id = :assigned_calendar_id AND calendar_date_id = :calendar_date_id', + [ + 'assigned_calendar_id' => $assigned_calendar_id, + 'calendar_date_id' => $this->date->id + ] + ); + if (!$assignment) { + $assignment = new CalendarDateAssignment(); + $assignment->range_id = $assigned_calendar_id; + $assignment->calendar_date_id = $this->date->id; + $assignment->store(); + } + } + + //Clear all exceptions for the event and set them again: + CalendarDateException::deleteByCalendar_date_id($this->date->id); + $new_exceptions = Request::getArray('exceptions'); + $stored_c = 0; + foreach ($new_exceptions as $exception) { + $date_parts = explode('-', $exception); + if (count($date_parts) === 3) { + //Should be a valid date string. + $e = new CalendarDateException(); + $e->calendar_date_id = $this->date->id; + $e->date = $exception; + if ($e->store()) { + $stored_c++; + } + } + } + if ($stored_c === count($new_exceptions)) { + PageLayout::postSuccess(_('Der Termin wurde gespeichert.')); + } else { + PageLayout::postWarning(_('Der Termin wurde gespeichert, aber nicht mit allen Terminausfällen!')); + } + if (Request::submitted('selected_date')) { + $selected_date = Request::getDateTime('selected_date'); + if ($selected_date) { + //Set the calendar default date to the previously selected date: + $_SESSION['calendar_date'] = $selected_date->format('Y-m-d'); + } + } else { + //Set the calendar default date to the beginning of the date: + $_SESSION['calendar_date'] = $begin->format('Y-m-d'); + } + $this->response->add_header('X-Dialog-Close', '1'); + } + } + + public function move_action($date_id) + { + $this->date = CalendarDate::find($date_id); + if (!$this->date) { + throw new InvalidArgumentException( + _('Der angegebene Termin wurde nicht gefunden.') + ); + } + if (!$this->date->isWritable($GLOBALS['user']->id)) { + throw new AccessDeniedException( + _('Sie sind nicht berechtigt, diesen Termin zu ändern.') + ); + } + + $this->begin = Request::getDateTime('begin', \DateTime::RFC3339); + $this->end = Request::getDateTime('end', \DateTime::RFC3339); + if (!$this->begin || !$this->end) { + throw new InvalidArgumentException(); + } + + if ($this->date->repetition_type) { + PageLayout::setTitle(_('Verschieben eines Termins aus einer Terminserie')); + //Show the dialog to decide what shall be done with the repetition. + if (Request::submitted('move')) { + CSRFProtection::verifyUnsafeRequest(); + $repetition_handling = Request::get('repetition_handling'); + $store_old_date = false; + if ($repetition_handling === 'create_single_date') { + //Create a new date with the new time range and then + //create an exception for the old date. + $new_date = new CalendarDate(); + $new_date->setData($this->date->toArray()); + $new_date->id = $new_date->getNewId(); + $new_date->unique_id = ''; + $new_date->begin = $this->begin->getTimestamp(); + $new_date->end = $this->end->getTimestamp(); + $new_date->author_id = $GLOBALS['user']->id; + $new_date->editor_id = $GLOBALS['user']->id; + $new_date->clearRepetitionFields(); + $new_date->store(); + foreach ($this->date->calendars as $calendar) { + $new_date_calendar = new CalendarDateAssignment(); + $new_date_calendar->calendar_date_id = $new_date->id; + $new_date_calendar->range_id = $calendar->range_id; + $new_date_calendar->store(); + } + $exception = CalendarDateException::findBySQL( + '`calendar_date_id` = :calendar_date_id AND `date` = :date', + [ + 'calendar_date_id' => $this->date->id, + 'date' => $this->begin->format('Y-m-d') + ] + ); + if (!$exception) { + $exception = new CalendarDateException(); + $exception->calendar_date_id = $this->date->id; + $exception->date = $this->begin->format('Y-m-d'); + $exception->store(); + } + $this->response->add_header('X-Dialog-Close', '1'); + return; + } elseif ($repetition_handling === 'change_times') { + //Set the new time for begin and end: + $date_begin = new DateTime(); + $date_begin->setTimestamp($this->date->begin); + $date_begin->setTime( + intval($this->begin->format('H')), + intval($this->begin->format('i')), + intval($this->begin->format('s')) + ); + $this->date->begin = $date_begin->getTimestamp(); + $date_end = new DateTime(); + $date_end->setTimestamp($this->date->end); + $date_end->setTime( + intval($this->end->format('H')), + intval($this->end->format('i')), + intval($this->end->format('s')) + ); + $this->date->end = $date_end->getTimestamp(); + + //Set the editor-ID: + $this->date->editor_id = $GLOBALS['user']->id; + + $store_old_date = true; + } elseif ($repetition_handling === 'change_all') { + $this->date->begin = $this->begin->getTimestamp(); + if ($this->date->repetition_end && intval($this->date->repetition_end) != pow(2,31) - 1) { + //The repetition end date is set to one specific date. + //It must be recalculated from the end date. + $old_end = new DateTime(); + $old_end->setTimestamp($this->date->end); + $old_repetition_end = new DateTime(); + $old_repetition_end ->setTimestamp($this->date->repetition_end); + $distance = $old_end->diff($old_repetition_end); + $this->date->end = $this->end->getTimestamp(); + $new_repetition_end = clone $this->end; + $new_repetition_end = $new_repetition_end->add($distance); + $this->date->repetition_end = $new_repetition_end->getTimestamp(); + } + $this->date->end = $this->end->getTimestamp(); + + //Set the editor-ID: + $this->date->editor_id = $GLOBALS['user']->id; + + $store_old_date = true; + } else { + //Invalid choice. + PageLayout::postError(_('Ungültige Auswahl!')); + return; + } + if ($store_old_date) { + $success = false; + if ($this->date->isDirty()) { + $success = $this->date->store(); + } else { + $success = true; + } + if ($success) { + $this->response->add_header('X-Dialog-Close', '1'); + $this->render_nothing(); + } else { + throw new Exception(_('Der Termin konnte nicht gespeichert werden.')); + } + } + } + } else { + //Set the new date and time directly. + $this->date->begin = $this->begin->getTimestamp(); + $this->date->end = $this->end->getTimestamp(); + //Set the editor-ID: + $this->date->editor_id = $GLOBALS['user']->id; + + $success = false; + if ($this->date->isDirty()) { + $success = $this->date->store(); + } else { + $success = true; + } + if ($success) { + $this->response->add_header('X-Dialog-Close', '1'); + $this->render_nothing(); + } else { + throw new Exception(_('Der Termin konnte nicht gespeichert werden.')); + } + } + } + + public function delete_action($date_id) + { + PageLayout::setTitle(_('Termin löschen')); + $this->date = CalendarDate::find($date_id); + if (!$this->date) { + PageLayout::postError( + _('Der Termin wurde nicht gefunden!') + ); + $this->render_nothing(); + } + $this->date_has_repetitions = !empty($this->date->repetition_type); + $this->selected_date = null; + if ($this->date_has_repetitions) { + $this->selected_date = Request::getDateTime('selected_date'); + if (!$this->selected_date) { + $this->selected_date = new DateTime(); + $this->selected_date->setTimestamp($this->date->begin); + } + } + $this->repetition_handling = Request::get('repetition_handling', 'create_exception'); + if (Request::submitted('delete')) { + $delete_whole_date = false; + CSRFProtection::verifyUnsafeRequest(); + if ($this->date_has_repetitions) { + if ($this->repetition_handling === 'create_exception') { + $exception = new CalendarDateException(); + $exception->calendar_date_id = $this->date->id; + $exception->date = $this->selected_date->format('Y-m-d'); + if ($exception->store()) { + PageLayout::postSuccess( + sprintf( + _('Die Ausnahme am %s wurde der Terminserie hinzugefügt.'), + $this->selected_date->format('d.m.Y') + ) + ); + $this->response->add_header('X-Dialog-Close', '1'); + $this->render_nothing(); + } else { + PageLayout::postError( + sprintf( + _('Die Ausnahme am %s konnte der Terminserie nicht hinzugefügt werden.'), + $this->selected_date->format('d.m.Y') + ) + ); + } + } elseif ($this->repetition_handling === 'delete_all') { + $delete_whole_date = true; + } + } else { + $delete_whole_date = true; + } + if ($delete_whole_date) { + if ($this->date->delete()) { + if ($this->date_has_repetitions) { + PageLayout::postSuccess(_('Die Terminserie wurde gelöscht!')); + } else { + PageLayout::postSuccess(_('Der Termin wurde gelöscht!')); + } + $this->response->add_header('X-Dialog-Close', '1'); + $this->render_nothing(); + } else { + if ($this->date_has_repetitions) { + PageLayout::postError(_('Die Terminserie konnte nicht gelöscht werden!')); + } else { + PageLayout::postError(_('Der Termin konnte nicht gelöscht werden!')); + } + } + } + } + } + + public function participation_action($date_id) + { + $this->calendar_assignment = CalendarDateAssignment::find([$GLOBALS['user']->id, $date_id]); + if (!$this->calendar_assignment) { + throw new AccessDeniedException(); + } + CSRFProtection::verifyUnsafeRequest(); + + $participation = Request::get('participation'); + if (!in_array($participation, ['', 'ACCEPTED', 'DECLINED', 'ACKNOWLEDGED'])) { + throw new InvalidArgumentException(); + } + + $this->calendar_assignment->participation = $participation; + if ($this->calendar_assignment->isDirty()) { + $this->calendar_assignment->store(); + $this->calendar_assignment->sendParticipationStatus(); + } + $this->response->add_header('X-Dialog-Close', '1'); + PageLayout::postSuccess(_('Ihre Teilnahmestatus wurde geändert.')); + $this->render_nothing(); + } +} |
