/** * Observer for role_assigned event. * * @param \core\event\role_assigned $event * @return void */ public static function role_assigned(\core\event\role_assigned $event) { global $CFG, $DB; $context = context::instance_by_id($event->contextid, MUST_EXIST); // If contextlevel is course then only subscribe user. Role assignment // at course level means user is enroled in course and can subscribe to twf. if ($context->contextlevel != CONTEXT_COURSE) { return; } // Forum lib required for the constant used below. require_once $CFG->dirroot . '/mod/twf/lib.php'; $userid = $event->relateduserid; $sql = "SELECT f.id, f.course as course, cm.id AS cmid, f.forcesubscribe\n FROM {twf} f\n JOIN {course_modules} cm ON (cm.instance = f.id)\n JOIN {modules} m ON (m.id = cm.module)\n LEFT JOIN {twf_subscriptions} fs ON (fs.twf = f.id AND fs.userid = :userid)\n WHERE f.course = :courseid\n AND f.forcesubscribe = :initial\n AND m.name = 'twf'\n AND fs.id IS NULL"; $params = array('courseid' => $context->instanceid, 'userid' => $userid, 'initial' => FORUM_INITIALSUBSCRIBE); $twfs = $DB->get_records_sql($sql, $params); foreach ($twfs as $twf) { // If user doesn't have allowforcesubscribe capability then don't subscribe. $modcontext = context_module::instance($twf->cmid); if (has_capability('mod/twf:allowforcesubscribe', $modcontext, $userid)) { \mod_twf\subscriptions::subscribe_user($userid, $twf, $modcontext); } } }
/** * Test that after toggling the twf subscription as another user, * the discussion subscription functionality works as expected. */ public function test_twf_subscribe_toggle_as_other_repeat_subscriptions() { global $DB; $this->resetAfterTest(true); // Create a course, with a twf. $course = $this->getDataGenerator()->create_course(); $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE); $twf = $this->getDataGenerator()->create_module('twf', $options); // Create a user enrolled in the course as a student. list($user) = $this->helper_create_users($course, 1); // Post a discussion to the twf. list($discussion, $post) = $this->helper_post_to_twf($twf, $user); // Confirm that the user is currently not subscribed to the twf. $this->assertFalse(\mod_twf\subscriptions::is_subscribed($user->id, $twf)); // Confirm that the user is unsubscribed from the discussion too. $this->assertFalse(\mod_twf\subscriptions::is_subscribed($user->id, $twf, $discussion->id)); // Confirm that we have no records in either of the subscription tables. $this->assertEquals(0, $DB->count_records('twf_subscriptions', array('userid' => $user->id, 'twf' => $twf->id))); $this->assertEquals(0, $DB->count_records('twf_discussion_subs', array('userid' => $user->id, 'discussion' => $discussion->id))); // Subscribing to the twf should create a record in the subscriptions table, but not the twf discussion // subscriptions table. \mod_twf\subscriptions::subscribe_user($user->id, $twf); $this->assertEquals(1, $DB->count_records('twf_subscriptions', array('userid' => $user->id, 'twf' => $twf->id))); $this->assertEquals(0, $DB->count_records('twf_discussion_subs', array('userid' => $user->id, 'discussion' => $discussion->id))); // Now unsubscribe from the discussion. This should return true. $this->assertTrue(\mod_twf\subscriptions::unsubscribe_user_from_discussion($user->id, $discussion)); // Attempting to unsubscribe again should return false because no change was made. $this->assertFalse(\mod_twf\subscriptions::unsubscribe_user_from_discussion($user->id, $discussion)); // Subscribing to the discussion again should return truthfully as the subscription preference was removed. $this->assertTrue(\mod_twf\subscriptions::subscribe_user_to_discussion($user->id, $discussion)); // Attempting to subscribe again should return false because no change was made. $this->assertFalse(\mod_twf\subscriptions::subscribe_user_to_discussion($user->id, $discussion)); // Now unsubscribe from the discussion. This should return true once more. $this->assertTrue(\mod_twf\subscriptions::unsubscribe_user_from_discussion($user->id, $discussion)); // And unsubscribing from the twf but not as a request from the user should maintain their preference. \mod_twf\subscriptions::unsubscribe_user($user->id, $twf); $this->assertEquals(0, $DB->count_records('twf_subscriptions', array('userid' => $user->id, 'twf' => $twf->id))); $this->assertEquals(1, $DB->count_records('twf_discussion_subs', array('userid' => $user->id, 'discussion' => $discussion->id))); // Subscribing to the discussion should return truthfully because a change was made. $this->assertTrue(\mod_twf\subscriptions::subscribe_user_to_discussion($user->id, $discussion)); $this->assertEquals(0, $DB->count_records('twf_subscriptions', array('userid' => $user->id, 'twf' => $twf->id))); $this->assertEquals(1, $DB->count_records('twf_discussion_subs', array('userid' => $user->id, 'discussion' => $discussion->id))); }
} if (!has_capability('mod/twf:viewdiscussion', $context)) { print_error('noviewdiscussionspermission', 'twf', get_local_referer(false)); } if (is_null($sesskey)) { // We came here via link in email. $PAGE->set_title($course->shortname); $PAGE->set_heading($course->fullname); echo $OUTPUT->header(); $viewurl = new moodle_url('/mod/twf/view.php', array('f' => $id)); if ($discussionid) { $a = new stdClass(); $a->twf = format_string($twf->name); $a->discussion = format_string($discussion->name); echo $OUTPUT->confirm(get_string('confirmsubscribediscussion', 'twf', $a), $PAGE->url, $viewurl); } else { echo $OUTPUT->confirm(get_string('confirmsubscribe', 'twf', format_string($twf->name)), $PAGE->url, $viewurl); } echo $OUTPUT->footer(); exit; } require_sesskey(); if ($discussionid == null) { \mod_twf\subscriptions::subscribe_user($user->id, $twf, $context, true); redirect($returnto, get_string("nowsubscribed", "twf", $info), 1); } else { $info->discussion = $discussion->name; \mod_twf\subscriptions::subscribe_user_to_discussion($user->id, $discussion, $context); redirect($returnto, get_string("discussionnowsubscribed", "twf", $info), 1); } }
public function test_optional_with_unsubscribed_discussion_in_subscribed_twf() { $this->resetAfterTest(true); // Create a course, with a twf. $course = $this->getDataGenerator()->create_course(); $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE); $twf = $this->getDataGenerator()->create_module('twf', $options); // Create two users enrolled in the course as students. list($author, $recipient) = $this->helper_create_users($course, 2); // Post a discussion to the twf. list($discussion, $post) = $this->helper_post_to_twf($twf, $author); // Unsubscribe the 'recipient' user from the discussion. \mod_twf\subscriptions::subscribe_user($recipient->id, $twf); // Then unsubscribe them from the discussion. \mod_twf\subscriptions::unsubscribe_user_from_discussion($recipient->id, $discussion); // We don't expect any users to receive this post. $expected = 0; // Run cron and check that the expected number of users received the notification. $messages = $this->helper_run_cron_check_count($post, $expected); }
/** * Adds user to the subscriber list * * @param int $userid * @param int $twfid * @param context_module|null $context Module context, may be omitted if not known or if called for the current module set in page. * @param boolean $userrequest Whether the user requested this change themselves. This has an effect on whether * discussion subscriptions are removed too. * @deprecated since Moodle 2.8 use \mod_twf\subscriptions::subscribe_user() instead */ function twf_subscribe($userid, $twfid, $context = null, $userrequest = false) { global $DB; debugging("twf_subscribe() has been deprecated, please use \\mod_twf\\subscriptions::subscribe_user() instead.", DEBUG_DEVELOPER); // Note: The new function does not take an integer form of twf. $twf = $DB->get_record('twf', array('id' => $twfid)); \mod_twf\subscriptions::subscribe_user($userid, $twf, $context, $userrequest); }
$options = array('twfid' => $twf->id, 'currentgroup' => $currentgroup, 'context' => $context); $existingselector = new mod_twf_existing_subscriber_selector('existingsubscribers', $options); $subscriberselector = new mod_twf_potential_subscriber_selector('potentialsubscribers', $options); $subscriberselector->set_existing_subscribers($existingselector->find_users('')); if (data_submitted()) { require_sesskey(); $subscribe = (bool) optional_param('subscribe', false, PARAM_RAW); $unsubscribe = (bool) optional_param('unsubscribe', false, PARAM_RAW); /** It has to be one or the other, not both or neither */ if (!($subscribe xor $unsubscribe)) { print_error('invalidaction'); } if ($subscribe) { $users = $subscriberselector->get_selected_users(); foreach ($users as $user) { if (!\mod_twf\subscriptions::subscribe_user($user->id, $twf)) { print_error('cannotaddsubscriber', 'twf', '', $user->id); } } } else { if ($unsubscribe) { $users = $existingselector->get_selected_users(); foreach ($users as $user) { if (!\mod_twf\subscriptions::unsubscribe_user($user->id, $twf)) { print_error('cannotremovesubscriber', 'twf', '', $user->id); } } } } $subscriberselector->invalidate_selected_users(); $existingselector->invalidate_selected_users();
/** * Test that the correct context is used in the events when subscribing * users. */ public function test_twf_subscription_page_context_valid() { global $CFG, $PAGE; require_once $CFG->dirroot . '/mod/twf/lib.php'; // Setup test data. $course = $this->getDataGenerator()->create_course(); $user = $this->getDataGenerator()->create_user(); $this->getDataGenerator()->enrol_user($user->id, $course->id); $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE); $twf = $this->getDataGenerator()->create_module('twf', $options); $quiz = $this->getDataGenerator()->create_module('quiz', $options); // Add a discussion. $record = array(); $record['course'] = $course->id; $record['twf'] = $twf->id; $record['userid'] = $user->id; $discussion = $this->getDataGenerator()->get_plugin_generator('mod_twf')->create_discussion($record); // Add a post. $record = array(); $record['discussion'] = $discussion->id; $record['userid'] = $user->id; $post = $this->getDataGenerator()->get_plugin_generator('mod_twf')->create_post($record); // Set up the default page event to use this twf. $PAGE = new moodle_page(); $cm = get_coursemodule_from_instance('twf', $discussion->twf); $context = \context_module::instance($cm->id); $PAGE->set_context($context); $PAGE->set_cm($cm, $course, $twf); // Trigger and capturing the event. $sink = $this->redirectEvents(); // Trigger the event by subscribing the user to the twf. \mod_twf\subscriptions::subscribe_user($user->id, $twf); $events = $sink->get_events(); $sink->clear(); $this->assertCount(1, $events); $event = reset($events); // Checking that the event contains the expected values. $this->assertInstanceOf('\\mod_twf\\event\\subscription_created', $event); $this->assertEquals($context, $event->get_context()); // Trigger the event by unsubscribing the user to the twf. \mod_twf\subscriptions::unsubscribe_user($user->id, $twf); $events = $sink->get_events(); $sink->clear(); $this->assertCount(1, $events); $event = reset($events); // Checking that the event contains the expected values. $this->assertInstanceOf('\\mod_twf\\event\\subscription_deleted', $event); $this->assertEquals($context, $event->get_context()); // Trigger the event by subscribing the user to the discussion. \mod_twf\subscriptions::subscribe_user_to_discussion($user->id, $discussion); $events = $sink->get_events(); $sink->clear(); $this->assertCount(1, $events); $event = reset($events); // Checking that the event contains the expected values. $this->assertInstanceOf('\\mod_twf\\event\\discussion_subscription_created', $event); $this->assertEquals($context, $event->get_context()); // Trigger the event by unsubscribing the user from the discussion. \mod_twf\subscriptions::unsubscribe_user_from_discussion($user->id, $discussion); $events = $sink->get_events(); $sink->clear(); $this->assertCount(1, $events); $event = reset($events); // Checking that the event contains the expected values. $this->assertInstanceOf('\\mod_twf\\event\\discussion_subscription_deleted', $event); $this->assertEquals($context, $event->get_context()); // Now try with the context for a different module (quiz). $PAGE = new moodle_page(); $cm = get_coursemodule_from_instance('quiz', $quiz->id); $quizcontext = \context_module::instance($cm->id); $PAGE->set_context($quizcontext); $PAGE->set_cm($cm, $course, $quiz); // Trigger and capturing the event. $sink = $this->redirectEvents(); // Trigger the event by subscribing the user to the twf. \mod_twf\subscriptions::subscribe_user($user->id, $twf); $events = $sink->get_events(); $sink->clear(); $this->assertCount(1, $events); $event = reset($events); // Checking that the event contains the expected values. $this->assertInstanceOf('\\mod_twf\\event\\subscription_created', $event); $this->assertEquals($context, $event->get_context()); // Trigger the event by unsubscribing the user to the twf. \mod_twf\subscriptions::unsubscribe_user($user->id, $twf); $events = $sink->get_events(); $sink->clear(); $this->assertCount(1, $events); $event = reset($events); // Checking that the event contains the expected values. $this->assertInstanceOf('\\mod_twf\\event\\subscription_deleted', $event); $this->assertEquals($context, $event->get_context()); // Trigger the event by subscribing the user to the discussion. \mod_twf\subscriptions::subscribe_user_to_discussion($user->id, $discussion); $events = $sink->get_events(); $sink->clear(); $this->assertCount(1, $events); $event = reset($events); // Checking that the event contains the expected values. $this->assertInstanceOf('\\mod_twf\\event\\discussion_subscription_created', $event); $this->assertEquals($context, $event->get_context()); // Trigger the event by unsubscribing the user from the discussion. \mod_twf\subscriptions::unsubscribe_user_from_discussion($user->id, $discussion); $events = $sink->get_events(); $sink->clear(); $this->assertCount(1, $events); $event = reset($events); // Checking that the event contains the expected values. $this->assertInstanceOf('\\mod_twf\\event\\discussion_subscription_deleted', $event); $this->assertEquals($context, $event->get_context()); // Now try with the course context - the module context should still be used. $PAGE = new moodle_page(); $coursecontext = \context_course::instance($course->id); $PAGE->set_context($coursecontext); // Trigger the event by subscribing the user to the twf. \mod_twf\subscriptions::subscribe_user($user->id, $twf); $events = $sink->get_events(); $sink->clear(); $this->assertCount(1, $events); $event = reset($events); // Checking that the event contains the expected values. $this->assertInstanceOf('\\mod_twf\\event\\subscription_created', $event); $this->assertEquals($context, $event->get_context()); // Trigger the event by unsubscribing the user to the twf. \mod_twf\subscriptions::unsubscribe_user($user->id, $twf); $events = $sink->get_events(); $sink->clear(); $this->assertCount(1, $events); $event = reset($events); // Checking that the event contains the expected values. $this->assertInstanceOf('\\mod_twf\\event\\subscription_deleted', $event); $this->assertEquals($context, $event->get_context()); // Trigger the event by subscribing the user to the discussion. \mod_twf\subscriptions::subscribe_user_to_discussion($user->id, $discussion); $events = $sink->get_events(); $sink->clear(); $this->assertCount(1, $events); $event = reset($events); // Checking that the event contains the expected values. $this->assertInstanceOf('\\mod_twf\\event\\discussion_subscription_created', $event); $this->assertEquals($context, $event->get_context()); // Trigger the event by unsubscribing the user from the discussion. \mod_twf\subscriptions::unsubscribe_user_from_discussion($user->id, $discussion); $events = $sink->get_events(); $sink->clear(); $this->assertCount(1, $events); $event = reset($events); // Checking that the event contains the expected values. $this->assertInstanceOf('\\mod_twf\\event\\discussion_subscription_deleted', $event); $this->assertEquals($context, $event->get_context()); }
// Can proceed now, the user is not guest and is enrolled foreach ($modinfo->get_instances_of('twf') as $twfid => $cm) { $twf = $twfs[$twfid]; $modcontext = context_module::instance($cm->id); $cansub = false; if (has_capability('mod/twf:viewdiscussion', $modcontext)) { $cansub = true; } if ($cansub && $cm->visible == 0 && !has_capability('mod/twf:managesubscriptions', $modcontext)) { $cansub = false; } if (!\mod_twf\subscriptions::is_forcesubscribed($twf)) { $subscribed = \mod_twf\subscriptions::is_subscribed($USER->id, $twf, null, $cm); $canmanageactivities = has_capability('moodle/course:manageactivities', $coursecontext, $USER->id); if (($canmanageactivities || \mod_twf\subscriptions::is_subscribable($twf)) && $subscribe && !$subscribed && $cansub) { \mod_twf\subscriptions::subscribe_user($USER->id, $twf, $modcontext, true); } else { if (!$subscribe && $subscribed) { \mod_twf\subscriptions::unsubscribe_user($USER->id, $twf, $modcontext, true); } } } } $returnto = twf_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', 'twf', $shortname), 1); } else { redirect($returnto, get_string('nowallunsubscribed', 'twf', $shortname), 1); } }
/** * Given an object containing all the necessary data, * (defined by the form in mod_form.php) this function * will update an existing instance with new data. * * @global object * @param object $twf twf instance (with magic quotes) * @return bool success */ function twf_update_instance($twf, $mform) { global $DB, $OUTPUT, $USER; $twf->timemodified = time(); $twf->id = $twf->instance; if (empty($twf->assessed)) { $twf->assessed = 0; } if (empty($twf->ratingtime) or empty($twf->assessed)) { $twf->assesstimestart = 0; $twf->assesstimefinish = 0; } $oldtwf = $DB->get_record('twf', array('id' => $twf->id)); // MDL-3942 - if the aggregation type or scale (i.e. max grade) changes then recalculate the grades for the entire twf // if scale changes - do we need to recheck the ratings, if ratings higher than scale how do we want to respond? // for count and sum aggregation types the grade we check to make sure they do not exceed the scale (i.e. max score) when calculating the grade if ($oldtwf->assessed != $twf->assessed or $oldtwf->scale != $twf->scale) { twf_update_grades($twf); // recalculate grades for the twf } if ($twf->type == 'single') { // Update related discussion and post. $discussions = $DB->get_records('twf_discussions', array('twf' => $twf->id), 'timemodified ASC'); if (!empty($discussions)) { if (count($discussions) > 1) { echo $OUTPUT->notification(get_string('warnformorepost', 'twf')); } $discussion = array_pop($discussions); } else { // try to recover by creating initial discussion - MDL-16262 $discussion = new stdClass(); $discussion->course = $twf->course; $discussion->twf = $twf->id; $discussion->name = $twf->name; $discussion->assessed = $twf->assessed; $discussion->message = $twf->intro; $discussion->messageformat = $twf->introformat; $discussion->messagetrust = true; $discussion->mailnow = false; $discussion->groupid = -1; $message = ''; twf_add_discussion($discussion, null, $message); if (!($discussion = $DB->get_record('twf_discussions', array('twf' => $twf->id)))) { print_error('cannotadd', 'twf'); } } if (!($post = $DB->get_record('twf_posts', array('id' => $discussion->firstpost)))) { print_error('cannotfindfirstpost', 'twf'); } $cm = get_coursemodule_from_instance('twf', $twf->id); $modcontext = context_module::instance($cm->id, MUST_EXIST); $post = $DB->get_record('twf_posts', array('id' => $discussion->firstpost), '*', MUST_EXIST); $post->subject = $twf->name; $post->message = $twf->intro; $post->messageformat = $twf->introformat; $post->messagetrust = trusttext_trusted($modcontext); $post->modified = $twf->timemodified; $post->userid = $USER->id; // MDL-18599, so that current teacher can take ownership of activities. if ($mform and $draftid = file_get_submitted_draft_itemid('introeditor')) { // Ugly hack - we need to copy the files somehow. $options = array('subdirs' => true); // Use the same options as intro field! $post->message = file_save_draft_area_files($draftid, $modcontext->id, 'mod_twf', 'post', $post->id, $options, $post->message); } $DB->update_record('twf_posts', $post); $discussion->name = $twf->name; $DB->update_record('twf_discussions', $discussion); } $DB->update_record('twf', $twf); $modcontext = context_module::instance($twf->coursemodule); if ($twf->forcesubscribe == FORUM_INITIALSUBSCRIBE && $oldtwf->forcesubscribe != $twf->forcesubscribe) { $users = \mod_twf\subscriptions::get_potential_subscribers($modcontext, 0, 'u.id, u.email', ''); foreach ($users as $user) { \mod_twf\subscriptions::subscribe_user($user->id, $twf, $modcontext); } } twf_grade_item_update($twf); return true; }