From 04ad36e3a9845a401d95d35880deda5ea390e9dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michaela=20Br=C3=BCckner?= <brueckner@data-quest.de> Date: Thu, 25 May 2023 14:05:36 +0000 Subject: [PATCH] closes #1327 Closes #1327 Merge request studip/studip!1147 --- app/controllers/admin/courses.php | 8 - app/controllers/course/room_requests.php | 1181 +++++++---------- app/controllers/course/timesrooms.php | 41 +- .../_new_request_form_footer.php | 41 + .../room_requests/_new_request_header.php | 18 + .../room_requests/_request_edit_header.php | 30 - .../room_requests/_request_form_footer.php | 28 - .../room_requests/_request_form_header.php | 4 - .../room_requests/_room_with_properties.php | 10 + app/views/course/room_requests/index.php | 12 +- app/views/course/room_requests/new.php | 47 - .../{request_start.php => new_request.php} | 101 +- .../request_find_available_properties.php | 124 ++ .../request_find_matching_rooms.php | 134 ++ .../request_select_properties.php | 65 - .../room_requests/request_select_room.php | 66 - .../room_requests/request_show_summary.php | 88 ++ .../course/room_requests/request_summary.php | 100 -- app/views/course/timesrooms/_cancel_form.php | 1 + .../course/timesrooms/_regularEvents.php | 11 +- app/views/course/timesrooms/_roomRequest.php | 114 +- .../course/timesrooms/_roomRequestInfo.php | 4 +- app/views/course/timesrooms/editDate.php | 4 +- app/views/course/timesrooms/index.php | 10 - .../ResourcePropertyDefinition.class.php | 23 +- lib/modules/CoreAdmin.class.php | 7 - .../javascripts/bootstrap/application.js | 3 + resources/assets/stylesheets/scss/forms.scss | 4 +- 28 files changed, 1082 insertions(+), 1197 deletions(-) create mode 100644 app/views/course/room_requests/_new_request_form_footer.php create mode 100644 app/views/course/room_requests/_new_request_header.php delete mode 100644 app/views/course/room_requests/_request_edit_header.php delete mode 100644 app/views/course/room_requests/_request_form_footer.php delete mode 100644 app/views/course/room_requests/_request_form_header.php create mode 100644 app/views/course/room_requests/_room_with_properties.php delete mode 100644 app/views/course/room_requests/new.php rename app/views/course/room_requests/{request_start.php => new_request.php} (54%) create mode 100644 app/views/course/room_requests/request_find_available_properties.php create mode 100644 app/views/course/room_requests/request_find_matching_rooms.php delete mode 100644 app/views/course/room_requests/request_select_properties.php delete mode 100644 app/views/course/room_requests/request_select_room.php create mode 100644 app/views/course/room_requests/request_show_summary.php delete mode 100644 app/views/course/room_requests/request_summary.php diff --git a/app/controllers/admin/courses.php b/app/controllers/admin/courses.php index 231099c1866..a683639e416 100644 --- a/app/controllers/admin/courses.php +++ b/app/controllers/admin/courses.php @@ -1055,14 +1055,6 @@ class Admin_CoursesController extends AuthenticatedController unset($actions[16]); } - if (Config::get()->RESOURCES_ENABLE && Config::get()->RESOURCES_ALLOW_ROOM_REQUESTS) { - $actions[4] = [ - 'name' => 'Raumanfragen', - 'title' => _('Raumanfragen'), - 'url' => 'dispatch.php/course/room_requests/index?cid=%s&origin=admin_courses', - 'attributes' => ['data-dialog' => 'size=big'], - ]; - } ksort($actions); foreach (PluginManager::getInstance()->getPlugins('AdminCourseAction') as $plugin) { diff --git a/app/controllers/course/room_requests.php b/app/controllers/course/room_requests.php index 95163634c00..3250ba2d580 100644 --- a/app/controllers/course/room_requests.php +++ b/app/controllers/course/room_requests.php @@ -10,6 +10,7 @@ * * @author André Noack <noack@data-quest.de> * @author Moritz Strohm <strohm@data-quest.de> + * @author Michaela Brückner <brueckner@data-quest.de> * @license http://www.gnu.org/licenses/gpl-2.0.html GPL version 2 * @category Stud.IP * @package admin @@ -30,6 +31,10 @@ class Course_RoomRequestsController extends AuthenticatedController parent::before_filter($action, $args); $this->current_user = User::findCurrent(); + $this->user_is_global_resource_admin = ResourceManager::userHasGlobalPermission( + $this->current_user, + 'admin' + ); $this->course_id = Request::option('cid', $args[0] ?? null); $pagetitle = ''; //Navigation in der Veranstaltung: @@ -48,6 +53,10 @@ class Course_RoomRequestsController extends AuthenticatedController $pagetitle .= Course::find($this->course_id)->getFullname() . ' - '; $pagetitle .= _('Verwalten von Raumanfragen'); PageLayout::setTitle($pagetitle); + + $this->available_room_categories = ResourceCategory::findByClass_name(Room::class); + $this->step = 0; + $this->max_preparation_time = Config::get()->RESOURCES_MAX_PREPARATION_TIME; } /** @@ -101,520 +110,323 @@ class Course_RoomRequestsController extends AuthenticatedController $this->render_template('course/room_requests/_request.php', null); } - /** - * create a new room request + * Start point to creating a new request */ - public function new_action() + public function new_request_action($request_id = '') { if (!Config::get()->RESOURCES_ALLOW_ROOM_REQUESTS) { throw new AccessDeniedException( _('Das Erstellen von Raumanfragen ist nicht erlaubt!') ); } - $options = []; - $this->url_params = []; - if (Request::get('origin') !== null) { - $this->url_params['origin'] = Request::get('origin'); - } - if (!RoomRequest::existsByCourse($this->course_id)) { - $options[] = [ - 'value' => 'course', - 'name' => _('alle regelmäßigen und unregelmäßigen Termine der Veranstaltung') - ]; - } - foreach (SeminarCycleDate::findBySeminar($this->course_id) as $cycle) { - if (!RoomRequest::existsByMetadate($cycle->getId())) { - $name = _("alle Termine einer regelmäßigen Zeit"); - $name .= ' (' . $cycle->toString('full') . ')'; - $options[] = ['value' => 'cycle_' . $cycle->getId(), 'name' => $name]; - } - } - foreach (CourseDate::findBySeminar_id($this->course_id) as $date) { - if (!RoomRequest::existsByDate($date['termin_id'])) { - $name = _("Einzeltermin der Veranstaltung"); - $name .= ' (' . $date->getFullname() . ')'; - $options[] = ['value' => 'date_' . $date['termin_id'], 'name' => $name]; - } - } - $this->options = $options; - Helpbar::get()->addPlainText(_('Information'), _('Hier können Sie festlegen, welche Art von Raumanfrage Sie erstellen möchten.')); - } + Helpbar::get()->addPlainText( + _('Information'), + _('Hier können Sie Angaben zu gewünschten Raumeigenschaften machen.') + ); + $this->request_id = $request_id; - /** - * Returns a reference to the session data array for the - * specified request-ID. - */ - protected function &getRequestSessionData($request_id = null) - { - $result = null; - if ($request_id) { - if (!isset($_SESSION['course_room_request'])) { - $_SESSION['course_room_request'] = []; - } - if (!isset($_SESSION['course_room_request'][$request_id])) { - $_SESSION['course_room_request'][$request_id] = []; - } - $result =& $_SESSION['course_room_request'][$request_id]; + if (Request::submitted('request_id')) { + $this->request_id = Request::get('request_id'); + } + if (!$this->request_id) { + $this->request_id = md5(uniqid('RoomRequest')); } - return $result; - } + // e.g. cycle, course, date + $this->request_range = Request::get('range_str'); - /** - * Returns a request instance that gets all its data set from the session. - * This is useful if a new request is being created. - */ - protected function getRequestInstanceFromSession($request_id) - { - $session_data = &$this->getRequestSessionData($request_id); - $request = new RoomRequest($request_id); - if ($session_data['range'] == 'date-multiple') { - $request->setRangeFields($session_data['range'], $session_data['range_ids']); - } else { - $request->setRangeFields($session_data['range'], [$session_data['range_id']]); + // multiple dates + $this->request_range_ids = Request::getArray('range_ids') ?: $_SESSION[$this->request_id]['range_ids'] ?? []; + // a single date or whole course + $this->request_range_id = Request::get('range_id', Context::getId()); + + if (!isset($_SESSION[$this->request_id])) { + $_SESSION[$this->request_id] = []; } - $request->course_id = $this->course_id; + $_SESSION[$this->request_id]['range'] = $this->request_range ?: $_SESSION[$this->request_id]['range'] ?? null; + $_SESSION[$this->request_id]['range_ids'] = $this->request_range_ids ?: [$this->request_range_id]; + $_SESSION[$this->request_id]['search_by'] = ''; + $_SESSION[$this->request_id]['room_category_id'] = ''; + $_SESSION[$this->request_id]['room_id'] = ''; + $_SESSION[$this->request_id]['room_name'] = ''; + $_SESSION[$this->request_id]['selected_properties'] = []; - return $request; - } + $this->request = null; + // look for existing request or create a new one + $this->request = new RoomRequest($this->request_id); + // time ranges (start date, end date) + $this->request->setRangeFields($_SESSION[$this->request_id]['range'], $_SESSION[$this->request_id]['range_ids']); + $this->request_time_intervals = $this->request->getTimeIntervals(); - /** - * This method loads data for the request editing actions. - * Depending on the editing step, more or less data have to - * be loaded. - * - * @param array $session_data Request data stored in the session. - * - * @param int $step The editing step: - * 1 = request_start - * 2 = request_select_properties - * 3 = request_select_room - * 4 = request_overview - */ - protected function loadData($session_data, $step = 1) - { - $this->available_room_categories = []; - $this->room_name = ''; - $this->category_id = ''; - $this->category = null; - $this->available_properties = []; - $this->selected_properties = []; - $this->seats = ''; - $this->comment = ''; - $this->reply_lecturers = false; - $this->preparation_time = 0; - - $this->course_id = Context::getId(); - $this->user_is_global_resource_admin = ResourceManager::userHasGlobalPermission( - $this->current_user, - 'admin' - ); - $this->config = Config::get(); - $this->direct_room_requests_only = $this->config->RESOURCES_DIRECT_ROOM_REQUESTS_ONLY; - if ($step >= 1) { - //Load all available room categories: - $this->available_room_categories = ResourceCategory::findByClass_name( - 'Room' - ); - } - if ($step >= 2) { - if (!empty($session_data['category_id'])) { - $this->category = ResourceCategory::find($session_data['category_id']); - if ($this->category) { - //Get all available properties for the category: - $this->available_properties = $this->category->getRequestableProperties(); - } - } - $this->room_name = $session_data['room_name'] ?? ''; - $this->category_id = $session_data['category_id'] ?? ''; - $this->preparation_time = $session_data['preparation_time'] ?? '0'; - } - if ($step >= 3) { - if ($this->category) { - $this->selected_properties = $session_data['selected_properties'] ?? []; - } - } - if ($step >= 4) { - $this->seats = $session_data['selected_properties']['seats'] ?? '0'; - $this->comment = $session_data['comment']?? ''; - $this->reply_lecturers = $session_data['reply_lecturers'] ?? ''; - $this->preparation_time = $session_data['preparation_time'] ?? ''; - } } - /** - * This action is the entry point for adding properties to a room request. + * Step 1: Either selecting a room category or searching for a room name initially + * @param String $request_id ID of the request */ - public function request_start_action($request_id = '') + public function request_first_step_action($request_id) { if (!Config::get()->RESOURCES_ALLOW_ROOM_REQUESTS) { throw new AccessDeniedException( _('Das Erstellen von Raumanfragen ist nicht erlaubt!') ); } - Helpbar::get()->addPlainText( - _('Information'), - _('Hier können Sie Angaben zu gewünschten Raumeigenschaften machen.') - ); $this->request_id = $request_id; - if (Request::submitted('request_id')) { - $this->request_id = Request::get('request_id'); - } - if (!$this->request_id) { - $this->request_id = md5(uniqid('RoomRequest')); - } - - $session_data = &$this->getRequestSessionData($this->request_id); - $this->loadData($session_data, 1); + if (Request::isPost()) { + CSRFProtection::verifyUnsafeRequest(); - $this->request = null; + $this->step = 1; - //Check if a request exists and set its ID in the session, - //it is needed later. - $this->request = RoomRequest::find(Request::get('request_id')); - if ($this->request instanceof RoomRequest) { - $session_data['request_id'] = $this->request->id; - $this->request_id = $this->request->id; - } elseif ($session_data['request_id']) { - //It is a new request that isn't stored yet. Load its basic data - //from the session and create a request object: - $this->request_id = $session_data['request_id']; - $this->request = $this->getRequestInstanceFromSession($this->request_id); - } else { - //A new request shall be created. - //Get the range from URL parameters. - $range = null; - $range_id = null; - $range_ids = []; - if (Request::submitted('range_str')) { - $range_str = explode('_', Request::get('range_str')); - $range = $range_str[0]; - if ($range == 'course') { - $range_id = $range_str[1]; - if (!$range_id) { - $range_id = Context::getId(); - } - } else { - if (count($range_str) > 2) { - //More than one ID has been specified. - $range_ids = array_slice($range_str, 1); - } else { - $range_id = $range_str[1]; - } - } - } else { - $range = Request::get('range'); - $range_id = Request::get('range_id'); - $range_ids = Request::getArray('range_ids'); - } - $session_data['range'] = $range; - $session_data['range_id'] = $range_id; - $session_data['range_ids'] = $range_ids; - $session_data['request_id'] = $this->request_id; - - //Create a request object: - $this->request = new RoomRequest($session_data['request_id']); - if ($range == 'date-multiple') { - $this->request->setRangeFields($range, $range_ids); - } else { - $this->request->setRangeFields($range, [$range_id]); + $this->category_id = Request::get('category_id'); + $this->search_by_category = Request::submitted('search_by_category'); + if (!isset($_SESSION[$request_id])) { + $_SESSION[$request_id] = []; } - $this->request->course_id = $this->course_id; - } - $available_rooms = RoomManager::countRequestableRooms(); - if (($available_rooms < 51) && !Request::submitted('select_properties')) { - //Redirect to the room selection page: - $session_data['request_id'] = $this->request_id; - $this->redirect( - 'course/room_requests/request_select_room/' . $this->request_id - ); - return; - } + $_SESSION[$request_id]['room_category_id'] = $this->category_id; - if (Request::isPost()) { - CSRFProtection::verifyUnsafeRequest(); $this->room_name = Request::get('room_name'); - $this->category_id = Request::get('category_id'); - if (Request::submitted('search_by_name')) { - if (!$this->room_name) { - PageLayout::postError( - _('Es wurde kein Raumname angegeben!') - ); - return; - } - $session_data['room_name'] = $this->room_name; - $session_data['request_id'] = $this->request_id; - //Redirect to the room selection action. + $this->search_by_roomname = Request::submitted('search_by_name'); + $_SESSION[$request_id]['room_name'] = $this->room_name; + + // user selects a room category OR enters a room name + if ($this->category_id !== null && $this->search_by_category) { + $_SESSION[$request_id]['search_by'] = 'category'; $this->redirect( - 'course/room_requests/request_select_room/' . $this->request_id + 'course/room_requests/request_find_available_properties/' . $this->request_id . '/' . $this->step . '/category' ); - } elseif (Request::submitted('select_properties')) { - if (!$this->category_id) { - PageLayout::postError( - _('Es wurde keine Raumkategorie ausgewählt!') - ); - return; - } - foreach ($this->available_room_categories as $category) { - if ($category->id == $this->category_id) { - //The selected category is in the array of - //available categories. - $session_data['request_id'] = $this->request_id; - $session_data['category_id'] = $this->category_id; - $session_data['room_name'] = $this->room_name; - //Redirect to the property selection page: - $this->redirect( - 'course/room_requests/request_select_properties/' . $this->request_id - ); - return; - } - } - - //If this point is reached, then the selected room category ID - //is not in the array of available room categories. - PageLayout::postError( - _('Die gewählte Raumkategorie wurde nicht gefunden!') + } elseif ($this->room_name && $this->search_by_roomname) { + $_SESSION[$request_id]['search_by'] = 'roomname'; + $this->redirect( + 'course/room_requests/request_find_matching_rooms/' . $this->request_id . '/' . $this->step . '/roomname' + ); + } else { + $this->redirect( + 'course/room_requests/new_request/' . $this->request_id ); } } - } + } /** - * This action is called from request_start in the case that a - * resource category has been selected. + * Searching for (a) matching room(s) via room name, e.g. 'hör%' + * @param String $request_id ID of the request + * @param String $step + * @return void */ - public function request_select_properties_action($request_id = '') + public function request_find_matching_rooms_action($request_id, $step) { if (!Config::get()->RESOURCES_ALLOW_ROOM_REQUESTS) { throw new AccessDeniedException( _('Das Erstellen von Raumanfragen ist nicht erlaubt!') ); } - Helpbar::get()->addPlainText( - _('Information'), - _('Hier können Sie Angaben zu gewünschten Raumeigenschaften machen.') - ); - - $this->max_preparation_time = Config::get()->RESOURCES_MAX_PREPARATION_TIME; $this->request_id = $request_id; - $session_data = &$this->getRequestSessionData($this->request_id); - $this->loadData($session_data, 2); + $this->step = (int)$step; + $this->room_name = $_SESSION[$request_id]['room_name']; - if ($this->direct_room_requests_only) { - throw new AccessDeniedException( - _('Das Erstellen von Raumanfragen anhand von Eigenschaften ist nicht erlaubt!') - ); + $this->request = new RoomRequest($this->request_id); + $this->request->setRangeFields($_SESSION[$this->request_id]['range'], $_SESSION[$this->request_id]['range_ids']); + + $search_properties = $_SESSION[$request_id]['selected_properties'] ?? []; + + if (!empty($_SESSION[$request_id]['room_category_id'])) { + $search_properties['room_category_id'] = $_SESSION[$request_id]['room_category_id']; } - $this->selected_properties = []; - $this->request = RoomRequest::find($this->request_id); - if ($this->request instanceof RoomRequest) { - //It is an existing request. If no properties have been selected - //via HTTP POST, set them from the request itself: - foreach ($this->request->properties as $property) { - $this->selected_properties[$property->name] = $property->state; - } - $this->category = $this->request->category; - $this->category_id = $this->request->category_id; - $this->seats = $this->request->seats; - $this->comment = $this->request->comment; - $this->reply_lecturers = $this->request->reply_recipients == 'lecturer'; - } else { - //It is a new request. Create the request object and do nothing else. - $this->request = $this->getRequestInstanceFromSession($this->request_id); - $this->category_id = Request::get('category_id', $session_data['category_id']); - $this->category = ResourceCategory::find($this->category_id); + if (!empty($search_properties['seats'])) { + //The seats property value is a minimum. + $search_properties['seats'] = [ + $search_properties['seats'], + null + ]; } - if (!($this->category instanceof ResourceCategory)) { - PageLayout::postError( - _('Die gewählte Raumkategorie wurde nicht gefunden!') + // find rooms matching to selected properties + $this->available_rooms = RoomManager::findRooms( + $this->room_name, + null, + null, + $search_properties, + [], + 'name ASC, mkdate ASC' + ); + + // small icons in front of room name to show whether they are bookable or not + $this->available_room_icons = $this->getRoomBookingIcons($this->available_rooms); + + // selected room and its category + $this->selected_room = Resource::find($_SESSION[$request_id]['room_id'] ?: $this->request->resource_id); + + $this->selected_room_category_id = $this->selected_room->category_id ?: $_SESSION[$request_id]['room_category_id']; + + $_SESSION[$request_id]['room_category_id'] = $_SESSION[$request_id]['room_category_id'] ?: $this->selected_room->category_id; + + // after selecting a room, go to next step or stay here if no room was selected at all + if (Request::submitted('select_room')) { + $this->selected_room_id = Request::get('selected_room_id'); + $_SESSION[$request_id]['room_id'] = $this->selected_room_id; + $_SESSION[$request_id]['select_room'] = true; + + $this->redirect( + 'course/room_requests/request_check_properties/' . $this->request_id ); return; } - $this->available_properties = $this->category->getRequestableProperties(); + // we might also search for new rooms and stay within step 1 + else if (Request::get('room_name') && Request::submitted('search_by_name')) { + $_SESSION[$request_id]['room_name'] = Request::get('room_name'); + $this->redirect( + 'course/room_requests/request_find_matching_rooms/' . $this->request_id . '/' . $this->step + ); + return; + } - if (empty($session_data['selected_properties']['seats'])) { - $this->course = Course::find($this->course_id); - $admission_turnout = $this->course->admission_turnout; - $this->selected_properties['seats'] = - $admission_turnout ?: Config::get()->RESOURCES_ROOM_REQUEST_DEFAULT_SEATS; + // or we filter via category + else if (Request::get('category_id') && Request::submitted('select_properties')) { + $_SESSION[$request_id]['search_by'] = 'category'; + $_SESSION[$request_id]['room_category_id'] = Request::get('category_id'); + $this->redirect( + 'course/room_requests/request_find_available_properties/' . $this->request_id . '/' . $this->step + ); + return; + } else if (Request::submitted('reset_category')) { + //Delete all selected properties from the session since the category is reset + $_SESSION[$request_id]['selected_properties'] = []; + $_SESSION[$request_id]['room_category_id'] = ''; + $_SESSION[$request_id]['room_name'] = ''; + $_SESSION[$request_id]['room_id'] = ''; + $this->redirect('course/room_requests/request_find_available_properties/' . $this->request_id . '/1'); + return; } - if (Request::isPost()) { - CSRFProtection::verifyUnsafeRequest(); - $this->selected_properties = Request::getArray('selected_properties'); - //Filter the selected properties so that only those properties - //that are available for the room category can be used. - $filtered_selected_properties = []; - foreach ($this->available_properties as $property) { - if (in_array($property->name, array_keys($this->selected_properties))) { - //Filter out all empty properties: - if ($this->selected_properties[$property->name]) { - $filtered_selected_properties[$property->name] = - $this->selected_properties[$property->name]; + // for step 2: after choosing a specific room OR searching via properties + if ($this->step === 2) { + if ($_SESSION[$request_id]['search_by'] == 'roomname') { + // find category via room + $this->category = ResourceCategory::find($this->selected_room_category_id); + if ($this->category) { + $this->available_properties = $this->category->getRequestableProperties(); + } + + $this->selected_properties = $_SESSION[$request_id]['selected_properties']; + $this->room = Room::find($_SESSION[$request_id]['room_id']); + $this->selected_properties['seats'] = $_SESSION[$request_id]['selected_properties']['seats'] + ?: $this->course->admission_turnout + ?: Config::get()->RESOURCES_ROOM_REQUEST_DEFAULT_SEATS; + $_SESSION[$request_id]['selected_properties']['seats'] = $this->selected_properties['seats']; + } else if ($_SESSION[$request_id]['search_by'] === 'category') { + $this->room = Room::find($_SESSION[$request_id]['room_id']); + if ($this->room) { + $this->grouped_properties = $this->room->getGroupedProperties(); + foreach ($this->grouped_properties as $properties) { + foreach ($properties as $property) { + $this->selected_properties[$property->name] = $property->state; + } } } + } - $this->selected_properties = $filtered_selected_properties; - $this->preparation_time = Request::get('preparation_time'); - if ($this->preparation_time > $this->max_preparation_time) { - PageLayout::postError( - sprintf( - _('Die eingegebene Rüstzeit überschreitet das erlaubte Maximum von %d Minuten!'), - $this->max_preparation_time - ) - ); - return; - } - $session_data['preparation_time'] = $this->preparation_time; - $session_data['category_id'] = $this->category_id; - - if (Request::submitted('search_by_name')) { - //Delete all selected properties from the session since the - //search by name (name only) has been used. - $session_data['selected_properties'] = []; - $session_data['room_name'] = Request::get('room_name'); - $this->redirect( - 'course/room_requests/request_select_room/' . $this->request_id - ); - } elseif (Request::submitted('reset_category')) { - //Delete all selected properties from the session since the - //category is reset: - $session_data['selected_properties'] = []; - $this->redirect( - 'course/room_requests/request_start/' . $this->request_id - ); - } elseif (Request::submitted('search_rooms')) { - //Store the selected properties in the session and redirect. - $session_data['selected_properties'] = $this->selected_properties; - $this->redirect( - 'course/room_requests/request_select_room/' . $this->request_id - ); - } elseif (Request::submitted('save') || Request::submitted('save_and_close')) { - //Save the request and stay on the page (save) or return - //to the overview page (save_and_close). - if ($this->selected_properties['seats'] < 1) { + // find rooms fitting to category and properties + if (Request::submitted('search_rooms')) { + $this->selected_properties = Request::getArray('selected_properties'); + $_SESSION[$request_id]['selected_properties'] = $this->selected_properties; + + // no min number of seats + if ( + (!$_SESSION[$request_id]['selected_properties']['seats'] || $_SESSION[$request_id]['selected_properties']['seats'] < 1) + && $_SESSION[$request_id]['search_by'] === 'category' + ) { PageLayout::postError( - _('Es wurde keine Anzahl an gewünschten Sitzplätzen angegeben!') + _('Die Mindestanzahl der Sitzplätze beträgt 1!') + ); + $this->redirect( + 'course/room_requests/request_find_matching_rooms/' . $request_id . '/' . $this->step ); return; - } - - $this->request->category_id = $session_data['category_id']; - if ($this->request->isNew()) { - //Set the requester: - $this->request->user_id = $this->current_user->id; - } else { - //Do another thing: Delete all previously set properties: - $this->request->properties->delete(); - } - $this->request->preparation_time = $this->preparation_time * 60; - $this->request->comment = Request::get('comment'); - if (Request::get('reply_lecturers')) { - $this->request->reply_recipients = 'lecturer'; - } else { - $this->request->reply_recipients = 'requester'; - } - - if ($this->request->isDirty()) { - $storing_successful = $this->request->store(); } else { - $storing_successful = true; - } - - if ($storing_successful) { - //Store the properties: - foreach ($this->selected_properties as $name => $state) { - $result = $this->request->setProperty($name, $state); - } - $this->request->store(); - //Delete the session data: - $session_data = []; - PageLayout::postSuccess(_('Die Anfrage wurde gespeichert!')); - if (Request::submitted('save_and_close')) { - $this->relocate('course/room_requests/index'); - } - } else { - PageLayout::postError( - _('Die Anfrage konnte nicht gespeichert werden!') + $this->redirect( + 'course/room_requests/request_find_matching_rooms/' . $request_id . '/' . $this->step ); + return; } } + + // let's find all the properties belonging to the selected category + $this->room_category_id = $_SESSION[$request_id]['room_category_id']; + $this->category = ResourceCategory::find($this->room_category_id); + $this->available_properties = $this->category->getRequestableProperties(); + + // properties, like 'Sitzplätze', 'behindertengerecht' etc + $this->selected_properties = $_SESSION[$request_id]['selected_properties']; + $this->preparation_time = $_SESSION[$request_id]['preparation_time']; + $this->comment = $_SESSION[$request_id]['comment']; + $this->request->category_id = $_SESSION[$request_id]['room_category_id']; + + // finally we want to show a summary + if (Request::submitted('show_summary')) { + $this->selected_room_id = Request::get('selected_room_id'); + $_SESSION[$request_id]['room_id'] = $this->selected_room_id; + $_SESSION[$request_id]['selected_properties'] = Request::getArray('selected_properties'); + $this->redirect('course/room_requests/request_show_summary/' . $this->request_id ); + } } } - /** - * This action is called either directly from request_start - * (in case a room name is set but no resource category) or after - * selecting properties in request_select_properties. - * It searches for rooms depending on the selected properties - * or the selected name. + * Searching for (a) matching room(s) by initially selecting a room category, e.g. 'Hörsaal' + * @param String $request_id ID of the request + * @param String $step + * @return void */ - public function request_select_room_action($request_id) + public function request_find_available_properties_action($request_id, $step) { if (!Config::get()->RESOURCES_ALLOW_ROOM_REQUESTS) { throw new AccessDeniedException( _('Das Erstellen von Raumanfragen ist nicht erlaubt!') ); } - Helpbar::get()->addPlainText( - _('Information'), - _('Hier können Sie Angaben zu gewünschten Raumeigenschaften machen.') - ); $this->request_id = $request_id; - $session_data = &$this->getRequestSessionData($this->request_id); - $this->max_preparation_time = Config::get()->RESOURCES_MAX_PREPARATION_TIME; - $this->loadData($session_data, 3); + $this->step = (int)$step; - $this->request = RoomRequest::find($this->request_id); - if (!($this->request instanceof RoomRequest)) { - //It is a new request. Create the request object and do nothing else. - $this->request = $this->getRequestInstanceFromSession($this->request_id); - } else { - $this->seats = $this->request->seats; - $this->comment = $this->request->comment; - $this->reply_lecturers = $this->request->reply_recipients == 'lecturer'; - } + $this->request = new RoomRequest($this->request_id); + $this->request->setRangeFields($_SESSION[$this->request_id]['range'], $_SESSION[$this->request_id]['range_ids']); - $search_properties = $this->selected_properties ?? []; - if (!empty($session_data['category_id'])) { - $search_properties['room_category_id'] = $session_data['category_id']; - } - if (!empty($search_properties['seats'])) { - //The seats property value is a minimum. + // let's find all the properties belonging to the selected category + $this->room_category_id = $_SESSION[$request_id]['room_category_id'] ?: $this->request->category_id; + $this->room_name = $_SESSION[$request_id]['room_name']; + $this->selected_room = Resource::find($_SESSION[$request_id]['room_id'] ?: $this->request->resource_id); + $this->category = $this->room_category_id ? ResourceCategory::find($this->room_category_id) : ''; + $this->available_properties = $this->room_category_id ? $this->category->getRequestableProperties() : ''; + $this->selected_properties = $_SESSION[$request_id]['selected_properties']; + + $this->course = Course::find($this->course_id); + $this->selected_properties['seats'] = $_SESSION[$request_id]['selected_properties']['seats'] + ?: $this->course->admission_turnout + ?: Config::get()->RESOURCES_ROOM_REQUEST_DEFAULT_SEATS; + + $this->preparation_time = $_SESSION[$request_id]['preparation_time']; + $this->comment = $_SESSION[$request_id]['comment']; + + // when searching for a room name, list found room + if ($_SESSION[$request_id]['room_name'] !== '') { + $search_properties['room_category_id'] = $this->room_category_id; $search_properties['seats'] = [ - $search_properties['seats'], + 1, null ]; - } - $this->matching_rooms = []; - if (!$this->room_name && !$this->selected_properties) { - //Load all requestable rooms: - $this->matching_rooms = RoomManager::findRooms( - '', - null, - null, - [], - [], - 'name ASC, mkdate ASC' - ); - } else { - //Search rooms by the selected properties: - $this->matching_rooms = RoomManager::findRooms( + + $this->available_rooms = RoomManager::findRooms( $this->room_name, null, null, @@ -622,374 +434,267 @@ class Course_RoomRequestsController extends AuthenticatedController [], 'name ASC, mkdate ASC' ); - } - $this->available_room_icons = []; - $request_time_intervals = $this->request->getTimeIntervals(); - foreach ($this->matching_rooms as $room) { - $request_dates_booked = 0; - foreach ($request_time_intervals as $interval) { - $booked = ResourceBookingInterval::countBySql( - 'resource_id = :room_id AND begin < :end AND end > :begin', - [ - 'room_id' => $room->id, - 'begin' => $interval['begin'], - 'end' => $interval['end'] - ] - ) > 0; - if ($booked) { - $request_dates_booked++; - } - } - if ($request_dates_booked == 0) { - $this->available_room_icons[$room->id] = - Icon::create('check-circle', Icon::ROLE_STATUS_GREEN)->asImg( - [ - 'class' => 'text-bottom', - 'title' => _('freier Raum') - ] - ); - $this->available_rooms[] = $room; - } elseif ($request_dates_booked < $request_time_intervals) { - $this->available_room_icons[$room->id] = - Icon::create('exclaim-circle', Icon::ROLE_STATUS_YELLOW)->asImg( - [ - 'class' => 'text-bottom', - 'title' => _('teilweise belegter Raum') - ] - ); - $this->available_rooms[] = $room; - } + + // small icons in front of room name to show whether they are bookable or not + $this->available_room_icons = $this->getRoomBookingIcons($this->available_rooms); } - if (Request::isPost()) { - CSRFProtection::verifyUnsafeRequest(); + } - $this->room_name = Request::get('room_name'); - $session_data['room_name'] = $this->room_name; + /** + * Check desired properties for a room category to go to step 2 + * @param String $request_id ID of the request + * @return void + * + */ + public function request_check_properties_action($request_id) + { + if (!Config::get()->RESOURCES_ALLOW_ROOM_REQUESTS) { + throw new AccessDeniedException( + _('Das Erstellen von Raumanfragen ist nicht erlaubt!') + ); + } + $this->request_id = $request_id; + + // select a room, search for a room name or search for rooms matching properties + if (Request::submitted('select_room')) { $this->selected_room_id = Request::get('selected_room_id'); - if ($this->selected_room_id) { - $room_found = false; - foreach ($this->available_rooms as $room) { - if ($this->selected_room_id == $room->id) { - $room_found = true; - break; - } - } - if (!$room_found) { - //The room could not be found in the list of available rooms. - PageLayout::postError(_('Der gewählte Raum wurde nicht gefunden!')); - return; - } - } - if (Request::submitted('search_by_name')) { - if (!$this->room_name) { - PageLayout::postError( - _('Es wurde kein Raumname angegeben!') - ); - return; - } - $session_data['room_name'] = $this->room_name; - $session_data['request_id'] = $this->request_id; - //Redirect to the room selection action. + $_SESSION[$request_id]['room_id'] = $this->selected_room_id; + $_SESSION[$request_id]['select_room'] = true; + $this->step = 2; + $this->request = new RoomRequest($this->request_id); + $this->redirect( + 'course/room_requests/request_find_matching_rooms/' . $this->request_id . '/' . $this->step + ); + } else if (Request::get('room_name') && Request::submitted('search_by_name')) { + $this->selected_properties = Request::getArray('selected_properties'); + $this->category_id = Request::get('category_id'); + $_SESSION[$request_id]['selected_properties'] = $this->selected_properties; + $_SESSION[$request_id]['room_category_id'] = $this->category_id; + $_SESSION[$request_id]['comment'] = $this->comment; + $_SESSION[$request_id]['room_name'] = Request::get('room_name'); + $this->request = new RoomRequest($this->request_id); + $this->redirect( + 'course/room_requests/request_find_available_properties/' . $this->request_id . '/1/category' + ); + + } else if (Request::submitted('search_rooms')) { + $this->selected_properties = Request::getArray('selected_properties'); + $this->category_id = Request::get('category_id'); + $_SESSION[$request_id]['room_category_id'] = $this->category_id; + $_SESSION[$request_id]['selected_properties'] = $this->selected_properties; + $_SESSION[$request_id]['room_name'] = ''; + + // no min number of seats + if ( + (!$_SESSION[$request_id]['selected_properties']['seats'] || $_SESSION[$request_id]['selected_properties']['seats'] < 1) + && $_SESSION[$request_id]['search_by'] === 'category' + ) { + PageLayout::postError( + _('Die Mindestanzahl der Sitzplätze beträgt 1!') + ); + $this->redirect( - 'course/room_requests/request_select_room/' . $this->request_id + 'course/room_requests/request_find_available_properties/' . $request_id . '/1/category' ); - } elseif (Request::submitted('search_rooms')) { - //Store the form data in the session and reload. - $session_data['selected_properties'] = Request::getArray('selected_properties'); - $this->redirect('course/room_requests/request_select_room/' . $this->request_id); - } elseif (Request::submitted('select_room')) { - $session_data['selected_properties'] = Request::getArray('selected_properties'); - $session_data['selected_room_id'] = $this->selected_room_id; - $this->redirect('course/room_requests/request_summary/' . $this->request_id); - } elseif (Request::submitted('select_properties')) { - $this->category_id = Request::get('category_id'); - if (!$this->category_id) { - PageLayout::postError( - _('Es wurde keine Raumkategorie ausgewählt!') - ); - return; - } - foreach ($this->available_room_categories as $category) { - if ($category->id == $this->category_id) { - //The selected category is in the array of - //available categories. - $session_data['request_id'] = $this->request_id; - $session_data['category_id'] = $this->category_id; - $session_data['room_name'] = $this->room_name; - //Redirect to the property selection page: - $this->redirect( - 'course/room_requests/request_select_properties/' . $this->request_id - ); - return; - } - } - } elseif (Request::submitted('reset_category')) { - //Delete all selected properties from the session since the - //category is reset: - $session_data['selected_properties'] = []; - $session_data['selected_room_id'] = $this->selected_room_id; - $session_data['category_id'] = ''; - $session_data['room_name'] = ''; - $this->redirect('course/room_requests/request_start/' . $this->request_id); - } elseif (Request::submitted('save') || Request::submitted('save_and_close')) { - $session_data['selected_properties'] = Request::getArray('selected_properties'); - if ($session_data['selected_properties']['seats'] < 1) { - PageLayout::postError( - _('Es wurde keine Anzahl an gewünschten Sitzplätzen angegeben!') + } else { + $this->step = 2; + $this->request = new RoomRequest($this->request_id); + $this->redirect( + 'course/room_requests/request_find_matching_rooms/' . $this->request_id . '/' . $this->step ); - return; - } - $session_data['selected_room_id'] = $this->selected_room_id; - //Store all request data from the session in the request: - $this->request->category_id = $session_data['category_id']; - $this->request->updateProperties($session_data['selected_properties']); - $this->request->resource_id = ( - $this->selected_room_id ?: '' - ); - $this->request->comment = Request::get('comment'); - if (Request::get('reply_lecturers')) { - $this->request->reply_recipients = 'lecturer'; - } else { - $this->request->reply_recipients = 'requester'; - } + } + } else if (Request::submitted('reset_category')) { + //Delete all selected properties from the session since the category is reset + $_SESSION[$request_id]['selected_properties'] = []; + $_SESSION[$request_id]['room_category_id'] = ''; + $this->redirect('course/room_requests/request_find_available_properties/' . $this->request_id . '/1'); + } else if (Request::submitted('search_by_category')) { + if (Request::get('category_id') === '0') { + $_SESSION[$request_id]['room_category_id'] = ''; + } else { + $_SESSION[$request_id]['room_category_id'] = Request::get('category_id'); + } - if ($this->request->isNew()) { - //Set the requester: - $this->request->user_id = $this->current_user->id; - } + $this->redirect( + 'course/room_requests/request_find_available_properties/' . $this->request_id . '/1' . '/category' + ); + } else if (Request::submitted('show_summary')) { + $this->request = new RoomRequest($this->request_id); + $this->selected_properties = Request::getArray('selected_properties'); - if ($this->request->isDirty()) { - $storing_successful = $this->request->store(); - } else { - $storing_successful = true; - } + $_SESSION[$request_id]['selected_properties'] = $this->selected_properties; + $this->selected_room_id = Request::get('selected_room_id'); + $_SESSION[$request_id]['room_id'] = $this->selected_room_id; - if ($storing_successful) { - //Delete the session data: - $session_data = []; - PageLayout::postSuccess(_('Die Anfrage wurde gespeichert!')); - if (Request::submitted('save_and_close')) { - $this->relocate('course/room_requests/index'); - } - } else { - PageLayout::postError( - _('Die Anfrage konnte nicht gespeichert werden!') - ); - } - } + $this->redirect('course/room_requests/request_show_summary/' . $this->request_id ); + } else { + $this->step = 2; + $this->request = new RoomRequest($this->request_id); + $this->redirect( + 'course/room_requests/request_find_matching_rooms/' . $this->request_id . '/' . $this->step + ); } - } + } /** - * This action is either called from request_select_room after a room - * has been selected, from request_select_properties after properties - * have been selected or when an existing request shall be edited. + * Show a summary of all request properties before storing; we have the possibility of going back and + * editing if necessary. This action is also used for editing a request via action menu + * @param String $request_id ID of the request + * @return void + * */ - public function request_summary_action($request_id = null) + public function request_show_summary_action($request_id) { if (!Config::get()->RESOURCES_ALLOW_ROOM_REQUESTS) { throw new AccessDeniedException( _('Das Erstellen von Raumanfragen ist nicht erlaubt!') ); } - Helpbar::get()->addPlainText( - _('Information'), - _('Hier können Sie Angaben zu gewünschten Raumeigenschaften machen.') - ); - - $this->course = Course::find($this->course_id); $this->request_id = $request_id; - $session_data = &$this->getRequestSessionData($this->request_id); + $this->step = 3; + if (Request::submitted('clear_cache')) { - $session_data = []; + $_SESSION[$request_id] = []; } - $this->loadData($session_data, 4); - - $this->max_preparation_time = $this->config->RESOURCES_MAX_PREPARATION_TIME; - - $this->request = RoomRequest::find($this->request_id); - $selected_room = null; - $this->seats = null; - if (($this->request instanceof RoomRequest) && !isset($session_data['request_id'])) { - //It is an existing request that hasn't been modified yet. - //Load its data directly. - if ($this->request->resource_id) { - $selected_room = Resource::find($this->request->resource_id); - } - $this->seats = $this->request->seats; - $this->comment = $this->request->comment; - $this->reply_lecturers = $this->request->reply_recipients == 'lecturer'; - $this->preparation_time = intval($this->request->preparation_time / 60); - $this->category_id = $this->request->category->id; - } else { - //It is a new request or an existing request that is being modified. - //Create the request object from the session and do nothing else. - $this->request = $this->getRequestInstanceFromSession($this->request_id); - if ($session_data['selected_room_id']) { - $selected_room = Resource::find($session_data['selected_room_id']); - } - $this->seats = $session_data['selected_properties']['seats']; - } - if ($selected_room instanceof Resource) { - $this->selected_room = $selected_room->getDerivedClassInstance(); - if (!($this->selected_room instanceof Room)) { - PageLayout::postWarning( - _('Die ausgewählte Ressource ist kein Raum!') - ); + $this->request = new RoomRequest($this->request_id); + $this->request->setRangeFields($_SESSION[$this->request_id]['range'], $_SESSION[$this->request_id]['range_ids']); + + $this->selected_room_category = ResourceCategory::find($_SESSION[$request_id]['room_category_id'] ?: $this->request->category_id); + + $this->selected_room = Resource::find($_SESSION[$request_id]['room_id'] ?: $this->request->resource_id); + + $this->room_id = $_SESSION[$request_id]['room_id'] ?: $this->request->resource_id; + $this->available_properties = $this->selected_room_category->getRequestableProperties(); + + $this->selected_properties = $_SESSION[$request_id]['selected_properties'] ?: []; + $this->request_properties = $this->request->properties; + + // either properties from stored request or those from session + if ($this->request_properties && !$_SESSION[$request_id]['selected_properties']) { + foreach ($this->request_properties as $property) { + $this->selected_properties[$property->name] = $property->state; } + $_SESSION[$request_id]['selected_properties'] = $this->selected_properties; } - if (!$this->seats) { - $admission_turnout = $this->course->admission_turnout; - $this->seats = $admission_turnout ?: Config::get()->RESOURCES_ROOM_REQUEST_DEFAULT_SEATS; + $this->preparation_time = intval($this->request->preparation_time / 60); + $this->reply_lecturers = $this->request->reply_recipients === 'lecturer'; + $this->comment = $this->request->comment; + + $_SESSION[$request_id]['search_by'] = $this->selected_room ? 'roomname' : 'category'; + $_SESSION[$request_id]['room_category_id'] = $this->selected_room_category->id; + $_SESSION[$request_id]['room_id'] = $this->selected_room->id; + } + + public function store_request_action($request_id) + { + if (!Config::get()->RESOURCES_ALLOW_ROOM_REQUESTS) { + throw new AccessDeniedException( + _('Das Erstellen von Raumanfragen ist nicht erlaubt!') + ); } + $this->request_id = $request_id; + $this->request = new RoomRequest($this->request_id); + $this->request->setRangeFields($_SESSION[$this->request_id]['range'], $_SESSION[$this->request_id]['range_ids']); + if (Request::isPost()) { CSRFProtection::verifyUnsafeRequest(); - $this->seats = Request::get('seats'); - $this->comment = Request::get('comment'); - $this->reply_lecturers = Request::get('reply_lecturers'); - $this->confirmed_selected_room_id = Request::get('confirmed_selected_room_id'); + $this->request->user_id = $this->current_user->id; $this->preparation_time = Request::get('preparation_time'); + $this->request->preparation_time = $this->preparation_time * 60; + $this->request->comment = Request::get('comment'); - if (Request::submitted('select_other_room') || Request::submitted('select_properties') - || Request::submitted('reset_category')) { - //The checks for the values of the seats property, the amount of - //preparation time and the other fields are skipped here since - //the request isn't stored. Even if it gets stored in one of - //the other steps that allow storing the request, the data - //from this step won't be stored with the request. - $session_data['selected_properties']['seats'] = $this->seats; - $session_data['comment'] = $this->comment; - $session_data['reply_lecturers'] = $this->reply_lecturers; - $session_data['preparation_time'] = $this->preparation_time; - $session_data['category_id'] = $this->category_id; - //Set the request-ID in the session to make it clear that the request has been modified: - $session_data['request_id'] = $this->request->id; - if (Request::submitted('select_other_room')) { - $this->redirect('course/room_requests/request_select_room/' . $this->request_id); - } elseif (Request::submitted('reset_category')) { - //Delete all selected properties from the session since the - //category is reset: - $session_data['selected_properties'] = []; - unset($session_data['category_id']); - $this->redirect('course/room_requests/request_start/' . $this->request_id); - } else { - $this->redirect('course/room_requests/request_select_properties/' . $this->request_id); - } - return; - } elseif (Request::submitted('save') || Request::submitted('save_and_close')) { - // if a closed request is stored again, reopen it - - if ($this->seats < 1) { - PageLayout::postError( - _('Es wurde keine Anzahl an Sitzplätzen angegeben!') - ); - return; - } - if ($this->preparation_time > $this->max_preparation_time) { - PageLayout::postError( - sprintf( - _('Die eingegebene Rüstzeit überschreitet das erlaubte Maximum von %d Minuten!'), - $this->max_preparation_time - ) - ); - return; - } - - if ($this->request->isNew()) { - //Set the requester: - $this->request->user_id = $this->current_user->id; - } - - $this->request->comment = $this->comment; - if ($this->reply_lecturers) { - $this->request->reply_recipients = 'lecturer'; - } else { - $this->request->reply_recipients = 'requester'; - } - $this->request->preparation_time = (int)$this->preparation_time * 60; + if (Request::get('reply_lecturers')) { + $this->request->reply_recipients = 'lecturer'; + } else { + $this->request->reply_recipients = 'requester'; + } + $this->request->category_id = $_SESSION[$request_id]['room_category_id'] ?: $this->request->category_id; - $this->request->course_id = $this->course_id; - $this->request->last_modified_by = $this->current_user->id; + $this->request->resource_id = $_SESSION[$request_id]['room_id'] ?: $this->request->resource_id; + $this->request->course_id = Context::getId(); + $this->request->last_modified_by = $this->current_user->id; - if ($this->selected_room) { - $this->request->resource_id = $this->selected_room->id; - $this->request->category_id = $this->selected_room->category_id; - } else { - $this->request->resource_id = ''; - $this->request->category_id = $this->category_id; - } + $this->request->store(); - if ($this->request->closed != 0) { - PageLayout::postInfo(_('Die Raumanfrage wurde wieder geöffnet und damit erneut gestellt.')); - $this->request->closed = 0; - } - - if ($this->request->isDirty()) { - $storing_successful = $this->request->store(); - } else { - $storing_successful = true; - } + //Store the properties: + foreach ($_SESSION[$request_id]['selected_properties'] as $name => $state) { + $this->request->setProperty($name, $state); + } - if ($storing_successful) { - //Store the properties: - $selected_properties = $session_data['selected_properties']; - if ($selected_properties) { - $selected_properties['seats'] = $this->seats; - foreach ($selected_properties as $name => $state) { - $result = $this->request->setProperty($name, $state); - } - } else { - $result = $this->request->setProperty('seats', $this->seats); - } - $this->request->store(); - //Delete the session data: - $session_data = []; - PageLayout::postSuccess(_('Die Anfrage wurde gespeichert!')); + // once stored, we can delete the session data for this request + $_SESSION[$this->request_id] = []; - if (Request::submitted('save_and_close')) { - $this->relocate('course/room_requests/index'); - } - } else { - PageLayout::postError( - _('Die Anfrage konnte nicht gespeichert werden!') - ); - } - } + PageLayout::postSuccess(_('Die Anfrage wurde gespeichert!')); + $this->relocate('course/timesrooms/'); } } - /** - * Stores the request. This is called from request_summary, - * request_select_room and request_select_properties after the user - * clicked on "save" or "save and close". + * Store a request and its properties + * @param string $request ID of the request + * @param array $properties desired properties + * @return void */ - public function request_store_action() + private function storeRequest($request, $properties) { - if (!Config::get()->RESOURCES_ALLOW_ROOM_REQUESTS) { - throw new AccessDeniedException( - _('Das Erstellen von Raumanfragen ist nicht erlaubt!') - ); - } - Helpbar::get()->addPlainText( - _('Information'), - _('Hier können Sie Angaben zu gewünschten Raumeigenschaften machen.') - ); + // once stored, we can delete the session data for this request + $request->store(); + $_SESSION[$request->id] = []; - $this->user_is_global_resource_admin = ResourceManager::userHasGlobalPermission( - $this->current_user, - 'admin' - ); + //Store the properties: + foreach ($properties as $name => $state) { + $request->setProperty($name, $state); + } } + private function getRoomBookingIcons($available_rooms) + { + $this->available_room_icons = []; + + $request_time_intervals = $this->request->getTimeIntervals(); + + foreach ($available_rooms as $room) { + $request_dates_booked = 0; + foreach ($request_time_intervals as $interval) { + $booked = ResourceBookingInterval::countBySql( + 'resource_id = :room_id AND begin < :end AND end > :begin', + [ + 'room_id' => $room->id, + 'begin' => $interval['begin'], + 'end' => $interval['end'] + ] + ) > 0; + if ($booked) { + $request_dates_booked++; + } + } + if ($request_dates_booked === 0) { + $this->available_room_icons[$room->id] = + Icon::create('check-circle', Icon::ROLE_STATUS_GREEN)->asImg( + [ + 'class' => 'text-bottom', + 'title' => _('freier Raum') + ] + ); + $available_rooms[] = $room; + } elseif ($request_dates_booked < $request_time_intervals) { + $this->available_room_icons[$room->id] = Icon::create('exclaim-circle', Icon::ROLE_STATUS_YELLOW)->asImg([ + 'class' => 'text-bottom', + 'title' => _('teilweise belegter Raum') + ]); + $available_rooms[] = $room; + } + } + return $this->available_room_icons; + } /** * delete one room request @@ -1012,6 +717,6 @@ class Course_RoomRequestsController extends AuthenticatedController } } } - $this->redirect('course/room_requests/index'); + $this->redirect('course/timesrooms/index'); } } diff --git a/app/controllers/course/timesrooms.php b/app/controllers/course/timesrooms.php index 3f72420bf3f..a00e266b2cc 100644 --- a/app/controllers/course/timesrooms.php +++ b/app/controllers/course/timesrooms.php @@ -130,7 +130,7 @@ class Course_TimesroomsController extends AuthenticatedController $this->show = [ 'regular' => true, 'irregular' => true, - 'roomRequest' => false, + 'roomRequest' => true, ]; } $this->linkAttributes = ['fromDialog' => Request::isXhr() ? 1 : 0]; @@ -187,7 +187,22 @@ class Course_TimesroomsController extends AuthenticatedController $dates = $this->course->getDatesWithExdates(); + $this->current_user = User::findCurrent(); + $this->user_has_permissions = ResourceManager::userHasGlobalPermission($this->current_user, 'admin'); + $check_room_requests = Config::get()->RESOURCES_ALLOW_ROOM_REQUESTS; + $this->room_requests = RoomRequest::findBySQL( + 'course_id = :course_id + ORDER BY course_id, metadate_id, termin_id', + [ + 'course_id' => $this->course->id + ] + ); + + $this->global_requests = $this->course->room_requests->filter(function (RoomRequest $request) { + return $request->closed < 2 && !$request->termin_id; + }); + $single_dates = []; $this->single_date_room_request_c = 0; foreach ($dates as $val) { @@ -793,9 +808,10 @@ class Course_TimesroomsController extends AuthenticatedController } $this->redirect( - 'course/room_requests/request_start', + 'course/room_requests/new_request', [ 'range' => 'date-multiple', + 'range_str' => 'date-multiple', 'range_ids' => $appointment_ids ] ); @@ -1471,9 +1487,23 @@ class Course_TimesroomsController extends AuthenticatedController } Sidebar::Get()->addWidget($widget); - if ($GLOBALS['perm']->have_studip_perm('admin', $this->course->id)) { - $widget = new CourseManagementSelectWidget(); - Sidebar::Get()->addWidget($widget); + if ($GLOBALS['perm']->have_perm('admin')) { + $list = new SelectWidget( + _('Veranstaltungen'), + $this->indexURL(), + 'cid' + ); + + foreach (AdminCourseFilter::get()->getCoursesForAdminWidget() as $seminar) { + $list->addElement(new SelectElement( + $seminar['Seminar_id'], + $seminar['Name'], + $seminar['Seminar_id'] === Context::getId(), + $seminar['VeranstaltungsNummer'] . ' ' . $seminar['Name'] + )); + } + $list->size = 8; + Sidebar::Get()->addWidget($list); } } @@ -1661,6 +1691,7 @@ class Course_TimesroomsController extends AuthenticatedController ]; } } + $this->selectable_rooms = []; $rooms_with_booking_permissions = 0; if ($current_user_is_resource_admin) { $rooms_with_booking_permissions = Room::countAll(); diff --git a/app/views/course/room_requests/_new_request_form_footer.php b/app/views/course/room_requests/_new_request_form_footer.php new file mode 100644 index 00000000000..4b847905002 --- /dev/null +++ b/app/views/course/room_requests/_new_request_form_footer.php @@ -0,0 +1,41 @@ + <br> + <footer data-dialog-button> + <? if ($step !== 3) : ?> + <?= \Studip\LinkButton::create( + _('Zurück auf Anfang'), + $controller->url_for('course/room_requests/new_request/' . $request_id), + ['data-dialog' => 'size=big'] + ) ?> + <? else: ?> + <?= \Studip\LinkButton::create( + _('Angaben bearbeiten'), + $controller->url_for('course/room_requests/request_find_available_properties/' . $request_id . '/1'), + ['data-dialog' => 'size=big'] + ) ?> + + <? endif ?> + + <? if ($step === 1 || $step === 2) : ?> + <? if ($_SESSION[$request_id]['search_by'] !== 'category') : ?> + <? \Studip\Button::create(_('Raum auswählen'), 'select_room') ?> + <? endif ?> + <? endif ?> + + <? if (($step === 1 && $_SESSION[$request_id]['room_category_id'] !== '0') + || $step === 2) : ?> + <?= \Studip\Button::create(_('Weiter'), 'show_summary') ?> + <? endif ?> + + <? if ($step === 3) : ?> + <?= \Studip\Button::create(_('Raumanfrage speichern'), 'save_request') ?> + <? endif ?> + + <?= \Studip\LinkButton::createCancel( + _('Abbrechen'), + $controller->url_for('course/room_requests/index/' . $course_id), + [ + 'title' => _('Abbrechen') + ] + ) ?> + </footer> +</form> diff --git a/app/views/course/room_requests/_new_request_header.php b/app/views/course/room_requests/_new_request_header.php new file mode 100644 index 00000000000..cd0d381545a --- /dev/null +++ b/app/views/course/room_requests/_new_request_header.php @@ -0,0 +1,18 @@ +<section class="resources-grid"> + <section class="contentbox"> + <header><h1><?= _('Anfrage') ?></h1></header> + <section> + <?= htmlready($request->getTypeString(), 1, 1) ?> + <? if ($request->getType() == 'course'): ?> + <? + $dates = $request->getDateString(true); + ?> + <?= tooltipHtmlIcon(implode('<br>', $dates)) ?> + <? endif ?> + </section> + </section> + <section class="contentbox"> + <header><h1><?= _('Bearbeitungsstatus') ?></h1></header> + <section><?= htmlReady($request->getStatusText()) ?></section> + </section> +</section> diff --git a/app/views/course/room_requests/_request_edit_header.php b/app/views/course/room_requests/_request_edit_header.php deleted file mode 100644 index 89790d6ab00..00000000000 --- a/app/views/course/room_requests/_request_edit_header.php +++ /dev/null @@ -1,30 +0,0 @@ -<? if ($direct_room_requests_only): ?> - <?= MessageBox::info( - _('Geben Sie bitte den gewünschten Raum an. Ihre Raumanfrage wird von der zuständigen Raumvergabe bearbeitet.'), - [_('<strong>Achtung:</strong> Geben Sie bitte immer die notwendige Sitzplatzanzahl mit an!')] - )?> -<? else: ?> - <?= MessageBox::info( - _('Geben Sie den gewünschten Raum und/oder Raumeigenschaften an. Ihre Raumanfrage wird von der zuständigen Raumvergabe bearbeitet.'), - [_('<strong>Achtung:</strong> Um später einen passenden Raum für Ihre Veranstaltung zu bekommen, geben Sie bitte immer die gewünschten Eigenschaften mit an!')] - )?> -<? endif ?> -<section class="resources-grid"> - <section class="contentbox"> - <header><h1><?= _('Anfrage') ?></h1></header> - <section> - <?= htmlready($request->getTypeString(), 1, 1) ?> - <? if ($request->getType() == 'course'): ?> - <? - $dates = $request->getDateString(true); - ?> - <?= tooltipHtmlIcon(implode('<br>', $dates)) ?> - <? endif ?> - </section> - </section> - <section class="contentbox"> - <header><h1><?= _('Bearbeitungsstatus') ?></h1></header> - <section><?= htmlReady($request->getStatusText()) ?></section> - </section> -</section> - diff --git a/app/views/course/room_requests/_request_form_footer.php b/app/views/course/room_requests/_request_form_footer.php deleted file mode 100644 index bfcd3e93620..00000000000 --- a/app/views/course/room_requests/_request_form_footer.php +++ /dev/null @@ -1,28 +0,0 @@ -<footer data-dialog-button> - <? if ($room_search_button) : ?> - <?= \Studip\Button::create( - _('Räume suchen'), - 'search_rooms', - [ - 'title' => _('Startet die Suche von Räumen anhand der gewählten Eigenschaften.') - ] - ) ?> - <? endif ?> - <? if ($room_select_button) : ?> - <?= \Studip\Button::create(_('Raum auswählen'), 'select_room') ?> - <? endif ?> - <? if ($save_buttons) : ?> - <?= \Studip\Button::create(_('Speichern'), 'save_and_close') ?> - <? endif ?> - <? if ($select_properties_button) : ?> - <?= \Studip\Button::create(_('Eigenschaften wählen'), 'select_properties') ?> - <? endif ?> - <?= \Studip\LinkButton::createCancel( - _('Abbrechen'), - $controller->link_for('course/room_requests/index/' . $course_id), - [ - 'title' => _('Abbrechen') - ] - ) ?> -</footer> -</form> diff --git a/app/views/course/room_requests/_request_form_header.php b/app/views/course/room_requests/_request_form_header.php deleted file mode 100644 index cdfe7bca72a..00000000000 --- a/app/views/course/room_requests/_request_form_header.php +++ /dev/null @@ -1,4 +0,0 @@ -<form method="post" name="room_request" class="default" - action="<?= $action ?>" <?= Request::isXhr() ? 'data-dialog="size=big"' : ''?>> - <input type="hidden" name="request_id" value="<?= htmlReady($request_id) ?>"> - <?= CSRFProtection::tokenTag() ?> diff --git a/app/views/course/room_requests/_room_with_properties.php b/app/views/course/room_requests/_room_with_properties.php new file mode 100644 index 00000000000..13ec336f68e --- /dev/null +++ b/app/views/course/room_requests/_room_with_properties.php @@ -0,0 +1,10 @@ +<? if ($selected_room): ?> + <label> + <?= _('Ausgewählter Raum') ?> + <input type="hidden" name="selected_room_id" + value="<?= htmlReady($selected_room->id) ?>"> + <br> + + <strong><?= htmlReady($selected_room->name) ?></strong> + </label> +<? endif ?> diff --git a/app/views/course/room_requests/index.php b/app/views/course/room_requests/index.php index 3f13b05a7dc..0f746b8bd51 100644 --- a/app/views/course/room_requests/index.php +++ b/app/views/course/room_requests/index.php @@ -14,12 +14,12 @@ echo $flash['message']; <col style="width: 50px"> </colgroup> <thead> - <tr> - <th><?= _('Art der Anfrage') ?></th> - <th><?= _('Anfragender') ?></th> - <th><?= _('Bearbeitungsstatus') ?></th> - <th></th> - </tr> + <tr> + <th><?= _('Art der Anfrage') ?></th> + <th><?= _('Anfragender') ?></th> + <th><?= _('Bearbeitungsstatus') ?></th> + <th></th> + </tr> </thead> <tbody> <? foreach ($room_requests as $rr): ?> diff --git a/app/views/course/room_requests/new.php b/app/views/course/room_requests/new.php deleted file mode 100644 index 18edbdcf5cc..00000000000 --- a/app/views/course/room_requests/new.php +++ /dev/null @@ -1,47 +0,0 @@ -<form method="POST" class="default" name="new_room_request" - action="<?= $this->controller->link_for('course/room_requests/request_start') ?>" - <?= Request::isXhr() ? 'data-dialog="size=big"' : '' ?>> - <?= CSRFProtection::tokenTag() ?> - - <fieldset> - <legend><?= _("Raumanfrage erstellen") ?></legend> - <? if (count($options)): ?> - <label> - <?= _("Art der Raumanfrage:") ?> - <select id="new_room_request_type" name="range_str"> - <? foreach ($options as $one) : ?> - <option value="<?= $one['value'] ?>"> - <?= htmlReady($one['name']) ?> - </option> - <? endforeach ?> - </select> - </label> - - <div class="text-center" data-dialog-button> - </div> - <? else : ?> - <?= MessageBox::info( - _("In dieser Veranstaltung können keine weiteren Raumanfragen gestellt werden.") - ) ?> - <? endif ?> - </fieldset> - - <footer data-dialog-button> - <? if (count($options)): ?> - <?= Studip\Button::create( - _('Erstellen'), - 'create_room_request' - ) ?> - <?= Studip\LinkButton::createCancel( - _('Abbrechen'), - $controller->link_for('course/room_requests/index/' . $course_id) - ) ?> - <? else: ?> - <?= Studip\LinkButton::create( - _('Zurück zur Übersicht'), - $controller->link_for('course/room_requests/index/' . $course_id), - ['data-dialog' => 'size=big'] - ) ?> - <? endif ?> - </footer> -</form> diff --git a/app/views/course/room_requests/request_start.php b/app/views/course/room_requests/new_request.php similarity index 54% rename from app/views/course/room_requests/request_start.php rename to app/views/course/room_requests/new_request.php index 763ef5ae95b..948db054208 100644 --- a/app/views/course/room_requests/request_start.php +++ b/app/views/course/room_requests/new_request.php @@ -1,45 +1,17 @@ -<? if (!$embedded) : ?> - <?= $this->render_partial( - 'course/room_requests/_request_form_header', - [ - 'action' => $this->controller->link_for('course/room_requests/request_start/' . $request_id), - 'request_id' => $request_id - ] - ) ?> - <?= $this->render_partial( - 'course/room_requests/_request_edit_header', - ['request' => $request] - ) ?> -<? endif ?> -<section class="resources-grid"> - <div> - <fieldset> - <legend><?= _('Raum suchen') ?></legend> - <label> - <?= _('Raumname') ?> - <span class="flex-row"> - <input type="text" name="room_name" value="<?= htmlReady($room_name) ?>"> - <?= Icon::create('search', Icon::ROLE_CLICKABLE)->asInput( - [ - 'name' => 'search_by_name', - 'class' => 'text-bottom', - 'style' => 'margin-left: 0.2em; margin-top: 0.6em;' - ] - ) ?> - <? if ($room_name) : ?> - <?= Icon::create('refresh', Icon::ROLE_CLICKABLE, ['title' => _('alle Angaben zurücksetzen')])->asInput( - [ - 'type' => 'image', - 'class' => 'text-bottom', - 'name' => 'reset_category', - 'style' => 'margin-left: 0.2em; margin-top: 0.6em;' - ] - ) ?> - <? endif?> - </span> - </label> +<form method="post" name="room_request" class="default" + action="<?= $controller->link_for('course/room_requests/request_first_step/' . $request_id) ?>" + <?= Request::isXhr() ? 'data-dialog="size=big"' : ''?>> + <input type="hidden" name="request_id" value="<?= htmlReady($request_id) ?>"> + <?= CSRFProtection::tokenTag() ?> + + <?= $this->render_partial('course/room_requests/_new_request_header') ?> + + <section class="resources-grid"> + <div> + <fieldset> + <legend><?= _('Suche nach Raumkategorie und Eigenschaften') ?></legend> + <? if ($available_room_categories): ?> - <strong><p><?= _('Wünschbare Eigenschaften') ?></p></strong> <label> <?= _('Raumkategorie') ?> <span class="flex-row"> @@ -47,16 +19,17 @@ <option value=""><?= _('bitte auswählen') ?></option> <? foreach ($available_room_categories as $rc): ?> <option value="<?= htmlReady($rc->id) ?>" - <?= ($category_id == $rc->id) - ? 'selected="selected"' + <?= $_SESSION[$request_id]['room_category'] === $rc->id + ? 'selected' : '' ?>> <?= htmlReady($rc->name) ?> </option> <? endforeach ?> </select> <? if ($category) : ?> - <?= Icon::create('refresh', Icon::ROLE_CLICKABLE, ['title' => _('alle Angaben zurücksetzen')])->asInput( + <?= Icon::create('decline')->asInput( [ + 'title' => _('alle Angaben zurücksetzen'), 'type' => 'image', 'class' => 'text-bottom', 'name' => 'reset_category', @@ -64,11 +37,12 @@ ] ) ?> <? else : ?> - <?= Icon::create('accept', Icon::ROLE_CLICKABLE, ['title' => _('Raumtyp auswählen')])->asInput( + <?= Icon::create('accept')->asInput( [ + 'title' => _('Raumtyp auswählen'), 'type' => 'image', 'class' => 'text-bottom', - 'name' => 'select_properties', + 'name' => 'search_by_category', 'value' => _('Raumtyp auswählen'), 'style' => 'margin-left: 0.2em; margin-top: 0.6em;' ] @@ -80,6 +54,39 @@ <? if (!$embedded) : ?> </fieldset> </div> + + <div> + <fieldset> + <legend><?= _('Raumsuche') ?></legend> + <label> + <?= _('Raumname') ?> + <span class="flex-row"> + <input type="text" name="room_name" value="<?= htmlReady($_SESSION[$request_id]['room_name']) ?>"> + <?= Icon::create('search')->asInput( + [ + 'title' => _('Räume suchen'), + 'name' => 'search_by_name', + 'class' => 'text-bottom', + 'style' => 'margin-left: 0.2em; margin-top: 0.6em;' + ] + ) ?> + <? if ($room_name) : ?> + <?= Icon::create('decline')->asInput( + [ + 'title' => _('alle Angaben zurücksetzen'), + 'type' => 'image', + 'class' => 'text-bottom', + 'name' => 'reset_name', + 'style' => 'margin-left: 0.2em; margin-top: 0.6em;' + ] + ) ?> + <? endif?> + </span> + </label> + + </fieldset> + + </div> </section> -<?= $this->render_partial('course/room_requests/_request_form_footer') ?> +<?= $this->render_partial('course/room_requests/_new_request_form_footer', ['step' => $step]) ?> <? endif ?> diff --git a/app/views/course/room_requests/request_find_available_properties.php b/app/views/course/room_requests/request_find_available_properties.php new file mode 100644 index 00000000000..ea0767f2e6d --- /dev/null +++ b/app/views/course/room_requests/request_find_available_properties.php @@ -0,0 +1,124 @@ +<form method="post" name="room_request" class="default" + action="<?= $controller->link_for('course/room_requests/request_check_properties/' . $request_id . '/' . $this->step) ?>" + <?= Request::isXhr() ? 'data-dialog="size=big"' : ''?>> + <input type="hidden" name="request_id" value="<?= htmlReady($request_id) ?>"> + <?= CSRFProtection::tokenTag() ?> + + <?= $this->render_partial('course/room_requests/_new_request_header') ?> + + <section class="resources-grid"> + <div> + <fieldset class="request-fieldset"> + <legend><?= _('Wünschbare Eigenschaften') ?></legend> + + <? if ($step === 1 || $step === 2) : ?> + <?= $this->render_partial('course/room_requests/_room_with_properties') ?> + <? endif ?> + + <? if ($available_room_categories): ?> + <label> + <?= _('Raumkategorie') ?> + <span class="flex-row"> + <select name="category_id" > + <option value="0"><?= _('bitte auswählen') ?></option> + <? foreach ($available_room_categories as $rc): ?> + <option value="<?= htmlReady($rc->id) ?>" + <?= $room_category_id === $rc->id + ? 'selected' + : '' ?>> + <?= htmlReady($rc->name) ?> + </option> + <? endforeach ?> + </select> + <?= Icon::create('accept')->asInput( + [ + 'title' => _('Raumtyp auswählen'), + 'type' => 'image', + 'class' => 'text-bottom', + 'name' => 'search_by_category', + 'value' => _('Raumtyp auswählen'), + 'style' => 'margin-left: 0.2em; margin-top: 0.6em;' + ] + ) ?> + <? if ($category) : ?> + <?= Icon::create('decline')->asInput( + [ + 'title' => _('alle Angaben zurücksetzen'), + 'type' => 'image', + 'class' => 'text-bottom', + 'name' => 'reset_category', + 'style' => 'margin-left: 0.2em; margin-top: 0.6em;' + ] + ) ?> + <? endif ?> + </span> + </label> + <? endif ?> + + <!-- ROOM CATEGORY PROPERTIES --> + <? if ($available_properties) : ?> + <? foreach ($available_properties as $property) : ?> + <?= $property->toHtmlInput( + $selected_properties[$property->name], + 'selected_properties[' . htmlReady($property->name) . ']', + true, + false + ) ?> + <? endforeach ?> + + <div> + <?= \Studip\Button::create(_('Räume suchen'), 'search_rooms') ?> + </div> + <? endif ?> + + </fieldset> + </div> + + <div> + <fieldset class="request-fieldset"> + <legend><?= _('Raumsuche') ?></legend> + <label> + <?= _('Raumname') ?> + <span class="flex-row"> + <input type="text" name="room_name" value="<?= htmlReady($room_name) ?>" > + <?= Icon::create('search')->asInput( + [ + 'title' => _('Räume suchen'), + 'name' => 'search_by_name', + 'class' => 'text-bottom', + 'style' => 'margin-left: 0.2em; margin-top: 0.6em;' + ] + ) ?> + </span> + </label> + <? if ($available_rooms) : ?> + <label><strong><?= _('Passende Räume') ?></strong> + <section class="selectbox" id="room_select"> + <? foreach ($available_rooms as $room): ?> + <div class="flex-row"> + <label class="horizontal"> + <?= $available_room_icons[$room->id] ?> + <input type="radio" name="selected_room_id" + data-activates="button[type='submit'][name='select_room']" + value="<?= htmlReady($room->id) ?>" + <? if ($_SESSION[$request_id]['room_id'] === $room->id) echo 'checked' ?>> + <?= htmlReady(mila($room->name, 50)) . ' (' . $room['category']->name . ')'?> + <? if ($room->properties): ?> + <? $property_names = $room->getInfolabelProperties() + ->pluck('fullname') ?> + <?= tooltipIcon(implode("\n", $property_names)) ?> + <? endif ?> + </label> + </div> + <? endforeach ?> + </section> + </label> + <?= \Studip\Button::create(_('Raum auswählen'), 'select_room') ?> + <? else : ?> + <? endif ?> + </fieldset> + + </div> + </section> + +<?= $this->render_partial('course/room_requests/_new_request_form_footer', ['step' => $step, 'search_by' => 'category']) ?> diff --git a/app/views/course/room_requests/request_find_matching_rooms.php b/app/views/course/room_requests/request_find_matching_rooms.php new file mode 100644 index 00000000000..a474ab2a77a --- /dev/null +++ b/app/views/course/room_requests/request_find_matching_rooms.php @@ -0,0 +1,134 @@ +<form method="post" name="room_request" class="default" + action="<?= $controller->link_for('course/room_requests/request_find_matching_rooms/' . $request_id . '/' . $this->step) ?>" + <?= Request::isXhr() ? 'data-dialog="size=big"' : ''?>> + <input type="hidden" name="request_id" value="<?= htmlReady($request_id) ?>"> + <?= CSRFProtection::tokenTag() ?> + + <?= $this->render_partial('course/room_requests/_new_request_header') ?> + + <section class="resources-grid"> + <div> + <fieldset class="request-fieldset"> + <legend><?= _('Wünschbare Eigenschaften') ?></legend> + + <? if ($step === 1 || $step === 2) : ?> + <?= $this->render_partial('course/room_requests/_room_with_properties') ?> + <? endif ?> + + <? if ($available_room_categories): ?> + <label> + <?= _('Raumkategorie') ?> + <span class="flex-row"> + <select name="category_id" > + <option value="0"><?= _('bitte auswählen') ?></option> + <? foreach ($available_room_categories as $rc): ?> + <option value="<?= htmlReady($rc->id) ?>" + <?= $_SESSION[$request_id]['room_category_id'] === $rc->id + ? 'selected' + : '' ?>> + <?= htmlReady($rc->name) ?> + </option> + <? endforeach ?> + </select> + <?= Icon::create('accept')->asInput( + [ + 'title' => _('Raumtyp auswählen'), + 'type' => 'image', + 'class' => 'text-bottom', + 'name' => 'select_properties', + 'value' => _('Raumtyp auswählen'), + 'style' => 'margin-left: 0.2em; margin-top: 0.6em;' + ] + ) ?> + + <? if ($category) : ?> + <?= Icon::create('decline')->asInput( + [ + 'title' => _('alle Angaben zurücksetzen'), + 'type' => 'image', + 'class' => 'text-bottom', + 'name' => 'reset_category', + 'style' => 'margin-left: 0.2em; margin-top: 0.6em;' + ] + ) ?> + <? endif ?> + </span> + </label> + <? endif ?> + + <? if ($step === 2) : ?> + <!-- After choosing a category or room --> + <? if ($available_properties) : ?> + <? foreach ($available_properties as $property) : ?> + <?= $property->toHtmlInput( + $selected_properties[$property->name], + 'selected_properties[' . htmlReady($property->name) . ']', + true, + false, + false + ) ?> + <? endforeach ?> + <? endif ?> + + <?= \Studip\Button::create(_('Räume suchen'), 'search_rooms') ?> + + <? endif ?> + + <? if (!$embedded) : ?> + </fieldset> + + </div> + + <div> + <fieldset class="request-fieldset"> + <legend><?= _('Raumsuche') ?></legend> + <label> + <?= _('Raumname') ?> + <span class="flex-row"> + <input type="text" name="room_name" value="<?= htmlReady($_SESSION[$request_id]['room_name']) ?>"> + <?= Icon::create('search')->asInput( + [ + 'title' => _('Räume suchen'), + 'name' => 'search_by_name', + 'class' => 'text-bottom', + 'style' => 'margin-left: 0.2em; margin-top: 0.6em;' + ] + ) ?> + </span> + </label> + <? if ($available_rooms) : ?> + <label> + <strong><?= _('Passende Räume') ?></strong> + <section class="selectbox" id="room_selection"> + <? foreach ($available_rooms as $room): ?> + <div class="flex-row"> + <label class="horizontal"> + <?= $available_room_icons[$room->id] ?> + <input type="radio" name="selected_room_id" + data-activates="button[type='submit'][name='select_room']" + value="<?= htmlReady($room->id) ?>" + <? if ($_SESSION[$request_id]['room_id'] === $room->id) echo 'checked' ?>> + <?= htmlReady(mila($room->name, 60)) . ' (' . $room['category']->name . ')'?> + <? if ($room->properties): ?> + <? $property_names = $room->getInfolabelProperties() + ->pluck('fullname') ?> + <?= tooltipIcon(implode("\n", $property_names)) ?> + <? endif ?> + </label> + </div> + <? endforeach ?> + </section> + </label> + <?= \Studip\Button::create(_('Raum auswählen'), 'select_room') ?> + + <? else : ?> + <?= MessageBox::info(_('Es wurden keine passenden Räume gefunden!')) ?> + <? endif ?> + + </fieldset> + + </div> + </section> + + <?= $this->render_partial('course/room_requests/_new_request_form_footer', ['step' => $step, 'search_by' => 'roomname']) ?> +<? endif ?> diff --git a/app/views/course/room_requests/request_select_properties.php b/app/views/course/room_requests/request_select_properties.php deleted file mode 100644 index de45b117bc0..00000000000 --- a/app/views/course/room_requests/request_select_properties.php +++ /dev/null @@ -1,65 +0,0 @@ -<? if (empty($embedded)) : ?> - <?= $this->render_partial( - 'course/room_requests/_request_form_header', - [ - 'action' => $this->controller->link_for('course/room_requests/request_select_properties/' . $request_id), - 'request_id' => $request_id - ] - ) ?> - <?= $this->render_partial( - 'course/room_requests/_request_edit_header', - ['request' => $request] - ) ?> - <?= $this->render_partial( - 'course/room_requests/request_start', - ['embedded' => true] - ) ?> -<? endif ?> - -<? if ($available_properties) : ?> - <? foreach ($available_properties as $property) : ?> - <?= $property->toHtmlInput( - $selected_properties[$property->name] ?? '', - 'selected_properties[' . htmlReady($property->name) . ']', - true, - false - ) ?> - <? endforeach ?> -<? endif ?> - -<label> - <?= _('Rüstzeit (in Minuten)') ?> - <input type="number" name="preparation_time" - value="<?= htmlReady($preparation_time) ?>" - min="0" max="<?= htmlReady($max_preparation_time) ?>"> -</label> - -<label> - <input type="checkbox" name="reply_lecturers" value="1" - <?= $reply_lecturers - ? 'checked="checked"' - : '' - ?>> - <?= _('Benachrichtigung bei Ablehnung der Raumanfrage auch an alle Lehrenden der Veranstaltung senden') ?> -</label> - - - <label> - <?= _('Nachricht an die Raumvergabe') ?> - <textarea name="comment" cols="58" rows="4" - placeholder="<?= _('Weitere Wünsche oder Bemerkungen zur angefragten Raumbelegung') ?>"><?= htmlReady($comment) ?></textarea> - </label> - -<? if (empty($embedded)) : ?> - </div> - </section> - <?= $this->render_partial( - 'course/room_requests/_request_form_footer', - [ - 'room_search_button' => true, - 'save_buttons' => true, - 'room_select_button' => false, - 'select_properties_button' => false - ] - ) ?> -<? endif ?> diff --git a/app/views/course/room_requests/request_select_room.php b/app/views/course/room_requests/request_select_room.php deleted file mode 100644 index 752ad9898d9..00000000000 --- a/app/views/course/room_requests/request_select_room.php +++ /dev/null @@ -1,66 +0,0 @@ -<? if (empty($embedded)) : ?> - <?= $this->render_partial( - 'course/room_requests/_request_form_header', - [ - 'action' => $this->controller->link_for('course/room_requests/request_select_room/' . $request_id), - 'request_id' => $request_id - ] - ) ?> - <?= $this->render_partial( - 'course/room_requests/_request_edit_header', - ['request' => $request] - ) ?> - <?= $this->render_partial( - 'course/room_requests/request_start', - ['embedded' => true] - ) ?> - <? if (($category instanceof ResourceCategory) && !$direct_room_requests_only): ?> - <?= $this->render_partial( - 'course/room_requests/request_select_properties', - ['embedded' => true] - ) ?> - <? endif ?> -<? endif ?> -</div> - -<div> -<? if ($available_rooms) : ?> - <section class="contentbox"> - <header><h1><?= _('Passende Räume') ?></h1></header> - <section class="selectbox"> - <fieldset> - <? foreach ($available_rooms as $room): ?> - <div class="flex-row"> - <label class="horizontal"> - <?= $available_room_icons[$room->id] ?> - <input type="radio" name="selected_room_id" - data-activates="button[type='submit'][name='select_room']" - value="<?= htmlReady($room->id) ?>"> - <?= htmlReady(mb_substr($room->name, 0, 50)); ?> - <? if ($room->properties): ?> - <? $property_names = $room->getInfolabelProperties() - ->pluck('fullname') ?> - <?= tooltipIcon(implode("\n", $property_names)) ?> - <? endif ?> - </label> - </div> - <? endforeach ?> - </fieldset> - </section> - </section> - <? else : ?> - <?= MessageBox::info(_('Es wurden keine passenden Räume gefunden!')) ?> - <? endif ?> - </div> -</section> -<? if (empty($embedded)) : ?> - <?= $this->render_partial( - 'course/room_requests/_request_form_footer', - [ - 'room_search_button' => true, - 'room_select_button' => true, - 'save_buttons' => true, - 'select_properties_button' => false - ] - ) ?> -<? endif ?> diff --git a/app/views/course/room_requests/request_show_summary.php b/app/views/course/room_requests/request_show_summary.php new file mode 100644 index 00000000000..732e2a4cb93 --- /dev/null +++ b/app/views/course/room_requests/request_show_summary.php @@ -0,0 +1,88 @@ +<form method="post" name="room_request" class="default" + action="<?= $controller->link_for('course/room_requests/store_request/' . $request_id) ?>" + <?= Request::isXhr() ? 'data-dialog="size=big"' : ''?>> + <input type="hidden" name="request_id" value="<?= htmlReady($request_id) ?>"> + <?= CSRFProtection::tokenTag() ?> + + + <?= $this->render_partial('course/room_requests/_new_request_header') ?> + <section class="resources-grid"> + <div> + <fieldset> + <legend> + <?= _('Zusammenfassung') ?> + </legend> + <label> + <?= _('Ausgewählte Raumkategorie') ?> + <input type="hidden" name="selected_room_id" + value="<?= htmlReady($selected_room->id) ?>"> + <br> + + <strong><?= htmlReady($selected_room_category->name) ?></strong> + </label> + + <label> + <?= _('Ausgewählter Raum') ?> + <? if ($selected_room): ?> + <input type="hidden" name="selected_room_id" + value="<?= htmlReady($selected_room->id) ?>"> + <br> + + <strong><?= htmlReady($selected_room->name) ?></strong> + <? else : ?> + <br> + + <strong><?= _('Es wurde kein spezifischer Raum gewählt.') ?></strong> + <? endif ?> + </label> + + <? foreach ($available_properties as $property) : ?> + <? foreach ($selected_properties as $key => $value) : ?> + <? if ($property->name === $key) : ?> + <?= $property->toHtmlInput( + $selected_properties[$property->name], + 'selected_properties[' . htmlReady($property->name) . ']', + true, + false, + true + ) ?> + <? endif ?> + <? endforeach ?> + <? endforeach ?> + + </fieldset> + </div> + <div> + <fieldset> + <legend> + <?= _('Sonstiges') ?> + </legend> + <label> + <?= _('Rüstzeit (in Minuten)') ?> + <input type="number" name="preparation_time" + value="<?= htmlReady($preparation_time) ?>" + min="0" max="<?= htmlReady($max_preparation_time) ?>"> + </label> + + <? if ($user_is_global_resource_admin) : ?> + <label> + <input type="checkbox" name="reply_lecturers" value="1" + <?= $reply_lecturers + ? 'checked' + : '' + ?>> + <?= _('Benachrichtigung bei Ablehnung der Raumanfrage auch an alle Lehrenden der Veranstaltung senden') ?> + </label> + <? endif ?> + + <label> + <?= _('Nachricht an die Raumvergabe') ?> + <textarea name="comment" cols="58" rows="4" + placeholder="<?= _('Weitere Wünsche oder Bemerkungen zur angefragten Raumbelegung') ?>"><?= htmlReady($comment) ?></textarea> + </label> + + </fieldset> + </div> + + </section> + <?= $this->render_partial('course/room_requests/_new_request_form_footer', ['step' => $step, 'search_by' => 'roomname']) ?> diff --git a/app/views/course/room_requests/request_summary.php b/app/views/course/room_requests/request_summary.php deleted file mode 100644 index 4108deb16cc..00000000000 --- a/app/views/course/room_requests/request_summary.php +++ /dev/null @@ -1,100 +0,0 @@ -<form method="post" name="room_request" class="default" - action="<?= $this->controller->link_for('course/room_requests/request_summary/' . $request_id) ?>"> - <input type="hidden" name="request_id" value="<?= htmlReady($request_id) ?>"> - <?= $this->render_partial( - 'course/room_requests/_request_edit_header', - ['request' => $request] - ) ?> - <?= CSRFProtection::tokenTag() ?> - <section class="resources-grid"> - <div> - <fieldset> - <legend><?= _('Ausgewählter Raum') ?></legend> - <? if (!empty($selected_room)): ?> - <input type="hidden" name="selected_room_id" - value="<?= htmlReady($selected_room->id) ?>"> - <input type="hidden" name="confirmed_selected_room_id" - value="<?= htmlReady($selected_room->id) ?>"> - <?= htmlReady($selected_room->name) ?> - <? if ($selected_room->properties): ?> - <? $property_names = $selected_room->properties - ->findBy('info_label', 1) - ->findBy('state', '', '!=') - ->pluck('fullname') ?> - <?= tooltipIcon( - implode("\n", $property_names) - ) ?> - <? endif ?> - <?= Studip\Button::create( - _('Anderen Raum wählen'), - 'select_other_room' - ) ?> - <? else: ?> - <?= MessageBox::info( - _('Es wurde kein konkreter Raum ausgewählt!') - ) ?> - <?= Studip\Button::create( - _('Eigenschaften neu wählen'), - 'select_properties' - ) ?> - <? endif ?> - <? if ($request->properties): ?> - <? foreach ($request->properties as $property): ?> - <? if (!in_array($property->name, ['seats'])): ?> - <dt><?= htmlReady($property->display_name) ?></dt> - <dd><?= htmlReady($property->__toString()) ?></dd> - <? endif ?> - <? endforeach ?> - <? endif ?> - <? if ($request->category): ?> - <dt><?= _('Gewünschter Raumtyp') ?>:</dt> - <dd><?= htmlReady($request->category->name) ?></dd> - <? endif ?> - <label> - <?= _('Erwartete Anzahl an Teilnehmenden') ?>: - <input type="number" name="seats" - value="<?= htmlReady($seats) ?>" - min="1"> - </label> - <label> - <?= _('Rüstzeit (in Minuten)') ?> - <input type="number" name="preparation_time" - value="<?= htmlReady($preparation_time) ?>" - min="0" max="<?= htmlReady($max_preparation_time) ?>"> - </label> - <label> - <input type="checkbox" name="reply_lecturers" value="1" - <?= $reply_lecturers - ? 'checked="checked"' - : '' - ?>> - <?= _('Benachrichtigung bei Ablehnung der Raumanfrage auch an alle Lehrenden der Veranstaltung senden') ?> - </label> - </fieldset> - </div> - <div> - <fieldset> - <legend><?= _('Nachricht an die Raumvergabe') ?></legend> - <textarea name="comment" cols="58" rows="4" - placeholder="<?= _('Weitere Wünsche oder Bemerkungen zur angefragten Raumbelegung') ?>"><?= htmlReady($comment) ?></textarea> - </fieldset> - </div> - </section> - <footer data-dialog-button> - <?= \Studip\Button::create( - _('Speichern'), - 'save' - ) ?> - <?= \Studip\Button::create( - _('Speichern und zurück zur Übersicht'), - 'save_and_close' - ) ?> - <?= \Studip\LinkButton::createCancel( - _('Abbrechen'), - $controller->link_for('course/room_requests/index/' . $course_id), - [ - 'title' => _('Abbrechen') - ] - ) ?> - </footer> -</form> diff --git a/app/views/course/timesrooms/_cancel_form.php b/app/views/course/timesrooms/_cancel_form.php index 8a2b7067424..eaadaf19d6b 100644 --- a/app/views/course/timesrooms/_cancel_form.php +++ b/app/views/course/timesrooms/_cancel_form.php @@ -17,3 +17,4 @@ if (isset($termin) && $termin instanceof CourseExDate) { <input type="checkbox" id="cancel_send_message" name="cancel_send_message" value="1"> <?= _('Benachrichtigung über ausfallende Termine an alle Teilnehmenden verschicken') ?> </label> + diff --git a/app/views/course/timesrooms/_regularEvents.php b/app/views/course/timesrooms/_regularEvents.php index f2b1829b396..baaa2d8852b 100644 --- a/app/views/course/timesrooms/_regularEvents.php +++ b/app/views/course/timesrooms/_regularEvents.php @@ -89,18 +89,19 @@ <? if (Config::get()->RESOURCES_ALLOW_ROOM_REQUESTS) : ?> <? $actionMenu->addLink( $controller->url_for( - 'course/room_requests/request_start/', + 'course/room_requests/new_request/', [ - 'range' => 'cycle', - 'range_id' => $metadate_id + 'cid' => $course->id, + 'range_str' => 'cycle', + 'range_id' => $metadate_id ] ), - _('Raumanfrage erstellen'), + _('Neue Raumanfrage'), Icon::create( 'room-request', Icon::ROLE_CLICKABLE, [ - 'title' => _('Raumanfrage erstellen'), + 'title' => _('Neue Raumanfrage'), 'style' => 'vertical-align: middle;' ] ), diff --git a/app/views/course/timesrooms/_roomRequest.php b/app/views/course/timesrooms/_roomRequest.php index 3eecb3c46b1..9f80e9625cf 100644 --- a/app/views/course/timesrooms/_roomRequest.php +++ b/app/views/course/timesrooms/_roomRequest.php @@ -1,12 +1,7 @@ -<?php -$global_requests = $course->room_requests->filter(function (RoomRequest $request) { - return $request->closed < 2 && !$request->termin_id; -}); -?> -<section class="contentbox"> +<section class="contentbox" id="request"> <header> <h1> - <?= _('Raumanfrage für die gesamte Veranstaltung') ?> + <?= _('Raumanfragen für die gesamte Veranstaltung') ?> </h1> <nav> @@ -14,7 +9,7 @@ $global_requests = $course->room_requests->filter(function (RoomRequest $request _('Hier können Sie für die gesamte Veranstaltung, also für alle regelmäßigen und unregelmäßigen Termine, ' . 'eine Raumanfrage erstellen.') ) ?> - <a class="link-add" href="<?= $controller->url_for('course/room_requests/request_start', + <a class="link-add" href="<?= $controller->link_for('course/room_requests/new_request', [ 'cid' => $course->id, 'range_str' => 'course', @@ -29,13 +24,102 @@ $global_requests = $course->room_requests->filter(function (RoomRequest $request </nav> </header> + <?= $flash['message'] ?> + + <? if (count($room_requests)) : ?> <section> - <? if (count($global_requests) > 0): ?> - <p><?= _('Für diese Veranstaltung liegt eine offene Raumanfrage vor') ?></p> - <?= Studip\LinkButton::create(_('Raumanfragen anzeigen'), - URLHelper::getURL('dispatch.php/course/room_requests/index/' . $course->getId())) ?> - <? else: ?> - <p><?= _('Keine Raumanfrage vorhanden') ?></p> - <? endif ?> + <table class="default sortable-table"> + <colgroup> + <col style="width: 40%"> + <col style="width: 20%"> + <col> + <col style="width: 50px"> + </colgroup> + <thead> + <tr class="sortable"> + <th data-sort="text"><?= _('Art der Anfrage') ?></th> + <th data-sort="text"><?= _('Anfragender') ?></th> + <th data-sort="text"><?= _('Bearbeitungsstatus') ?></th> + <th></th> + </tr> + </thead> + <tbody> + <? foreach ($room_requests as $rr): ?> + <tr> + <td> + <?= htmlReady($rr->getTypeString(), 1, 1) ?> + </td> + <td> + <?= htmlReady($rr->user ? $rr->user->getFullName() : '') ?> + </td> + <td> + <?= htmlReady($rr->getStatusText()) ?> + </td> + <td class="actions"> + <a class="load-in-new-row" + href="<?= $controller->link_for('course/room_requests/info/' . $rr->id) ?>" + aria-expanded="false"> + <?= Icon::create('info')->asImg(['title' => _('Weitere Informationen einblenden')]) ?> + </a> + <? $params = [] ?> + <? $dialog = []; ?> + <? if (Request::isXhr()) : ?> + <? $params['asDialog'] = true; ?> + <? $dialog['data-dialog'] = 'size=big' ?> + <? endif ?> + + <? $actionMenu = ActionMenu::get()->setContext($rr->getTypeString()) ?> + <? $actionMenu->addLink( + $controller->url_for('course/room_requests/request_show_summary/' . $rr->id, ['clear_cache' => 1]), + _('Diese Anfrage bearbeiten'), + Icon::create('edit'), + ['title' => _('Diese Anfrage bearbeiten'), 'data-dialog' => 'size=big'] + ) ?> + + <?php + if ($rr->room && !$user_has_permissions) { + $user_has_permissions = $rr->room->userHasPermission($current_user, 'admin'); + } + ?> + + <? if ($user_has_permissions && !$rr->closed): ?> + <? $actionMenu->addLink( + URLHelper::getURL( + 'dispatch.php/resources/room_request/resolve/' . $rr->id, + [ + 'reload-on-close' => 1, + 'single-request' => 1 + ] + ), + _('Diese Anfrage selbst auflösen'), + Icon::create('admin'), + ['title' => _('Diese Anfrage selbst auflösen')], + ['data-dialog' => '1'] + ) ?> + <? endif ?> + <? $actionMenu->addLink( + $controller->url_for('course/room_requests/delete/' . $rr->id), + _('Diese Anfrage löschen'), + Icon::create('trash'), + ['title' => _('Diese Anfrage löschen')] + ) ?> + <?= $actionMenu->render() ?> + </td> + </tr> + <? endforeach ?> + <? if ($request_id === $rr->id) : ?> + <tr> + <td colspan="4"> + <?= $this->render_partial('course/room_requests/_request.php', ['request' => $rr]); ?> + </td> + </tr> + <? endif ?> + </tbody> + </table> </section> + <? else : ?> + <?= MessageBox::info(_('Zu dieser Veranstaltung sind noch keine Raumanfragen vorhanden.')) ?> + <? endif ?> + + </section> diff --git a/app/views/course/timesrooms/_roomRequestInfo.php b/app/views/course/timesrooms/_roomRequestInfo.php index 7bc36603d5f..6b3315bb543 100644 --- a/app/views/course/timesrooms/_roomRequestInfo.php +++ b/app/views/course/timesrooms/_roomRequestInfo.php @@ -8,7 +8,5 @@ $open_requests = $course->room_requests->filter(function (RoomRequest $request) 'Für diese Veranstaltung liegt eine offene Raumanfrage vor.', 'Für diese Veranstaltung liegen %u offene Raumanfragen vor', count($open_requests) - ), count($open_requests)) . '<br>' - . Studip\LinkButton::create(_('Raumanfragen anzeigen'), - URLHelper::getURL('dispatch.php/course/room_requests/index/' . $course->getId()))) ?> + ), count($open_requests))) ?> <? endif; ?> diff --git a/app/views/course/timesrooms/editDate.php b/app/views/course/timesrooms/editDate.php index 3be5e7c709f..a8dea31c655 100644 --- a/app/views/course/timesrooms/editDate.php +++ b/app/views/course/timesrooms/editDate.php @@ -228,8 +228,8 @@ 'course/room_requests/request_summary/' . $request_id ) : $controller->url_for( - 'course/room_requests/request_start/' . $request_id, - array_merge($params, ['range_str' => 'date_' . $date->id,'origin' => 'course_timesrooms']) + 'course/room_requests/new_request/' . $request_id, + array_merge($params, ['range_str' => 'date', 'range_id' => $date->id]) ) ), ['data-dialog' => 'size=big']) ?> diff --git a/app/views/course/timesrooms/index.php b/app/views/course/timesrooms/index.php index 8636ebbd658..e82409d973d 100644 --- a/app/views/course/timesrooms/index.php +++ b/app/views/course/timesrooms/index.php @@ -22,13 +22,3 @@ <?= $this->render_partial('course/timesrooms/_roomRequest.php') ?> <? endif ?> -<? if (Request::isXhr() && !$locked && Config::get()->RESOURCES_ENABLE && Config::get()->RESOURCES_ALLOW_ROOM_REQUESTS): ?> - <div data-dialog-button> - <?= Studip\LinkButton::create( - _('Raumanfrage erstellen'), - $controller->url_for('course/room_requests/request_start', - ['cid' => $course->id, 'range_str' => 'course', 'origin' => 'admin_courses']), - ['data-dialog' => 'size=big'] - ) ?> - </div> -<? endif ?> diff --git a/lib/models/resources/ResourcePropertyDefinition.class.php b/lib/models/resources/ResourcePropertyDefinition.class.php index 37fa89b95d3..c3a84d69fa6 100644 --- a/lib/models/resources/ResourcePropertyDefinition.class.php +++ b/lib/models/resources/ResourcePropertyDefinition.class.php @@ -140,7 +140,8 @@ class ResourcePropertyDefinition extends SimpleORMap $value = '', $special_name = '', $with_label = false, - $allow_boolean_false = true + $allow_boolean_false = true, + $disabled = false ) { $label_html_classes = ''; @@ -155,16 +156,18 @@ class ResourcePropertyDefinition extends SimpleORMap //whether a false state shall be selectable or not. if ($allow_boolean_false) { $input_html = sprintf( - '<input type="hidden" name="%1$s" value="0" %2$s>' + '<input type="hidden" name="%1$s" value="0" %2$s %3$s>' . '<input type="checkbox" name="%1$s" value="1" %2$s>', htmlReady($input_name), - $value ? 'checked="checked"' : '' + $value ? 'checked' : '', + $disabled ? 'disabled' : '' ); } else { $input_html = sprintf( - '<input type="checkbox" name="%1$s" value="1" %2$s>', + '<input type="checkbox" name="%1$s" value="1" %2$s %3$s>', htmlReady($input_name), - $value ? 'checked="checked"' : '' + $value ? 'checked' : '', + $disabled ? 'disabled' : '' ); } if ($with_label) { @@ -254,7 +257,7 @@ class ResourcePropertyDefinition extends SimpleORMap } if ($with_label) { return sprintf( - '<label %1$s>%5$s<input type="%2$s" name="%3$s" value="%4$s"></label>', + '<label %1$s>%5$s<input type="%2$s" name="%3$s" value="%4$s" %5$s></label>', ( $label_html_classes ? 'class="' . htmlReady($label_html_classes) . '"' @@ -263,14 +266,16 @@ class ResourcePropertyDefinition extends SimpleORMap $input_type, htmlReady($input_name), $value, - htmlReady($this->__toString()) + htmlReady($this->__toString()), + $disabled ? 'disabled' : '' ); } else { return sprintf( - '<input type="%1$s" name="%2$s" value="%3$s">', + '<input type="%1$s" name="%2$s" value="%3$s" %4$s>', $input_type, htmlReady($input_name), - $value + $value, + $disabled ? 'disabled' : '' ); } } diff --git a/lib/modules/CoreAdmin.class.php b/lib/modules/CoreAdmin.class.php index b02cf932e86..ada2af02aa2 100644 --- a/lib/modules/CoreAdmin.class.php +++ b/lib/modules/CoreAdmin.class.php @@ -63,13 +63,6 @@ class CoreAdmin extends CorePlugin implements StudipModule $item->setDescription(_('Regelmäßige Veranstaltungszeiten, Einzeltermine und Ortsangaben ändern.')); $navigation->addSubNavigation('dates', $item); - if (Config::get()->RESOURCES_ENABLE && Config::get()->RESOURCES_ALLOW_ROOM_REQUESTS) { - $item = new Navigation(_('Raumanfragen'), 'dispatch.php/course/room_requests/index/' . $course_id); - $item->setImage(Icon::create('resources')); - $item->setDescription(_('Raumanfragen zu Veranstaltungszeiten verwalten.')); - $navigation->addSubNavigation('room_requests', $item); - } - $item = new Navigation(_('Zugangsberechtigungen'), 'dispatch.php/course/admission'); $item->setImage(Icon::create('lock-locked')); $item->setDescription(_('Zugangsbeschränkungen, Anmeldeverfahren oder einen Passwortschutz für diese Veranstaltung einrichten.')); diff --git a/resources/assets/javascripts/bootstrap/application.js b/resources/assets/javascripts/bootstrap/application.js index 1f0561e0ce5..d673455f733 100644 --- a/resources/assets/javascripts/bootstrap/application.js +++ b/resources/assets/javascripts/bootstrap/application.js @@ -122,6 +122,7 @@ STUDIP.domReady(function () { if ($(this).closest('tr').next().hasClass('loaded-details')) { $(this).closest('tr').next().remove(); + $('a.load-in-new-row').attr('aria-expanded', 'false'); return false; } $(this).showAjaxNotification().data('busy', true); @@ -140,6 +141,8 @@ STUDIP.domReady(function () { $(that).data('busy', false); $('body').trigger('ajaxLoaded'); + $('a.load-in-new-row').attr('aria-expanded', 'true'); + }); return false; diff --git a/resources/assets/stylesheets/scss/forms.scss b/resources/assets/stylesheets/scss/forms.scss index bdd34df0f0b..d1336153c09 100644 --- a/resources/assets/stylesheets/scss/forms.scss +++ b/resources/assets/stylesheets/scss/forms.scss @@ -199,8 +199,8 @@ form.default { } .selectbox { - padding:5px; - max-height:200px; + padding: 5px; + max-height: 200px; overflow:auto; > fieldset { -- GitLab