ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilNotification.php
Go to the documentation of this file.
1 <?php
2 
20 {
21  public const THRESHOLD = 180; // time between mails in minutes
22  public const TYPE_EXERCISE_SUBMISSION = 1;
23  public const TYPE_WIKI = 2;
24  public const TYPE_WIKI_PAGE = 3;
25  public const TYPE_BLOG = 4;
26  public const TYPE_DATA_COLLECTION = 5;
27  public const TYPE_POLL = 6;
28  public const TYPE_LM_BLOCKED_USERS = 7;
29  public const TYPE_BOOK = 8;
30  public const TYPE_LM = 9;
31  public const TYPE_LM_PAGE = 10;
32 
36  public static function hasNotification(
37  int $type,
38  int $user_id,
39  int $id
40  ): bool {
41  global $DIC;
42 
43  $ilDB = $DIC->database();
44  $tree = $DIC->repositoryTree();
45 
46  $notification = false;
47 
48  $setting = new ilObjNotificationSettings($id);
49  if ($setting->getMode() !== ilObjNotificationSettings::MODE_DEF_OFF_USER_ACTIVATION) {
50  // check membership, members should be notidifed...
51  foreach (ilObject::_getAllReferences($id) as $ref_id) {
52  $grp_ref_id = $tree->checkForParentType($ref_id, 'grp');
53  if (($grp_ref_id > 0) && ilGroupParticipants::_isParticipant($grp_ref_id, $user_id)) {
54  $notification = true;
55  }
56  $crs_ref_id = $tree->checkForParentType($ref_id, 'crs');
57  if (($crs_ref_id > 0) && ilCourseParticipants::_isParticipant($crs_ref_id, $user_id)) {
58  $notification = true;
59  }
60  }
61 
62  if ($notification && $setting->getMode() === ilObjNotificationSettings::MODE_DEF_ON_OPT_OUT) {
63  $set = $ilDB->query("SELECT user_id FROM notification" .
64  " WHERE type = " . $ilDB->quote($type, "integer") .
65  " AND user_id = " . $ilDB->quote($user_id, "integer") .
66  " AND id = " . $ilDB->quote($id, "integer") .
67  " AND activated = " . $ilDB->quote(0, "integer"));
68  $rec = $ilDB->fetchAssoc($set);
69  // if there is no user record, take the default value
70  if (!isset($rec["user_id"])) {
71  return $notification;
72  }
73  // ... except when the opted out
74  return isset($rec["user_id"]) && ((int) $rec["user_id"] !== $user_id);
75  }
76 
77  if ($notification && $setting->getMode() === ilObjNotificationSettings::MODE_DEF_ON_NO_OPT_OUT) {
78  return true;
79  }
80  }
81 
82 
83  $set = $ilDB->query("SELECT user_id FROM notification" .
84  " WHERE type = " . $ilDB->quote($type, "integer") .
85  " AND user_id = " . $ilDB->quote($user_id, "integer") .
86  " AND id = " . $ilDB->quote($id, "integer") .
87  " AND activated = " . $ilDB->quote(1, "integer"));
88 
89  return (bool) $ilDB->numRows($set);
90  }
91 
95  public static function hasOptOut(int $obj_id): bool
96  {
97  $setting = new ilObjNotificationSettings($obj_id);
98  return $setting->getMode() !== ilObjNotificationSettings::MODE_DEF_ON_NO_OPT_OUT;
99  }
100 
104  public static function getNotificationsForObject(
105  int $type,
106  int $id,
107  ?int $page_id = null,
108  bool $ignore_threshold = false
109  ): array {
110  global $DIC;
111 
112  $ilDB = $DIC->database();
113  $tree = $DIC->repositoryTree();
114 
115 
117  $log->debug("Get notifications for type " . $type . ", id " . $id . ", page_id " . $page_id .
118  ", ignore threshold " . $ignore_threshold);
119 
120  // currently done for blog
121  $recipients = array();
122  $setting = new ilObjNotificationSettings($id);
123  if ($setting->getMode() !== ilObjNotificationSettings::MODE_DEF_OFF_USER_ACTIVATION) {
124  foreach (ilObject::_getAllReferences($id) as $ref_id) {
125  $grp_ref_id = $tree->checkForParentType($ref_id, 'grp');
126  if ($grp_ref_id > 0) {
128  foreach ($p->getMembers() as $user_id) {
129  if (!in_array($user_id, $recipients)) {
130  $recipients[$user_id] = $user_id;
131  }
132  }
133  }
134  $crs_ref_id = $tree->checkForParentType($ref_id, 'crs');
135  if ($crs_ref_id > 0) {
137  foreach ($p->getMembers() as $user_id) {
138  if (!in_array($user_id, $recipients)) {
139  $recipients[$user_id] = $user_id;
140  }
141  }
142  }
143  }
144  }
145 
146  $log->debug("Step 1 recipients: " . print_r($recipients, true));
147 
148  // remove all users that deactivated the feature
149  if ($setting->getMode() === ilObjNotificationSettings::MODE_DEF_ON_OPT_OUT) {
150  $sql = "SELECT user_id FROM notification" .
151  " WHERE type = " . $ilDB->quote($type, "integer") .
152  " AND id = " . $ilDB->quote($id, "integer") .
153  " AND activated = " . $ilDB->quote(0, "integer") .
154  " AND " . $ilDB->in("user_id", $recipients, false, "integer");
155  $set = $ilDB->query($sql);
156  while ($rec = $ilDB->fetchAssoc($set)) {
157  unset($recipients[$rec["user_id"]]);
158  $log->debug("Remove due to deactivation: " . $rec["user_id"]);
159  }
160  }
161 
162  // get single subscriptions
163  if ($setting->getMode() !== ilObjNotificationSettings::MODE_DEF_ON_NO_OPT_OUT) {
164  $sql = "SELECT user_id FROM notification" .
165  " WHERE type = " . $ilDB->quote($type, "integer") .
166  " AND id = " . $ilDB->quote($id, "integer") .
167  " AND activated = " . $ilDB->quote(1, "integer");
168  if (!$ignore_threshold) {
169  $sql .= " AND (last_mail < " . $ilDB->quote(date(
170  "Y-m-d H:i:s",
171  strtotime("-" . self::THRESHOLD . "minutes")
172  ), "timestamp") .
173  " OR last_mail IS NULL";
174  if ($page_id) {
175  $sql .= " OR page_id <> " . $ilDB->quote($page_id, "integer");
176  }
177  $sql .= ")";
178  }
179  $set = $ilDB->query($sql);
180  while ($row = $ilDB->fetchAssoc($set)) {
181  $recipients[$row["user_id"]] = $row["user_id"];
182  $log->debug("Adding single subscription: " . $row["user_id"]);
183  }
184  }
185 
186  // remove all users that got a mail
187  // see #22773
188  //if ($setting->getMode() !== ilObjNotificationSettings::MODE_DEF_OFF_USER_ACTIVATION && !$ignore_threshold) {
189  if (!$ignore_threshold) {
190  $sql = "SELECT user_id FROM notification" .
191  " WHERE type = " . $ilDB->quote($type, "integer") .
192  " AND id = " . $ilDB->quote($id, "integer") .
193  " AND " . $ilDB->in("user_id", $recipients, false, "integer");
194  $sql .= " AND (last_mail > " . $ilDB->quote(date(
195  "Y-m-d H:i:s",
196  strtotime("-" . self::THRESHOLD . "minutes")
197  ), "timestamp");
198  if ($page_id) {
199  $sql .= " AND page_id = " . $ilDB->quote($page_id, "integer");
200  }
201  $sql .= ")";
202  $set = $ilDB->query($sql);
203  while ($rec = $ilDB->fetchAssoc($set)) {
204  unset($recipients[$rec["user_id"]]);
205  $log->debug("Remove due to got mail: " . $rec["user_id"]);
206  }
207 
208  if ($type === self::TYPE_WIKI) {
209  $sql = "SELECT user_id FROM notification" .
210  " WHERE type = " . $ilDB->quote(self::TYPE_WIKI_PAGE, "integer") .
211  " AND id = " . $ilDB->quote($page_id, "integer") .
212  " AND " . $ilDB->in("user_id", $recipients, false, "integer");
213  $sql .= " AND (last_mail > " . $ilDB->quote(date(
214  "Y-m-d H:i:s",
215  strtotime("-" . self::THRESHOLD . "minutes")
216  ), "timestamp");
217  $sql .= ")";
218  $set = $ilDB->query($sql);
219  while ($rec = $ilDB->fetchAssoc($set)) {
220  unset($recipients[$rec["user_id"]]);
221  $log->debug("Remove due to got mail: " . $rec["user_id"]);
222  }
223  }
224  }
225 
226 
227  return $recipients;
228  }
229 
233  public static function setNotification(
234  int $type,
235  int $user_id,
236  int $id,
237  bool $status = true
238  ): void {
239  global $DIC;
240 
241  $ilDB = $DIC->database();
242 
243  $fields = array(
244  "type" => array("integer", $type),
245  "user_id" => array("integer", $user_id),
246  "id" => array("integer", $id)
247  );
248  $ilDB->replace("notification", $fields, array("activated" => array("integer", (int) $status)));
249  }
250 
254  public static function updateNotificationTime(
255  int $type,
256  int $id,
257  array $user_ids,
258  ?int $page_id = null,
259  bool $activate_new_entries = true
260  ): void {
261  global $DIC;
262 
263  $ilDB = $DIC->database();
264 
265  // create initial entries, if not existing
266  // see #22773, currently only done for wiki, might be feasible for other variants
267  if (in_array($type, [self::TYPE_WIKI_PAGE, self::TYPE_WIKI, self::TYPE_BLOG])) {
268  $set = $ilDB->queryF(
269  "SELECT user_id FROM notification " .
270  " WHERE type = %s AND id = %s AND " .
271  $ilDB->in("user_id", $user_ids, false, "integer"),
272  ["integer", "integer"],
273  [$type, $id]
274  );
275  $noti_users = [];
276  while ($rec = $ilDB->fetchAssoc($set)) {
277  $noti_users[] = $rec["user_id"];
278  }
279  foreach ($user_ids as $user_id) {
280  if (!in_array($user_id, $noti_users)) {
281  $ilDB->insert("notification", [
282  "type" => ["integer", $type],
283  "id" => ["integer", $id],
284  "user_id" => ["integer", $user_id],
285  "page_id" => ["integer", (int) $page_id],
286  "activated" => ["integer", (int) $activate_new_entries]
287  ]);
288  }
289  }
290  }
291 
292  $sql = "UPDATE notification" .
293  " SET last_mail = " . $ilDB->quote(date("Y-m-d H:i:s"), "timestamp");
294 
295  if ($page_id) {
296  $sql .= ", page_id = " . $ilDB->quote($page_id, "integer");
297  }
298 
299  $sql .= " WHERE type = " . $ilDB->quote($type, "integer") .
300  " AND id = " . $ilDB->quote($id, "integer") .
301  " AND " . $ilDB->in("user_id", $user_ids, false, "integer");
302  $ilDB->query($sql);
303  }
304 
308  public static function removeForObject(
309  int $type,
310  int $id
311  ): void {
312  global $DIC;
313 
314  $ilDB = $DIC->database();
315 
316  $ilDB->query("DELETE FROM notification" .
317  " WHERE type = " . $ilDB->quote($type, "integer") .
318  " AND id = " . $ilDB->quote($id, "integer"));
319  }
320 
324  public static function removeForUser(
325  int $user_id
326  ): void {
327  global $DIC;
328 
329  $ilDB = $DIC->database();
330 
331  $ilDB->query("DELETE FROM notification" .
332  " WHERE user_id = " . $ilDB->quote($user_id, "integer"));
333  }
334 
339  public static function getActivatedNotifications(
340  int $type,
341  int $user_id
342  ): array {
343  global $DIC;
344 
345  $db = $DIC->database();
346 
347  $set = $db->queryF(
348  "SELECT id FROM notification " .
349  " WHERE type = %s " .
350  " AND user_id = %s " .
351  " AND activated = %s ",
352  array("integer", "integer", "integer"),
353  array($type, $user_id, 1)
354  );
355  $ids = [];
356  while ($rec = $db->fetchAssoc($set)) {
357  $ids[] = $rec["id"];
358  }
359 
360  return $ids;
361  }
362 }
static _isParticipant(int $a_ref_id, int $a_usr_id)
Static function to check if a user is a participant of the container object.
static getLogger(string $a_component_id)
Get component logger.
$type
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _getAllReferences(int $id)
get all reference ids for object ID
static getNotificationsForObject(int $type, int $id, ?int $page_id=null, bool $ignore_threshold=false)
Get all users/recipients for given object.
static getActivatedNotifications(int $type, int $user_id)
Get activated notifications of give type for user.
global $DIC
Definition: feed.php:28
$ref_id
Definition: ltiauth.php:67
static _getInstanceByObjId(int $a_obj_id)
static setNotification(int $type, int $user_id, int $id, bool $status=true)
Set notification status for object and user.
$log
Definition: result.php:33
static removeForUser(int $user_id)
Remove all notifications for given user.
static _lookupObjectId(int $ref_id)
static updateNotificationTime(int $type, int $id, array $user_ids, ?int $page_id=null, bool $activate_new_entries=true)
Update the last mail timestamp for given object and users.
static _getInstanceByObjId(int $a_obj_id)
Get singleton instance.
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
static hasNotification(int $type, int $user_id, int $id)
Check notification status for object and user.
static removeForObject(int $type, int $id)
Remove all notifications for given object.
static _isParticipant(int $a_ref_id, int $a_usr_id)
Static function to check if a user is a participant of the container object.
static hasOptOut(int $obj_id)
Is opt out (disable notification) allowed?