1<?php 2 3/* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */ 4 5/** 6* Class ilNotification 7* 8* @author Jörg Lützenkirchen <luetzenkirchen@leifos.com> 9* $Id: class.ilObjExerciseGUI.php 24003 2010-05-26 14:35:42Z akill $ 10* 11* @ilCtrl_Calls ilNotification: 12* 13* @ingroup ServicesNotification 14*/ 15class ilNotification 16{ 17 const TYPE_EXERCISE_SUBMISSION = 1; 18 const TYPE_WIKI = 2; 19 const TYPE_WIKI_PAGE = 3; 20 const TYPE_BLOG = 4; 21 const TYPE_DATA_COLLECTION = 5; 22 const TYPE_POLL = 6; 23 const TYPE_LM_BLOCKED_USERS = 7; 24 const TYPE_BOOK = 8; 25 const TYPE_LM = 9; 26 const TYPE_LM_PAGE = 10; 27 28 const THRESHOLD = 180; // time between mails in minutes 29 30 /** 31 * Check notification status for object and user 32 * 33 * @param int $type 34 * @param int $user_id 35 * @param int $id 36 * @return bool 37 */ 38 public static function hasNotification($type, $user_id, $id) 39 { 40 global $DIC; 41 42 $ilDB = $DIC->database(); 43 $tree = $DIC->repositoryTree(); 44 45 $notification = false; 46 47 include_once("./Services/Notification/classes/class.ilObjNotificationSettings.php"); 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) { 54 include_once("./Modules/Group/classes/class.ilGroupParticipants.php"); 55 if (ilGroupParticipants::_isParticipant($grp_ref_id, $user_id)) { 56 $notification = true; 57 } 58 } 59 $crs_ref_id = $tree->checkForParentType($ref_id, 'crs'); 60 if ($crs_ref_id > 0) { 61 include_once("./Modules/Course/classes/class.ilCourseParticipants.php"); 62 if (ilCourseParticipants::_isParticipant($crs_ref_id, $user_id)) { 63 $notification = true; 64 } 65 } 66 } 67 68 if ($notification && $setting->getMode() == ilObjNotificationSettings::MODE_DEF_ON_OPT_OUT) { 69 $set = $ilDB->query("SELECT user_id FROM notification" . 70 " WHERE type = " . $ilDB->quote($type, "integer") . 71 " AND user_id = " . $ilDB->quote($user_id, "integer") . 72 " AND id = " . $ilDB->quote($id, "integer") . 73 " AND activated = " . $ilDB->quote(0, "integer")); 74 $rec = $ilDB->fetchAssoc($set); 75 // ... except when the opted out 76 if ($rec["user_id"] == $user_id) { 77 return false; 78 } 79 return true; 80 } 81 82 if ($notification && $setting->getMode() == ilObjNotificationSettings::MODE_DEF_ON_NO_OPT_OUT) { 83 return true; 84 } 85 } 86 87 88 $set = $ilDB->query("SELECT user_id FROM notification" . 89 " WHERE type = " . $ilDB->quote($type, "integer") . 90 " AND user_id = " . $ilDB->quote($user_id, "integer") . 91 " AND id = " . $ilDB->quote($id, "integer") . 92 " AND activated = " . $ilDB->quote(1, "integer")); 93 94 return (bool) $ilDB->numRows($set); 95 } 96 97 /** 98 * Is opt out (disable notification) allowed? 99 * 100 * @param int $obj_id 101 * @return bool 102 */ 103 public static function hasOptOut($obj_id) 104 { 105 include_once("./Services/Notification/classes/class.ilObjNotificationSettings.php"); 106 $setting = new ilObjNotificationSettings($obj_id); 107 if ($setting->getMode() == ilObjNotificationSettings::MODE_DEF_ON_NO_OPT_OUT) { 108 return false; 109 } 110 return true; 111 } 112 113 /** 114 * Get all users for given object 115 * 116 * @param int $type 117 * @param int $id 118 * @param int $page_id 119 * @param bool $ignore_threshold 120 * @return array 121 */ 122 public static function getNotificationsForObject($type, $id, $page_id = null, $ignore_threshold = false) 123 { 124 global $DIC; 125 126 $ilDB = $DIC->database(); 127 $tree = $DIC->repositoryTree(); 128 129 include_once("./Services/Notification/classes/class.ilObjNotificationSettings.php"); 130 131 // currently done for blog 132 $recipients = array(); 133 $setting = new ilObjNotificationSettings($id); 134 if ($setting->getMode() != ilObjNotificationSettings::MODE_DEF_OFF_USER_ACTIVATION) { 135 foreach (ilObject::_getAllReferences($id) as $ref_id) { 136 $grp_ref_id = $tree->checkForParentType($ref_id, 'grp'); 137 if ($grp_ref_id > 0) { 138 include_once("./Modules/Group/classes/class.ilGroupParticipants.php"); 139 $p = ilGroupParticipants::_getInstanceByObjId(ilObject::_lookupObjectId($grp_ref_id)); 140 foreach ($p->getMembers() as $user_id) { 141 if (!in_array($user_id, $recipients)) { 142 $recipients[$user_id] = $user_id; 143 } 144 } 145 } 146 $crs_ref_id = $tree->checkForParentType($ref_id, 'crs'); 147 if ($crs_ref_id > 0) { 148 include_once("./Modules/Course/classes/class.ilCourseParticipants.php"); 149 $p = ilCourseParticipants::_getInstanceByObjId(ilObject::_lookupObjectId($crs_ref_id)); 150 foreach ($p->getMembers() as $user_id) { 151 if (!in_array($user_id, $recipients)) { 152 $recipients[$user_id] = $user_id; 153 } 154 } 155 } 156 } 157 } 158 159 // remove all users that deactivated the feature 160 if ($setting->getMode() == ilObjNotificationSettings::MODE_DEF_ON_OPT_OUT) { 161 $sql = "SELECT user_id FROM notification" . 162 " WHERE type = " . $ilDB->quote($type, "integer") . 163 " AND id = " . $ilDB->quote($id, "integer") . 164 " AND activated = " . $ilDB->quote(0, "integer") . 165 " AND " . $ilDB->in("user_id", $recipients, false, "integer"); 166 $set = $ilDB->query($sql); 167 while ($rec = $ilDB->fetchAssoc($set)) { 168 unset($recipients[$rec["user_id"]]); 169 } 170 } 171 172 // remove all users that got a mail 173 if ($setting->getMode() != ilObjNotificationSettings::MODE_DEF_OFF_USER_ACTIVATION && !$ignore_threshold) { 174 $sql = "SELECT user_id FROM notification" . 175 " WHERE type = " . $ilDB->quote($type, "integer") . 176 " AND id = " . $ilDB->quote($id, "integer") . 177 " AND activated = " . $ilDB->quote(1, "integer") . 178 " AND " . $ilDB->in("user_id", $recipients, false, "integer"); 179 $sql .= " AND (last_mail > " . $ilDB->quote(date( 180 "Y-m-d H:i:s", 181 strtotime("-" . self::THRESHOLD . "minutes") 182 ), "timestamp"); 183 if ($page_id) { 184 $sql .= " AND page_id = " . $ilDB->quote($page_id, "integer"); 185 } 186 $sql .= ")"; 187 188 $set = $ilDB->query($sql); 189 while ($rec = $ilDB->fetchAssoc($set)) { 190 unset($recipients[$rec["user_id"]]); 191 } 192 } 193 194 // get single subscriptions 195 if ($setting->getMode() != ilObjNotificationSettings::MODE_DEF_ON_NO_OPT_OUT) { 196 $sql = "SELECT user_id FROM notification" . 197 " WHERE type = " . $ilDB->quote($type, "integer") . 198 " AND id = " . $ilDB->quote($id, "integer") . 199 " AND activated = " . $ilDB->quote(1, "integer"); 200 if (!$ignore_threshold) { 201 $sql .= " AND (last_mail < " . $ilDB->quote(date( 202 "Y-m-d H:i:s", 203 strtotime("-" . self::THRESHOLD . "minutes") 204 ), "timestamp") . 205 " OR last_mail IS NULL"; 206 if ($page_id) { 207 $sql .= " OR page_id <> " . $ilDB->quote($page_id, "integer"); 208 } 209 $sql .= ")"; 210 } 211 $set = $ilDB->query($sql); 212 while ($row = $ilDB->fetchAssoc($set)) { 213 $recipients[$row["user_id"]] = $row["user_id"]; 214 } 215 } 216 217 return $recipients; 218 } 219 220 /** 221 * Set notification status for object and user 222 * 223 * @param int $type 224 * @param int $user_id 225 * @param int $id 226 * @param bool $status 227 */ 228 public static function setNotification($type, $user_id, $id, $status = true) 229 { 230 global $DIC; 231 232 $ilDB = $DIC->database(); 233 234 $fields = array( 235 "type" => array("integer", $type), 236 "user_id" => array("integer", $user_id), 237 "id" => array("integer", $id) 238 ); 239 $ilDB->replace("notification", $fields, array("activated" => array("integer", (int) $status))); 240 } 241 242 /** 243 * Update the last mail timestamp for given object and users 244 * 245 * @param int $type 246 * @param int $id 247 * @param array $user_ids 248 * @param int $page_id 249 */ 250 public static function updateNotificationTime($type, $id, array $user_ids, $page_id = false) 251 { 252 global $DIC; 253 254 $ilDB = $DIC->database(); 255 256 $sql = "UPDATE notification" . 257 " SET last_mail = " . $ilDB->quote(date("Y-m-d H:i:s"), "timestamp"); 258 259 if ($page_id) { 260 $sql .= ", page_id = " . $ilDB->quote($page_id, "integer"); 261 } 262 263 $sql .= " WHERE type = " . $ilDB->quote($type, "integer") . 264 " AND id = " . $ilDB->quote($id, "integer") . 265 " AND " . $ilDB->in("user_id", $user_ids, false, "integer"); 266 267 $ilDB->query($sql); 268 } 269 270 /** 271 * Remove all notifications for given object 272 * 273 * @param int $type 274 * @param int $id 275 */ 276 public static function removeForObject($type, $id) 277 { 278 global $DIC; 279 280 $ilDB = $DIC->database(); 281 282 $ilDB->query("DELETE FROM notification" . 283 " WHERE type = " . $ilDB->quote($type, "integer") . 284 " AND id = " . $ilDB->quote($id, "integer")); 285 } 286 287 /** 288 * Remove all notifications for given user 289 * 290 * @param int $user_id 291 */ 292 public static function removeForUser($user_id) 293 { 294 global $DIC; 295 296 $ilDB = $DIC->database(); 297 298 $ilDB->query("DELETE FROM notification" . 299 " WHERE user_id = " . $ilDB->quote($user_id, "integer")); 300 } 301 302 /** 303 * Get activated notifications of give type for user 304 * 305 * @param int $type 306 * @param int $user_id 307 * @return int[] 308 */ 309 public static function getActivatedNotifications(int $type, int $user_id) : array 310 { 311 global $DIC; 312 313 $db = $DIC->database(); 314 315 $set = $db->queryF( 316 "SELECT id FROM notification " . 317 " WHERE type = %s " . 318 " AND user_id = %s " . 319 " AND activated = %s ", 320 array("integer", "integer", "integer"), 321 array($type, $user_id, 1) 322 ); 323 $ids = []; 324 while ($rec = $db->fetchAssoc($set)) { 325 $ids[] = $rec["id"]; 326 } 327 328 return $ids; 329 } 330} 331