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
|
<?php
namespace MassWidget;
use DBManager;
use JSONArrayObject;
use Plugin;
use Semester;
use SimpleORMap;
use User;
use UserFilter;
use UserFilterRange;
use WidgetUser;
class MassWidget extends SimpleORMap implements UserFilterRange
{
protected static function configure($config = [])
{
$config['db_table'] = 'masswidget';
$config['serialized_fields']['settings'] = JSONArrayObject::class;
$config['has_one']['author'] = [
'class_name' => User::class,
'foreign_key' => 'author_id',
'assoc_foreign_key' => 'user_id'
];
$config['has_many']['filters'] = [
'class_name' => MassWidgetFilter::class,
'assoc_foreign_key' => 'masswidget_id',
'on_store' => 'store',
'on_delete' => 'delete'
];
$config['has_one']['plugin'] = [
'class_name' => Plugin::class,
'foreign_key' => 'plugin_id',
'assoc_foreign_key' => 'pluginid'
];
parent::configure($config);
}
public static function getTargets(): array
{
return [
'all' => _('alle'),
'students' => _('Studierende'),
'employees' => _('Mitarbeitende'),
'lecturers' => _('Aktive Lehrende'),
'courses' => _('Veranstaltungen'),
'usernames' => _('Liste von Nutzernamen'),
];
}
/**
* Gets the real recipient list for this widget.
* @return string[] The list of user IDs that will receive this widget.
*/
public function getTargetUserIds(): array
{
$ids = [];
switch ($this->target) {
// Everyone studying something or working at an institute.
case 'all':
$students = DBManager::get()->fetchFirst("SELECT DISTINCT `user_id` FROM `user_studiengang`");
$employees = DBManager::get()->fetchFirst(
"SELECT DISTINCT `user_id` FROM `user_inst` WHERE `inst_perms` IN (:perms)",
['perms' => ['autor', 'tutor', 'dozent']]
);
$ids = array_unique(array_merge($students, $employees));
break;
// Students are users with at least one studycourse assignment in user_studiengang.
case 'students':
$ids = DBManager::get()->fetchFirst("SELECT DISTINCT `user_id` FROM `user_studiengang`");
if (count($this->filters) > 0) {
$filtered = [];
foreach ($this->filters as $filter) {
$f = new UserFilter($filter->filter_id);
$filtered = array_merge($filtered, $f->getUsers());
}
$ids = array_unique(array_intersect($ids, $filtered));
}
break;
// Employees are users with at least one institute assignment at 'autor" level or more.
case 'employees':
$ids = DBManager::get()->fetchFirst(
"SELECT DISTINCT `user_id` FROM `user_inst` WHERE `inst_perms` IN (:perms)",
['perms' => ['autor', 'tutor', 'dozent']]
);
if (count($this->filters) > 0) {
$filtered = [];
foreach ($this->filters as $filter) {
$f = new UserFilter($filter->filter_id);
$filtered = array_merge($filtered, $f->getUsers());
}
$ids = array_unique(array_intersect($ids, $filtered));
}
break;
// Course members having the specified permission level.
case 'courses':
$courses = array_map(
fn ($course) => $course['id'],
$this->settings['courses']->getArrayCopy()
);
$permission = $this->settings['perm'];
$ids = DBManager::get()->fetchFirst(
"SELECT DISTINCT `user_id` FROM `seminar_user` WHERE `Seminar_id` IN (:courses) AND `status` = :perm",
['courses' => $courses, 'perm' => $permission]
);
break;
// Lecturers of at least one course in the given semester
case 'lecturers':
$ids = DBManager::get()->fetchFirst(
"SELECT DISTINCT u.`user_id` FROM `seminar_user` u
LEFT JOIN `semester_courses` sc ON (sc.`course_id` = u.`Seminar_id`)
JOIN `seminare` s ON (s.`Seminar_id` = u.`Seminar_id`)
JOIN `sem_types` t ON (t.`id` = s.`status`)
WHERE (sc.`semester_id` = :semester OR sc.`semester_id` IS NULL)
AND t.`class` IN (:categories)
AND u.`status` = 'dozent'",
[
'semester' => $this->settings['semester'],
'categories' => \Config::get()->MASSMAIL_LECTURER_SEM_CATEGORIES
]
);
break;
case 'usernames':
$ids = DBManager::get()->fetchFirst(
"SELECT DISTINCT `user_id` FROM `auth_user_md5` WHERE `Username` IN (:usernames)",
['usernames' => explode("\n", $this->settings['usernames'])]
);
}
return DBManager::get()->fetchFirst(
"SELECT DISTINCT `user_id`
FROM `auth_user_md5`
WHERE `visible` != :visible
AND `locked` = :locked
AND `user_id` IN (:ids)
AND `username` NOT IN (:exclude)
ORDER BY `username`
",
[
'visible' => 'never',
'locked' => 0,
'ids' => $ids,
'exclude' => $this->exclude_users ? explode("\n", $this->exclude_users) : ['']
]
);
}
public function deleteUserWidgets(): self
{
$recipientIds = $this->getTargetUserIds();
WidgetUser::deleteBySQL(
'pluginid = :plugin_id AND range_id IN (:user_ids)',
['plugin_id' => $this->plugin_id, 'user_ids' => $recipientIds]
);
return $this;
}
public function canEditFilter(User $user, UserFilter $filter): bool
{
return $GLOBALS['perm']->have_perm('root');
}
}
|