From 5d5b2e5bc4b36519426f1ee10309fa760d3a7922 Mon Sep 17 00:00:00 2001 From: SimonGschnell Date: Tue, 19 Nov 2024 11:35:20 +0100 Subject: [PATCH 1/2] fix(FHCAPI_Controller): adjusts the php doc types of parameters --- application/core/FHCAPI_Controller.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/application/core/FHCAPI_Controller.php b/application/core/FHCAPI_Controller.php index c843e2de6..c1e57a0f2 100644 --- a/application/core/FHCAPI_Controller.php +++ b/application/core/FHCAPI_Controller.php @@ -197,7 +197,7 @@ class FHCAPI_Controller extends Auth_Controller } /** - * @param array $error + * @param string|array|object $error * @param string $type (optional) * @param integer $status (optional) * @return void @@ -213,7 +213,7 @@ class FHCAPI_Controller extends Auth_Controller /** * @param stdclass $result * @param string $errortype - * @return void + * @return mixed */ protected function getDataOrTerminateWithError($result, $errortype = self::ERROR_TYPE_GENERAL) { From 8d01995722a94358aababf971ca99361a820ac31 Mon Sep 17 00:00:00 2001 From: SimonGschnell Date: Tue, 19 Nov 2024 12:51:12 +0100 Subject: [PATCH 2/2] refactor(Studenplan Query):queries all studiensemester from start_date to end_date and matches the gruppen and studentlehrverbaende to the associated studiensemester in the query --- .../api/frontend/v1/Stundenplan.php | 187 ++++++++++++------ .../organisation/Studiensemester_model.php | 15 ++ .../models/ressource/Stundenplan_model.php | 78 +++++--- 3 files changed, 195 insertions(+), 85 deletions(-) diff --git a/application/controllers/api/frontend/v1/Stundenplan.php b/application/controllers/api/frontend/v1/Stundenplan.php index daef2ab1a..373e5a9f9 100644 --- a/application/controllers/api/frontend/v1/Stundenplan.php +++ b/application/controllers/api/frontend/v1/Stundenplan.php @@ -107,10 +107,13 @@ class Stundenplan extends FHCAPI_Controller * @access public * */ + //TODO: getStundenplan fuer Mitarbeiter anpassen public function getStundenplan(){ - // Query fuer Studenten MVP - //TODO: getStundenplan fuer Mitarbeiter anpassen + $this->load->model('ressource/Mitarbeiter_model','MitarbeiterModel'); + $this->load->model('organisation/Studiensemester_model','StudiensemesterModel'); + $this->load->model('education/Studentlehrverband_model', 'StudentlehrverbandModel'); + $this->load->model('person/Benutzergruppe_model','BenutzergruppeModel'); // form validation $this->load->library('form_validation'); @@ -124,9 +127,9 @@ class Stundenplan extends FHCAPI_Controller $start_date = $this->input->get('start_date', TRUE); $end_date = $this->input->get('end_date', TRUE); - $student_uid = getAuthUID(); + $student_uid = getAuthUID(); + // check if authUID is mitarbeiter - $this->load->model('ressource/Mitarbeiter_model','MitarbeiterModel'); $is_mitarbeiter = getData($this->MitarbeiterModel->isMitarbeiter($student_uid)); if($is_mitarbeiter) { @@ -137,73 +140,95 @@ class Stundenplan extends FHCAPI_Controller $this->terminateWithError("No UID"); } - //semester des Studenten ermitteln - $lvplan_load_ueber_semesterhaelfte = false; - if (defined('LVPLAN_LOAD_UEBER_SEMESTERHAELFTE') && LVPLAN_LOAD_UEBER_SEMESTERHAELFTE === true) - $lvplan_load_ueber_semesterhaelfte = true; - else - $lvplan_load_ueber_semesterhaelfte = false; + // gets all studiensemester from the student from start_date to end_date + $semester_range = $this->StudiensemesterModel->getByDate($start_date,$end_date); + $semester_range = array_map( + function($sem) + { + return $sem->studiensemester_kurzbz; + }, + $this->getDataOrTerminateWithError($semester_range) + ); - $this->load->model('organisation/Studiensemester_model','StudiensemesterModel'); - $aktuelle_studiensemester = $this->StudiensemesterModel->getNearest(); - $aktuelle_studiensemester = $this->getDataOrTerminateWithError($aktuelle_studiensemester); - if (count($aktuelle_studiensemester) == 0) { - $this->terminateWithError("No aktuelles semester"); - } - $aktuelle_studiensemester = current($aktuelle_studiensemester)->studiensemester_kurzbz; - if($lvplan_load_ueber_semesterhaelfte) + // if no studiensemester is found for the given timespan, get the nearest studiensemester + if(count($semester_range) == 0) { - $next_studiensemester = $this->StudiensemesterModel->getNextFrom($aktuelle_studiensemester); + $aktuelle_studiensemester = $this->StudiensemesterModel->getNearest(); + $aktuelle_studiensemester = $this->getDataOrTerminateWithError($aktuelle_studiensemester); + if (count($aktuelle_studiensemester) == 0) { + $this->terminateWithError("No aktuelles semester"); + } + $aktuelle_studiensemester = current($aktuelle_studiensemester)->studiensemester_kurzbz; + // push aktuelles semester in active semester array + array_push($semester_range, $aktuelle_studiensemester); + + } + + + $this->sortStudienSemester($semester_range); + + //semester des Studenten ermitteln + if (defined('LVPLAN_LOAD_UEBER_SEMESTERHAELFTE') && LVPLAN_LOAD_UEBER_SEMESTERHAELFTE === true) + { + // get next studiensemester + $next_studiensemester = $this->StudiensemesterModel->getNextFrom($semester_range[(count($semester_range)-1)]); $next_studiensemester = $this->getDataOrTerminateWithError($next_studiensemester); if(count($next_studiensemester) == 0) { $this->terminateWithError("No next semester"); } $next_studiensemester = current($next_studiensemester)->studiensemester_kurzbz; - $previous_studiensemester = $this->StudiensemesterModel->getPreviousFrom($aktuelle_studiensemester); + //push next semester in active semester array + array_push($semester_range, $next_studiensemester); + $this->sortStudienSemester($semester_range); + + // get previous studiensemester + $previous_studiensemester = $this->StudiensemesterModel->getPreviousFrom($semester_range[0]); $previous_studiensemester = $this->getDataOrTerminateWithError($previous_studiensemester); if (count($previous_studiensemester) == 0) { $this->terminateWithError("No previous semester"); } $previous_studiensemester = current($previous_studiensemester)->studiensemester_kurzbz; - } + // push previous semester in active semester array + array_push($semester_range, $previous_studiensemester); + $this->sortStudienSemester($semester_range); + } else { - $nearest_studiensemester = $this->StudiensemesterModel->getNearestFrom($aktuelle_studiensemester); + $nearest_studiensemester = $this->StudiensemesterModel->getNearestFrom($semester_range[(count($semester_range)-1)]); $nearest_studiensemester = $this->getDataOrTerminateWithError($nearest_studiensemester); if (count($nearest_studiensemester) == 0) { $this->terminateWithError("No nearest semester"); } $nearest_studiensemester = current($nearest_studiensemester)->studiensemester_kurzbz; + // push nearest semester in active semester array + array_push($semester_range, $nearest_studiensemester); + $this->sortStudienSemester($semester_range); + } + // getting the gruppen_kurzbz of the student in the different studiensemester - $this->load->model('person/Benutzergruppe_model','BenutzergruppeModel'); - $benutzer_gruppen = null; - if ($lvplan_load_ueber_semesterhaelfte) + $benutzer_gruppen = []; + + foreach($semester_range as $semester) { - $benutzer_gruppen = $this->BenutzergruppeModel->execReadOnlyQuery(" - SELECT * FROM tbl_benutzergruppe where uid = ? AND studiensemester_kurzbz IN ?",[$student_uid, [$aktuelle_studiensemester, $next_studiensemester, $previous_studiensemester]]); - $benutzer_gruppen = $this->getDataOrTerminateWithError($benutzer_gruppen); - $benutzer_gruppen = array_map(function($item){ return "'".$item->gruppe_kurzbz. "'";}, $benutzer_gruppen); - } - else - { - $benutzer_gruppen = $this->BenutzergruppeModel->execReadOnlyQuery(" - SELECT * FROM tbl_benutzergruppe where uid = ? AND studiensemester_kurzbz IN ?", [$student_uid, [$aktuelle_studiensemester,$nearest_studiensemester]]); - $benutzer_gruppen = $this->getDataOrTerminateWithError($benutzer_gruppen); - $benutzer_gruppen = array_map(function ($item) { return "'".$item->gruppe_kurzbz. "'";}, $benutzer_gruppen); + // for each active semester query the benutzer_gruppen associated to the semester + $benutzer_query = $this->BenutzergruppeModel->execReadOnlyQuery(" + SELECT * FROM tbl_benutzergruppe where uid = ? AND studiensemester_kurzbz = ?",[$student_uid, $semester]); + $benutzer_query_result = $this->getDataOrTerminateWithError($benutzer_query); + $benutzer_gruppen[$semester] = array_map(function($item){ return "'".$item->gruppe_kurzbz. "'";}, $benutzer_query_result); } - // getting the student_lehrverbaende of the student in the different studiensemester - $this->load->model('education/Studentlehrverband_model', 'StudentlehrverbandModel'); - $student_lehrverbaende = null; - if ($lvplan_load_ueber_semesterhaelfte) + $student_lehrverband = []; + + foreach($semester_range as $semester) { - $student_lehrverbaende = $this->BenutzergruppeModel->execReadOnlyQuery(" - SELECT * FROM tbl_studentlehrverband where student_uid = ? AND studiensemester_kurzbz IN ?", [$student_uid, [$aktuelle_studiensemester,$next_studiensemester, $previous_studiensemester]]); - $student_lehrverbaende = $this->getDataOrTerminateWithError($student_lehrverbaende); - $student_lehrverbaende = array_map( + // for each active semester query the student_lehrverband associated to the semester + $lehrverband_query = $this->BenutzergruppeModel->execReadOnlyQuery(" + SELECT * FROM tbl_studentlehrverband where student_uid = ? AND studiensemester_kurzbz = ?", [$student_uid, $semester]); + $lehrverband_query_result = $this->getDataOrTerminateWithError($lehrverband_query); + $student_lehrverband[$semester] = array_map( function ($item) { $result = new stdClass(); @@ -213,27 +238,19 @@ class Stundenplan extends FHCAPI_Controller $result->gruppe = $item->gruppe; return $result; }, - $student_lehrverbaende); - } - else - { - $student_lehrverbaende = $this->BenutzergruppeModel->execReadOnlyQuery(" - SELECT * FROM tbl_studentlehrverband where student_uid = ? AND studiensemester_kurzbz IN ?", [$student_uid, [$aktuelle_studiensemester,$nearest_studiensemester]]); - $student_lehrverbaende = $this->getDataOrTerminateWithError($student_lehrverbaende); - $student_lehrverbaende = array_map( - function ($item) { - $result = new stdClass(); - $result->studiengang_kz = $item->studiengang_kz; - $result->semester = $item->semester; - $result->verband = $item->verband; - $result->gruppe = $item->gruppe; - return $result; - }, - $student_lehrverbaende - ); + $lehrverband_query_result); + } - $stundenplan_data = $this->StundenplanModel->stundenplanGruppierung($this->StundenplanModel->getStundenplanQuery($start_date, $end_date, $benutzer_gruppen, $student_lehrverbaende)); + $studienSemesterDateRanges=[]; + foreach($semester_range as $semester){ + $semester_start_ende = $this->StudiensemesterModel->getStartEndeFromStudiensemester($semester); + $semester_start_ende = current($this->getDataOrTerminateWithError($semester_start_ende)); + $studienSemesterDateRanges[$semester] = $semester_start_ende; + } + $semester_range = $studienSemesterDateRanges; + + $stundenplan_data = $this->StundenplanModel->stundenplanGruppierung($this->StundenplanModel->getStundenplanQuery($start_date, $end_date, $semester_range, $benutzer_gruppen, $student_lehrverband)); $stundenplan_data = $this->getDataOrTerminateWithError($stundenplan_data) ?? []; $this->expand_object_information($stundenplan_data); @@ -274,6 +291,8 @@ class Stundenplan extends FHCAPI_Controller $this->terminateWithSuccess($result); } + // ################# Private Functions + private function expand_object_information($data){ foreach ($data as $item) @@ -328,6 +347,48 @@ class Stundenplan extends FHCAPI_Controller } } + // function used to sort an array of studiensemester strings + private function sortStudienSemester(&$semester_range){ + usort( + $semester_range, + function($first,$second) + { + $sem_first = null; + $year_first = null; + $match_first = null; + $sem_second = null; + $year_second = null; + $match_second = null; + + preg_match('/([WS]+)([0-9]+)/',$first,$match_first); + preg_match('/([WS]+)([0-9]+)/',$second,$match_second); + + $sem_first = $match_first[1]; + $year_first = intval($match_first[2]); + + $sem_second = $match_second[1]; + $year_second = intval($match_second[2]); + + if($year_first < $year_second) + { + return -1; + } + else if($year_first > $year_second) + { + return 1; + } + else if($year_first == $year_second && $sem_first > $sem_second) + { + return 1; + } + else if($year_first == $year_second && $sem_first < $sem_second) + { + return -1; + } + return 0; + } + ); + } } diff --git a/application/models/organisation/Studiensemester_model.php b/application/models/organisation/Studiensemester_model.php index 0f8c3c620..291a010f9 100644 --- a/application/models/organisation/Studiensemester_model.php +++ b/application/models/organisation/Studiensemester_model.php @@ -272,4 +272,19 @@ class Studiensemester_model extends DB_Model if (is_numeric($studienjahrNumber) && mb_substr($studiensemester_kurzbz, 0, 2) == 'SS') (int)$studienjahrNumber -= 1; return $studienjahrNumber; } + + /** + * Holt Start und Ende des Studiensemester_kurzbz + * @param studiensemester_kurzbz + * @return stdClass + */ + public function getStartEndeFromStudiensemester($studiensemester_kurzbz) + { + return $this->execReadOnlyQuery(" + SELECT + start, ende + FROM public.tbl_studiensemester + WHERE studiensemester_kurzbz = ?",[$studiensemester_kurzbz]); + + } } diff --git a/application/models/ressource/Stundenplan_model.php b/application/models/ressource/Stundenplan_model.php index d8821ed43..92d03b701 100644 --- a/application/models/ressource/Stundenplan_model.php +++ b/application/models/ressource/Stundenplan_model.php @@ -192,43 +192,77 @@ class Stundenplan_model extends DB_Model * * @return string */ - public function getStundenplanQuery($start_date, $end_date,$gruppen,$studentlehrverbaende){ - + public function getStundenplanQuery($start_date, $end_date,$semester,$gruppen,$studentlehrverbaende){ + + // helper function to check if either $gruppen or $studentlehrverbaende are empty for each semester + $emptyCheck = function($toBeCheckedArray) use ($semester){ + $result = true; + $sem = array_keys($semester); + foreach($sem as $s){ + if(count($toBeCheckedArray[$s]) > 0){ + $result = false; + break; + } + } + return $result; + }; + $query = "select sp.* from lehre.vw_stundenplan sp WHERE sp.datum >= ".$this->escape($start_date)." AND sp.datum <= ".$this->escape($end_date); - - if(count($gruppen) != 0 || count($studentlehrverbaende) != 0) + + // adds the AND sql chain only if both $gruppen and $studentlehrverbaende are not empty + if(!$emptyCheck($gruppen) || !$emptyCheck($studentlehrverbaende)) { $query .= " AND ( "; - } - - if(count($gruppen) != 0) + } + + foreach($semester as $sem => $date_range) { - $query .="sp.gruppe_kurzbz IN (".implode(',',$gruppen).")"; - } - - foreach($studentlehrverbaende as $key=>$lehrverband){ - // only append OR if not first entry or previous condition was added - if(($key == 0 && count($gruppen) != 0) || ($key > 0)) + if(count($gruppen[$sem]) > 0) { - $query .= " OR "; + // converts the array of gruppen strings into a sql IN (_,_,_) chain + $query .="(sp.gruppe_kurzbz IN (" .implode(',',$gruppen[$sem]).") AND sp.datum BETWEEN ".$this->escape($date_range->start)." AND ".$this->escape($date_range->ende)." )"; + + // adds the OR sql chain only if the $studentlehrverbaende array is not empty + // DOES not include the sql OR if the $studentlehrverbaende are empty and it is the last gruppen element in the iteration + if(key($semester) != $sem || !$emptyCheck($studentlehrverbaende)) + { + $query .="OR"; + } + } + } + + foreach($semester as $sem=>$date_range) + { + + if(count($studentlehrverbaende[$sem]) > 0) + { + foreach($studentlehrverbaende[$sem] as $key=>$lehrverband) + { + // adds the OR sql chain only if its not the first element in the first semester of the $studentlehrverbaende array + if($lehrverband != $studentlehrverbaende[array_keys($semester)[0]][0]) + { + $query .="OR"; + } + $query .= "((sp.studiengang_kz = ".$this->escape($lehrverband->studiengang_kz)." AND sp.semester = ".$this->escape($lehrverband->semester)." AND sp.verband = ".$this->escape($lehrverband->verband)." AND sp.gruppe = ".$this->escape($lehrverband->gruppe)." AND sp.datum BETWEEN ".$this->escape($date_range->start)." AND ".$this->escape($date_range->ende).")"; + // Eintraege fuer den ganzen Verband + $query .= "OR (sp.studiengang_kz = ".$this->escape($lehrverband->studiengang_kz)." AND sp.semester = ".$this->escape($lehrverband->semester)." AND sp.verband = ".$this->escape($lehrverband->verband)." AND (sp.gruppe is null OR sp.gruppe='') AND sp.datum BETWEEN ".$this->escape($date_range->start)." AND ".$this->escape($date_range->ende).")"; + // Eintraege fuer das ganze Semester + $query .= "OR (sp.studiengang_kz = ".$this->escape($lehrverband->studiengang_kz)." AND sp.semester = ".$this->escape($lehrverband->semester)." AND (sp.verband is null OR sp.verband='') AND sp.datum BETWEEN ".$this->escape($date_range->start)." AND ".$this->escape($date_range->ende).") AND gruppe_kurzbz is null)"; + } + } - // Eintraege fuer die spezifische Gruppe - $query .= "(sp.studiengang_kz = ".$this->escape($lehrverband->studiengang_kz)." AND sp.semester = ".$this->escape($lehrverband->semester)." AND sp.verband = ".$this->escape($lehrverband->verband)." AND sp.gruppe = ".$this->escape($lehrverband->gruppe).")"; - // Eintraege fuer den ganzen Verband - $query .= "OR (sp.studiengang_kz = ".$this->escape($lehrverband->studiengang_kz)." AND sp.semester = ".$this->escape($lehrverband->semester)." AND sp.verband = ".$this->escape($lehrverband->verband)." AND (sp.gruppe is null OR sp.gruppe=''))"; - // Eintraege fuer das ganze Semester - $query .= "OR (sp.studiengang_kz = ".$this->escape($lehrverband->studiengang_kz)." AND sp.semester = ".$this->escape($lehrverband->semester)." AND (sp.verband is null OR sp.verband='')) AND gruppe_kurzbz is null"; } - if(count($gruppen) != 0 || count($studentlehrverbaende) != 0) + // closes the AND sql chain only if it was opened previously + if(!$emptyCheck($gruppen) || !$emptyCheck($studentlehrverbaende)) { $query .= ")"; - } + } return $query; }