reimplemented coodle participant search with search library

This commit is contained in:
adisposkofh
2026-07-27 15:36:17 +02:00
parent 40a6acb61e
commit f1ca657226
4 changed files with 119 additions and 129 deletions
+16
View File
@@ -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)"
];
@@ -0,0 +1,53 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
$CI =& get_instance();
$config['employee'] = $CI->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",
];
@@ -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");
@@ -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;
}