[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Forum subscription manager. 19 * 20 * @package mod_forum 21 * @copyright 2014 Andrew Nicols <andrew@nicols.co.uk> 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace mod_forum; 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 /** 30 * Forum subscription manager. 31 * 32 * @copyright 2014 Andrew Nicols <andrew@nicols.co.uk> 33 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 */ 35 class subscriptions { 36 37 /** 38 * The status value for an unsubscribed discussion. 39 * 40 * @var int 41 */ 42 const FORUM_DISCUSSION_UNSUBSCRIBED = -1; 43 44 /** 45 * The subscription cache for forums. 46 * 47 * The first level key is the user ID 48 * The second level is the forum ID 49 * The Value then is bool for subscribed of not. 50 * 51 * @var array[] An array of arrays. 52 */ 53 protected static $forumcache = array(); 54 55 /** 56 * The list of forums which have been wholly retrieved for the forum subscription cache. 57 * 58 * This allows for prior caching of an entire forum to reduce the 59 * number of DB queries in a subscription check loop. 60 * 61 * @var bool[] 62 */ 63 protected static $fetchedforums = array(); 64 65 /** 66 * The subscription cache for forum discussions. 67 * 68 * The first level key is the user ID 69 * The second level is the forum ID 70 * The third level key is the discussion ID 71 * The value is then the users preference (int) 72 * 73 * @var array[] 74 */ 75 protected static $forumdiscussioncache = array(); 76 77 /** 78 * The list of forums which have been wholly retrieved for the forum discussion subscription cache. 79 * 80 * This allows for prior caching of an entire forum to reduce the 81 * number of DB queries in a subscription check loop. 82 * 83 * @var bool[] 84 */ 85 protected static $discussionfetchedforums = array(); 86 87 /** 88 * Whether a user is subscribed to this forum, or a discussion within 89 * the forum. 90 * 91 * If a discussion is specified, then report whether the user is 92 * subscribed to posts to this particular discussion, taking into 93 * account the forum preference. 94 * 95 * If it is not specified then only the forum preference is considered. 96 * 97 * @param int $userid The user ID 98 * @param \stdClass $forum The record of the forum to test 99 * @param int $discussionid The ID of the discussion to check 100 * @param $cm The coursemodule record. If not supplied, this will be calculated using get_fast_modinfo instead. 101 * @return boolean 102 */ 103 public static function is_subscribed($userid, $forum, $discussionid = null, $cm = null) { 104 // If forum is force subscribed and has allowforcesubscribe, then user is subscribed. 105 if (self::is_forcesubscribed($forum)) { 106 if (!$cm) { 107 $cm = get_fast_modinfo($forum->course)->instances['forum'][$forum->id]; 108 } 109 if (has_capability('mod/forum:allowforcesubscribe', \context_module::instance($cm->id), $userid)) { 110 return true; 111 } 112 } 113 114 if ($discussionid === null) { 115 return self::is_subscribed_to_forum($userid, $forum); 116 } 117 118 $subscriptions = self::fetch_discussion_subscription($forum->id, $userid); 119 120 // Check whether there is a record for this discussion subscription. 121 if (isset($subscriptions[$discussionid])) { 122 return ($subscriptions[$discussionid] != self::FORUM_DISCUSSION_UNSUBSCRIBED); 123 } 124 125 return self::is_subscribed_to_forum($userid, $forum); 126 } 127 128 /** 129 * Whether a user is subscribed to this forum. 130 * 131 * @param int $userid The user ID 132 * @param \stdClass $forum The record of the forum to test 133 * @return boolean 134 */ 135 protected static function is_subscribed_to_forum($userid, $forum) { 136 return self::fetch_subscription_cache($forum->id, $userid); 137 } 138 139 /** 140 * Helper to determine whether a forum has it's subscription mode set 141 * to forced subscription. 142 * 143 * @param \stdClass $forum The record of the forum to test 144 * @return bool 145 */ 146 public static function is_forcesubscribed($forum) { 147 return ($forum->forcesubscribe == FORUM_FORCESUBSCRIBE); 148 } 149 150 /** 151 * Helper to determine whether a forum has it's subscription mode set to disabled. 152 * 153 * @param \stdClass $forum The record of the forum to test 154 * @return bool 155 */ 156 public static function subscription_disabled($forum) { 157 return ($forum->forcesubscribe == FORUM_DISALLOWSUBSCRIBE); 158 } 159 160 /** 161 * Helper to determine whether the specified forum can be subscribed to. 162 * 163 * @param \stdClass $forum The record of the forum to test 164 * @return bool 165 */ 166 public static function is_subscribable($forum) { 167 return (!\mod_forum\subscriptions::is_forcesubscribed($forum) && 168 !\mod_forum\subscriptions::subscription_disabled($forum)); 169 } 170 171 /** 172 * Set the forum subscription mode. 173 * 174 * By default when called without options, this is set to FORUM_FORCESUBSCRIBE. 175 * 176 * @param \stdClass $forum The record of the forum to set 177 * @param int $status The new subscription state 178 * @return bool 179 */ 180 public static function set_subscription_mode($forumid, $status = 1) { 181 global $DB; 182 return $DB->set_field("forum", "forcesubscribe", $status, array("id" => $forumid)); 183 } 184 185 /** 186 * Returns the current subscription mode for the forum. 187 * 188 * @param \stdClass $forum The record of the forum to set 189 * @return int The forum subscription mode 190 */ 191 public static function get_subscription_mode($forum) { 192 return $forum->forcesubscribe; 193 } 194 195 /** 196 * Returns an array of forums that the current user is subscribed to and is allowed to unsubscribe from 197 * 198 * @return array An array of unsubscribable forums 199 */ 200 public static function get_unsubscribable_forums() { 201 global $USER, $DB; 202 203 // Get courses that $USER is enrolled in and can see. 204 $courses = enrol_get_my_courses(); 205 if (empty($courses)) { 206 return array(); 207 } 208 209 $courseids = array(); 210 foreach($courses as $course) { 211 $courseids[] = $course->id; 212 } 213 list($coursesql, $courseparams) = $DB->get_in_or_equal($courseids, SQL_PARAMS_NAMED, 'c'); 214 215 // Get all forums from the user's courses that they are subscribed to and which are not set to forced. 216 // It is possible for users to be subscribed to a forum in subscription disallowed mode so they must be listed 217 // here so that that can be unsubscribed from. 218 $sql = "SELECT f.id, cm.id as cm, cm.visible, f.course 219 FROM {forum} f 220 JOIN {course_modules} cm ON cm.instance = f.id 221 JOIN {modules} m ON m.name = :modulename AND m.id = cm.module 222 LEFT JOIN {forum_subscriptions} fs ON (fs.forum = f.id AND fs.userid = :userid) 223 WHERE f.forcesubscribe <> :forcesubscribe 224 AND fs.id IS NOT NULL 225 AND cm.course 226 $coursesql"; 227 $params = array_merge($courseparams, array( 228 'modulename'=>'forum', 229 'userid' => $USER->id, 230 'forcesubscribe' => FORUM_FORCESUBSCRIBE, 231 )); 232 $forums = $DB->get_recordset_sql($sql, $params); 233 234 $unsubscribableforums = array(); 235 foreach($forums as $forum) { 236 if (empty($forum->visible)) { 237 // The forum is hidden - check if the user can view the forum. 238 $context = \context_module::instance($forum->cm); 239 if (!has_capability('moodle/course:viewhiddenactivities', $context)) { 240 // The user can't see the hidden forum to cannot unsubscribe. 241 continue; 242 } 243 } 244 245 $unsubscribableforums[] = $forum; 246 } 247 $forums->close(); 248 249 return $unsubscribableforums; 250 } 251 252 /** 253 * Get the list of potential subscribers to a forum. 254 * 255 * @param context_module $context the forum context. 256 * @param integer $groupid the id of a group, or 0 for all groups. 257 * @param string $fields the list of fields to return for each user. As for get_users_by_capability. 258 * @param string $sort sort order. As for get_users_by_capability. 259 * @return array list of users. 260 */ 261 public static function get_potential_subscribers($context, $groupid, $fields, $sort = '') { 262 global $DB; 263 264 // Only active enrolled users or everybody on the frontpage. 265 list($esql, $params) = get_enrolled_sql($context, 'mod/forum:allowforcesubscribe', $groupid, true); 266 if (!$sort) { 267 list($sort, $sortparams) = users_order_by_sql('u'); 268 $params = array_merge($params, $sortparams); 269 } 270 271 $sql = "SELECT $fields 272 FROM {user} u 273 JOIN ($esql) je ON je.id = u.id 274 ORDER BY $sort"; 275 276 return $DB->get_records_sql($sql, $params); 277 } 278 279 /** 280 * Fetch the forum subscription data for the specified userid and forum. 281 * 282 * @param int $forumid The forum to retrieve a cache for 283 * @param int $userid The user ID 284 * @return boolean 285 */ 286 public static function fetch_subscription_cache($forumid, $userid) { 287 if (isset(self::$forumcache[$userid]) && isset(self::$forumcache[$userid][$forumid])) { 288 return self::$forumcache[$userid][$forumid]; 289 } 290 self::fill_subscription_cache($forumid, $userid); 291 292 if (!isset(self::$forumcache[$userid]) || !isset(self::$forumcache[$userid][$forumid])) { 293 return false; 294 } 295 296 return self::$forumcache[$userid][$forumid]; 297 } 298 299 /** 300 * Fill the forum subscription data for the specified userid and forum. 301 * 302 * If the userid is not specified, then all subscription data for that forum is fetched in a single query and used 303 * for subsequent lookups without requiring further database queries. 304 * 305 * @param int $forumid The forum to retrieve a cache for 306 * @param int $userid The user ID 307 * @return void 308 */ 309 public static function fill_subscription_cache($forumid, $userid = null) { 310 global $DB; 311 312 if (!isset(self::$fetchedforums[$forumid])) { 313 // This forum has not been fetched as a whole. 314 if (isset($userid)) { 315 if (!isset(self::$forumcache[$userid])) { 316 self::$forumcache[$userid] = array(); 317 } 318 319 if (!isset(self::$forumcache[$userid][$forumid])) { 320 if ($DB->record_exists('forum_subscriptions', array( 321 'userid' => $userid, 322 'forum' => $forumid, 323 ))) { 324 self::$forumcache[$userid][$forumid] = true; 325 } else { 326 self::$forumcache[$userid][$forumid] = false; 327 } 328 } 329 } else { 330 $subscriptions = $DB->get_recordset('forum_subscriptions', array( 331 'forum' => $forumid, 332 ), '', 'id, userid'); 333 foreach ($subscriptions as $id => $data) { 334 if (!isset(self::$forumcache[$data->userid])) { 335 self::$forumcache[$data->userid] = array(); 336 } 337 self::$forumcache[$data->userid][$forumid] = true; 338 } 339 self::$fetchedforums[$forumid] = true; 340 $subscriptions->close(); 341 } 342 } 343 } 344 345 /** 346 * Fill the forum subscription data for all forums that the specified userid can subscribe to in the specified course. 347 * 348 * @param int $courseid The course to retrieve a cache for 349 * @param int $userid The user ID 350 * @return void 351 */ 352 public static function fill_subscription_cache_for_course($courseid, $userid) { 353 global $DB; 354 355 if (!isset(self::$forumcache[$userid])) { 356 self::$forumcache[$userid] = array(); 357 } 358 359 $sql = "SELECT 360 f.id AS forumid, 361 s.id AS subscriptionid 362 FROM {forum} f 363 LEFT JOIN {forum_subscriptions} s ON (s.forum = f.id AND s.userid = :userid) 364 WHERE f.course = :course 365 AND f.forcesubscribe <> :subscriptionforced"; 366 367 $subscriptions = $DB->get_recordset_sql($sql, array( 368 'course' => $courseid, 369 'userid' => $userid, 370 'subscriptionforced' => FORUM_FORCESUBSCRIBE, 371 )); 372 373 foreach ($subscriptions as $id => $data) { 374 self::$forumcache[$userid][$id] = !empty($data->subscriptionid); 375 } 376 $subscriptions->close(); 377 } 378 379 /** 380 * Returns a list of user objects who are subscribed to this forum. 381 * 382 * @param stdClass $forum The forum record. 383 * @param int $groupid The group id if restricting subscriptions to a group of users, or 0 for all. 384 * @param context_module $context the forum context, to save re-fetching it where possible. 385 * @param string $fields requested user fields (with "u." table prefix). 386 * @param boolean $includediscussionsubscriptions Whether to take discussion subscriptions and unsubscriptions into consideration. 387 * @return array list of users. 388 */ 389 public static function fetch_subscribed_users($forum, $groupid = 0, $context = null, $fields = null, 390 $includediscussionsubscriptions = false) { 391 global $CFG, $DB; 392 393 if (empty($fields)) { 394 $allnames = get_all_user_name_fields(true, 'u'); 395 $fields ="u.id, 396 u.username, 397 $allnames, 398 u.maildisplay, 399 u.mailformat, 400 u.maildigest, 401 u.imagealt, 402 u.email, 403 u.emailstop, 404 u.city, 405 u.country, 406 u.lastaccess, 407 u.lastlogin, 408 u.picture, 409 u.timezone, 410 u.theme, 411 u.lang, 412 u.trackforums, 413 u.mnethostid"; 414 } 415 416 // Retrieve the forum context if it wasn't specified. 417 $context = forum_get_context($forum->id, $context); 418 419 if (self::is_forcesubscribed($forum)) { 420 $results = \mod_forum\subscriptions::get_potential_subscribers($context, $groupid, $fields, "u.email ASC"); 421 422 } else { 423 // Only active enrolled users or everybody on the frontpage. 424 list($esql, $params) = get_enrolled_sql($context, '', $groupid, true); 425 $params['forumid'] = $forum->id; 426 427 if ($includediscussionsubscriptions) { 428 $params['sforumid'] = $forum->id; 429 $params['dsforumid'] = $forum->id; 430 $params['unsubscribed'] = self::FORUM_DISCUSSION_UNSUBSCRIBED; 431 432 $sql = "SELECT $fields 433 FROM ( 434 SELECT userid FROM {forum_subscriptions} s 435 WHERE 436 s.forum = :sforumid 437 UNION 438 SELECT userid FROM {forum_discussion_subs} ds 439 WHERE 440 ds.forum = :dsforumid AND ds.preference <> :unsubscribed 441 ) subscriptions 442 JOIN {user} u ON u.id = subscriptions.userid 443 JOIN ($esql) je ON je.id = u.id 444 ORDER BY u.email ASC"; 445 446 } else { 447 $sql = "SELECT $fields 448 FROM {user} u 449 JOIN ($esql) je ON je.id = u.id 450 JOIN {forum_subscriptions} s ON s.userid = u.id 451 WHERE 452 s.forum = :forumid 453 ORDER BY u.email ASC"; 454 } 455 $results = $DB->get_records_sql($sql, $params); 456 } 457 458 // Guest user should never be subscribed to a forum. 459 unset($results[$CFG->siteguest]); 460 461 // Apply the activity module availability resetrictions. 462 $cm = get_coursemodule_from_instance('forum', $forum->id, $forum->course); 463 $modinfo = get_fast_modinfo($forum->course); 464 $info = new \core_availability\info_module($modinfo->get_cm($cm->id)); 465 $results = $info->filter_user_list($results); 466 467 return $results; 468 } 469 470 /** 471 * Retrieve the discussion subscription data for the specified userid and forum. 472 * 473 * This is returned as an array of discussions for that forum which contain the preference in a stdClass. 474 * 475 * @param int $forumid The forum to retrieve a cache for 476 * @param int $userid The user ID 477 * @return array of stdClass objects with one per discussion in the forum. 478 */ 479 public static function fetch_discussion_subscription($forumid, $userid = null) { 480 self::fill_discussion_subscription_cache($forumid, $userid); 481 482 if (!isset(self::$forumdiscussioncache[$userid]) || !isset(self::$forumdiscussioncache[$userid][$forumid])) { 483 return array(); 484 } 485 486 return self::$forumdiscussioncache[$userid][$forumid]; 487 } 488 489 /** 490 * Fill the discussion subscription data for the specified userid and forum. 491 * 492 * If the userid is not specified, then all discussion subscription data for that forum is fetched in a single query 493 * and used for subsequent lookups without requiring further database queries. 494 * 495 * @param int $forumid The forum to retrieve a cache for 496 * @param int $userid The user ID 497 * @return void 498 */ 499 public static function fill_discussion_subscription_cache($forumid, $userid = null) { 500 global $DB; 501 502 if (!isset(self::$discussionfetchedforums[$forumid])) { 503 // This forum hasn't been fetched as a whole yet. 504 if (isset($userid)) { 505 if (!isset(self::$forumdiscussioncache[$userid])) { 506 self::$forumdiscussioncache[$userid] = array(); 507 } 508 509 if (!isset(self::$forumdiscussioncache[$userid][$forumid])) { 510 $subscriptions = $DB->get_recordset('forum_discussion_subs', array( 511 'userid' => $userid, 512 'forum' => $forumid, 513 ), null, 'id, discussion, preference'); 514 foreach ($subscriptions as $id => $data) { 515 self::add_to_discussion_cache($forumid, $userid, $data->discussion, $data->preference); 516 } 517 $subscriptions->close(); 518 } 519 } else { 520 $subscriptions = $DB->get_recordset('forum_discussion_subs', array( 521 'forum' => $forumid, 522 ), null, 'id, userid, discussion, preference'); 523 foreach ($subscriptions as $id => $data) { 524 self::add_to_discussion_cache($forumid, $data->userid, $data->discussion, $data->preference); 525 } 526 self::$discussionfetchedforums[$forumid] = true; 527 $subscriptions->close(); 528 } 529 } 530 } 531 532 /** 533 * Add the specified discussion and user preference to the discussion 534 * subscription cache. 535 * 536 * @param int $forumid The ID of the forum that this preference belongs to 537 * @param int $userid The ID of the user that this preference belongs to 538 * @param int $discussion The ID of the discussion that this preference relates to 539 * @param int $preference The preference to store 540 */ 541 protected static function add_to_discussion_cache($forumid, $userid, $discussion, $preference) { 542 if (!isset(self::$forumdiscussioncache[$userid])) { 543 self::$forumdiscussioncache[$userid] = array(); 544 } 545 546 if (!isset(self::$forumdiscussioncache[$userid][$forumid])) { 547 self::$forumdiscussioncache[$userid][$forumid] = array(); 548 } 549 550 self::$forumdiscussioncache[$userid][$forumid][$discussion] = $preference; 551 } 552 553 /** 554 * Reset the discussion cache. 555 * 556 * This cache is used to reduce the number of database queries when 557 * checking forum discussion subscription states. 558 */ 559 public static function reset_discussion_cache() { 560 self::$forumdiscussioncache = array(); 561 self::$discussionfetchedforums = array(); 562 } 563 564 /** 565 * Reset the forum cache. 566 * 567 * This cache is used to reduce the number of database queries when 568 * checking forum subscription states. 569 */ 570 public static function reset_forum_cache() { 571 self::$forumcache = array(); 572 self::$fetchedforums = array(); 573 } 574 575 /** 576 * Adds user to the subscriber list. 577 * 578 * @param int $userid The ID of the user to subscribe 579 * @param \stdClass $forum The forum record for this forum. 580 * @param \context_module|null $context Module context, may be omitted if not known or if called for the current 581 * module set in page. 582 * @param boolean $userrequest Whether the user requested this change themselves. This has an effect on whether 583 * discussion subscriptions are removed too. 584 * @return bool|int Returns true if the user is already subscribed, or the forum_subscriptions ID if the user was 585 * successfully subscribed. 586 */ 587 public static function subscribe_user($userid, $forum, $context = null, $userrequest = false) { 588 global $DB; 589 590 if (self::is_subscribed($userid, $forum)) { 591 return true; 592 } 593 594 $sub = new \stdClass(); 595 $sub->userid = $userid; 596 $sub->forum = $forum->id; 597 598 $result = $DB->insert_record("forum_subscriptions", $sub); 599 600 if ($userrequest) { 601 $discussionsubscriptions = $DB->get_recordset('forum_discussion_subs', array('userid' => $userid, 'forum' => $forum->id)); 602 $DB->delete_records_select('forum_discussion_subs', 603 'userid = :userid AND forum = :forumid AND preference <> :preference', array( 604 'userid' => $userid, 605 'forumid' => $forum->id, 606 'preference' => self::FORUM_DISCUSSION_UNSUBSCRIBED, 607 )); 608 609 // Reset the subscription caches for this forum. 610 // We know that the there were previously entries and there aren't any more. 611 if (isset(self::$forumdiscussioncache[$userid]) && isset(self::$forumdiscussioncache[$userid][$forum->id])) { 612 foreach (self::$forumdiscussioncache[$userid][$forum->id] as $discussionid => $preference) { 613 if ($preference != self::FORUM_DISCUSSION_UNSUBSCRIBED) { 614 unset(self::$forumdiscussioncache[$userid][$forum->id][$discussionid]); 615 } 616 } 617 } 618 } 619 620 // Reset the cache for this forum. 621 self::$forumcache[$userid][$forum->id] = true; 622 623 $context = forum_get_context($forum->id, $context); 624 $params = array( 625 'context' => $context, 626 'objectid' => $result, 627 'relateduserid' => $userid, 628 'other' => array('forumid' => $forum->id), 629 630 ); 631 $event = event\subscription_created::create($params); 632 if ($userrequest && $discussionsubscriptions) { 633 foreach ($discussionsubscriptions as $subscription) { 634 $event->add_record_snapshot('forum_discussion_subs', $subscription); 635 } 636 $discussionsubscriptions->close(); 637 } 638 $event->trigger(); 639 640 return $result; 641 } 642 643 /** 644 * Removes user from the subscriber list 645 * 646 * @param int $userid The ID of the user to unsubscribe 647 * @param \stdClass $forum The forum record for this forum. 648 * @param \context_module|null $context Module context, may be omitted if not known or if called for the current 649 * module set in page. 650 * @param boolean $userrequest Whether the user requested this change themselves. This has an effect on whether 651 * discussion subscriptions are removed too. 652 * @return boolean Always returns true. 653 */ 654 public static function unsubscribe_user($userid, $forum, $context = null, $userrequest = false) { 655 global $DB; 656 657 $sqlparams = array( 658 'userid' => $userid, 659 'forum' => $forum->id, 660 ); 661 $DB->delete_records('forum_digests', $sqlparams); 662 663 if ($forumsubscription = $DB->get_record('forum_subscriptions', $sqlparams)) { 664 $DB->delete_records('forum_subscriptions', array('id' => $forumsubscription->id)); 665 666 if ($userrequest) { 667 $discussionsubscriptions = $DB->get_recordset('forum_discussion_subs', $sqlparams); 668 $DB->delete_records('forum_discussion_subs', 669 array('userid' => $userid, 'forum' => $forum->id, 'preference' => self::FORUM_DISCUSSION_UNSUBSCRIBED)); 670 671 // We know that the there were previously entries and there aren't any more. 672 if (isset(self::$forumdiscussioncache[$userid]) && isset(self::$forumdiscussioncache[$userid][$forum->id])) { 673 self::$forumdiscussioncache[$userid][$forum->id] = array(); 674 } 675 } 676 677 // Reset the cache for this forum. 678 self::$forumcache[$userid][$forum->id] = false; 679 680 $context = forum_get_context($forum->id, $context); 681 $params = array( 682 'context' => $context, 683 'objectid' => $forumsubscription->id, 684 'relateduserid' => $userid, 685 'other' => array('forumid' => $forum->id), 686 687 ); 688 $event = event\subscription_deleted::create($params); 689 $event->add_record_snapshot('forum_subscriptions', $forumsubscription); 690 if ($userrequest && $discussionsubscriptions) { 691 foreach ($discussionsubscriptions as $subscription) { 692 $event->add_record_snapshot('forum_discussion_subs', $subscription); 693 } 694 $discussionsubscriptions->close(); 695 } 696 $event->trigger(); 697 } 698 699 return true; 700 } 701 702 /** 703 * Subscribes the user to the specified discussion. 704 * 705 * @param int $userid The userid of the user being subscribed 706 * @param \stdClass $discussion The discussion to subscribe to 707 * @param \context_module|null $context Module context, may be omitted if not known or if called for the current 708 * module set in page. 709 * @return boolean Whether a change was made 710 */ 711 public static function subscribe_user_to_discussion($userid, $discussion, $context = null) { 712 global $DB; 713 714 // First check whether the user is subscribed to the discussion already. 715 $subscription = $DB->get_record('forum_discussion_subs', array('userid' => $userid, 'discussion' => $discussion->id)); 716 if ($subscription) { 717 if ($subscription->preference != self::FORUM_DISCUSSION_UNSUBSCRIBED) { 718 // The user is already subscribed to the discussion. Ignore. 719 return false; 720 } 721 } 722 // No discussion-level subscription. Check for a forum level subscription. 723 if ($DB->record_exists('forum_subscriptions', array('userid' => $userid, 'forum' => $discussion->forum))) { 724 if ($subscription && $subscription->preference == self::FORUM_DISCUSSION_UNSUBSCRIBED) { 725 // The user is subscribed to the forum, but unsubscribed from the discussion, delete the discussion preference. 726 $DB->delete_records('forum_discussion_subs', array('id' => $subscription->id)); 727 unset(self::$forumdiscussioncache[$userid][$discussion->forum][$discussion->id]); 728 } else { 729 // The user is already subscribed to the forum. Ignore. 730 return false; 731 } 732 } else { 733 if ($subscription) { 734 $subscription->preference = time(); 735 $DB->update_record('forum_discussion_subs', $subscription); 736 } else { 737 $subscription = new \stdClass(); 738 $subscription->userid = $userid; 739 $subscription->forum = $discussion->forum; 740 $subscription->discussion = $discussion->id; 741 $subscription->preference = time(); 742 743 $subscription->id = $DB->insert_record('forum_discussion_subs', $subscription); 744 self::$forumdiscussioncache[$userid][$discussion->forum][$discussion->id] = $subscription->preference; 745 } 746 } 747 748 $context = forum_get_context($discussion->forum, $context); 749 $params = array( 750 'context' => $context, 751 'objectid' => $subscription->id, 752 'relateduserid' => $userid, 753 'other' => array( 754 'forumid' => $discussion->forum, 755 'discussion' => $discussion->id, 756 ), 757 758 ); 759 $event = event\discussion_subscription_created::create($params); 760 $event->trigger(); 761 762 return true; 763 } 764 /** 765 * Unsubscribes the user from the specified discussion. 766 * 767 * @param int $userid The userid of the user being unsubscribed 768 * @param \stdClass $discussion The discussion to unsubscribe from 769 * @param \context_module|null $context Module context, may be omitted if not known or if called for the current 770 * module set in page. 771 * @return boolean Whether a change was made 772 */ 773 public static function unsubscribe_user_from_discussion($userid, $discussion, $context = null) { 774 global $DB; 775 776 // First check whether the user's subscription preference for this discussion. 777 $subscription = $DB->get_record('forum_discussion_subs', array('userid' => $userid, 'discussion' => $discussion->id)); 778 if ($subscription) { 779 if ($subscription->preference == self::FORUM_DISCUSSION_UNSUBSCRIBED) { 780 // The user is already unsubscribed from the discussion. Ignore. 781 return false; 782 } 783 } 784 // No discussion-level preference. Check for a forum level subscription. 785 if (!$DB->record_exists('forum_subscriptions', array('userid' => $userid, 'forum' => $discussion->forum))) { 786 if ($subscription && $subscription->preference != self::FORUM_DISCUSSION_UNSUBSCRIBED) { 787 // The user is not subscribed to the forum, but subscribed from the discussion, delete the discussion subscription. 788 $DB->delete_records('forum_discussion_subs', array('id' => $subscription->id)); 789 unset(self::$forumdiscussioncache[$userid][$discussion->forum][$discussion->id]); 790 } else { 791 // The user is not subscribed from the forum. Ignore. 792 return false; 793 } 794 } else { 795 if ($subscription) { 796 $subscription->preference = self::FORUM_DISCUSSION_UNSUBSCRIBED; 797 $DB->update_record('forum_discussion_subs', $subscription); 798 } else { 799 $subscription = new \stdClass(); 800 $subscription->userid = $userid; 801 $subscription->forum = $discussion->forum; 802 $subscription->discussion = $discussion->id; 803 $subscription->preference = self::FORUM_DISCUSSION_UNSUBSCRIBED; 804 805 $subscription->id = $DB->insert_record('forum_discussion_subs', $subscription); 806 } 807 self::$forumdiscussioncache[$userid][$discussion->forum][$discussion->id] = $subscription->preference; 808 } 809 810 $context = forum_get_context($discussion->forum, $context); 811 $params = array( 812 'context' => $context, 813 'objectid' => $subscription->id, 814 'relateduserid' => $userid, 815 'other' => array( 816 'forumid' => $discussion->forum, 817 'discussion' => $discussion->id, 818 ), 819 820 ); 821 $event = event\discussion_subscription_deleted::create($params); 822 $event->trigger(); 823 824 return true; 825 } 826 827 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |