From f1ca657226b054d1f63f602392b0bbb4ee3eb2ee Mon Sep 17 00:00:00 2001 From: adisposkofh Date: Mon, 27 Jul 2026 15:36:17 +0200 Subject: [PATCH] reimplemented coodle participant search with search library --- application/config/search.php | 16 +++ .../config/searchCoodleParticipants.php | 53 +++++++ .../api/frontend/v1/coodle/CoodleSurvey.php | 134 ++---------------- .../CoodleSurvey/CoodleSurveyParticipants.js | 45 +++++- 4 files changed, 119 insertions(+), 129 deletions(-) create mode 100644 application/config/searchCoodleParticipants.php diff --git a/application/config/search.php b/application/config/search.php index bedf8d888..25015e963 100644 --- a/application/config/search.php +++ b/application/config/search.php @@ -872,3 +872,19 @@ $config['dms'] = [ ) )" ]; + +$config['group'] = [ + 'primarykey' => 'gruppe_kurzbz', + 'table' => 'public.tbl_gruppe', + 'searchfields' => [ + 'gruppe_kurzbz' => [ + 'comparison' => 'similar', + 'field' => 'gruppe_kurzbz', + ], + ], + 'resultfields' => [ + "g.gruppe_kurzbz as name", + ], + 'resultjoin' => " + JOIN public.tbl_gruppe g USING (gruppe_kurzbz)" +]; diff --git a/application/config/searchCoodleParticipants.php b/application/config/searchCoodleParticipants.php new file mode 100644 index 000000000..e8f61feb5 --- /dev/null +++ b/application/config/searchCoodleParticipants.php @@ -0,0 +1,53 @@ +config->item('employee', 'search'); +$config['employee']['resultfields'] = [ + "m.mitarbeiter_uid AS uid", + "(p.vorname || ' ' || p.nachname) AS name", +]; +$config['employee']['resultjoin'] = " + JOIN public.tbl_mitarbeiter m USING (mitarbeiter_uid) + JOIN public.tbl_benutzer b ON (b.uid = m.mitarbeiter_uid AND b.aktiv = true) + JOIN public.tbl_person p USING(person_id) + LEFT JOIN ( + SELECT kontakt, standort_id + FROM public.tbl_kontakt + WHERE kontakttyp = 'telefon' + ) k ON (k.standort_id = m.standort_id)"; + +$config['student'] = $CI->config->item('student', 'search'); +unset($config['student']['searchfields']['email']); +unset($config['student']['searchfields']['tel']); +$config['student']['resultfields'] = [ + "s.student_uid AS uid", + "(p.vorname || ' ' || p.nachname) AS name", +]; +$config['student']['resultjoin'] = " + JOIN public.tbl_student s USING (student_uid) + JOIN public.tbl_benutzer b ON(b.uid = s.student_uid AND b.aktiv = true) + JOIN public.tbl_person p USING(person_id)"; + +$config['group'] = $CI->config->item('group', 'search'); +$config['group']['resultfields'] = [ + "g.gruppe_kurzbz as name", + "ARRAY( + SELECT bg.uid as uid + FROM public.tbl_benutzergruppe bg + WHERE bg.gruppe_kurzbz = g.gruppe_kurzbz + ORDER BY bg.uid + ) AS user_uids", + "ARRAY( + SELECT p.vorname || ' ' || p.nachname AS name + FROM public.tbl_benutzergruppe bg + JOIN public.tbl_benutzer b ON(b.uid = bg.uid) + JOIN public.tbl_person p ON(p.person_id = b.person_id) + WHERE bg.gruppe_kurzbz = g.gruppe_kurzbz + ORDER BY bg.uid + ) AS user_names", +]; \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/coodle/CoodleSurvey.php b/application/controllers/api/frontend/v1/coodle/CoodleSurvey.php index da3f009ff..3695a22ab 100644 --- a/application/controllers/api/frontend/v1/coodle/CoodleSurvey.php +++ b/application/controllers/api/frontend/v1/coodle/CoodleSurvey.php @@ -338,16 +338,18 @@ class CoodleSurvey extends FHCAPI_Controller public function searchParticipants() { $searchString = $this->input->post("searchString"); + $this->form_validation->set_data([ + "searchString" => $searchString, + ]); + $this->form_validation->set_rules("searchString", "Search text", "required|max_length[255]"); + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); - if (!$searchString || !strlen($searchString)) - $this->terminateWithError("Empty search input!"); + $this->load->library('SearchLib', ["config" => "searchCoodleParticipants"]); + $result = $this->searchlib->search($searchString, ["employee", "student", "group"]); + $data = $this->getDataOrTerminateWithError($result); - $users = $this->searchUsersAsParticipants($searchString); - $groups = $this->searchGroupsAsParticipants($searchString); - - $potentialParticipants = array_merge($users, $groups); - - $this->terminateWithSuccess($potentialParticipants); + $this->terminateWithSuccess($data); } public function submitParticipantSelection() @@ -914,122 +916,6 @@ class CoodleSurvey extends FHCAPI_Controller return $result; } - private function searchUsersAsParticipants($searchString) - { - $searchStrings = explode(" ", strtolower($searchString)); - - $firstSearchString = $searchStrings[0]; - $remainingSearchStrings = array_slice($searchStrings, 1); - - $query = "SELECT - 'user' AS type, - benutzer.uid AS uid, - person.vorname || ' ' || person.nachname AS name - FROM public.tbl_person person - JOIN public.tbl_benutzer benutzer ON(benutzer.person_id = person.person_id) - WHERE (LOWER(person.vorname || ' ' || person.nachname) LIKE '%" . $firstSearchString . "%' - OR benutzer.uid LIKE '%" . $firstSearchString . "%') - "; - - if (count($remainingSearchStrings)) { - foreach ($remainingSearchStrings as $remainingSearchString) { - $query .= " AND (LOWER(person.vorname || ' ' || person.nachname) LIKE '%" . $remainingSearchString . "%' - OR benutzer.uid LIKE '%" . $remainingSearchString . "%')"; - } - } - - $query .= "ORDER BY benutzer.uid - LIMIT 25"; - - $dbModel = new DB_Model(); - $usersQueryResult = $dbModel->execReadOnlyQuery($query); - - if (hasData($usersQueryResult)) { - return getData($usersQueryResult); - } else { - return []; - } - - } - - private function searchGroupsAsParticipants($searchString) - { - $searchStrings = explode(" ", strtolower($searchString)); - - $firstSearchString = $searchStrings[0]; - $remainingSearchStrings = array_slice($searchStrings, 1); - - $groupsQuery = " - SELECT - 'group' AS type, - gruppe_kurzbz AS name - FROM public.tbl_gruppe - WHERE LOWER(gruppe_kurzbz) LIKE '%" . $firstSearchString . "%' - "; - - if (count($remainingSearchStrings)) { - foreach ($remainingSearchStrings as $remainingSearchString) { - $groupsQuery .= " AND LOWER(gruppe_kurzbz) LIKE '%" . $remainingSearchString . "%'"; - } - } - - $groupsQuery .= " LIMIT 25"; - - $dbModel = new DB_Model(); - $groupsQueryResult = $dbModel->execReadOnlyQuery($groupsQuery); - // return getData($groupsQueryResult); - - $groups = hasData($groupsQueryResult) ? getData($groupsQueryResult) : []; - if (!count($groups)) - return $groups; - - $groupNames = array_map(function ($group) { - return $group->name; - }, $groups); - - - $userGroupsQuery = "SELECT - benutzerGruppe.uid as uid, - benutzerGruppe.gruppe_kurzbz as group, - person.vorname || ' ' || person.nachname AS name - FROM public.tbl_benutzergruppe benutzerGruppe - JOIN public.tbl_benutzer benutzer ON(benutzer.uid = benutzerGruppe.uid) - JOIN public.tbl_person person ON(person.person_id = benutzer.person_id) - WHERE gruppe_kurzbz IN ('" . implode("', '", $groupNames) . "') - "; - $userGroupsQueryResult = $dbModel->execReadOnlyQuery($userGroupsQuery); - - $users = hasData($userGroupsQueryResult) ? getData($userGroupsQueryResult) : []; - if (!count($users)) - return []; - - $groupedUsers = []; - - foreach ($users as $user) { - $userData = [ - "uid" => $user->uid, - "name" => $user->name, - ]; - - $group = $user->group; - - if (isset($groupedUsers[$group])) { - $groupedUsers[$group][] = $userData; - } else { - $groupedUsers[$group] = [$userData]; - } - } - - $groups = array_map(function ($group) use ($groupedUsers) { - $group->users = isset($groupedUsers[$group->name]) ? $groupedUsers[$group->name] : []; - return $group; - }, $groups); - $groups = array_filter($groups, function ($group) { - return count($group->users); - }); - return $groups; - } - private function writeToCoodleIcsFile($calendarFilePath, $id, $title, $startUTC, $endUTC, $location, $organizerName, $organizerEmail) { $formattedStart = $startUTC->format("Ymd\THis\Z"); diff --git a/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyParticipants.js b/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyParticipants.js index e091d4699..8a8ce41f8 100644 --- a/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyParticipants.js +++ b/public/js/components/Cis/Coodle/Components/CoodleSurvey/CoodleSurveyParticipants.js @@ -40,9 +40,11 @@ export default { CoodleApi.searchParticipants(this.searchInput), { signal: this.searchParticipantsAbortController.signal }, ); - this.searchResults = participantsSearchResponse.data; - this.isSearchingForParticipants = false; + + this.parseParticipantSearchResults( + participantsSearchResponse.data, + ); }, 300), hideSearchResults: debounce(async () => { this.areSearchResultsShown = false; @@ -107,13 +109,44 @@ export default { }, }, methods: { + parseParticipantSearchResults(searchResults) { + this.searchResults = searchResults + .map((searchResult) => { + let data = JSON.parse(searchResult.data); + if (data.uid) { + return { + rank: searchResult.rank, + type: "user", + name: data.name, + uid: data.uid, + }; + } else { + return { + rank: searchResult.rank, + type: "group", + name: data.name, + users: data.user_uids.map((userUid, index) => { + return { + uid: userUid, + name: data.user_names[index], + }; + }), + }; + } + }) + .toSorted( + (searchResultA, searchResultB) => + searchResultB.rank - searchResultA.rank, + ); + }, async selectSearchResult(searchResult) { if ( searchResult.type === "group" && searchResult.users.length >= this.warningGroupSize ) { - let groupSizeWarningMessage = - this.$p.t("coodle/group_size_warning"); + let groupSizeWarningMessage = this.$p.t( + "coodle/group_size_warning", + ); groupSizeWarningMessage = groupSizeWarningMessage.replace( "(((groupName)))", searchResult.name, @@ -231,7 +264,9 @@ export default { externalParticipant.email === emailInput, ) ) { - this.$fhcAlert.alertError(this.$p.t("coodle/duplicates_not_allowed")); + this.$fhcAlert.alertError( + this.$p.t("coodle/duplicates_not_allowed"), + ); return; }