public function test_automatic_with_unsubscribed_discussion() { $this->resetAfterTest(true); // Create a course, with a quora. $course = $this->getDataGenerator()->create_course(); $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE); $quora = $this->getDataGenerator()->create_module('quora', $options); // Create two users enrolled in the course as students. list($author, $recipient) = $this->helper_create_users($course, 2); // Post a discussion to the quora. list($discussion, $post) = $this->helper_post_to_quora($quora, $author); // Unsubscribe the 'author' user from the discussion. \mod_quora\subscriptions::unsubscribe_user_from_discussion($author->id, $discussion); $this->assertFalse(\mod_quora\subscriptions::is_subscribed($author->id, $quora, $discussion->id)); $this->assertTrue(\mod_quora\subscriptions::is_subscribed($recipient->id, $quora, $discussion->id)); // We expect only one user to receive this post. $expected = 1; // Run cron and check that the expected number of users received the notification. $messages = $this->helper_run_cron_check_count($post, $expected); $seenauthor = false; $seenrecipient = false; foreach ($messages as $message) { // They should both be from our user. $this->assertEquals($author->id, $message->useridfrom); if ($message->useridto == $author->id) { $seenauthor = true; } else { if ($message->useridto = $recipient->id) { $seenrecipient = true; } } } // Check we only saw one user. $this->assertFalse($seenauthor); $this->assertTrue($seenrecipient); }
/** * Test that providing a context_module instance to is_subscribed does not result in additional lookups to retrieve * the context_module. */ public function test_is_subscribed_cm() { global $DB; $this->resetAfterTest(true); // Create a course, with a quora. $course = $this->getDataGenerator()->create_course(); $options = array('course' => $course->id, 'forcesubscribe' => FORUM_FORCESUBSCRIBE); $quora = $this->getDataGenerator()->create_module('quora', $options); // Create a user enrolled in the course as a student. list($user) = $this->helper_create_users($course, 1); // Retrieve the $cm now. $cm = get_fast_modinfo($quora->course)->instances['quora'][$quora->id]; // Reset get_fast_modinfo. get_fast_modinfo(0, 0, true); // Call is_subscribed without passing the $cmid - this should result in a lookup and filling of some of the // caches. This provides us with consistent data to start from. $this->assertTrue(\mod_quora\subscriptions::is_subscribed($user->id, $quora)); $this->assertTrue(\mod_quora\subscriptions::is_subscribed($user->id, $quora)); // Make a note of the number of DB calls. $basecount = $DB->perf_get_reads(); // Call is_subscribed - it should give return the correct result (False), and result in no additional queries. $this->assertTrue(\mod_quora\subscriptions::is_subscribed($user->id, $quora, null, $cm)); // The capability check does require some queries, so we don't test it directly. // We don't assert here because this is dependant upon linked code which could change at any time. $suppliedcmcount = $DB->perf_get_reads() - $basecount; // Call is_subscribed without passing the $cmid now - this should result in a lookup. get_fast_modinfo(0, 0, true); $basecount = $DB->perf_get_reads(); $this->assertTrue(\mod_quora\subscriptions::is_subscribed($user->id, $quora)); $calculatedcmcount = $DB->perf_get_reads() - $basecount; // There should be more queries than when we performed the same check a moment ago. $this->assertGreaterThan($suppliedcmcount, $calculatedcmcount); }
$context = context_module::instance($cm->id); if ($user) { require_sesskey(); if (!has_capability('mod/quora:managesubscriptions', $context)) { print_error('nopermissiontosubscribe', 'quora'); } $user = $DB->get_record('user', array('id' => $user), '*', MUST_EXIST); } else { $user = $USER; } if (isset($cm->groupmode) && empty($course->groupmodeforce)) { $groupmode = $cm->groupmode; } else { $groupmode = $course->groupmode; } $issubscribed = \mod_quora\subscriptions::is_subscribed($user->id, $quora, $discussionid, $cm); // For a user to subscribe when a groupmode is set, they must have access to at least one group. if ($groupmode && !$issubscribed && !has_capability('moodle/site:accessallgroups', $context)) { if (!groups_get_all_groups($course->id, $USER->id)) { print_error('cannotsubscribe', 'quora'); } } require_login($course, false, $cm); if (is_null($mode) and !is_enrolled($context, $USER, '', true)) { // Guests and visitors can't subscribe - only enrolled $PAGE->set_title($course->shortname); $PAGE->set_heading($course->fullname); if (isguestuser()) { echo $OUTPUT->header(); echo $OUTPUT->confirm(get_string('subscribeenrolledonly', 'quora') . '<br /><br />' . get_string('liketologin'), get_login_url(), new moodle_url('/mod/quora/view.php', array('f' => $id))); echo $OUTPUT->footer();
/** * Adds module specific settings to the settings block * * @param settings_navigation $settings The settings navigation object * @param navigation_node $quoranode The node to add module settings to */ function quora_extend_settings_navigation(settings_navigation $settingsnav, navigation_node $quoranode) { global $USER, $PAGE, $CFG, $DB, $OUTPUT; $quoraobject = $DB->get_record("quora", array("id" => $PAGE->cm->instance)); if (empty($PAGE->cm->context)) { $PAGE->cm->context = context_module::instance($PAGE->cm->instance); } $params = $PAGE->url->params(); if (!empty($params['d'])) { $discussionid = $params['d']; } // for some actions you need to be enrolled, beiing admin is not enough sometimes here $enrolled = is_enrolled($PAGE->cm->context, $USER, '', false); $activeenrolled = is_enrolled($PAGE->cm->context, $USER, '', true); $canmanage = has_capability('mod/quora:managesubscriptions', $PAGE->cm->context); $subscriptionmode = \mod_quora\subscriptions::get_subscription_mode($quoraobject); $cansubscribe = $activeenrolled && !\mod_quora\subscriptions::is_forcesubscribed($quoraobject) && (!\mod_quora\subscriptions::subscription_disabled($quoraobject) || $canmanage); if ($canmanage) { $mode = $quoranode->add(get_string('subscriptionmode', 'quora'), null, navigation_node::TYPE_CONTAINER); $allowchoice = $mode->add(get_string('subscriptionoptional', 'quora'), new moodle_url('/mod/quora/subscribe.php', array('id' => $quoraobject->id, 'mode' => FORUM_CHOOSESUBSCRIBE, 'sesskey' => sesskey())), navigation_node::TYPE_SETTING); $forceforever = $mode->add(get_string("subscriptionforced", "quora"), new moodle_url('/mod/quora/subscribe.php', array('id' => $quoraobject->id, 'mode' => FORUM_FORCESUBSCRIBE, 'sesskey' => sesskey())), navigation_node::TYPE_SETTING); $forceinitially = $mode->add(get_string("subscriptionauto", "quora"), new moodle_url('/mod/quora/subscribe.php', array('id' => $quoraobject->id, 'mode' => FORUM_INITIALSUBSCRIBE, 'sesskey' => sesskey())), navigation_node::TYPE_SETTING); $disallowchoice = $mode->add(get_string('subscriptiondisabled', 'quora'), new moodle_url('/mod/quora/subscribe.php', array('id' => $quoraobject->id, 'mode' => FORUM_DISALLOWSUBSCRIBE, 'sesskey' => sesskey())), navigation_node::TYPE_SETTING); switch ($subscriptionmode) { case FORUM_CHOOSESUBSCRIBE: // 0 $allowchoice->action = null; $allowchoice->add_class('activesetting'); break; case FORUM_FORCESUBSCRIBE: // 1 $forceforever->action = null; $forceforever->add_class('activesetting'); break; case FORUM_INITIALSUBSCRIBE: // 2 $forceinitially->action = null; $forceinitially->add_class('activesetting'); break; case FORUM_DISALLOWSUBSCRIBE: // 3 $disallowchoice->action = null; $disallowchoice->add_class('activesetting'); break; } } else { if ($activeenrolled) { switch ($subscriptionmode) { case FORUM_CHOOSESUBSCRIBE: // 0 $notenode = $quoranode->add(get_string('subscriptionoptional', 'quora')); break; case FORUM_FORCESUBSCRIBE: // 1 $notenode = $quoranode->add(get_string('subscriptionforced', 'quora')); break; case FORUM_INITIALSUBSCRIBE: // 2 $notenode = $quoranode->add(get_string('subscriptionauto', 'quora')); break; case FORUM_DISALLOWSUBSCRIBE: // 3 $notenode = $quoranode->add(get_string('subscriptiondisabled', 'quora')); break; } } } if ($cansubscribe) { if (\mod_quora\subscriptions::is_subscribed($USER->id, $quoraobject, null, $PAGE->cm)) { $linktext = get_string('unsubscribe', 'quora'); } else { $linktext = get_string('subscribe', 'quora'); } $url = new moodle_url('/mod/quora/subscribe.php', array('id' => $quoraobject->id, 'sesskey' => sesskey())); $quoranode->add($linktext, $url, navigation_node::TYPE_SETTING); if (isset($discussionid)) { if (\mod_quora\subscriptions::is_subscribed($USER->id, $quoraobject, $discussionid, $PAGE->cm)) { $linktext = get_string('unsubscribediscussion', 'quora'); } else { $linktext = get_string('subscribediscussion', 'quora'); } $url = new moodle_url('/mod/quora/subscribe.php', array('id' => $quoraobject->id, 'sesskey' => sesskey(), 'd' => $discussionid, 'returnurl' => $PAGE->url->out())); $quoranode->add($linktext, $url, navigation_node::TYPE_SETTING); } } if (has_capability('mod/quora:viewsubscribers', $PAGE->cm->context)) { $url = new moodle_url('/mod/quora/subscribers.php', array('id' => $quoraobject->id)); $quoranode->add(get_string('showsubscribers', 'quora'), $url, navigation_node::TYPE_SETTING); } if ($enrolled && quora_tp_can_track_quoras($quoraobject)) { // keep tracking info for users with suspended enrolments if ($quoraobject->trackingtype == FORUM_TRACKING_OPTIONAL || !$CFG->quora_allowforcedreadtracking && $quoraobject->trackingtype == FORUM_TRACKING_FORCED) { if (quora_tp_is_tracked($quoraobject)) { $linktext = get_string('notrackquora', 'quora'); } else { $linktext = get_string('trackquora', 'quora'); } $url = new moodle_url('/mod/quora/settracking.php', array('id' => $quoraobject->id, 'sesskey' => sesskey())); $quoranode->add($linktext, $url, navigation_node::TYPE_SETTING); } } if (!isloggedin() && $PAGE->course->id == SITEID) { $userid = guest_user()->id; } else { $userid = $USER->id; } $hascourseaccess = $PAGE->course->id == SITEID || can_access_course($PAGE->course, $userid); $enablerssfeeds = !empty($CFG->enablerssfeeds) && !empty($CFG->quora_enablerssfeeds); if ($enablerssfeeds && $quoraobject->rsstype && $quoraobject->rssarticles && $hascourseaccess) { if (!function_exists('rss_get_url')) { require_once "{$CFG->libdir}/rsslib.php"; } if ($quoraobject->rsstype == 1) { $string = get_string('rsssubscriberssdiscussions', 'quora'); } else { $string = get_string('rsssubscriberssposts', 'quora'); } $url = new moodle_url(rss_get_url($PAGE->cm->context->id, $userid, "mod_quora", $quoraobject->id)); $quoranode->add($string, $url, settings_navigation::TYPE_SETTING, null, null, new pix_icon('i/rss', '')); } }
// there should not be any links leading to this place, just redirect redirect(new moodle_url('/mod/quora/index.php', array('id' => $id)), get_string('subscribeenrolledonly', 'quora')); } // Can proceed now, the user is not guest and is enrolled foreach ($modinfo->get_instances_of('quora') as $quoraid => $cm) { $quora = $quoras[$quoraid]; $modcontext = context_module::instance($cm->id); $cansub = false; if (has_capability('mod/quora:viewdiscussion', $modcontext)) { $cansub = true; } if ($cansub && $cm->visible == 0 && !has_capability('mod/quora:managesubscriptions', $modcontext)) { $cansub = false; } if (!\mod_quora\subscriptions::is_forcesubscribed($quora)) { $subscribed = \mod_quora\subscriptions::is_subscribed($USER->id, $quora, null, $cm); $canmanageactivities = has_capability('moodle/course:manageactivities', $coursecontext, $USER->id); if (($canmanageactivities || \mod_quora\subscriptions::is_subscribable($quora)) && $subscribe && !$subscribed && $cansub) { \mod_quora\subscriptions::subscribe_user($USER->id, $quora, $modcontext, true); } else { if (!$subscribe && $subscribed) { \mod_quora\subscriptions::unsubscribe_user($USER->id, $quora, $modcontext, true); } } } } $returnto = quora_go_back_to("index.php?id={$course->id}"); $shortname = format_string($course->shortname, true, array('context' => context_course::instance($course->id))); if ($subscribe) { redirect($returnto, get_string('nowallsubscribed', 'quora', $shortname), 1); } else {
$includetext = optional_param('includetext', false, PARAM_BOOL); $quora = $DB->get_record('quora', array('id' => $quoraid), '*', MUST_EXIST); $course = $DB->get_record('course', array('id' => $quora->course), '*', MUST_EXIST); $discussion = $DB->get_record('quora_discussions', array('id' => $discussionid), '*', MUST_EXIST); $cm = get_coursemodule_from_instance('quora', $quora->id, $course->id, false, MUST_EXIST); $context = context_module::instance($cm->id); require_sesskey(); require_login($course, false, $cm); require_capability('mod/quora:viewdiscussion', $context); $return = new stdClass(); if (is_guest($context, $USER)) { // is_guest should be used here as this also checks whether the user is a guest in the current course. // Guests and visitors cannot subscribe - only enrolled users. throw new moodle_exception('noguestsubscribe', 'mod_quora'); } if (!\mod_quora\subscriptions::is_subscribable($quora)) { // Nothing to do. We won't actually output any content here though. echo json_encode($return); die; } if (\mod_quora\subscriptions::is_subscribed($USER->id, $quora, $discussion->id, $cm)) { // The user is subscribed, unsubscribe them. \mod_quora\subscriptions::unsubscribe_user_from_discussion($USER->id, $discussion, $context); } else { // The user is unsubscribed, subscribe them. \mod_quora\subscriptions::subscribe_user_to_discussion($USER->id, $discussion, $context); } // Now return the updated subscription icon. $return->icon = quora_get_discussion_subscription_icon($quora, $discussion->id, null, $includetext); echo json_encode($return); die;
} // For each subscribed user in this quora and discussion, copy over per-discussion subscriptions if required. $discussiongroup = $discussion->groupid == -1 ? 0 : $discussion->groupid; $potentialsubscribers = \mod_quora\subscriptions::fetch_subscribed_users($quora, $discussiongroup, $modcontext, 'u.id', true); // Pre-seed the subscribed_discussion caches. // Firstly for the quora being moved to. \mod_quora\subscriptions::fill_subscription_cache($quorato->id); // And also for the discussion being moved. \mod_quora\subscriptions::fill_subscription_cache($quora->id); $subscriptionchanges = array(); $subscriptiontime = time(); foreach ($potentialsubscribers as $subuser) { $userid = $subuser->id; $targetsubscription = \mod_quora\subscriptions::is_subscribed($userid, $quorato, null, $cmto); $discussionsubscribed = \mod_quora\subscriptions::is_subscribed($userid, $quora, $discussion->id); $quorasubscribed = \mod_quora\subscriptions::is_subscribed($userid, $quora); if ($quorasubscribed && !$discussionsubscribed && $targetsubscription) { // The user has opted out of this discussion and the move would cause them to receive notifications again. // Ensure they are unsubscribed from the discussion still. $subscriptionchanges[$userid] = \mod_quora\subscriptions::FORUM_DISCUSSION_UNSUBSCRIBED; } else { if (!$quorasubscribed && $discussionsubscribed && !$targetsubscription) { // The user has opted into this discussion and would otherwise not receive the subscription after the move. // Ensure they are subscribed to the discussion still. $subscriptionchanges[$userid] = $subscriptiontime; } } } $DB->set_field('quora_discussions', 'quora', $quorato->id, array('id' => $discussion->id)); $DB->set_field('quora_read', 'quoraid', $quorato->id, array('discussionid' => $discussion->id)); // Delete the existing per-discussion subscriptions and replace them with the newly calculated ones.
/** * Test subscription using disallow subscription on create. */ public function test_quora_disallow_subscribe_on_create() { global $CFG; $this->resetAfterTest(); $usercount = 5; $course = $this->getDataGenerator()->create_course(); $users = array(); for ($i = 0; $i < $usercount; $i++) { $user = $this->getDataGenerator()->create_user(); $users[] = $user; $this->getDataGenerator()->enrol_user($user->id, $course->id); } $options = array('course' => $course->id, 'forcesubscribe' => FORUM_DISALLOWSUBSCRIBE); // Subscription prevented. $quora = $this->getDataGenerator()->create_module('quora', $options); $result = \mod_quora\subscriptions::fetch_subscribed_users($quora); // No subscriptions by default. $this->assertEquals(0, count($result)); foreach ($users as $user) { $this->assertFalse(\mod_quora\subscriptions::is_subscribed($user->id, $quora)); } }
$draftid_editor = file_get_submitted_draft_itemid('message'); $currenttext = file_prepare_draft_area($draftid_editor, $modcontext->id, 'mod_quora', 'post', $postid, mod_quora_post_form::editor_options($modcontext, $postid), $post->message); $manageactivities = has_capability('moodle/course:manageactivities', $coursecontext); if (\mod_quora\subscriptions::subscription_disabled($quora) && !$manageactivities) { // User does not have permission to subscribe to this discussion at all. $discussionsubscribe = false; } else { if (\mod_quora\subscriptions::is_forcesubscribed($quora)) { // User does not have permission to unsubscribe from this discussion at all. $discussionsubscribe = true; } else { if (isset($discussion) && \mod_quora\subscriptions::is_subscribed($USER->id, $quora, $discussion->id, $cm)) { // User is subscribed to the discussion - continue the subscription. $discussionsubscribe = true; } else { if (!isset($discussion) && \mod_quora\subscriptions::is_subscribed($USER->id, $quora, null, $cm)) { // Starting a new discussion, and the user is subscribed to the quora - subscribe to the discussion. $discussionsubscribe = true; } else { // User is not subscribed to either quora or discussion. Follow user preference. $discussionsubscribe = $USER->autosubscribe; } } } } $mform_post->set_data(array('attachments' => $draftitemid, 'general' => $heading, 'subject' => $post->subject, 'message' => array('text' => $currenttext, 'format' => empty($post->messageformat) ? editors_get_preferred_format() : $post->messageformat, 'itemid' => $draftid_editor), 'discussionsubscribe' => $discussionsubscribe, 'mailnow' => !empty($post->mailnow), 'userid' => $post->userid, 'parent' => $post->parent, 'discussion' => $post->discussion, 'course' => $course->id) + $page_params + (isset($post->format) ? array('format' => $post->format) : array()) + (isset($discussion->timestart) ? array('timestart' => $discussion->timestart) : array()) + (isset($discussion->timeend) ? array('timeend' => $discussion->timeend) : array()) + (isset($post->groupid) ? array('groupid' => $post->groupid) : array()) + (isset($discussion->id) ? array('discussion' => $discussion->id) : array())); if ($mform_post->is_cancelled()) { if (!isset($discussion->id) || $quora->type === 'qanda') { // Q and A quoras don't have a discussion page, so treat them like a new thread.. redirect(new moodle_url('/mod/quora/view.php', array('f' => $quora->id))); } else {