ILIAS  release_8 Revision v8.24
class.ilForumNotification.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22{
24 private static array $node_data_cache = [];
26 private static array $forced_events_cache = [];
27
30 private int $notification_id;
31 private ?int $user_id = null;
32 private int $forum_id;
33 private int $thread_id;
34 private bool $admin_force = false;
35 private bool $user_toggle = false;
36 private int $interested_events = 0;
37 private int $ref_id;
38 private int $user_id_noti;
39
40 public function __construct(int $ref_id)
41 {
42 global $DIC;
43
44 $this->db = $DIC->database();
45 $this->user = $DIC->user();
46 $this->ref_id = $ref_id;
47 $this->forum_id = $DIC['ilObjDataCache']->lookupObjId($ref_id);
48 }
49
50 public function setNotificationId(int $a_notification_id): void
51 {
52 $this->notification_id = $a_notification_id;
53 }
54
55 public function getNotificationId(): int
56 {
58 }
59
60 public function setUserId(?int $a_user_id): void
61 {
62 $this->user_id = $a_user_id;
63 }
64
65 public function getUserId(): ?int
66 {
67 return $this->user_id;
68 }
69
70 public function setForumId(int $a_forum_id): void
71 {
72 $this->forum_id = $a_forum_id;
73 }
74
75 public function getForumId(): int
76 {
77 return $this->forum_id;
78 }
79
80 public function setThreadId(int $a_thread_id): void
81 {
82 $this->thread_id = $a_thread_id;
83 }
84
85 public function getThreadId(): int
86 {
87 return $this->thread_id;
88 }
89
91 {
92 $this->interested_events = $interested_events;
93 }
94
95 public function getInterestedEvents(): int
96 {
98 }
99
100 public function setAdminForce(bool $a_admin_force): void
101 {
102 $this->admin_force = $a_admin_force;
103 }
104
105 public function getAdminForce(): bool
106 {
107 return $this->admin_force;
108 }
109
110 public function setUserToggle(bool $a_user_toggle): void
111 {
112 $this->user_toggle = $a_user_toggle;
113 }
114
115 public function getUserToggle(): bool
116 {
117 return $this->user_toggle;
118 }
119
120 public function setForumRefId(int $a_ref_id): void
121 {
122 $this->ref_id = $a_ref_id;
123 }
124
125 public function getForumRefId(): int
126 {
127 return $this->ref_id;
128 }
129
130 //user_id of who sets the setting to notify members
131 public function setUserIdNoti(int $a_user_id_noti): void
132 {
133 $this->user_id_noti = $a_user_id_noti;
134 }
135
136 //user_id of who sets the setting to notify members
137 public function getUserIdNoti(): int
138 {
139 return $this->user_id_noti;
140 }
141
142 public function isAdminForceNotification(): bool
143 {
144 $res = $this->db->queryF(
145 '
146 SELECT admin_force_noti FROM frm_notification
147 WHERE user_id = %s
148 AND frm_id = %s
149 AND user_id_noti > %s ',
150 ['integer', 'integer', 'integer'],
151 [(int) $this->getUserId(), $this->getForumId(), 0]
152 );
153
154 if ($row = $this->db->fetchAssoc($res)) {
155 return (bool) $row['admin_force_noti'];
156 }
157
158 return false;
159 }
160
161 public function isUserToggleNotification(): bool
162 {
163 $res = $this->db->queryF(
164 '
165 SELECT user_toggle_noti FROM frm_notification
166 WHERE user_id = %s
167 AND frm_id = %s
168 AND user_id_noti > %s',
169 ['integer', 'integer', 'integer'],
170 [(int) $this->getUserId(), $this->getForumId(), 0]
171 );
172
173 if ($row = $this->db->fetchAssoc($res)) {
174 return (bool) $row['user_toggle_noti'];
175 }
176 return false;
177 }
178
179 public function insertAdminForce(): void
180 {
181 $next_id = $this->db->nextId('frm_notification');
182 $this->setNotificationId($next_id);
183
184 $this->db->manipulateF(
185 '
186 INSERT INTO frm_notification
187 (notification_id, user_id, frm_id, admin_force_noti, user_toggle_noti, user_id_noti)
188 VALUES(%s, %s, %s, %s, %s, %s)',
189 ['integer', 'integer', 'integer', 'integer', 'integer', 'integer'],
190 [
191 $next_id,
192 (int) $this->getUserId(),
193 $this->getForumId(),
194 $this->getAdminForce(),
195 $this->getUserToggle(),
196 $this->user->getId()
197 ]
198 );
199 }
200
201 public function deleteAdminForce(): void
202 {
203 $this->db->manipulateF(
204 '
205 DELETE FROM frm_notification
206 WHERE user_id = %s
207 AND frm_id = %s
208 AND admin_force_noti = %s
209 AND user_id_noti > %s',
210 ['integer', 'integer', 'integer', 'integer'],
211 [(int) $this->getUserId(), $this->getForumId(), 1, 0]
212 );
213 }
214
215 public function deleteUserToggle(): void
216 {
217 $this->db->manipulateF(
218 '
219 DELETE FROM frm_notification
220 WHERE user_id = %s
221 AND frm_id = %s
222 AND admin_force_noti = %s
223 AND user_toggle_noti = %s
224 AND user_id_noti > %s',
225 ['integer', 'integer', 'integer', 'integer', 'integer'],
226 [(int) $this->getUserId(), $this->getForumId(), 1, 1, 0]
227 );
228 }
229
230 public function updateUserToggle(): void
231 {
232 $this->db->manipulateF(
233 'UPDATE frm_notification SET user_toggle_noti = %s WHERE user_id = %s AND frm_id = %s AND admin_force_noti = %s',
234 ['integer', 'integer', 'integer', 'integer'],
235 [$this->getUserToggle(), (int) $this->getUserId(), $this->getForumId(), 1]
236 );
237 }
238
239 /* If a new member enters a Course or a Group, this function checks
240 * if this CRS/GRP contains a forum and a notification setting set by admin or moderator
241 * and inserts the new member into frm_notification
242 * */
243 public static function checkForumsExistsInsert(int $ref_id, int $user_id): void
244 {
245 global $DIC;
246
247 $ilUser = $DIC->user();
248
249 $node_data = self::getCachedNodeData($ref_id);
250
251 foreach ($node_data as $data) {
252 //check frm_properties if frm_noti is enabled
253 $frm_noti = new ilForumNotification((int) $data['ref_id']);
254 if ($user_id !== 0) {
255 $frm_noti->setUserId($user_id);
256 } else {
257 $frm_noti->setUserId($ilUser->getId());
258 }
259
261 $frm_noti->setAdminForce($admin_force);
262
264 if ($user_toggle) {
265 $frm_noti->setAdminForce(true);
266 }
267
268 if ($admin_force || $user_toggle) {
269 $frm_noti->setUserToggle($user_toggle);
270 $frm_noti->setForumId((int) $data['obj_id']);
271 if ($frm_noti->existsNotification() === false) {
272 $frm_noti->insertAdminForce();
273 }
274 }
275 }
276 }
277
278 public static function checkForumsExistsDelete(int $ref_id, int $user_id): void
279 {
280 global $DIC;
281
282 $ilUser = $DIC->user();
283
284 $node_data = self::getCachedNodeData($ref_id);
285
286 foreach ($node_data as $data) {
287 $frm_noti = new ilForumNotification((int) $data['ref_id']);
288 $objFrmMods = new ilForumModerators((int) $data['ref_id']);
289 $moderator_ids = $objFrmMods->getCurrentModerators();
290
291 if ($user_id !== 0) {
292 $frm_noti->setUserId($user_id);
293 } else {
294 $frm_noti->setUserId($ilUser->getId());
295 }
296
297 $frm_noti->setForumId((int) $data['obj_id']);
298 if (!in_array($frm_noti->getUserId(), $moderator_ids, true)) {
299 $frm_noti->deleteAdminForce();
300 }
301 }
302 }
303
304 public static function getCachedNodeData(int $ref_id): array
305 {
306 global $DIC;
307
308 if (!array_key_exists($ref_id, self::$node_data_cache)) {
309 $node_data = $DIC->repositoryTree()->getSubTree(
310 $DIC->repositoryTree()->getNodeData($ref_id),
311 true,
312 ['frm']
313 );
314 $node_data = array_filter($node_data, static function (array $forum_node) use ($DIC, $ref_id): bool {
315 // filter out forum if a grp lies in the path (#0027702)
316 foreach ($DIC->repositoryTree()->getNodePath((int) $forum_node['child'], $ref_id) as $path_node) {
317 $notRootNode = (int) $path_node['child'] !== (int) $ref_id;
318 $isGroup = $path_node['type'] === 'grp';
319 if ($notRootNode && $isGroup) {
320 return false;
321 }
322 }
323
324 return true;
325 });
326 self::$node_data_cache[$ref_id] = $node_data;
327 }
328
329 return self::$node_data_cache[$ref_id];
330 }
331
332 public static function _isParentNodeGrpCrs(int $a_ref_id): bool
333 {
334 global $DIC;
335
336 $parent_ref_id = $DIC->repositoryTree()->getParentId($a_ref_id);
337 $parent_obj = ilObjectFactory::getInstanceByRefId($parent_ref_id);
338
339 return $parent_obj->getType() === 'crs' || $parent_obj->getType() === 'grp';
340 }
341
342 public static function _clearForcedForumNotifications(array $move_tree_event): void
343 {
344 global $DIC;
345 $ilDB = $DIC->database();
346 $ilObjDataCache = $DIC['ilObjDataCache'];
347
348 if ($move_tree_event['tree'] !== 'tree') {
349 return;
350 }
351
352 $ref_id = (int) $move_tree_event['source_id'];
353 $is_parent = self::_isParentNodeGrpCrs($ref_id);
354
355 if ($is_parent) {
356 $forum_id = $ilObjDataCache->lookupObjId($ref_id);
357
358 $ilDB->manipulateF(
359 'DELETE FROM frm_notification WHERE frm_id = %s AND admin_force_noti = %s',
360 ['integer', 'integer'],
361 [$forum_id, 1]
362 );
363 }
364 }
365
366 public function update(): void
367 {
368 $this->db->manipulateF(
369 'UPDATE frm_notification SET admin_force_noti = %s, user_toggle_noti = %s, ' .
370 'interested_events = %s WHERE user_id = %s AND frm_id = %s',
371 ['integer', 'integer', 'integer', 'integer', 'integer'],
372 [
373 (int) $this->getAdminForce(),
374 (int) $this->getUserToggle(),
375 $this->getInterestedEvents(),
376 (int) $this->getUserId(),
377 $this->getForumId()
378 ]
379 );
380 }
381
382 public function deleteNotificationAllUsers(): void
383 {
384 $this->db->manipulateF(
385 'DELETE FROM frm_notification WHERE frm_id = %s AND user_id_noti > %s',
386 ['integer', 'integer'],
387 [$this->getForumId(), 0]
388 );
389 }
390
394 public function read(): array
395 {
396 $result = [];
397
398 $res = $this->db->queryF('SELECT * FROM frm_notification WHERE frm_id = %s', ['integer'], [$this->getForumId()]);
399 while ($row = $this->db->fetchAssoc($res)) {
400 $result[(int) $row['user_id']]['notification_id'] = (int) $row['notification_id'];
401 $result[(int) $row['user_id']]['user_id'] = (int) $row['user_id'];
402 $result[(int) $row['user_id']]['frm_id'] = (int) $row['frm_id'];
403 $result[(int) $row['user_id']]['thread_id'] = (int) $row['thread_id'];
404 $result[(int) $row['user_id']]['admin_force_noti'] = (int) $row['admin_force_noti'];
405 $result[(int) $row['user_id']]['user_toggle_noti'] = (int) $row['user_toggle_noti'];
406 $result[(int) $row['user_id']]['interested_events'] = (int) $row['interested_events'];
407 $result[(int) $row['user_id']]['user_id_noti'] = (int) $row['user_id_noti'];
408 }
409
410 return $result;
411 }
412
413 public static function mergeThreadNotifications($merge_source_thread_id, $merge_target_thread_id): void
414 {
415 global $DIC;
416
417 $ilDB = $DIC->database();
418
419 $res = $ilDB->queryF(
420 'SELECT notification_id, user_id FROM frm_notification WHERE frm_id = %s AND thread_id = %s ORDER BY user_id ASC',
421 ['integer', 'integer'],
422 [0, $merge_source_thread_id]
423 );
424
425 $res_2 = $ilDB->queryF(
426 'SELECT DISTINCT user_id FROM frm_notification WHERE frm_id = %s AND thread_id = %s ORDER BY user_id ASC',
427 ['integer', 'integer'],
428 [0, $merge_target_thread_id]
429 );
430
431 $users_already_notified = [];
432 while ($users_row = $ilDB->fetchAssoc($res_2)) {
433 $users_already_notified[(int) $users_row['user_id']] = (int) $users_row['user_id'];
434 }
435
436 while ($row = $ilDB->fetchAssoc($res)) {
437 if (isset($users_already_notified[(int) $row['user_id']])) {
438 $ilDB->manipulateF(
439 'DELETE FROM frm_notification WHERE notification_id = %s',
440 ['integer'],
441 [$row['notification_id']]
442 );
443 } else {
444 $ilDB->update(
445 'frm_notification',
446 ['thread_id' => ['integer', $merge_target_thread_id]],
447 ['thread_id' => ['integer', $merge_source_thread_id]]
448 );
449 }
450 }
451 }
452
453 public function existsNotification(): bool
454 {
455 $res = $this->db->queryF(
456 'SELECT user_id FROM frm_notification WHERE user_id = %s AND frm_id = %s AND admin_force_noti = %s',
457 ['integer', 'integer', 'integer'],
458 [(int) $this->getUserId(), $this->getForumId(), (int) $this->getAdminForce()]
459 );
460
461 return $this->db->numRows($res) > 0;
462 }
463
464 public function cloneFromSource(int $sourceRefId): void
465 {
466 $sourceNotificationSettings = new self($sourceRefId);
467 $records = $sourceNotificationSettings->read();
468
469 foreach ($records as $usrId => $row) {
470 $this->setUserId($usrId);
471 $this->setAdminForce((bool) $row['admin_force_noti']);
472 $this->setUserToggle((bool) $row['user_toggle_noti']);
473 $this->setUserIdNoti((int) $row['user_id_noti']);
474 $this->setInterestedEvents((int) $row['interested_events']);
475
476 $this->insertAdminForce();
477 }
478 }
479
480 public function updateInterestedEvents(): void
481 {
482 $this->db->manipulateF(
483 'UPDATE frm_notification SET interested_events = %s WHERE user_id = %s AND frm_id = %s',
484 ['integer', 'integer', 'integer'],
485 [$this->getInterestedEvents(), (int) $this->getUserId(), $this->getForumId()]
486 );
487 }
488
489 public function readInterestedEvents(): int
490 {
491 $interested_events = ilForumNotificationEvents::DEACTIVATED;
492
493 $this->db->setLimit(1);
494 $res = $this->db->queryF(
495 'SELECT interested_events FROM frm_notification WHERE user_id = %s AND frm_id = %s',
496 ['integer', 'integer'],
497 [(int) $this->getUserId(), $this->getForumId()]
498 );
499
500 while ($row = $this->db->fetchAssoc($res)) {
501 $interested_events = (int) $row['interested_events'];
502 }
503
504 return $interested_events;
505 }
506
510 public function readAllForcedEvents(): array
511 {
512 $res = $this->db->queryF(
513 'SELECT * FROM frm_notification WHERE admin_force_noti = %s AND frm_id = %s',
514 ['integer', 'integer'],
515 [1, $this->forum_id]
516 );
517
518 while ($row = $this->db->fetchAssoc($res)) {
519 $notificationConfig = new self($this->ref_id);
520 $notificationConfig->setNotificationId((int) $row['notification_id']);
521 $notificationConfig->setUserId((int) $row['user_id']);
522 $notificationConfig->setForumId((int) $row['frm_id']);
523 $notificationConfig->setAdminForce((bool) $row['admin_force_noti']);
524 $notificationConfig->setUserToggle((bool) $row['user_toggle_noti']);
525 $notificationConfig->setInterestedEvents((int) $row['interested_events']);
526
527 self::$forced_events_cache[(int) $row['user_id']] = $notificationConfig;
528 }
529
530 return self::$forced_events_cache;
531 }
532
533 public function getForcedEventsObjectByUserId(int $user_id): self
534 {
535 if (!isset(self::$forced_events_cache[$user_id])) {
536 $this->readAllForcedEvents();
537 }
538
539 if (!isset(self::$forced_events_cache[$user_id])) {
540 self::$forced_events_cache[$user_id] = $this->createMissingNotification($user_id);
541 }
542
543 return self::$forced_events_cache[$user_id];
544 }
545
546 private function createMissingNotification(int $user_id): self
547 {
548 $new_object = new self($this->ref_id);
549 $new_object->setUserId($user_id);
550 $new_object->setForumId($this->forum_id);
551 $new_object->insertAdminForce();
552
553 return $new_object;
554 }
555}
Class ilForumModerators.
static checkForumsExistsInsert(int $ref_id, int $user_id)
static mergeThreadNotifications($merge_source_thread_id, $merge_target_thread_id)
static _clearForcedForumNotifications(array $move_tree_event)
setUserToggle(bool $a_user_toggle)
getForcedEventsObjectByUserId(int $user_id)
setUserIdNoti(int $a_user_id_noti)
setNotificationId(int $a_notification_id)
static getCachedNodeData(int $ref_id)
setAdminForce(bool $a_admin_force)
setInterestedEvents($interested_events)
static _isParentNodeGrpCrs(int $a_ref_id)
static checkForumsExistsDelete(int $ref_id, int $user_id)
static _isAdminForceNoti(int $a_obj_id)
static _isUserToggleNoti(int $a_obj_id)
User class.
static getInstanceByRefId(int $ref_id, bool $stop_on_error=true)
get an instance of an Ilias object by reference id
global $DIC
Definition: feed.php:28
$ilUser
Definition: imgupload.php:34
Interface ilDBInterface.
$ref_id
Definition: ltiauth.php:67
$res
Definition: ltiservices.php:69