1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
|
<?php
/**
* Class AdminCourseFilter
*
* The main class to filter all courses for admins. It's a singleton class, so you
* better call it with AdminCourseFilter::get(). The whole class is created to
* provide a nice hook for plugins to add special filters into the admin-area of
* Stud.IP.
*
* To add a filter with a plugin, listen to the notification "AdminCourseFilterWillQuery"
* like this:
*
* NotificationCenter::addObserver($this, "addMyFilter", "AdminCourseFilterWillQuery");
*
* Where $this is an object and "addMyFilter" a method. Such a method might look like this:
*
* public function addLectureshipFilter($event, $filter)
* {
* if ($GLOBALS['user']->cfg->getValue("LECTURESHIP_FILTER")) {
* $filter->query->join('lehrauftrag', 'seminare.Seminar_id = lehrauftrag.seminar_id');
* }
* }
*
* Within this method you alter the public $filter->query object. That query object is of type SQLQuery.
*
*/
class AdminCourseFilter
{
static protected $instance = null;
public $query = 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.
*/
public function __construct()
{
$this->initSettings();
}
protected function initSettings()
{
$this->query = SQLQuery::table('seminare');
$this->query->join('sem_types', 'sem_types', 'sem_types.id = seminare.status');
$this->query->join('sem_classes', 'sem_classes', 'sem_classes.id = sem_types.class');
$this->query->where("sem_classes.studygroup_mode = '0'");
$this->query->groupBy('seminare.Seminar_id');
if ($GLOBALS['user']->cfg->ADMIN_COURSES_SEARCHTEXT) {
$this->query->join('teachers_su', 'seminar_user', "teachers_su.Seminar_id = seminare.Seminar_id AND teachers_su.status = 'dozent'");
$this->query->join('teachers', 'auth_user_md5', 'teachers.user_id = teachers_su.user_id');
$this->query->where(
'search',
"(seminare.name LIKE :search OR seminare.VeranstaltungsNummer LIKE :search OR seminare.untertitel LIKE :search OR CONCAT(teachers.Vorname, ' ', teachers.Nachname) LIKE :search)",
['search' => '%'.$GLOBALS['user']->cfg->ADMIN_COURSES_SEARCHTEXT.'%']
);
}
if (Request::option('course_id')) {
$this->query->where('course_id', 'seminare.Seminar_id = :course_id', ['course_id' => Request::option('course_id')]);
}
$inst_ids = [];
if (
!$GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT
|| $GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT === 'all'
) {
$inst = new SimpleCollection(Institute::getMyInstitutes($GLOBALS['user']->id));
$inst_ids = $inst->map(function ($a) {
return $a['Institut_id'];
});
} else {
//We must check, if the institute ID belongs to a faculty
//and has the string _i appended to it.
//In that case we must display the courses of the faculty
//and all its institutes.
//Otherwise we just display the courses of the faculty.
$include_children = false;
$inst_id = $GLOBALS['user']->cfg->MY_INSTITUTES_DEFAULT;
if (str_contains($inst_id, '_')) {
$inst_id = substr($inst_id, 0, strpos($inst_id, '_'));
$include_children = true;
}
$inst_ids[] = $inst_id;
if ($include_children) {
$inst = Institute::find($inst_id);
if ($inst && $inst->isFaculty()) {
foreach ($inst->sub_institutes->pluck('Institut_id') as $institut_id) {
$inst_ids[] = $institut_id;
}
}
}
}
if (Config::get()->ALLOW_ADMIN_RELATED_INST) {
$sem_inst = 'seminar_inst';
$this->query->join('seminar_inst', 'seminar_inst', 'seminar_inst.seminar_id = seminare.Seminar_id');
} else {
$sem_inst = 'seminare';
}
$this->query->where('seminar_inst', "$sem_inst.institut_id IN (:institut_ids)");
$this->query->parameter('institut_ids', $inst_ids);
if ($GLOBALS['user']->cfg->MY_COURSES_SELECTED_CYCLE) {
$this->query->join('semester_courses', 'semester_courses.course_id = seminare.Seminar_id', 'LEFT JOIN');
$this->query->where('semester_id', '(semester_courses.semester_id = :semester_id OR semester_courses.semester_id IS NULL)', [
'semester_id' => $GLOBALS['user']->cfg->MY_COURSES_SELECTED_CYCLE
]);
}
if ($GLOBALS['user']->cfg->MY_COURSES_TYPE_FILTER && $GLOBALS['user']->cfg->MY_COURSES_TYPE_FILTER !== 'all') {
if (str_contains($GLOBALS['user']->cfg->MY_COURSES_TYPE_FILTER, '_')) {
list($sem_class_id, $sem_type_id) = explode('_', $GLOBALS['user']->cfg->MY_COURSES_TYPE_FILTER);
$this->query->where('course_type', 'seminare.status = :course_type', ['course_type' => $sem_type_id]);
} else {
//sem class
$this->query->where('course_class', 'sem_types.class = :course_class', [
'course_class' => $GLOBALS['user']->cfg->MY_COURSES_TYPE_FILTER
]);
}
}
if ($GLOBALS['user']->cfg->MY_COURSES_SELECTED_STGTEIL) {
$this->query->join('mvv_lvgruppe_seminar', '`mvv_lvgruppe_seminar`.`seminar_id` = `seminare`.`Seminar_id`');
$this->query->join('mvv_lvgruppe_modulteil', '`mvv_lvgruppe_modulteil`.`lvgruppe_id` = `mvv_lvgruppe_seminar`.`lvgruppe_id`');
$this->query->join('mvv_modulteil', '`mvv_modulteil`.`modulteil_id` = `mvv_lvgruppe_modulteil`.`modulteil_id`');
$this->query->join('mvv_modul', '`mvv_modul`.`modul_id` = `mvv_modulteil`.`modul_id`');
$this->query->join('mvv_stgteilabschnitt_modul', '`mvv_stgteilabschnitt_modul`.`modul_id` = `mvv_modul`.`modul_id`');
$this->query->join('mvv_stgteilabschnitt', '`mvv_stgteilabschnitt`.`abschnitt_id` = `mvv_stgteilabschnitt_modul`.`abschnitt_id`');
$this->query->join('mvv_stgteilversion', '`mvv_stgteilversion`.`version_id` = `mvv_stgteilabschnitt`.`version_id`');
$this->query->where('stgteil', 'mvv_stgteilversion.stgteil_id = :stgteil_id', [
'stgteil_id' => $GLOBALS['user']->cfg->MY_COURSES_SELECTED_STGTEIL
]);
}
if ($GLOBALS['user']->cfg->ADMIN_COURSES_TEACHERFILTER) {
$this->query->join('teachers_su', 'seminar_user', "teachers_su.Seminar_id = seminare.Seminar_id AND teachers_su.status = 'dozent'");
$this->query->where(
'teacher_filter',
"teachers_su.user_id = :teacher_id",
['teacher_id' => $GLOBALS['user']->cfg->ADMIN_COURSES_TEACHERFILTER]
);
}
$datafields_filters = $GLOBALS['user']->cfg->ADMIN_COURSES_DATAFIELDS_FILTERS;
foreach ($datafields_filters as $datafield_id => $value) {
$this->query->join('de_'.$datafield_id, 'datafields_entries', 'de_'.$datafield_id.'.range_id = seminare.Seminar_id AND `de_'.$datafield_id.'`.datafield_id = :de_'.$datafield_id.'_id');
$this->query->where('de_' . $datafield_id . '_contents', 'de_' . $datafield_id . '.`content` LIKE :de_' . $datafield_id . '_content',
[
'de_' . $datafield_id . '_id' => $datafield_id,
'de_' . $datafield_id . '_content' => '%' . $value . '%'
]);
}
}
/**
* 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()
{
NotificationCenter::postNotification("AdminCourseFilterWillQuery", $this);
return $this->query->fetchAll(Course::class);
}
/**
* @return integer number of courses that this filter would return
*/
public function countCourses()
{
NotificationCenter::postNotification("AdminCourseFilterWillQuery", $this);
return $this->query->count();
}
/**
* Returns the data of the resultset of the AdminCourseFilter.
*
* @param string $order_by possible values name or number
*
* 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(string $order_by = 'name')
{
$count_courses = $this->countCourses();
$order = 'seminare.name';
if ($order_by === 'number') {
$order = 'seminare.veranstaltungsnummer, seminare.name';
}
if ($count_courses && $count_courses <= $this->max_show_courses) {
$this->query->orderBy($order);
return $this->getCourses();
}
return [];
}
}
|