diff --git a/application/controllers/LvPlanCSVDownload.php b/application/controllers/LvPlanCSVDownload.php index bffaa8240..42900b5c1 100644 --- a/application/controllers/LvPlanCSVDownload.php +++ b/application/controllers/LvPlanCSVDownload.php @@ -19,6 +19,8 @@ class LvPlanCSVDownload extends Auth_Controller ]); $this->load->model('person/Benutzer_model', 'BenutzerModel'); + $this->load->model('ressource/Ort_model', 'OrtModel'); + $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); } /** @@ -29,20 +31,31 @@ class LvPlanCSVDownload extends Auth_Controller public function index() { $type = $this->getType(); - $uid = $this->getUid(); + $uid = getAuthUID(); + $ortKurzbz = null; + $verbandFilters = null; + if ($type === 'ort') + $ortKurzbz = $this->getRoom(); + elseif ($type === 'verband') + $verbandFilters = $this->getVerbandFilters(); + else + { + $uid = $this->getUid(); + $this->authorizeUid($uid); + $this->validateUid($uid); + } $target = $this->getTarget(); list($begin, $ende) = $this->getDateRange(); - $this->authorizeUid($uid); - $this->validateUid($uid); - $this->load->library('LvPlanCSVLib'); $content = $this->lvplancsvlib->getContent( $uid, $begin, $ende, $type, - $target + $target, + $ortKurzbz, + $verbandFilters ); $filename = 'FH-Kalender_'.date('m_Y', $begin); @@ -65,7 +78,7 @@ class LvPlanCSVDownload extends Auth_Controller { $type = $this->input->get('type', true); - if (!in_array($type, array('student', 'lektor'), true)) + if (!in_array($type, array('student', 'lektor', 'ort', 'verband'), true)) show_error('Ungueltiger Parameter: type', 400); return $type; @@ -84,6 +97,80 @@ class LvPlanCSVDownload extends Auth_Controller return $uid; } + /** + * @return string Requested room identifier. + */ + private function getRoom() + { + $ortKurzbz = $this->input->get('ort_kurzbz', true); + if (!is_string($ortKurzbz) || $ortKurzbz === '' || !check_utf8($ortKurzbz)) + show_error('Ungueltiger Parameter: ort_kurzbz', 400); + + $this->OrtModel->addSelect('ort_kurzbz'); + $room = $this->OrtModel->load($ortKurzbz); + if (isError($room)) + show_error(getError($room), 500); + if (!hasData($room)) + show_error('Ungueltiger Parameter: ort_kurzbz', 400); + + return $ortKurzbz; + } + + /** + * @return array Requested Lehrverband filters. + */ + private function getVerbandFilters() + { + $stgKz = $this->getInteger('stg_kz', true); + $semester = $this->getInteger('sem', false); + $verband = $this->getOptionalFilter('ver'); + $gruppe = $this->getOptionalFilter('grp'); + + $this->StudiengangModel->addSelect('studiengang_kz'); + $studiengang = $this->StudiengangModel->load($stgKz); + if (isError($studiengang)) + show_error(getError($studiengang), 500); + if (!hasData($studiengang)) + show_error('Ungueltiger Parameter: stg_kz', 400); + + return array( + 'stg_kz' => $stgKz, + 'sem' => $semester, + 'ver' => $verband, + 'grp' => $gruppe + ); + } + + private function getInteger($name, $signed) + { + $value = $this->input->get($name, true); + $pattern = $signed ? '/^-?\d+$/' : '/^\d+$/'; + if (!is_string($value) || !preg_match($pattern, $value)) + show_error('Ungueltiger Parameter: '.$name, 400); + + $integer = filter_var($value, FILTER_VALIDATE_INT); + if ($integer === false || (!$signed && $integer < 0)) + show_error('Ungueltiger Parameter: '.$name, 400); + + return $integer; + } + + private function getOptionalFilter($name) + { + $value = $this->input->get($name, true); + if ($value === null || $value === '' || $value === '0') + return null; + if (!is_string($value) + || !check_utf8($value) + || mb_strlen($value) > 20 + || !preg_match('/^[[:alnum:]_-]+$/u', $value)) + { + show_error('Ungueltiger Parameter: '.$name, 400); + } + + return $value; + } + /** * @return string|null Requested CSV target. */ diff --git a/application/controllers/LvPlanExcelDownload.php b/application/controllers/LvPlanExcelDownload.php index 2796eefaf..fb71a64e3 100644 --- a/application/controllers/LvPlanExcelDownload.php +++ b/application/controllers/LvPlanExcelDownload.php @@ -19,6 +19,8 @@ class LvPlanExcelDownload extends Auth_Controller ]); $this->load->model('person/Benutzer_model', 'BenutzerModel'); + $this->load->model('ressource/Ort_model', 'OrtModel'); + $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); } /** @@ -29,18 +31,29 @@ class LvPlanExcelDownload extends Auth_Controller public function index() { $type = $this->getType(); - $uid = $this->getUid(); + $uid = getAuthUID(); + $ortKurzbz = null; + $verbandFilters = null; + if ($type === 'ort') + $ortKurzbz = $this->getRoom(); + elseif ($type === 'verband') + $verbandFilters = $this->getVerbandFilters(); + else + { + $uid = $this->getUid(); + $this->authorizeUid($uid); + $this->validateUid($uid); + } list($begin, $ende) = $this->getDateRange(); - $this->authorizeUid($uid); - $this->validateUid($uid); - $this->load->library('LvPlanExcelLib'); $content = $this->lvplanexcellib->getContent( $uid, $begin, $ende, - $type + $type, + $ortKurzbz, + $verbandFilters ); $filename = 'FH-Kalender_'.date('m_Y', $begin).'.xls'; @@ -60,7 +73,7 @@ class LvPlanExcelDownload extends Auth_Controller { $type = $this->input->get('type', true); - if (!in_array($type, array('student', 'lektor'), true)) + if (!in_array($type, array('student', 'lektor', 'ort', 'verband'), true)) show_error('Ungueltiger Parameter: type', 400); return $type; @@ -79,6 +92,80 @@ class LvPlanExcelDownload extends Auth_Controller return $uid; } + /** + * @return string Requested room identifier. + */ + private function getRoom() + { + $ortKurzbz = $this->input->get('ort_kurzbz', true); + if (!is_string($ortKurzbz) || $ortKurzbz === '' || !check_utf8($ortKurzbz)) + show_error('Ungueltiger Parameter: ort_kurzbz', 400); + + $this->OrtModel->addSelect('ort_kurzbz'); + $room = $this->OrtModel->load($ortKurzbz); + if (isError($room)) + show_error(getError($room), 500); + if (!hasData($room)) + show_error('Ungueltiger Parameter: ort_kurzbz', 400); + + return $ortKurzbz; + } + + /** + * @return array Requested Lehrverband filters. + */ + private function getVerbandFilters() + { + $stgKz = $this->getInteger('stg_kz', true); + $semester = $this->getInteger('sem', false); + $verband = $this->getOptionalFilter('ver'); + $gruppe = $this->getOptionalFilter('grp'); + + $this->StudiengangModel->addSelect('studiengang_kz'); + $studiengang = $this->StudiengangModel->load($stgKz); + if (isError($studiengang)) + show_error(getError($studiengang), 500); + if (!hasData($studiengang)) + show_error('Ungueltiger Parameter: stg_kz', 400); + + return array( + 'stg_kz' => $stgKz, + 'sem' => $semester, + 'ver' => $verband, + 'grp' => $gruppe + ); + } + + private function getInteger($name, $signed) + { + $value = $this->input->get($name, true); + $pattern = $signed ? '/^-?\d+$/' : '/^\d+$/'; + if (!is_string($value) || !preg_match($pattern, $value)) + show_error('Ungueltiger Parameter: '.$name, 400); + + $integer = filter_var($value, FILTER_VALIDATE_INT); + if ($integer === false || (!$signed && $integer < 0)) + show_error('Ungueltiger Parameter: '.$name, 400); + + return $integer; + } + + private function getOptionalFilter($name) + { + $value = $this->input->get($name, true); + if ($value === null || $value === '' || $value === '0') + return null; + if (!is_string($value) + || !check_utf8($value) + || mb_strlen($value) > 20 + || !preg_match('/^[[:alnum:]_-]+$/u', $value)) + { + show_error('Ungueltiger Parameter: '.$name, 400); + } + + return $value; + } + /** * Validates and expands the requested range to complete weeks. * diff --git a/application/controllers/LvPlanHTMLPreview.php b/application/controllers/LvPlanHTMLPreview.php index d249951f7..899a25e59 100644 --- a/application/controllers/LvPlanHTMLPreview.php +++ b/application/controllers/LvPlanHTMLPreview.php @@ -19,7 +19,9 @@ class LvPlanHTMLPreview extends Auth_Controller ]); $this->load->model('person/Benutzer_model', 'BenutzerModel'); + $this->load->model('crm/Student_model', 'StudentModel'); $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); + $this->load->model('ressource/Ort_model', 'OrtModel'); } /** @@ -31,9 +33,12 @@ class LvPlanHTMLPreview extends Auth_Controller { $type = $this->getType(); list($begin, $ende) = $this->getDateRange(); - $filters = $type === 'verband' - ? $this->getVerbandFilters() - : $this->getPersonalFilters(); + if ($type === 'verband') + $filters = $this->getVerbandFilters(); + elseif ($type === 'ort') + $filters = $this->getRoomFilters(); + else + $filters = $this->getPersonalFilters($type); $this->load->library('LvPlanHTMLLib'); $content = $this->lvplanhtmllib->getContent( @@ -56,7 +61,7 @@ class LvPlanHTMLPreview extends Auth_Controller { $type = $this->input->get('type', true); - if (!in_array($type, array('student', 'lektor', 'verband'), true)) + if (!in_array($type, array('student', 'lektor', 'verband', 'ort'), true)) show_error('Ungueltiger Parameter: type', 400); return $type; @@ -65,8 +70,10 @@ class LvPlanHTMLPreview extends Auth_Controller /** * @return array Personal preview filters. */ - private function getPersonalFilters() + private function getPersonalFilters($type) { + // Legacy wochenplan calendar links include empty Lehrverband parameters + // for personal plans. They are irrelevant when type is student or lektor. if ($this->hasVerbandParameters()) show_error('Ungueltige Parameterkombination', 400); @@ -80,15 +87,81 @@ class LvPlanHTMLPreview extends Auth_Controller show_error('Forbidden', 403); } - $this->BenutzerModel->addSelect('uid'); + $this->BenutzerModel->addSelect( + 'tbl_benutzer.uid, tbl_person.titelpre, tbl_person.vorname, ' + .'tbl_person.nachname, tbl_person.titelpost' + ); + $this->BenutzerModel->addJoin('public.tbl_person', 'person_id', 'LEFT'); $user = $this->BenutzerModel->load(array($uid)); if (isError($user)) show_error(getError($user), 500); if (!hasData($user)) show_error('Ungueltiger Parameter: pers_uid', 400); + $users = getData($user); + $userData = reset($users); + $nameParts = array(); + foreach (array('titelpre', 'vorname', 'nachname', 'titelpost') as $property) + { + if (isset($userData->{$property}) && trim($userData->{$property}) !== '') + $nameParts[] = trim($userData->{$property}); + } - return array('uid' => $uid); + $filters = array( + 'uid' => $uid, + 'full_name' => implode(' ', $nameParts) + ); + + if ($type === 'student') + { + $this->StudentModel->addSelect( + 'studiengang_kz, semester, verband, gruppe' + ); + $student = $this->StudentModel->load(array($uid)); + + if (isError($student)) + show_error(getError($student), 500); + if (!hasData($student)) + show_error('Ungueltiger Parameter: pers_uid', 400); + + $students = getData($student); + $studentData = reset($students); + $filters['stg_kz'] = $studentData->studiengang_kz; + $filters['sem'] = $studentData->semester; + $filters['ver'] = $studentData->verband; + $filters['grp'] = $studentData->gruppe; + } + + return $filters; + } + + /** + * Legacy room links also carry pers_uid, but the UID does not filter or + * authorize a room plan. Only ort_kurzbz identifies the requested plan. + * + * @return array Room preview filters. + */ + private function getRoomFilters() + { + $ortKurzbz = $this->input->get('ort_kurzbz', true); + if (!is_string($ortKurzbz) || $ortKurzbz === '' || !check_utf8($ortKurzbz)) + show_error('Ungueltiger Parameter: ort_kurzbz', 400); + + $this->OrtModel->addSelect('ort_kurzbz, bezeichnung'); + $room = $this->OrtModel->load($ortKurzbz); + + if (isError($room)) + show_error(getError($room), 500); + if (!hasData($room)) + show_error('Ungueltiger Parameter: ort_kurzbz', 400); + + $rooms = getData($room); + $roomData = reset($rooms); + + return array( + 'ort_kurzbz' => $ortKurzbz, + 'bezeichnung' => isset($roomData->bezeichnung) ? $roomData->bezeichnung : '' + ); } /** @@ -96,24 +169,30 @@ class LvPlanHTMLPreview extends Auth_Controller */ private function getVerbandFilters() { - if ($this->input->get('pers_uid', true) !== null) - show_error('Ungueltige Parameterkombination', 400); - + // Legacy wochenplan links always carry pers_uid. It does not filter or + // authorize a Lehrverband plan and is intentionally ignored here. $stgKz = $this->getInteger('stg_kz', true); $semester = $this->getInteger('sem', false); $verband = $this->getOptionalFilter('ver'); $gruppe = $this->getOptionalFilter('grp'); - $this->StudiengangModel->addSelect('studiengang_kz'); + $this->StudiengangModel->addSelect( + 'studiengang_kz, UPPER(typ || kurzbz) AS stg_kurzbz' + ); $studiengang = $this->StudiengangModel->load($stgKz); if (isError($studiengang)) show_error(getError($studiengang), 500); if (!hasData($studiengang)) show_error('Ungueltiger Parameter: stg_kz', 400); + $studiengaenge = getData($studiengang); + $studiengangData = reset($studiengaenge); return array( 'stg_kz' => $stgKz, + 'stg_kurzbz' => isset($studiengangData->stg_kurzbz) + ? $studiengangData->stg_kurzbz + : '', 'sem' => $semester, 'ver' => $verband, 'grp' => $gruppe @@ -121,13 +200,14 @@ class LvPlanHTMLPreview extends Auth_Controller } /** - * @return bool Whether any Lehrverband-only parameters were supplied. + * @return bool Whether any non-empty Lehrverband-only parameters were supplied. */ private function hasVerbandParameters() { foreach (array('stg_kz', 'sem', 'ver', 'grp') as $name) { - if ($this->input->get($name, true) !== null) + $value = $this->input->get($name, true); + if ($value !== null && $value !== '') return true; } diff --git a/application/controllers/LvPlanICALDownload.php b/application/controllers/LvPlanICALDownload.php index d1ca022ca..6a9375220 100644 --- a/application/controllers/LvPlanICALDownload.php +++ b/application/controllers/LvPlanICALDownload.php @@ -19,6 +19,8 @@ class LvPlanICALDownload extends Auth_Controller ]); $this->load->model('person/Benutzer_model', 'BenutzerModel'); + $this->load->model('ressource/Ort_model', 'OrtModel'); + $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); } /** @@ -29,20 +31,31 @@ class LvPlanICALDownload extends Auth_Controller public function index() { $type = $this->getType(); - $uid = $this->getUid(); + $uid = getAuthUID(); + $ortKurzbz = null; + $verbandFilters = null; + if ($type === 'ort') + $ortKurzbz = $this->getRoom(); + elseif ($type === 'verband') + $verbandFilters = $this->getVerbandFilters(); + else + { + $uid = $this->getUid(); + $this->authorizeUid($uid); + $this->validateUid($uid); + } $version = $this->getVersion(); list($begin, $ende) = $this->getDateRange(); - $this->authorizeUid($uid); - $this->validateUid($uid); - $this->load->library('LvPlanICALLib'); $content = $this->lvplanicallib->getContent( $uid, $begin, $ende, $type, - $version + $version, + $ortKurzbz, + $verbandFilters ); $filename = 'FH-Kalender_'.date('m_Y', $begin).'_ical'.$version.'.ics'; @@ -62,7 +75,7 @@ class LvPlanICALDownload extends Auth_Controller { $type = $this->input->get('type', true); - if (!in_array($type, array('student', 'lektor'), true)) + if (!in_array($type, array('student', 'lektor', 'ort', 'verband'), true)) show_error('Ungueltiger Parameter: type', 400); return $type; @@ -81,6 +94,80 @@ class LvPlanICALDownload extends Auth_Controller return $uid; } + /** + * @return string Requested room identifier. + */ + private function getRoom() + { + $ortKurzbz = $this->input->get('ort_kurzbz', true); + if (!is_string($ortKurzbz) || $ortKurzbz === '' || !check_utf8($ortKurzbz)) + show_error('Ungueltiger Parameter: ort_kurzbz', 400); + + $this->OrtModel->addSelect('ort_kurzbz'); + $room = $this->OrtModel->load($ortKurzbz); + if (isError($room)) + show_error(getError($room), 500); + if (!hasData($room)) + show_error('Ungueltiger Parameter: ort_kurzbz', 400); + + return $ortKurzbz; + } + + /** + * @return array Requested Lehrverband filters. + */ + private function getVerbandFilters() + { + $stgKz = $this->getInteger('stg_kz', true); + $semester = $this->getInteger('sem', false); + $verband = $this->getOptionalFilter('ver'); + $gruppe = $this->getOptionalFilter('grp'); + + $this->StudiengangModel->addSelect('studiengang_kz'); + $studiengang = $this->StudiengangModel->load($stgKz); + if (isError($studiengang)) + show_error(getError($studiengang), 500); + if (!hasData($studiengang)) + show_error('Ungueltiger Parameter: stg_kz', 400); + + return array( + 'stg_kz' => $stgKz, + 'sem' => $semester, + 'ver' => $verband, + 'grp' => $gruppe + ); + } + + private function getInteger($name, $signed) + { + $value = $this->input->get($name, true); + $pattern = $signed ? '/^-?\d+$/' : '/^\d+$/'; + if (!is_string($value) || !preg_match($pattern, $value)) + show_error('Ungueltiger Parameter: '.$name, 400); + + $integer = filter_var($value, FILTER_VALIDATE_INT); + if ($integer === false || (!$signed && $integer < 0)) + show_error('Ungueltiger Parameter: '.$name, 400); + + return $integer; + } + + private function getOptionalFilter($name) + { + $value = $this->input->get($name, true); + if ($value === null || $value === '' || $value === '0') + return null; + if (!is_string($value) + || !check_utf8($value) + || mb_strlen($value) > 20 + || !preg_match('/^[[:alnum:]_-]+$/u', $value)) + { + show_error('Ungueltiger Parameter: '.$name, 400); + } + + return $value; + } + /** * @return int Requested iCalendar major version. */ diff --git a/application/controllers/system/MigrateKalender.php b/application/controllers/system/MigrateKalender.php index 2617ba286..49e895dbc 100644 --- a/application/controllers/system/MigrateKalender.php +++ b/application/controllers/system/MigrateKalender.php @@ -460,21 +460,6 @@ class MigrateKalender extends CLI_Controller } } - $rooms = is_array($block->orte_kurzbz) ? $block->orte_kurzbz : explode(',', $block->orte_kurzbz ?? ''); - foreach ($rooms as $room_kurzbz) - { - $room_kurzbz = trim($room_kurzbz); - if (!empty($room_kurzbz)) - { - $this->KalenderOrtModel->insert( - array ( - 'kalender_id' => $kalender_id, - 'ort_kurzbz' => $room_kurzbz - ) - ); - } - } - foreach ($block->svg_kombis as $kombi_str) { $kombi_str = trim($kombi_str, '()'); diff --git a/application/libraries/KalenderLib.php b/application/libraries/KalenderLib.php index a3afc8c87..5e6d917e8 100644 --- a/application/libraries/KalenderLib.php +++ b/application/libraries/KalenderLib.php @@ -299,6 +299,20 @@ class KalenderLib return $this->_mapEvents($data); } + /** + * Returns the published timetable for one room without collision checks. + */ + public function getPlanForRoom($start_date, $end_date, $ort) + { + $this->_getBasePlan($start_date, $end_date); + + $this->_ci->KalenderModel->db->where('tbl_kalender_ort.ort_kurzbz', $ort); + $this->_ci->KalenderModel->db->where('tbl_kalender.status_kurzbz', 'live'); + $data = $this->_ci->KalenderModel->load(); + + return $this->_mapEvents($data, false); + } + public function getForRaumvorschlag($start_date, $end_date, $lektor_uids = [], $gruppen_kurzbz = [], $lehrverband_gruppen = []) diff --git a/application/libraries/LvPlanCSVLib.php b/application/libraries/LvPlanCSVLib.php index 451dfadac..a59972ab9 100644 --- a/application/libraries/LvPlanCSVLib.php +++ b/application/libraries/LvPlanCSVLib.php @@ -62,16 +62,34 @@ class LvPlanCSVLib * @param string $uid User UID. * @param int $begin First included date as Unix timestamp. * @param int $ende Last included date as Unix timestamp. - * @param string $type Timetable type (student or lektor). + * @param string $type Timetable type (student, lektor, ort or verband). * @param string|null $target Optional CSV target (outlook). + * @param string|null $ortKurzbz Room identifier for room plans. + * @param array|null $verbandFilters Lehrverband filters. * @return string */ - public function getContent($uid, $begin, $ende, $type, $target = null) - { - if (!in_array($type, array('student', 'lektor'), true)) + public function getContent( + $uid, + $begin, + $ende, + $type, + $target = null, + $ortKurzbz = null, + $verbandFilters = null + ) { + if (!in_array($type, array('student', 'lektor', 'ort', 'verband'), true)) throw new InvalidArgumentException('Unsupported timetable type'); if ($target !== null && $target !== self::TARGET_OUTLOOK) throw new InvalidArgumentException('Unsupported CSV target'); + if ($type === 'ort' && (!is_string($ortKurzbz) || $ortKurzbz === '')) + throw new InvalidArgumentException('Missing room timetable filter'); + if ($type === 'verband' + && (!is_array($verbandFilters) + || !array_key_exists('stg_kz', $verbandFilters) + || !array_key_exists('sem', $verbandFilters))) + { + throw new InvalidArgumentException('Missing Lehrverband timetable filters'); + } $isLecturer = $type === 'lektor'; $this->ci->load->library('KalenderLib', array('uid' => $uid)); @@ -79,7 +97,23 @@ class LvPlanCSVLib $startDate = date('Y-m-d', $begin); $endDate = date('Y-m-d', $ende); - if ($isLecturer) + if ($type === 'verband') + { + $events = $this->ci->kalenderlib->getPlanForVerband( + $startDate, + $endDate, + $verbandFilters['stg_kz'], + $verbandFilters['sem'], + isset($verbandFilters['ver']) ? $verbandFilters['ver'] : null, + isset($verbandFilters['grp']) ? $verbandFilters['grp'] : null + ); + } + elseif ($type === 'ort') + { + $events = $this->ci->kalenderlib + ->getPlanForRoom($startDate, $endDate, $ortKurzbz); + } + elseif ($isLecturer) { $events = $this->ci->kalenderlib ->getPlanForLecturerByLecturer($startDate, $endDate, $uid); diff --git a/application/libraries/LvPlanExcelLib.php b/application/libraries/LvPlanExcelLib.php index b18770e3a..4af18dca2 100644 --- a/application/libraries/LvPlanExcelLib.php +++ b/application/libraries/LvPlanExcelLib.php @@ -35,13 +35,30 @@ class LvPlanExcelLib * @param string $uid User UID. * @param int $begin First included date as Unix timestamp. * @param int $ende Last included date as Unix timestamp. - * @param string $type Timetable type (student or lektor). + * @param string $type Timetable type (student, lektor, ort or verband). + * @param string|null $ortKurzbz Room identifier for room plans. + * @param array|null $verbandFilters Lehrverband filters. * @return string Binary workbook content. */ - public function getContent($uid, $begin, $ende, $type) - { - if (!in_array($type, array('student', 'lektor'), true)) + public function getContent( + $uid, + $begin, + $ende, + $type, + $ortKurzbz = null, + $verbandFilters = null + ) { + if (!in_array($type, array('student', 'lektor', 'ort', 'verband'), true)) throw new InvalidArgumentException('Unsupported timetable type'); + if ($type === 'ort' && (!is_string($ortKurzbz) || $ortKurzbz === '')) + throw new InvalidArgumentException('Missing room timetable filter'); + if ($type === 'verband' + && (!is_array($verbandFilters) + || !array_key_exists('stg_kz', $verbandFilters) + || !array_key_exists('sem', $verbandFilters))) + { + throw new InvalidArgumentException('Missing Lehrverband timetable filters'); + } $isLecturer = $type === 'lektor'; $this->ci->load->library('KalenderLib', array('uid' => $uid)); @@ -50,7 +67,23 @@ class LvPlanExcelLib $startDate = date('Y-m-d', $begin); $endDate = date('Y-m-d', $ende); - if ($isLecturer) + if ($type === 'verband') + { + $events = $this->ci->kalenderlib->getPlanForVerband( + $startDate, + $endDate, + $verbandFilters['stg_kz'], + $verbandFilters['sem'], + isset($verbandFilters['ver']) ? $verbandFilters['ver'] : null, + isset($verbandFilters['grp']) ? $verbandFilters['grp'] : null + ); + } + elseif ($type === 'ort') + { + $events = $this->ci->kalenderlib + ->getPlanForRoom($startDate, $endDate, $ortKurzbz); + } + elseif ($isLecturer) { $events = $this->ci->kalenderlib ->getPlanForLecturerByLecturer($startDate, $endDate, $uid); diff --git a/application/libraries/LvPlanHTMLLib.php b/application/libraries/LvPlanHTMLLib.php index 6912cfc51..267acac77 100644 --- a/application/libraries/LvPlanHTMLLib.php +++ b/application/libraries/LvPlanHTMLLib.php @@ -6,6 +6,8 @@ if (!defined('BASEPATH')) class LvPlanHTMLLib { const TIMEZONE = 'Europe/Vienna'; + const DETAIL_WINDOW_NAME = 'Details'; + const DETAIL_WINDOW_OPTIONS = 'height=320,width=550,left=0,top=0,hotkeys=0,resizable=yes,status=no,scrollbars=no,toolbar=no,location=no,menubar=no,dependent=yes'; private $ci; @@ -25,12 +27,16 @@ class LvPlanHTMLLib */ public function getContent($begin, $ende, $type, array $filters) { - if (!in_array($type, array('student', 'lektor', 'verband'), true)) + if (!in_array($type, array('student', 'lektor', 'verband', 'ort'), true)) throw new InvalidArgumentException('Unsupported timetable type'); - $events = $type === 'verband' - ? $this->getVerbandEvents($begin, $ende, $filters) - : $this->getPersonalEvents($begin, $ende, $type, $filters); + if ($type === 'verband') + $events = $this->getVerbandEvents($begin, $ende, $filters); + elseif ($type === 'ort') + $events = $this->getRoomEvents($begin, $ende, $filters); + else + $events = $this->getPersonalEvents($begin, $ende, $type, $filters); + $hourRaster = $this->loadHourRaster(); $normalizedEvents = $this->normalizeEvents($events); @@ -73,6 +79,28 @@ class LvPlanHTMLLib return is_array($events) ? $events : array(); } + /** + * @return array Room plan events. + */ + private function getRoomEvents($begin, $ende, array $filters) + { + if (!isset($filters['ort_kurzbz']) + || !is_string($filters['ort_kurzbz']) + || $filters['ort_kurzbz'] === '') + { + throw new InvalidArgumentException('Missing room timetable filter'); + } + + $this->ci->load->library('KalenderLib', array('uid' => getAuthUID())); + $events = $this->ci->kalenderlib->getPlanForRoom( + $this->formatLocalDate($begin), + $this->formatLocalDate($ende), + $filters['ort_kurzbz'] + ); + + return is_array($events) ? $events : array(); + } + /** * @return array Lehrverband plan events. */ @@ -168,6 +196,9 @@ class LvPlanHTMLLib isset($event->ort_kurzbz) ? $event->ort_kurzbz : '', ' / ' ), + 'detail_ort_kurzbz' => $this->getFirstScalarValue( + isset($event->ort_kurzbz) ? $event->ort_kurzbz : '' + ), 'lecturers' => $this->getLecturers($event), 'groups' => $this->getGroups($event), 'note' => $this->getEventNote($event, $isReservation), @@ -210,7 +241,7 @@ class LvPlanHTMLLib $html .= '
Keine Termine im gewählten Zeitraum.
'; @@ -300,7 +331,7 @@ class LvPlanHTMLLib /** * Renders one printable week. */ - private function renderWeek(array $week, array $raster, $type) + private function renderWeek(array $week, array $raster, $type, array $filters) { $weekdayNames = array( 1 => 'Montag', @@ -331,7 +362,7 @@ class LvPlanHTMLLib $html .= '
escape($event['note']).'" alt="">';
- }
- if (($type === 'lektor' || $type === 'verband') && $event['groups'] !== '')
- $html .= '