. */ if (! defined('BASEPATH')) exit('No direct script access allowed'); use \stdClass as stdClass; /** * */ class SearchBarLib { // Error constats const ERROR_WRONG_JSON = 'ERR001'; const ERROR_WRONG_SEARCHSTR = 'ERR002'; const ERROR_NO_TYPES = 'ERR003'; const ERROR_WRONG_TYPES = 'ERR004'; const ERROR_NOT_AUTH = 'ERR005'; // List of allowed types of search const ALLOWED_TYPES = ['mitarbeiter', 'mitarbeiter_ohne_zuordnung', 'organisationunit', 'raum', 'person', 'student', 'prestudent', 'document', 'cms']; const PHOTO_IMG_URL = '/cis/public/bild.php?src=person&person_id='; private $_ci; // Code igniter instance /** * Gets the CI instance and loads model */ public function __construct() { $this->_ci =& get_instance(); // get code igniter instance // It is loaded only to have the DB_Model available $this->_ci->load->model('person/Benutzer_model', 'BenutzerModel'); } //------------------------------------------------------------------------------------------------------------------ // Public methods /** * It performes the search of the given search string using the specified search types */ public function search($searchstr, $types) { // Checks if the given parameters are fine $search = $this->_checkParameters($searchstr, $types); // If the check was successful then perform the search if (isSuccess($search)) $search = $this->_search($searchstr, $types); return $search; // return the result } //------------------------------------------------------------------------------------------------------------------ // Private methods /** * Checks: * - The given searchstr is a not empty string * - The given types is a not empty array and contains allowed search types */ private function _checkParameters($searchstr, $types) { // If searchstr is empty if (isEmptyString($searchstr)) return error(self::ERROR_WRONG_SEARCHSTR); // If types is not an array or it is empty if (isEmptyArray($types)) return error(self::ERROR_NO_TYPES); // If all the elements in types are allowed search types if (!isEmptyArray(array_diff($types, self::ALLOWED_TYPES))) return error(self::ERROR_WRONG_TYPES); return success(); // The check is fine! } /** * Loops on types and perform the search of that type using searchstr * Then it collects all the returned data into an array as property of an object */ private function _search($searchstr, $types) { // Object to be returned $result = new stdClass(); $result->data = array(); // For each search type foreach ($types as $type) { // Perform the search and then add the result to data $result->data = array_merge($result->data, $this->{'_'.$type}($searchstr, $type)); } return $result; } private function _mitarbeiter_ohne_zuordnung($searchstr, $type) { $dbModel = new DB_Model(); $sql = ' SELECT \''.$type.'\' AS type, b.uid AS uid, p.person_id AS person_id, p.vorname || \' \' || p.nachname AS name, ARRAY_AGG(DISTINCT(org.bezeichnung)) AS organisationunit_name, COALESCE(b.alias, b.uid) || \''.'@'.DOMAIN.'\' AS email, TRIM(COALESCE(k.kontakt, \'\') || \' \' || COALESCE(m.telefonklappe, \'\')) AS phone, \''.base_url(self::PHOTO_IMG_URL).'\' || p.person_id AS photo_url, ARRAY_AGG(DISTINCT(stdkst.bezeichnung)) AS standardkostenstelle FROM public.tbl_mitarbeiter m JOIN public.tbl_benutzer b ON(b.uid = m.mitarbeiter_uid) LEFT JOIN ( SELECT \'[\' || ot.bezeichnung || \'] \' || o.bezeichnung AS bezeichnung, bf.uid FROM public.tbl_benutzerfunktion bf JOIN public.tbl_organisationseinheit o USING(oe_kurzbz) JOIN public.tbl_organisationseinheittyp ot USING(organisationseinheittyp_kurzbz) WHERE bf.funktion_kurzbz = \'kstzuordnung\' AND (bf.datum_von IS NULL OR bf.datum_von <= NOW()) AND (bf.datum_bis IS NULL OR bf.datum_bis >= NOW()) GROUP BY o.bezeichnung, ot.bezeichnung, bf.uid ) stdkst ON stdkst.uid = b.uid JOIN public.tbl_person p USING(person_id) LEFT JOIN ( SELECT \'[\' || ot.bezeichnung || \'] \' || o.bezeichnung AS bezeichnung, bf.uid FROM public.tbl_benutzerfunktion bf JOIN public.tbl_organisationseinheit o USING(oe_kurzbz) JOIN public.tbl_organisationseinheittyp ot USING(organisationseinheittyp_kurzbz) WHERE bf.funktion_kurzbz = \'oezuordnung\' AND (bf.datum_von IS NULL OR bf.datum_von <= NOW()) AND (bf.datum_bis IS NULL OR bf.datum_bis >= NOW()) GROUP BY o.bezeichnung, ot.bezeichnung, bf.uid ) org ON org.uid = b.uid LEFT JOIN ( SELECT kontakt, standort_id FROM public.tbl_kontakt WHERE kontakttyp = \'telefon\' ) k ON(k.standort_id = m.standort_id) WHERE (stdkst.bezeichnung IS NULL OR org.bezeichnung IS NULL) AND ( ' . $this->buildSearchClause( $dbModel, array('b.uid', 'p.vorname', 'p.nachname'), $searchstr ) . ' ) GROUP BY type, b.uid, p.person_id, name, email, m.telefonklappe, phone '; $employees = $dbModel->execReadOnlyQuery($sql); // If something has been found then return it if (hasData($employees)) return getData($employees); // Otherwise return an empty array return array(); } protected function buildSearchClause(DB_Model $dbModel, array $columns, $searchstr) { $document = implode(' || \' \' || ', $columns); $query = '\'' . implode(':* & ', explode(' ', trim($searchstr))) . ':*\''; $reversequery = '\'*:' . implode(' & *:', explode(' ', trim($searchstr))) . '\''; $nospacequery = '\'' . implode('', explode(' ', trim($searchstr))) . ':*\''; $searchclause = <<execReadOnlyQuery(' SELECT \''.$type.'\' AS type, b.uid AS uid, p.person_id AS person_id, p.vorname || \' \' || p.nachname AS name, ARRAY_AGG(DISTINCT(org.bezeichnung)) AS organisationunit_name, COALESCE(b.alias, b.uid) || \''.'@'.DOMAIN.'\' AS email, TRIM(COALESCE(k.kontakt, \'\') || \' \' || COALESCE(m.telefonklappe, \'\')) AS phone, \''.base_url(self::PHOTO_IMG_URL).'\' || p.person_id AS photo_url, ARRAY_AGG(DISTINCT(stdkst.bezeichnung)) AS standardkostenstelle FROM public.tbl_mitarbeiter m JOIN public.tbl_benutzer b ON(b.uid = m.mitarbeiter_uid) JOIN ( SELECT \'[\' || ot.bezeichnung || \'] \' || o.bezeichnung AS bezeichnung, bf.uid FROM public.tbl_benutzerfunktion bf JOIN public.tbl_organisationseinheit o USING(oe_kurzbz) JOIN public.tbl_organisationseinheittyp ot USING(organisationseinheittyp_kurzbz) WHERE bf.funktion_kurzbz = \'kstzuordnung\' AND (bf.datum_von IS NULL OR bf.datum_von <= NOW()) AND (bf.datum_bis IS NULL OR bf.datum_bis >= NOW()) GROUP BY o.bezeichnung, ot.bezeichnung, bf.uid ) stdkst ON stdkst.uid = b.uid JOIN public.tbl_person p USING(person_id) JOIN ( SELECT \'[\' || ot.bezeichnung || \'] \' || o.bezeichnung AS bezeichnung, bf.uid FROM public.tbl_benutzerfunktion bf JOIN public.tbl_organisationseinheit o USING(oe_kurzbz) JOIN public.tbl_organisationseinheittyp ot USING(organisationseinheittyp_kurzbz) WHERE bf.funktion_kurzbz = \'oezuordnung\' AND (bf.datum_von IS NULL OR bf.datum_von <= NOW()) AND (bf.datum_bis IS NULL OR bf.datum_bis >= NOW()) GROUP BY o.bezeichnung, ot.bezeichnung, bf.uid ) org ON org.uid = b.uid LEFT JOIN ( SELECT kontakt, standort_id FROM public.tbl_kontakt WHERE kontakttyp = \'telefon\' ) k ON(k.standort_id = m.standort_id) WHERE ' . $this->buildSearchClause( $dbModel, array('b.uid', 'p.vorname', 'p.nachname', 'org.bezeichnung', 'stdkst.bezeichnung'), $searchstr ) . ' GROUP BY type, b.uid, p.person_id, name, email, m.telefonklappe, phone '); // If something has been found then return it if (hasData($employees)) return getData($employees); // Otherwise return an empty array return array(); } /** * Seach for organisation units */ private function _organisationunit($searchstr, $type) { $dbModel = new DB_Model(); $ous = $dbModel->execReadOnlyQuery(' SELECT \''.$type.'\' AS type, o.oe_kurzbz AS oe_kurzbz, \'[\' || ot.bezeichnung || \'] \' || o.bezeichnung AS name, oParent.oe_kurzbz AS parentoe_kurzbz, (CASE WHEN oParent.bezeichnung IS NOT NULL THEN \'[\' || otParent.bezeichnung || \'] \' || oParent.bezeichnung END) AS parentoe_name, ARRAY_AGG(DISTINCT(bfLeader.uid)) AS leader_uid, ARRAY_AGG(DISTINCT(bfLeader.vorname || \' \' || bfLeader.nachname)) AS leader_name, COUNT(bfCount.benutzerfunktion_id) AS number_of_people, (CASE WHEN o.mailverteiler = TRUE THEN o.oe_kurzbz || \''.'@'.DOMAIN.'\' END) AS mailgroup FROM public.tbl_organisationseinheit o JOIN public.tbl_organisationseinheittyp ot USING(organisationseinheittyp_kurzbz) LEFT JOIN public.tbl_organisationseinheit oParent ON(oParent.oe_kurzbz = o.oe_parent_kurzbz) LEFT JOIN public.tbl_organisationseinheittyp otParent ON(oParent.organisationseinheittyp_kurzbz = otParent.organisationseinheittyp_kurzbz) LEFT JOIN ( SELECT benutzerfunktion_id, oe_kurzbz FROM public.tbl_benutzerfunktion WHERE funktion_kurzbz = \'oezuordnung\' AND (datum_von IS NULL OR datum_von <= NOW()) AND (datum_bis IS NULL OR datum_bis >= NOW()) ) bfCount ON(bfCount.oe_kurzbz = o.oe_kurzbz) LEFT JOIN ( SELECT bf.oe_kurzbz, bf.uid, p.vorname, p.nachname FROM public.tbl_benutzerfunktion bf JOIN public.tbl_benutzer b USING(uid) JOIN public.tbl_person p USING(person_id) WHERE funktion_kurzbz = \'Leitung\' AND (datum_von IS NULL OR datum_von <= NOW()) AND (datum_bis IS NULL OR datum_bis >= NOW()) AND b.aktiv = TRUE ) bfLeader ON(bfLeader.oe_kurzbz = o.oe_kurzbz) WHERE ' . $this->buildSearchClause( $dbModel, array('o.oe_kurzbz', 'o.bezeichnung', 'ot.bezeichnung'), $searchstr ) . ' GROUP BY type, o.oe_kurzbz, o.bezeichnung, ot.bezeichnung, oParent.oe_kurzbz, oParent.bezeichnung, otParent.bezeichnung '); // If something has been found if (hasData($ous)) { // Loop through the returned dataset foreach (getData($ous) as $ou) { // Create the new property leaders as an empty array $ou->leaders = array(); // Loop through the found leaders for this organisation unit for ($i = 0; $i < count($ou->leader_uid); $i++) { // If a leader exists for this organisationunit and has a name :D if (!isEmptyString($ou->leader_uid[$i]) && !isEmptyString($ou->leader_name[$i])) { // Empty object that will contains the leader uid and name $leader = new stdClass(); // Set the properties name and uid $leader->uid = $ou->leader_uid[$i]; $leader->name = $ou->leader_name[$i]; // Add the leader object to the leaders array $ou->leaders[] = $leader; } } // Remove the not needed properties leader_uid and leader_name unset($ou->leader_uid); unset($ou->leader_name); } // Returns the changed dataset return getData($ous); } // Otherwise return an empty array return array(); } /** * Search for persons */ private function _person($searchstr, $type) { return array(); } /** * Search for students */ private function _student($searchstr, $type) { return array(); } /** * Search for prestudents */ private function _prestudent($searchstr, $type) { return array(); } /** * Search for documents */ private function _document($searchstr, $type) { return array(); } /** * Search for CMSs */ private function _cms($searchstr, $type) { return array(); } /** * Search for rooms */ private function _raum($searchstr, $type) { return array(); } }