BioTorrents.de’s version of Gazelle
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

notificationsmanager.class.php 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. <?php
  2. declare(strict_types = 1);
  3. class NotificationsManager
  4. {
  5. // Option types
  6. const OPT_DISABLED = 0;
  7. const OPT_POPUP = 1;
  8. const OPT_TRADITIONAL = 2;
  9. // Importances
  10. const IMPORTANT = 'information';
  11. const CRITICAL = 'error';
  12. const WARNING = 'warning';
  13. const INFO = 'confirmation';
  14. public static $Importances = array(
  15. 'important' => self::IMPORTANT,
  16. 'critical' => self::CRITICAL,
  17. 'warning' => self::WARNING,
  18. 'info' => self::INFO
  19. );
  20. // Types. These names must correspond to column names in users_notifications_settings
  21. const NEWS = 'News';
  22. const BLOG = 'Blog';
  23. const STAFFPM = 'StaffPM';
  24. const INBOX = 'Inbox';
  25. const QUOTES = 'Quotes';
  26. const SUBSCRIPTIONS = 'Subscriptions';
  27. const TORRENTS = 'Torrents';
  28. const COLLAGES = 'Collages';
  29. const SITEALERTS = 'SiteAlerts';
  30. const FORUMALERTS = 'ForumAlerts';
  31. const REQUESTALERTS = 'RequestAlerts';
  32. const COLLAGEALERTS = 'CollageAlerts';
  33. const TORRENTALERTS = 'TorrentAlerts';
  34. const GLOBALNOTICE = 'Global';
  35. public static $Types = array(
  36. 'News',
  37. 'Blog',
  38. 'StaffPM',
  39. 'Inbox',
  40. 'Quotes',
  41. 'Subscriptions',
  42. 'Torrents',
  43. 'Collages',
  44. 'SiteAlerts',
  45. 'ForumAlerts',
  46. 'RequestAlerts',
  47. 'CollageAlerts',
  48. 'TorrentAlerts'
  49. );
  50. private $UserID;
  51. private $Notifications;
  52. private $Settings;
  53. private $Skipped;
  54. public function __construct($UserID, $Skip = [], $Load = true, $AutoSkip = true)
  55. {
  56. $this->UserID = $UserID;
  57. $this->Notifications = [];
  58. $this->Settings = self::get_settings($UserID);
  59. $this->Skipped = $Skip;
  60. if ($AutoSkip) {
  61. foreach ($this->Settings as $Key => $Value) {
  62. // Skip disabled and traditional settings
  63. if ($Value === self::OPT_DISABLED || $this->is_traditional($Key)) {
  64. $this->Skipped[$Key] = true;
  65. }
  66. }
  67. }
  68. if ($Load) {
  69. $this->load_global_notification();
  70. if (!isset($this->Skipped[self::NEWS])) {
  71. $this->load_news();
  72. }
  73. if (!isset($this->Skipped[self::BLOG])) {
  74. $this->load_blog();
  75. }
  76. if (!isset($this->Skipped[self::STAFFPM])) {
  77. $this->load_staff_pms();
  78. }
  79. if (!isset($this->Skipped[self::INBOX])) {
  80. $this->load_inbox();
  81. }
  82. if (!isset($this->Skipped[self::TORRENTS])) {
  83. $this->load_torrent_notifications();
  84. }
  85. if (!isset($this->Skipped[self::COLLAGES])) {
  86. $this->load_collage_subscriptions();
  87. }
  88. if (!isset($this->Skipped[self::QUOTES])) {
  89. $this->load_quote_notifications();
  90. }
  91. if (!isset($this->Skipped[self::SUBSCRIPTIONS])) {
  92. $this->load_subscriptions();
  93. }
  94. // $this->load_one_reads(); // The code that sets these notices is commented out.
  95. }
  96. }
  97. public function get_notifications()
  98. {
  99. return $this->Notifications;
  100. }
  101. public function clear_notifications_array()
  102. {
  103. unset($this->Notifications);
  104. $this->Notifications = [];
  105. }
  106. private function create_notification($Type, $ID, $Message, $URL, $Importance)
  107. {
  108. $this->Notifications[$Type] = array(
  109. 'id' => (int) $ID,
  110. 'message' => $Message,
  111. 'url' => $URL,
  112. 'importance' => $Importance
  113. );
  114. }
  115. public static function notify_user($UserID, $Type, $Message, $URL, $Importance)
  116. {
  117. self::notify_users(array($UserID), $Type, $Message, $URL, $Importance);
  118. }
  119. public static function notify_users($UserIDs, $Type, $Message, $URL, $Importance)
  120. {
  121. /*
  122. if (!isset($Importance)) {
  123. $Importance = self::INFO;
  124. }
  125. $Type = db_string($Type);
  126. if (!empty($UserIDs)) {
  127. $UserIDs = implode(',', $UserIDs);
  128. $QueryID = G::$DB->get_query_id();
  129. G::$DB->query("
  130. SELECT UserID
  131. FROM users_notifications_settings
  132. WHERE $Type != 0
  133. AND UserID IN ($UserIDs)");
  134. $UserIDs = [];
  135. while (list($ID) = G::$DB->next_record()) {
  136. $UserIDs[] = $ID;
  137. }
  138. G::$DB->set_query_id($QueryID);
  139. foreach ($UserIDs as $UserID) {
  140. $OneReads = G::$Cache->get_value("notifications_one_reads_$UserID");
  141. if (!$OneReads) {
  142. $OneReads = [];
  143. }
  144. array_unshift($OneReads, $this->create_notification($OneReads, "oneread_" . uniqid(), null, $Message, $URL, $Importance));
  145. $OneReads = array_filter($OneReads);
  146. G::$Cache->cache_value("notifications_one_reads_$UserID", $OneReads, 0);
  147. }
  148. }
  149. */
  150. }
  151. public static function get_notification_enabled_users($Type, $UserID)
  152. {
  153. $Type = db_string($Type);
  154. $UserWhere = '';
  155. if (isset($UserID)) {
  156. $UserID = (int)$UserID;
  157. $UserWhere = " AND UserID = '$UserID'";
  158. }
  159. $QueryID = G::$DB->get_query_id();
  160. G::$DB->query("
  161. SELECT UserID
  162. FROM users_notifications_settings
  163. WHERE $Type != 0
  164. $UserWhere");
  165. $IDs = [];
  166. while (list($ID) = G::$DB->next_record()) {
  167. $IDs[] = $ID;
  168. }
  169. G::$DB->set_query_id($QueryID);
  170. return $IDs;
  171. }
  172. public function load_one_reads()
  173. {
  174. $OneReads = G::$Cache->get_value('notifications_one_reads_' . G::$LoggedUser['ID']);
  175. if (is_array($OneReads)) {
  176. $this->Notifications = $this->Notifications + $OneReads;
  177. }
  178. }
  179. public static function clear_one_read($ID)
  180. {
  181. $OneReads = G::$Cache->get_value('notifications_one_reads_' . G::$LoggedUser['ID']);
  182. if ($OneReads) {
  183. unset($OneReads[$ID]);
  184. if (count($OneReads) > 0) {
  185. G::$Cache->cache_value('notifications_one_reads_' . G::$LoggedUser['ID'], $OneReads, 0);
  186. } else {
  187. G::$Cache->delete_value('notifications_one_reads_' . G::$LoggedUser['ID']);
  188. }
  189. }
  190. }
  191. public function load_global_notification()
  192. {
  193. $GlobalNotification = G::$Cache->get_value('global_notification');
  194. if ($GlobalNotification) {
  195. $Read = G::$Cache->get_value('user_read_global_' . G::$LoggedUser['ID']);
  196. if (!$Read) {
  197. $this->create_notification(self::GLOBALNOTICE, 0, $GlobalNotification['Message'], $GlobalNotification['URL'], $GlobalNotification['Importance']);
  198. }
  199. }
  200. }
  201. public static function get_global_notification()
  202. {
  203. return G::$Cache->get_value('global_notification');
  204. }
  205. public static function set_global_notification($Message, $URL, $Importance, $Expiration)
  206. {
  207. if (empty($Message) || empty($Expiration)) {
  208. error('Error setting notification');
  209. }
  210. G::$Cache->cache_value('global_notification', array("Message" => $Message, "URL" => $URL, "Importance" => $Importance, "Expiration" => $Expiration), $Expiration);
  211. }
  212. public static function delete_global_notification()
  213. {
  214. G::$Cache->delete_value('global_notification');
  215. }
  216. public static function clear_global_notification()
  217. {
  218. $GlobalNotification = G::$Cache->get_value('global_notification');
  219. if ($GlobalNotification) {
  220. // This is some trickery
  221. // since we can't know which users have the read cache key set
  222. // we set the expiration time of their cache key to that of the length of the notification
  223. // this gaurantees that their cache key will expire after the notification expires
  224. G::$Cache->cache_value('user_read_global_' . G::$LoggedUser['ID'], true, $GlobalNotification['Expiration']);
  225. }
  226. }
  227. public function load_news()
  228. {
  229. $MyNews = G::$LoggedUser['LastReadNews'];
  230. $CurrentNews = G::$Cache->get_value('news_latest_id');
  231. $Title = G::$Cache->get_value('news_latest_title');
  232. if ($CurrentNews === false || $Title === false) {
  233. $QueryID = G::$DB->get_query_id();
  234. G::$DB->query('
  235. SELECT ID, Title
  236. FROM news
  237. ORDER BY Time DESC
  238. LIMIT 1');
  239. if (G::$DB->has_results()) {
  240. list($CurrentNews, $Title) = G::$DB->next_record();
  241. } else {
  242. $CurrentNews = -1;
  243. }
  244. G::$DB->set_query_id($QueryID);
  245. G::$Cache->cache_value('news_latest_id', $CurrentNews, 0);
  246. G::$Cache->cache_value('news_latest_title', $Title, 0);
  247. }
  248. if ($MyNews < $CurrentNews) {
  249. $this->create_notification(self::NEWS, $CurrentNews, "Announcement: $Title", "index.php#news$CurrentNews", self::IMPORTANT);
  250. }
  251. }
  252. public function load_blog()
  253. {
  254. $MyBlog = G::$LoggedUser['LastReadBlog'];
  255. $CurrentBlog = G::$Cache->get_value('blog_latest_id');
  256. $Title = G::$Cache->get_value('blog_latest_title');
  257. if ($CurrentBlog === false) {
  258. $QueryID = G::$DB->get_query_id();
  259. G::$DB->query('
  260. SELECT ID, Title
  261. FROM blog
  262. WHERE Important = 1
  263. ORDER BY Time DESC
  264. LIMIT 1');
  265. if (G::$DB->has_results()) {
  266. list($CurrentBlog, $Title) = G::$DB->next_record();
  267. } else {
  268. $CurrentBlog = -1;
  269. }
  270. G::$DB->set_query_id($QueryID);
  271. G::$Cache->cache_value('blog_latest_id', $CurrentBlog, 0);
  272. G::$Cache->cache_value('blog_latest_title', $Title, 0);
  273. }
  274. if ($MyBlog < $CurrentBlog) {
  275. $this->create_notification(self::BLOG, $CurrentBlog, "Blog: $Title", "blog.php#blog$CurrentBlog", self::IMPORTANT);
  276. }
  277. }
  278. public function load_staff_pms()
  279. {
  280. $NewStaffPMs = G::$Cache->get_value('staff_pm_new_' . G::$LoggedUser['ID']);
  281. if ($NewStaffPMs === false) {
  282. $QueryID = G::$DB->get_query_id();
  283. G::$DB->query("
  284. SELECT COUNT(ID)
  285. FROM staff_pm_conversations
  286. WHERE UserID = '" . G::$LoggedUser['ID'] . "'
  287. AND Unread = '1'");
  288. list($NewStaffPMs) = G::$DB->next_record();
  289. G::$DB->set_query_id($QueryID);
  290. G::$Cache->cache_value('staff_pm_new_' . G::$LoggedUser['ID'], $NewStaffPMs, 0);
  291. }
  292. if ($NewStaffPMs > 0) {
  293. $Title = 'You have ' . ($NewStaffPMs === 1 ? 'a' : $NewStaffPMs) . ' new Staff PM' . ($NewStaffPMs > 1 ? 's' : '');
  294. $this->create_notification(self::STAFFPM, 0, $Title, 'staffpm.php', self::INFO);
  295. }
  296. }
  297. public function load_inbox()
  298. {
  299. $NewMessages = G::$Cache->get_value('inbox_new_' . G::$LoggedUser['ID']);
  300. if ($NewMessages === false) {
  301. $QueryID = G::$DB->get_query_id();
  302. G::$DB->query("
  303. SELECT COUNT(UnRead)
  304. FROM pm_conversations_users
  305. WHERE UserID = '" . G::$LoggedUser['ID'] . "'
  306. AND UnRead = '1'
  307. AND InInbox = '1'");
  308. list($NewMessages) = G::$DB->next_record();
  309. G::$DB->set_query_id($QueryID);
  310. G::$Cache->cache_value('inbox_new_' . G::$LoggedUser['ID'], $NewMessages, 0);
  311. }
  312. if ($NewMessages > 0) {
  313. $Title = 'You have ' . ($NewMessages === 1 ? 'a' : $NewMessages) . ' new message' . ($NewMessages > 1 ? 's' : '');
  314. $this->create_notification(self::INBOX, 0, $Title, Inbox::get_inbox_link(), self::INFO);
  315. }
  316. }
  317. public function load_torrent_notifications()
  318. {
  319. if (check_perms('site_torrents_notify')) {
  320. $NewNotifications = G::$Cache->get_value('notifications_new_' . G::$LoggedUser['ID']);
  321. if ($NewNotifications === false) {
  322. $QueryID = G::$DB->get_query_id();
  323. G::$DB->query("
  324. SELECT COUNT(UserID)
  325. FROM users_notify_torrents
  326. WHERE UserID = ' " . G::$LoggedUser['ID'] . "'
  327. AND UnRead = '1'");
  328. list($NewNotifications) = G::$DB->next_record();
  329. G::$DB->set_query_id($QueryID);
  330. G::$Cache->cache_value('notifications_new_' . G::$LoggedUser['ID'], $NewNotifications, 0);
  331. }
  332. }
  333. if (isset($NewNotifications) && $NewNotifications > 0) {
  334. $Title = 'You have ' . ($NewNotifications === 1 ? 'a' : $NewNotifications) . ' new torrent notification' . ($NewNotifications > 1 ? 's' : '');
  335. $this->create_notification(self::TORRENTS, 0, $Title, 'torrents.php?action=notify', self::INFO);
  336. }
  337. }
  338. public function load_collage_subscriptions()
  339. {
  340. if (check_perms('site_collages_subscribe')) {
  341. $NewCollages = G::$Cache->get_value('collage_subs_user_new_' . G::$LoggedUser['ID']);
  342. if ($NewCollages === false) {
  343. $QueryID = G::$DB->get_query_id();
  344. G::$DB->query("
  345. SELECT COUNT(DISTINCT s.CollageID)
  346. FROM users_collage_subs AS s
  347. JOIN collages AS c ON s.CollageID = c.ID
  348. JOIN collages_torrents AS ct ON ct.CollageID = c.ID
  349. WHERE s.UserID = " . G::$LoggedUser['ID'] . "
  350. AND ct.AddedOn > s.LastVisit
  351. AND c.Deleted = '0'");
  352. list($NewCollages) = G::$DB->next_record();
  353. G::$DB->set_query_id($QueryID);
  354. G::$Cache->cache_value('collage_subs_user_new_' . G::$LoggedUser['ID'], $NewCollages, 0);
  355. }
  356. if ($NewCollages > 0) {
  357. $Title = 'You have ' . ($NewCollages === 1 ? 'a' : $NewCollages) . ' new collage update' . ($NewCollages > 1 ? 's' : '');
  358. $this->create_notification(self::COLLAGES, 0, $Title, 'userhistory.php?action=subscribed_collages', self::INFO);
  359. }
  360. }
  361. }
  362. public function load_quote_notifications()
  363. {
  364. if (isset(G::$LoggedUser['NotifyOnQuote']) && G::$LoggedUser['NotifyOnQuote']) {
  365. $QuoteNotificationsCount = Subscriptions::has_new_quote_notifications();
  366. if ($QuoteNotificationsCount > 0) {
  367. $Title = 'New quote' . ($QuoteNotificationsCount > 1 ? 's' : '');
  368. $this->create_notification(self::QUOTES, 0, $Title, 'userhistory.php?action=quote_notifications', self::INFO);
  369. }
  370. }
  371. }
  372. public function load_subscriptions()
  373. {
  374. $SubscriptionsCount = Subscriptions::has_new_subscriptions();
  375. if ($SubscriptionsCount > 0) {
  376. $Title = 'New subscription' . ($SubscriptionsCount > 1 ? 's' : '');
  377. $this->create_notification(self::SUBSCRIPTIONS, 0, $Title, 'userhistory.php?action=subscriptions', self::INFO);
  378. }
  379. }
  380. public static function clear_news($News)
  381. {
  382. $QueryID = G::$DB->get_query_id();
  383. if (!$News) {
  384. if (!$News = G::$Cache->get_value('news')) {
  385. G::$DB->query('
  386. SELECT
  387. ID,
  388. Title,
  389. Body,
  390. Time
  391. FROM news
  392. ORDER BY Time DESC
  393. LIMIT 1');
  394. $News = G::$DB->to_array(false, MYSQLI_NUM, false);
  395. G::$Cache->cache_value('news_latest_id', $News[0][0], 0);
  396. }
  397. }
  398. if (G::$LoggedUser['LastReadNews'] !== $News[0][0]) {
  399. G::$Cache->begin_transaction('user_info_heavy_' . G::$LoggedUser['ID']);
  400. G::$Cache->update_row(false, array('LastReadNews' => $News[0][0]));
  401. G::$Cache->commit_transaction(0);
  402. G::$DB->query("
  403. UPDATE users_info
  404. SET LastReadNews = '".$News[0][0]."'
  405. WHERE UserID = " . G::$LoggedUser['ID']);
  406. G::$LoggedUser['LastReadNews'] = $News[0][0];
  407. }
  408. G::$DB->set_query_id($QueryID);
  409. }
  410. public static function clear_blog($Blog)
  411. {
  412. $QueryID = G::$DB->get_query_id();
  413. if (!isset($Blog) || !$Blog) {
  414. if (!$Blog = G::$Cache->get_value('blog')) {
  415. G::$DB->query("
  416. SELECT
  417. b.ID,
  418. um.Username,
  419. b.UserID,
  420. b.Title,
  421. b.Body,
  422. b.Time,
  423. b.ThreadID
  424. FROM blog AS b
  425. LEFT JOIN users_main AS um ON b.UserID = um.ID
  426. ORDER BY Time DESC
  427. LIMIT 1");
  428. $Blog = G::$DB->to_array();
  429. }
  430. }
  431. if (G::$LoggedUser['LastReadBlog'] < $Blog[0][0]) {
  432. G::$Cache->begin_transaction('user_info_heavy_' . G::$LoggedUser['ID']);
  433. G::$Cache->update_row(false, array('LastReadBlog' => $Blog[0][0]));
  434. G::$Cache->commit_transaction(0);
  435. G::$DB->query("
  436. UPDATE users_info
  437. SET LastReadBlog = '". $Blog[0][0]."'
  438. WHERE UserID = " . G::$LoggedUser['ID']);
  439. G::$LoggedUser['LastReadBlog'] = $Blog[0][0];
  440. }
  441. G::$DB->set_query_id($QueryID);
  442. }
  443. public static function clear_staff_pms()
  444. {
  445. $QueryID = G::$DB->get_query_id();
  446. G::$DB->query("
  447. SELECT ID
  448. FROM staff_pm_conversations
  449. WHERE Unread = true
  450. AND UserID = " . G::$LoggedUser['ID']);
  451. $IDs = [];
  452. while (list($ID) = G::$DB->next_record()) {
  453. $IDs[] = $ID;
  454. }
  455. $IDs = implode(',', $IDs);
  456. if (!empty($IDs)) {
  457. G::$DB->query("
  458. UPDATE staff_pm_conversations
  459. SET Unread = false
  460. WHERE ID IN ($IDs)");
  461. }
  462. G::$Cache->delete_value('staff_pm_new_' . G::$LoggedUser['ID']);
  463. G::$DB->set_query_id($QueryID);
  464. }
  465. public static function clear_inbox()
  466. {
  467. $QueryID = G::$DB->get_query_id();
  468. G::$DB->query("
  469. SELECT ConvID
  470. FROM pm_conversations_users
  471. WHERE Unread = '1'
  472. AND UserID = " . G::$LoggedUser['ID']);
  473. $IDs = [];
  474. while (list($ID) = G::$DB->next_record()) {
  475. $IDs[] = $ID;
  476. }
  477. $IDs = implode(',', $IDs);
  478. if (!empty($IDs)) {
  479. G::$DB->query("
  480. UPDATE pm_conversations_users
  481. SET Unread = '0'
  482. WHERE ConvID IN ($IDs)
  483. AND UserID = " . G::$LoggedUser['ID']);
  484. }
  485. G::$Cache->delete_value('inbox_new_' . G::$LoggedUser['ID']);
  486. G::$DB->set_query_id($QueryID);
  487. }
  488. public static function clear_torrents()
  489. {
  490. $QueryID = G::$DB->get_query_id();
  491. G::$DB->query("
  492. SELECT TorrentID
  493. FROM users_notify_torrents
  494. WHERE UserID = ' " . G::$LoggedUser['ID'] . "'
  495. AND UnRead = '1'");
  496. $IDs = [];
  497. while (list($ID) = G::$DB->next_record()) {
  498. $IDs[] = $ID;
  499. }
  500. $IDs = implode(',', $IDs);
  501. if (!empty($IDs)) {
  502. G::$DB->query("
  503. UPDATE users_notify_torrents
  504. SET Unread = '0'
  505. WHERE TorrentID IN ($IDs)
  506. AND UserID = " . G::$LoggedUser['ID']);
  507. }
  508. G::$Cache->delete_value('notifications_new_' . G::$LoggedUser['ID']);
  509. G::$DB->set_query_id($QueryID);
  510. }
  511. public static function clear_collages()
  512. {
  513. $QueryID = G::$DB->get_query_id();
  514. G::$DB->query("
  515. UPDATE users_collage_subs
  516. SET LastVisit = NOW()
  517. WHERE UserID = " . G::$LoggedUser['ID']);
  518. G::$Cache->delete_value('collage_subs_user_new_' . G::$LoggedUser['ID']);
  519. G::$DB->set_query_id($QueryID);
  520. }
  521. public static function clear_quotes()
  522. {
  523. $QueryID = G::$DB->get_query_id();
  524. G::$DB->query("
  525. UPDATE users_notify_quoted
  526. SET UnRead = '0'
  527. WHERE UserID = " . G::$LoggedUser['ID']);
  528. G::$Cache->delete_value('notify_quoted_' . G::$LoggedUser['ID']);
  529. G::$DB->set_query_id($QueryID);
  530. }
  531. public static function clear_subscriptions()
  532. {
  533. $QueryID = G::$DB->get_query_id();
  534. if (($UserSubscriptions = G::$Cache->get_value('subscriptions_user_' . G::$LoggedUser['ID'])) === false) {
  535. G::$DB->query("
  536. SELECT TopicID
  537. FROM users_subscriptions
  538. WHERE UserID = " . G::$LoggedUser['ID']);
  539. if ($UserSubscriptions = G::$DB->collect(0)) {
  540. G::$Cache->cache_value('subscriptions_user_' . G::$LoggedUser['ID'], $UserSubscriptions, 0);
  541. }
  542. }
  543. if (!empty($UserSubscriptions)) {
  544. G::$DB->query("
  545. INSERT INTO forums_last_read_topics (UserID, TopicID, PostID)
  546. SELECT '" . G::$LoggedUser['ID'] . "', ID, LastPostID
  547. FROM forums_topics
  548. WHERE ID IN (".implode(',', $UserSubscriptions).')
  549. ON DUPLICATE KEY UPDATE
  550. PostID = LastPostID');
  551. }
  552. G::$Cache->delete_value('subscriptions_user_new_' . G::$LoggedUser['ID']);
  553. G::$DB->set_query_id($QueryID);
  554. }
  555. /*
  556. // todo: Figure out what these functions are supposed to do and fix them
  557. public static function send_notification($UserID, $ID, $Type, $Message, $URL, $Importance = 'alert', $AutoExpire = false) {
  558. $Notifications = G::$Cache->get_value("user_cache_notifications_$UserID");
  559. if (empty($Notifications)) {
  560. $Notifications = [];
  561. }
  562. array_unshift($Notifications, $this->create_notification($Type, $ID, $Message, $URL, $Importance, $AutoExpire));
  563. G::$Cache->cache_value("user_cache_notifications_$UserID", $Notifications, 0);
  564. }
  565. public static function clear_notification($UserID, $Index) {
  566. $Notifications = G::$Cache->get_value("user_cache_notifications_$UserID");
  567. if (count($Notifications)) {
  568. unset($Notifications[$Index]);
  569. $Notifications = array_values($Notifications);
  570. G::$Cache->cache_value("user_cache_notifications_$UserID", $Notifications, 0);
  571. }
  572. }
  573. */
  574. public static function get_settings($UserID)
  575. {
  576. $Results = G::$Cache->get_value("users_notifications_settings_$UserID");
  577. if (!$Results) {
  578. $QueryID = G::$DB->get_query_id();
  579. G::$DB->query("
  580. SELECT *
  581. FROM users_notifications_settings
  582. WHERE UserID = ?", $UserID);
  583. $Results = G::$DB->next_record(MYSQLI_ASSOC, false);
  584. G::$DB->set_query_id($QueryID);
  585. G::$Cache->cache_value("users_notifications_settings_$UserID", $Results, 0);
  586. }
  587. return $Results;
  588. }
  589. public static function save_settings($UserID, $Settings = false)
  590. {
  591. if (!is_array($Settings)) {
  592. // A little cheat technique, gets all keys in the $_POST array starting with 'notifications_'
  593. $Settings = array_intersect_key($_POST, array_flip(preg_grep('/^notifications_/', array_keys($_POST))));
  594. }
  595. $Update = [];
  596. foreach (self::$Types as $Type) {
  597. $Popup = array_key_exists("notifications_{$Type}_popup", $Settings);
  598. $Traditional = array_key_exists("notifications_{$Type}_traditional", $Settings);
  599. $Result = self::OPT_DISABLED;
  600. if ($Popup) {
  601. $Result = self::OPT_POPUP;
  602. } elseif ($Traditional) {
  603. $Result = self::OPT_TRADITIONAL;
  604. }
  605. $Update[] = "$Type = $Result";
  606. }
  607. $Update = implode(',', $Update);
  608. $QueryID = G::$DB->get_query_id();
  609. G::$DB->query("
  610. UPDATE users_notifications_settings
  611. SET $Update
  612. WHERE UserID = ?", $UserID);
  613. G::$DB->set_query_id($QueryID);
  614. G::$Cache->delete_value("users_notifications_settings_$UserID");
  615. }
  616. public function is_traditional($Type)
  617. {
  618. return $this->Settings[$Type] === self::OPT_TRADITIONAL;
  619. }
  620. public function is_skipped($Type)
  621. {
  622. return isset($this->Skipped[$Type]);
  623. }
  624. public function use_noty()
  625. {
  626. return in_array(self::OPT_POPUP, $this->Settings);
  627. }
  628. }