Skip to content
Snippets Groups Projects
room_requests.php 28.9 KiB
Newer Older
<?php
# Lifter010: TODO
/**
 * room_requests.php - administration of room requests
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * @author      André Noack <noack@data-quest.de>
 * @author      Moritz Strohm <strohm@data-quest.de>
Michaela Brückner's avatar
Michaela Brückner committed
 * @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
 */
class Course_RoomRequestsController extends AuthenticatedController
{
    /**
     * Common tasks for all actions
     *
     * @param string $action Called action
     * @param array  $args   Possible arguments
     */
    public function before_filter(&$action, &$args)
    {
        $this->current_action = $action;

        parent::before_filter($action, $args);

        $this->current_user = User::findCurrent();
Michaela Brückner's avatar
Michaela Brückner committed
        $this->user_is_global_resource_admin = ResourceManager::userHasGlobalPermission(
            $this->current_user,
            'admin'
        );
Moritz Strohm's avatar
Moritz Strohm committed
        $this->course_id = Request::option('cid', $args[0] ?? null);
        $pagetitle = '';
        //Navigation in der Veranstaltung:
        if (Navigation::hasItem('/course/admin/room_requests')) {
            Navigation::activateItem('/course/admin/room_requests');
        }

        if (!get_object_type($this->course_id, ['sem']) ||
            SeminarCategories::GetBySeminarId($this->course_id)->studygroup_mode ||
            !$GLOBALS['perm']->have_studip_perm("tutor", $this->course_id)
        ) {
            throw new Trails_Exception(400);
        }

        PageLayout::setHelpKeyword('Basis.VeranstaltungenVerwaltenAendernVonZeitenUndTerminen');
        $pagetitle .= Course::find($this->course_id)->getFullName() . ' - ';
        $pagetitle .= _('Verwalten von Raumanfragen');
        PageLayout::setTitle($pagetitle);
Michaela Brückner's avatar
Michaela Brückner committed

        $this->available_room_categories = ResourceCategory::findByClass_name(Room::class);
        $this->step = 0;
        $this->max_preparation_time = Config::get()->RESOURCES_MAX_PREPARATION_TIME;
    }

    /**
     * Display the list of room requests
     */
    public function index_action()
    {
        if (!Config::get()->RESOURCES_ALLOW_ROOM_REQUESTS) {
            throw new AccessDeniedException(
                _('Das Erstellen von Raumanfragen ist nicht erlaubt!')
            );
        }
        $this->url_params = [];
        if (Request::get('origin') !== null) {
            $this->url_params['origin'] = Request::get('origin');
        }

        $this->room_requests = RoomRequest::findBySQL(
            'course_id = :course_id
            ORDER BY course_id, metadate_id, termin_id',
            [
                'course_id' => $this->course_id
            ]
        );
        $this->request_id = Request::option('request_id');

        $actions = new ActionsWidget();
        $actions->addLink(
            _('Neue Raumanfrage erstellen'),
            $this->url_for('course/room_requests/new'),
            Icon::create('add', 'clickable')
        );
        Sidebar::get()->addWidget($actions);

        if ($GLOBALS['perm']->have_studip_perm('admin', $this->course_id)) {
            $widget = new CourseManagementSelectWidget();
            Sidebar::Get()->addWidget($widget);
        }
    }


    /**
     * Show information about a request
     *
     * @param String $request_id Id of the request
     */
    public function info_action($request_id)
    {
        $request = RoomRequest::find($request_id);
        $this->request = $request;
        $this->render_template('course/room_requests/_request.php', null);
    }

    /**
Michaela Brückner's avatar
Michaela Brückner committed
     * Start point to creating a new request
Michaela Brückner's avatar
Michaela Brückner committed
    public function new_request_action($request_id = '')
    {
        if (!Config::get()->RESOURCES_ALLOW_ROOM_REQUESTS) {
            throw new AccessDeniedException(
                _('Das Erstellen von Raumanfragen ist nicht erlaubt!')
            );
        }

Michaela Brückner's avatar
Michaela Brückner committed
        Helpbar::get()->addPlainText(
            _('Information'),
            _('Hier können Sie Angaben zu gewünschten Raumeigenschaften machen.')
        );
Michaela Brückner's avatar
Michaela Brückner committed
        $this->request_id = $request_id;
Michaela Brückner's avatar
Michaela Brückner committed
        if (Request::submitted('request_id')) {
            $this->request_id = Request::get('request_id');
        }
        if (!$this->request_id) {
            $this->request_id = md5(uniqid('RoomRequest'));
Michaela Brückner's avatar
Michaela Brückner committed
        // e.g. cycle, course, date
        $this->request_range = Request::get('range_str');
Michaela Brückner's avatar
Michaela Brückner committed
        // 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());

David Siegfried's avatar
David Siegfried committed
        $this->init_session();
Michaela Brückner's avatar
Michaela Brückner committed
        $_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];
Michaela Brückner's avatar
Michaela Brückner committed
        // 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();
Michaela Brückner's avatar
Michaela Brückner committed
     * Step 1: Either selecting a room category or searching for a room name initially
     * @param String $request_id ID of the request
Michaela Brückner's avatar
Michaela Brückner committed
    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!')
            );
        }

        $this->request_id = $request_id;

Michaela Brückner's avatar
Michaela Brückner committed
        if (Request::isPost()) {
            CSRFProtection::verifyUnsafeRequest();
Michaela Brückner's avatar
Michaela Brückner committed
            $this->step = 1;
Michaela Brückner's avatar
Michaela Brückner committed
            $this->category_id = Request::get('category_id');
            $this->search_by_category = Request::submitted('search_by_category');
            if (!isset($_SESSION[$request_id])) {
                $_SESSION[$request_id] = [];
Michaela Brückner's avatar
Michaela Brückner committed
            $_SESSION[$request_id]['room_category_id'] = $this->category_id;
            $this->room_name = Request::get('room_name');
Michaela Brückner's avatar
Michaela Brückner committed
            $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(
Michaela Brückner's avatar
Michaela Brückner committed
                    'course/room_requests/request_find_available_properties/' . $this->request_id . '/' . $this->step . '/category'
Michaela Brückner's avatar
Michaela Brückner committed
            } 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
Michaela Brückner's avatar
Michaela Brückner committed
    }
Michaela Brückner's avatar
Michaela Brückner committed
     * 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
Michaela Brückner's avatar
Michaela Brückner committed
    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!')
            );
        }
        $this->request_id = $request_id;
Michaela Brückner's avatar
Michaela Brückner committed
        $this->step = (int)$step;
        $this->room_name = $_SESSION[$request_id]['room_name'];
Michaela Brückner's avatar
Michaela Brückner committed
        $this->request = new RoomRequest($this->request_id);
        $this->request->setRangeFields($_SESSION[$this->request_id]['range'], $_SESSION[$this->request_id]['range_ids'] ?? []);
Michaela Brückner's avatar
Michaela Brückner committed

        $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'];
Michaela Brückner's avatar
Michaela Brückner committed
        if (!empty($search_properties['seats'])) {
            //The seats property value is a minimum.
            $search_properties['seats'] = [
                $search_properties['seats'],
                null
            ];
Michaela Brückner's avatar
Michaela Brückner committed
        // 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);

Jan-Hendrik Willms's avatar
Jan-Hendrik Willms committed
        $this->selected_room_category_id = $this->selected_room->category_id ?? $_SESSION[$request_id]['room_category_id'] ?? null;
        $this->category = $this->selected_room_category_id ? ResourceCategory::find($this->selected_room_category_id) : null;
Jan-Hendrik Willms's avatar
Jan-Hendrik Willms committed
        $_SESSION[$request_id]['room_category_id'] = $_SESSION[$request_id]['room_category_id'] ?? $this->selected_room->category_id ?? null;
Michaela Brückner's avatar
Michaela Brückner committed

        // 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');
David Siegfried's avatar
David Siegfried committed
            $room = Room::find($this->selected_room_id);
Michaela Brückner's avatar
Michaela Brückner committed
            $_SESSION[$request_id]['room_id'] = $this->selected_room_id;
David Siegfried's avatar
David Siegfried committed
            $_SESSION[$request_id]['room_category_id'] = $room->category_id;
Michaela Brückner's avatar
Michaela Brückner committed
            $_SESSION[$request_id]['select_room'] = true;
            $this->redirect(
                'course/room_requests/request_check_properties/' . $this->request_id
Michaela Brückner's avatar
Michaela Brückner committed
        // 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;
        }
        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')) {
David Siegfried's avatar
David Siegfried committed
            $this->init_session();
            $this->redirect('course/room_requests/new_request');
Michaela Brückner's avatar
Michaela Brückner committed
            return;
Michaela Brückner's avatar
Michaela Brückner committed
        // for step 2: after choosing a specific room OR searching via properties
        if ($this->step === 2) {
David Siegfried's avatar
David Siegfried committed
            if (!empty(Request::getArray('selected_properties'))) {
Michaela Brückner's avatar
Michaela Brückner committed
                $this->selected_properties = Request::getArray('selected_properties');
David Siegfried's avatar
David Siegfried committed
            } else {
                $this->selected_properties =  $_SESSION[$request_id]['selected_properties'];
David Siegfried's avatar
David Siegfried committed
            $_SESSION[$request_id]['selected_properties'] = $this->selected_properties;
David Siegfried's avatar
David Siegfried committed
            if ($_SESSION[$request_id]['search_by'] === 'roomname') {
                $this->selected_properties = $_SESSION[$request_id]['selected_properties'] ?? null;
                $this->room = Room::find($_SESSION[$request_id]['room_id']);
                if (!isset($_SESSION[$request_id]['selected_properties']['seats'])) {
                    $this->selected_properties['seats'] = $this->course->admission_turnout ?? Config::get()->RESOURCES_ROOM_REQUEST_DEFAULT_SEATS;
                }
                $_SESSION[$request_id]['selected_properties']['seats'] = $this->selected_properties['seats'];
                $_SESSION[$request_id]['room_category_id'] = $this->selected_room_category_id;
            } else {
                // let's find all the properties belonging to the selected category
                $this->room_category_id = $_SESSION[$request_id]['room_category_id'];
            }
David Siegfried's avatar
David Siegfried committed
            if ($this->category) {
                $this->available_properties = $this->category->getRequestableProperties();
            }
Jan-Hendrik Willms's avatar
Jan-Hendrik Willms committed
            $this->preparation_time = $_SESSION[$request_id]['preparation_time'] ?? null;
            $this->comment = $_SESSION[$request_id]['comment'] ?? null;
Michaela Brückner's avatar
Michaela Brückner committed
            $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;
David Siegfried's avatar
David Siegfried committed
                $room = Room::find($this->selected_room_id);
                if ($room) {
                    $_SESSION[$request_id]['room_category_id'] = $room->category_id;
                }
Michaela Brückner's avatar
Michaela Brückner committed
                $this->redirect('course/room_requests/request_show_summary/' . $this->request_id );
            }
Michaela Brückner's avatar
Michaela Brückner committed
     * 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
Michaela Brückner's avatar
Michaela Brückner committed
    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!')
            );
        }
        $this->request_id = $request_id;
Michaela Brückner's avatar
Michaela Brückner committed
        $this->step = (int)$step;
Michaela Brückner's avatar
Michaela Brückner committed
        $this->request = new RoomRequest($this->request_id);
Jan-Hendrik Willms's avatar
Jan-Hendrik Willms committed
        $this->request->setRangeFields(
            $_SESSION[$this->request_id]['range'] ?? null,
            $_SESSION[$this->request_id]['range_ids'] ?? null
        );
Michaela Brückner's avatar
Michaela Brückner committed
        // 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;
Jan-Hendrik Willms's avatar
Jan-Hendrik Willms committed
        $this->room_name = $_SESSION[$request_id]['room_name'] ?? '';
Michaela Brückner's avatar
Michaela Brückner committed
        $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'] ?? [];
Michaela Brückner's avatar
Michaela Brückner committed

        $this->course = Course::find($this->course_id);
        $this->selected_properties['seats'] = $_SESSION[$request_id]['selected_properties']['seats']
Jan-Hendrik Willms's avatar
Jan-Hendrik Willms committed
            ?? $this->course->admission_turnout
Michaela Brückner's avatar
Michaela Brückner committed
            ?: Config::get()->RESOURCES_ROOM_REQUEST_DEFAULT_SEATS;

Jan-Hendrik Willms's avatar
Jan-Hendrik Willms committed
        $this->preparation_time = $_SESSION[$request_id]['preparation_time'] ?? null;
        $this->comment = $_SESSION[$request_id]['comment'] ?? null;
Michaela Brückner's avatar
Michaela Brückner committed

        // when searching for a room name, list found room
Jan-Hendrik Willms's avatar
Jan-Hendrik Willms committed
        if (
            isset($_SESSION[$request_id]['room_name'])
            && $_SESSION[$request_id]['room_name'] !== ''
        ) {
Michaela Brückner's avatar
Michaela Brückner committed
            $search_properties['room_category_id'] = $this->room_category_id;
            $search_properties['seats'] = [
Michaela Brückner's avatar
Michaela Brückner committed
                1,
Michaela Brückner's avatar
Michaela Brückner committed

            $this->available_rooms = RoomManager::findRooms(
                $this->room_name,
                null,
                null,
                $search_properties,
                'name ASC, mkdate ASC'
            );
Michaela Brückner's avatar
Michaela Brückner committed

            // small icons in front of room name to show whether they are bookable or not
            $this->available_room_icons = $this->getRoomBookingIcons($this->available_rooms);
Michaela Brückner's avatar
Michaela Brückner committed
    }
Michaela Brückner's avatar
Michaela Brückner committed
    /**
     * 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!')
            );
        }
Michaela Brückner's avatar
Michaela Brückner committed
        $this->request_id = $request_id;
David Siegfried's avatar
David Siegfried committed
        $this->selected_properties = Request::getArray('selected_properties');
Michaela Brückner's avatar
Michaela Brückner committed
        // 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');
David Siegfried's avatar
David Siegfried committed
            $room = Room::find($this->selected_room_id);
Michaela Brückner's avatar
Michaela Brückner committed
            $_SESSION[$request_id]['room_id'] = $this->selected_room_id;
David Siegfried's avatar
David Siegfried committed
            $_SESSION[$request_id]['room_category_id'] = $room->category_id;
Michaela Brückner's avatar
Michaela Brückner committed
            $_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->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->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(
Michaela Brückner's avatar
Michaela Brückner committed
                    'course/room_requests/request_find_available_properties/' . $request_id . '/1/category'
Michaela Brückner's avatar
Michaela Brückner committed
            } 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
Michaela Brückner's avatar
Michaela Brückner committed
            }
        } else if (Request::submitted('reset_category')) {
            //Delete all selected properties from the session since the category is reset
David Siegfried's avatar
David Siegfried committed
            $this->init_session();
Michaela Brückner's avatar
Michaela Brückner committed
            $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');
            }
Michaela Brückner's avatar
Michaela Brückner committed
            $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_room_id = Request::get('selected_room_id');
David Siegfried's avatar
David Siegfried committed
            $room = Room::find($this->selected_room_id);
Michaela Brückner's avatar
Michaela Brückner committed
            $_SESSION[$request_id]['room_id'] = $this->selected_room_id;
David Siegfried's avatar
David Siegfried committed
            $_SESSION[$request_id]['room_category_id'] = $room->category_id ?? $_SESSION[$request_id]['room_category_id'];
David Siegfried's avatar
David Siegfried committed
            $_SESSION[$request_id]['selected_properties'] = $this->selected_properties;
Michaela Brückner's avatar
Michaela Brückner committed
            $this->redirect('course/room_requests/request_show_summary/' . $this->request_id  );
        } else {
            $room = Room::find($_SESSION[$request_id]['room_id']);
Michaela Brückner's avatar
Michaela Brückner committed
            $this->step = 2;
            $this->request = new RoomRequest($this->request_id);
            $_SESSION[$request_id]['room_category_id'] = $room->category_id;
Michaela Brückner's avatar
Michaela Brückner committed
            $this->redirect(
                'course/room_requests/request_find_matching_rooms/' . $this->request_id . '/' . $this->step
            );
Michaela Brückner's avatar
Michaela Brückner committed
    }
Michaela Brückner's avatar
Michaela Brückner committed
     * 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
     *
Michaela Brückner's avatar
Michaela Brückner committed
    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!')
            );
        }

        $this->request_id = $request_id;
Michaela Brückner's avatar
Michaela Brückner committed
        $this->step = 3;

        if (Request::submitted('clear_cache')) {
Michaela Brückner's avatar
Michaela Brückner committed
            $_SESSION[$request_id] = [];
Michaela Brückner's avatar
Michaela Brückner committed
        $this->request = new RoomRequest($this->request_id);
Jan-Hendrik Willms's avatar
Jan-Hendrik Willms committed
        $this->request->setRangeFields(
            $_SESSION[$this->request_id]['range'] ?? '',
            $_SESSION[$this->request_id]['range_ids'] ?? []
        );
Jan-Hendrik Willms's avatar
Jan-Hendrik Willms committed
        $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);
Jan-Hendrik Willms's avatar
Jan-Hendrik Willms committed
        $this->room_id = $_SESSION[$request_id]['room_id'] ?? $this->request->resource_id;
Michaela Brückner's avatar
Michaela Brückner committed
        $this->available_properties = $this->selected_room_category->getRequestableProperties();

Jan-Hendrik Willms's avatar
Jan-Hendrik Willms committed
        $this->selected_properties = $_SESSION[$request_id]['selected_properties'] ?? [];
Michaela Brückner's avatar
Michaela Brückner committed
        $this->request_properties = $this->request->properties;

        // either properties from stored request or those from session
Jan-Hendrik Willms's avatar
Jan-Hendrik Willms committed
        if ($this->request_properties && empty($_SESSION[$request_id]['selected_properties'])) {
Michaela Brückner's avatar
Michaela Brückner committed
            foreach ($this->request_properties as $property) {
                $this->selected_properties[$property->name] = $property->state;
Michaela Brückner's avatar
Michaela Brückner committed
            $_SESSION[$request_id]['selected_properties'] = $this->selected_properties;
Michaela Brückner's avatar
Michaela Brückner committed
        $this->preparation_time = intval($this->request->preparation_time / 60);
Jan-Hendrik Willms's avatar
Jan-Hendrik Willms committed
        $this->reply_lecturers = $this->request->reply_recipients === ResourceRequest::REPLY_LECTURER;
Michaela Brückner's avatar
Michaela Brückner committed
        $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 ? $this->selected_room->id : '';
Michaela Brückner's avatar
Michaela Brückner committed
    }

    public function store_request_action($request_id)
    {
        if (!Config::get()->RESOURCES_ALLOW_ROOM_REQUESTS) {
            throw new AccessDeniedException(
                _('Das Erstellen von Raumanfragen ist nicht erlaubt!')
            );
Michaela Brückner's avatar
Michaela Brückner committed
        $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();

Michaela Brückner's avatar
Michaela Brückner committed
            $this->request->user_id = $this->current_user->id;
David Siegfried's avatar
David Siegfried committed
            $this->preparation_time = Request::int('preparation_time', 0);
Michaela Brückner's avatar
Michaela Brückner committed
            $this->request->preparation_time = $this->preparation_time * 60;
            $this->request->comment = Request::get('comment');
Michaela Brückner's avatar
Michaela Brückner committed
            if (Request::get('reply_lecturers')) {
Jan-Hendrik Willms's avatar
Jan-Hendrik Willms committed
                $this->request->reply_recipients = ResourceRequest::REPLY_LECTURER;
Michaela Brückner's avatar
Michaela Brückner committed
            } else {
Jan-Hendrik Willms's avatar
Jan-Hendrik Willms committed
                $this->request->reply_recipients = ResourceRequest::REPLY_REQUESTER;
Michaela Brückner's avatar
Michaela Brückner committed
            }
            $this->request->category_id = $_SESSION[$request_id]['room_category_id'] ?: $this->request->category_id;
Michaela Brückner's avatar
Michaela Brückner committed
            $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;
Michaela Brückner's avatar
Michaela Brückner committed
            $this->request->store();
Michaela Brückner's avatar
Michaela Brückner committed
            //Store the properties:
            foreach ($_SESSION[$request_id]['selected_properties'] as $name => $state) {
                if (!empty($state)) {
                    $this->request->setProperty($name, $state);
                }
Michaela Brückner's avatar
Michaela Brückner committed
            }
Michaela Brückner's avatar
Michaela Brückner committed
            // once stored, we can delete the session data for this request
            $_SESSION[$this->request_id] = [];
Michaela Brückner's avatar
Michaela Brückner committed
            PageLayout::postSuccess(_('Die Anfrage wurde gespeichert!'));
            $this->relocate('course/timesrooms/');
Michaela Brückner's avatar
Michaela Brückner committed
     * Store a request and its properties
     * @param string $request ID of the request
     * @param array $properties desired properties
     * @return void
Michaela Brückner's avatar
Michaela Brückner committed
    private function storeRequest($request, $properties)
Michaela Brückner's avatar
Michaela Brückner committed
        // once stored, we can delete the session data for this request
        $request->store();
        $_SESSION[$request->id] = [];
Michaela Brückner's avatar
Michaela Brückner committed
        //Store the properties:
        foreach ($properties as $name => $state) {
            $request->setProperty($name, $state);
        }
Michaela Brückner's avatar
Michaela Brückner committed
    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
     */
    public function delete_action($request_id)
    {
        $request = RoomRequest::find($request_id);
        if (!$request) {
            throw new Trails_Exception(403);
        }
        if (Request::isGet()) {
            PageLayout::postQuestion(sprintf(
                _('Möchten Sie die Raumanfrage "%s" löschen?'),
                htmlReady($request->getTypeString())), $this->url_for('course/room_requests/delete/' . $request_id));
        } else {
            CSRFProtection::verifyUnsafeRequest();
            if (Request::submitted('yes')) {
                if ($request->delete()) {
                    PageLayout::postSuccess("Die Raumanfrage wurde gelöscht.");
                }
            }
        }
Michaela Brückner's avatar
Michaela Brückner committed
        $this->redirect('course/timesrooms/index');
David Siegfried's avatar
David Siegfried committed

    private function init_session()
    {
        $_SESSION[$this->request_id] = array_merge(
            $_SESSION[$this->request_id] ?? [],
            [
                'search_by'           => '',
                'room_category_id'    => '',
                'room_id'             => '',
                'room_name'           => '',
                'select_room'         => false,
                'selected_properties' => [],
            ]
        );
    }