cfg->getValue("LECTURESHIP_FILTER")) { * $filter->settings['query']['joins']['lehrauftrag'] = array( * 'join' => "INNER JOIN", * 'on' => "seminare.Seminar_id = lehrauftrag.seminar_id" * ); * } * } * * Within this method you alter the public $filter->settings array, because this array * describes entirely the big query for the admin-search. In our example above * we simple add an INNER JOIN to filter for the course having an entry in * the lehrauftrag table. * * Description of this array is as follows: * * $filter->settings['query'] : The main sql query as a prepared statement. * $filter->settings['query']['select'] : An assoc array. $filter->settings['query']['select']['Number_of_teachers'] = "COUNT(DISTINCT dozenten.user_id)" * will select the result of COUNT as the variable Number_of_teachers. * $filter->settings['query']['joins'] : Example $filter->settings['query']['joins']['dozenten'] = array( * 'join' => "INNER JOIN", //default value, else use "LEFT JOIN" * 'table' => "seminar_user", //can me omitted if you don't want to use a table-alias * 'on' => "dozenten.Seminar_id = seminare.Seminar_id AND dozenten.status = 'dozent'" * ) * if 'table' differs from the index, the index will be the alias of the table. * So normally you don't need to name a table if you don't want it to be aliased. * $filter->settings['query']['where'] : You might want to use the method $filter->where($sql, $parameter) instead. * $filter->settings['query']['orderby'] : You might want to use $filter->orderBy($attribute, $flag = "ASC") instead. * $filter->settings['parameter'] : An assoc array of parameter that will be passed to * the prepared statement. * */ class AdminCourseFilter { static protected $instance = null; public $max_show_courses = 500; public $settings = []; /** * returns an AdminCourseFilter singleton object * @return AdminCourseFilter or derived-class object */ static public function get($reset_settings = false) { if (!self::$instance) { $class = get_called_class(); self::$instance = new $class($reset_settings); } return self::$instance; } /** * Constructor of the singleton-object. The settings might come from the session * if $reset_settings is false. * @param bool $reset_settings : should the session settings of the singleton be reset? */ public function __construct($reset_settings = false) { $this->initSettings(); if ($reset_settings) { $this->resetSettings(); } else { $this->restoreSettings(); } } /** * store settings in session */ public function storeSettings() { $_SESSION['AdminCourseFilter_settings'] = $this->settings; } /** * restore settings from session */ public function restoreSettings() { if ($_SESSION['AdminCourseFilter_settings']) { $this->settings = $_SESSION['AdminCourseFilter_settings']; } } /** * reset settings */ public function resetSettings() { $this->initSettings(); unset($_SESSION['AdminCourseFilter_settings']); } /** * initialize settings */ public function initSettings() { $this->settings = []; $this->settings['query']['select'] = [ 'Institut' => "Institute.Name", 'teilnehmer' => "(SELECT COUNT(seminar_id) FROM seminar_user WHERE seminar_id = seminare.Seminar_id AND status != 'dozent' AND status != 'tutor')", 'prelim' => "(SELECT COUNT(seminar_id) FROM admission_seminar_user WHERE seminar_id = seminare.Seminar_id AND status = 'accepted')", 'waiting' => "(SELECT COUNT(seminar_id) FROM admission_seminar_user WHERE seminar_id = seminare.Seminar_id AND status = 'awaiting')", 'requests' => "(SELECT COUNT(id) FROM resource_requests WHERE course_id = seminare.Seminar_id)", 'course_set' => "(SELECT set_id FROM seminar_courseset WHERE seminar_id = seminare.Seminar_id LIMIT 1)" ]; $this->settings['query']['joins'] = [ 'seminar_inst' => [ 'join' => "INNER JOIN", 'on' => "seminare.Seminar_id = seminar_inst.seminar_id" ], 'Institute' => [ 'join' => "INNER JOIN", 'on' => "seminar_inst.institut_id = Institute.Institut_id" ], 'sem_types' => [ 'join' => "LEFT JOIN", 'on' => "sem_types.id = seminare.status" ], 'sem_classes' => [ 'join' => "LEFT JOIN", 'on' => "sem_classes.id = sem_types.class" ] ]; $this->settings['query']['where'] = []; $this->settings['query']['orderby'] = Config::get()->IMPORTANT_SEMNUMBER ? "seminare.veranstaltungsnummer, seminare.name" : "seminare.name"; } /** * Adds a filter for all courses of the given semester. * @param string $semester_id : ID of the given semester. * @return $this * @throws Exception if semester_id does not exist */ public function filterBySemester($semester_id) { $semester = Semester::find($semester_id); if (!$semester) { throw new Exception("Das ausgewählte Semester scheint nicht zu existieren."); } $this->settings['query']['joins']['semester_courses'] = [ 'join' => "LEFT JOIN", 'on' => "semester_courses.course_id = seminare.Seminar_id" ]; $this->settings['query']['where']['semester'] = "(semester_courses.semester_id IS NULL OR semester_courses.semester_id = :semester_id)"; $this->settings['parameter']['semester_beginn'] = $semester['beginn']; $this->settings['parameter']['semester_id'] = $semester['id']; return $this; } /** * Adds a filter for a sem_type or many sem_types if the parameter is an array. * @param array|integer $type : id or ids of sem_types * @return $this */ public function filterByType($type) { if (is_array($type)) { $this->settings['query']['where']['status'] = "seminare.status IN (:types)"; $this->settings['parameter']['types'] = $type; } else { $this->settings['query']['where']['status'] = "seminare.status = :type"; $this->settings['parameter']['type'] = (int) $type; } return $this; } /** * Adds a filter for an institut_id or many institut_ids if the parameter is an array. * @param array|integer $institut_ids : id or ids of institutes * @return $this */ public function filterByInstitute($institut_ids) { if (Config::get()->ALLOW_ADMIN_RELATED_INST) { $sem_inst = 'seminar_inst'; } else { $sem_inst = 'seminare'; } if (is_array($institut_ids)) { $this->settings['query']['where']['institute'] = "$sem_inst.institut_id IN (:institut_ids)"; $this->settings['parameter']['institut_ids'] = $institut_ids; } else { $this->settings['query']['where']['status'] = "$sem_inst.institut_id = :institut_id"; $this->settings['parameter']['institut_id'] = (string) $institut_ids; } return $this; } /** * Adds a filter for an stgteil_id or many stgteil_ids if the parameter is an array. * @param array|integer $stgteil_ids : id or ids of stgteile * @return $this */ public function filterByStgTeil($stgteil_ids) { $this->settings['query']['joins']['mvv_lvgruppe_seminar'] = [ 'join' => "LEFT JOIN", 'table' => "mvv_lvgruppe_seminar", 'on' => "mvv_lvgruppe_seminar.seminar_id = seminare.Seminar_id" ]; $this->settings['query']['joins']['mvv_lvgruppe_modulteil'] = [ 'join' => "LEFT JOIN", 'table' => "mvv_lvgruppe_modulteil", 'on' => "mvv_lvgruppe_modulteil.lvgruppe_id = mvv_lvgruppe_seminar.lvgruppe_id" ]; $this->settings['query']['joins']['mvv_modulteil'] = [ 'join' => "LEFT JOIN", 'table' => "mvv_modulteil", 'on' => "mvv_modulteil.modulteil_id = mvv_lvgruppe_modulteil.modulteil_id" ]; $this->settings['query']['joins']['mvv_stgteilabschnitt_modul'] = [ 'join' => "LEFT JOIN", 'table' => "mvv_stgteilabschnitt_modul", 'on' => "mvv_stgteilabschnitt_modul.modul_id = mvv_modulteil.modul_id" ]; $this->settings['query']['joins']['mvv_stgteilabschnitt'] = [ 'join' => "LEFT JOIN", 'table' => "mvv_stgteilabschnitt", 'on' => "mvv_stgteilabschnitt.abschnitt_id = mvv_stgteilabschnitt_modul.abschnitt_id" ]; $this->settings['query']['joins']['mvv_stgteilversion'] = [ 'join' => "LEFT JOIN", 'table' => "mvv_stgteilversion", 'on' => "mvv_stgteilversion.version_id = mvv_stgteilabschnitt.version_id" ]; if (is_array($stgteil_ids)) { $this->settings['query']['where']['mvv_stgteilversion'] = "mvv_stgteilversion.stgteil_id IN (:stgteil_ids)"; $this->settings['parameter']['stgteil_ids'] = $stgteil_ids; } else { $this->settings['query']['where']['mvv_stgteilversion'] = "mvv_stgteilversion.stgteil_id = :stgteil_id"; $this->settings['parameter']['stgteil_id'] = (string) $stgteil_ids; } return $this; } public function filterByDozent($user_ids) { $this->settings['query']['joins']['dozenten'] = [ 'join' => "INNER JOIN", 'table' => "seminar_user", 'on' => "dozenten.Seminar_id = seminare.Seminar_id AND dozenten.status = 'dozent'" ]; if (is_array($user_ids)) { $this->settings['query']['where']['dozenten'] = "dozenten.user_id IN (:dozenten_ids)"; $this->settings['parameter']['dozenten_ids'] = $user_ids; } else { $this->settings['query']['where']['dozenten'] = "dozenten.user_id = :dozenten_id"; $this->settings['parameter']['dozenten_id'] = (string) $user_ids; } return $this; } /** * Adds a filter for a textstring, that can be the coursenumber, the name of the course * or the last name of one of the dozenten. * @param string $text : the searchstring * @return $this */ public function filterBySearchstring($text) { $this->settings['query']['joins']['dozenten'] = [ 'join' => "INNER JOIN", 'table' => "seminar_user", 'on' => "dozenten.Seminar_id = seminare.Seminar_id AND dozenten.status = 'dozent'" ]; $this->settings['query']['joins']['dozentendata'] = [ 'join' => "INNER JOIN", 'table' => "auth_user_md5", 'on' => "dozenten.user_id = dozentendata.user_id" ]; $this->settings['query']['where']['search'] = "(CONCAT_WS(' ', seminare.VeranstaltungsNummer, seminare.name, seminare.Untertitel, dozentendata.Nachname) LIKE :search OR CONCAT(dozentendata.Nachname, ', ', dozentendata.Vorname) LIKE :search OR CONCAT_WS(' ', dozentendata.Vorname, dozentendata.Nachname) LIKE :search OR dozentendata.Vorname LIKE :search OR dozentendata.Nachname LIKE :search )"; $this->settings['parameter']['search'] = "%".$text."%"; return $this; } /** * @param string $attribute : column, name of the column, yb whcih we should order the results * @param string $flag : "ASC" or "DESC for ascending order or descending order, * @return $this * @throws Exception if $flag does not exist */ public function orderBy($attribute, $flag = 'ASC') { $flag = mb_strtoupper($flag); if (!in_array($flag, words('ASC DESC'))) { throw new Exception("Sortierreihenfolge undefiniert."); } if (in_array($attribute, words('VeranstaltungsNummer Name status teilnehmer waiting prelim requests completion start_time'))) { $this->settings['query']['orderby'] = $attribute . ' ' . $flag; } return $this; } /** * Adds a where filter. * @param string $where : any where condition like "sem_classes.overview = 'CoreOverview'" * @param array $parameter : an array of parameter that appear in the $where query. * @param null|string $id : an id of the where-query. Use this to possibly * avoid double where conditions or allow deleting the condition * by plugins if necessary. Can be omitted. * @return $this */ public function where($where, $parameter = [], $id = null) { if (!$id) { $id = md5($where); } $this->settings['query']['where'][$id] = $where; $this->settings['parameter'] = array_merge((array) $this->settings['parameter'], $parameter); return $this; } /** * Returns the data of the resultset of the AdminCourseFilter. * Also saves the settings in the session. * Note that a notification AdminCourseFilterWillQuery will be posted, before the result is computed. * Plugins may register at this event to fully alter this AdminCourseFilter-object and so the resultset. * @return array : associative array with seminar_ids as keys and seminar-data-arrays as values. */ public function getCourses($grouped = true) { NotificationCenter::postNotification("AdminCourseFilterWillQuery", $this); if (empty($this->settings['query']['where'])) { return []; } $statement = DBManager::get()->prepare($this->createQuery()); $statement->execute($this->settings['parameter']); $_SESSION['AdminCourseFilter_settings'] = $this->settings; return $statement->fetchAll($grouped ? (PDO::FETCH_GROUP | PDO::FETCH_ASSOC) : PDO::FETCH_ASSOC); } /** * @return number of courses that this filter would return */ public function countCourses() { NotificationCenter::postNotification("AdminCourseFilterWillQuery", $this); if (empty($this->settings['query']['where'])) { return 0; } return DBManager::get()->fetchColumn($this->createQuery(true), $this->settings['parameter']); } /** * Returns the data of the resultset of the AdminCourseFilter. * * Note that a notification AdminCourseFilterWillQuery will be posted, before the result is computed. * Plugins may register at this event to fully alter this AdminCourseFilter-object and so the resultset. * @return array : associative array with seminar_ids as keys and seminar-data-arrays as values. */ public function getCoursesForAdminWidget() { $count_courses = $this->countCourses(); if ($count_courses && $count_courses <= $this->max_show_courses) { $settings = $this->settings; $this->settings['query']['select'] = []; $this->settings['query']['orderby'] = Config::get()->IMPORTANT_SEMNUMBER ? 'seminare.veranstaltungsnummer, seminare.name' : 'seminare.name'; $ret = $this->getCourses(false); $this->settings = $settings; return $ret; } return []; } /** * Creates the sql-query from the $this->settings['query'] * @only_count : boolean * @return string : the big query */ public function createQuery($only_count = false) { if ($only_count) { $select_query = "COUNT(DISTINCT seminare.Seminar_id) "; } else { $select_query = "seminare.* "; foreach ((array) $this->settings['query']['select'] as $alias => $select) { $select_query .= ", ".$select." AS ".$alias." "; } } $join_query = ""; foreach ((array) $this->settings['query']['joins'] as $alias => $joininfo) { $table = isset($joininfo['table']) ? $joininfo['table']." AS ".$alias : $alias; $on = isset($joininfo['on']) ? " ON (".$joininfo['on'].")" : ""; $join_query .= " ".(isset($joininfo['join']) ? $joininfo['join'] : "INNER JOIN")." ".$table.$on." "; } $where_query = ""; if (count($this->settings['query']['where']) > 0) { $where_query .= implode(" AND ", $this->settings['query']['where']); } $query = " SELECT ".$select_query." FROM seminare ".$join_query." ".($where_query ? "WHERE ".$where_query : ""); if (!$only_count) { $query .= " GROUP BY seminare.Seminar_id ORDER BY ".$this->settings['query']['orderby'].($this->settings['query']['orderby'] !== "seminare.name" ? ", seminare.name" : ""); } return $query; } }