From 04cd8ae3c0c079249fc753a8e0d2b98ee658d6a6 Mon Sep 17 00:00:00 2001 From: Juan Leyva Date: Mon, 16 Nov 2015 15:30:55 +0100 Subject: [PATCH] MDL-52165 mod_forum: New Web Service mod_forum_can_add_discussion --- lib/db/services.php | 1 + mod/forum/db/services.php | 8 +++ mod/forum/externallib.php | 66 ++++++++++++++++++ mod/forum/tests/externallib_test.php | 33 +++++++++ mod/forum/tests/lib_test.php | 100 +++++++++++++++++++++++++++ mod/forum/version.php | 2 +- version.php | 2 +- 7 files changed, 210 insertions(+), 2 deletions(-) diff --git a/lib/db/services.php b/lib/db/services.php index 8060d7fb83a..d3b5ae30896 100644 --- a/lib/db/services.php +++ b/lib/db/services.php @@ -1187,6 +1187,7 @@ $services = array( 'mod_forum_get_forum_discussion_posts', 'mod_forum_add_discussion_post', 'mod_forum_add_discussion', + 'mod_forum_can_add_discussion', 'core_files_get_files', 'core_message_get_messages', 'core_message_create_contacts', diff --git a/mod/forum/db/services.php b/mod/forum/db/services.php index 03b3763181b..43cf00eb932 100644 --- a/mod/forum/db/services.php +++ b/mod/forum/db/services.php @@ -99,4 +99,12 @@ $functions = array( 'type' => 'write', 'capabilities' => 'mod/forum:startdiscussion' ), + + 'mod_forum_can_add_discussion' => array( + 'classname' => 'mod_forum_external', + 'methodname' => 'can_add_discussion', + 'classpath' => 'mod/forum/externallib.php', + 'description' => 'Check if the current user can add discussions in the given forum (and optionally for the given group).', + 'type' => 'read' + ), ); diff --git a/mod/forum/externallib.php b/mod/forum/externallib.php index 20c7890206d..f45f7dfe0a3 100644 --- a/mod/forum/externallib.php +++ b/mod/forum/externallib.php @@ -1260,4 +1260,70 @@ class mod_forum_external extends external_api { ); } + /** + * Returns description of method parameters + * + * @return external_function_parameters + * @since Moodle 3.1 + */ + public static function can_add_discussion_parameters() { + return new external_function_parameters( + array( + 'forumid' => new external_value(PARAM_INT, 'Forum instance ID'), + 'groupid' => new external_value(PARAM_INT, 'The group to check, default to active group. + Use -1 to check if the user can post in all the groups.', VALUE_DEFAULT, null) + ) + ); + } + + /** + * Check if the current user can add discussions in the given forum (and optionally for the given group). + * + * @param int $forumid the forum instance id + * @param int $groupid the group to check, default to active group. Use -1 to check if the user can post in all the groups. + * @return array of warnings and the status (true if the user can add discussions) + * @since Moodle 3.1 + * @throws moodle_exception + */ + public static function can_add_discussion($forumid, $groupid = null) { + global $DB, $CFG; + require_once($CFG->dirroot . "/mod/forum/lib.php"); + + $params = self::validate_parameters(self::can_add_discussion_parameters(), + array( + 'forumid' => $forumid, + 'groupid' => $groupid, + )); + $warnings = array(); + + // Request and permission validation. + $forum = $DB->get_record('forum', array('id' => $params['forumid']), '*', MUST_EXIST); + list($course, $cm) = get_course_and_cm_from_instance($forum, 'forum'); + + $context = context_module::instance($cm->id); + self::validate_context($context); + + $status = forum_user_can_post_discussion($forum, $params['groupid'], -1, $cm, $context); + + $result = array(); + $result['status'] = $status; + $result['warnings'] = $warnings; + return $result; + } + + /** + * Returns description of method result value + * + * @return external_description + * @since Moodle 3.1 + */ + public static function can_add_discussion_returns() { + return new external_single_structure( + array( + 'status' => new external_value(PARAM_BOOL, 'True if the user can add discussions, false otherwise.'), + 'warnings' => new external_warnings() + ) + ); + } + } diff --git a/mod/forum/tests/externallib_test.php b/mod/forum/tests/externallib_test.php index 5981e5c0cec..afe8d8b72df 100644 --- a/mod/forum/tests/externallib_test.php +++ b/mod/forum/tests/externallib_test.php @@ -1010,4 +1010,37 @@ class mod_forum_external_testcase extends externallib_advanced_testcase { } + /* + * Test can_add_discussion. A basic test since all the API functions are already covered by unit tests. + */ + public function test_can_add_discussion() { + + $this->resetAfterTest(true); + + // Create courses to add the modules. + $course = self::getDataGenerator()->create_course(); + + $user = self::getDataGenerator()->create_user(); + + // First forum with tracking off. + $record = new stdClass(); + $record->course = $course->id; + $record->type = 'news'; + $forum = self::getDataGenerator()->create_module('forum', $record); + + // User with no permissions to add in a news forum. + self::setUser($user); + $this->getDataGenerator()->enrol_user($user->id, $course->id); + + $result = mod_forum_external::can_add_discussion($forum->id); + $result = external_api::clean_returnvalue(mod_forum_external::can_add_discussion_returns(), $result); + $this->assertFalse($result['status']); + + self::setAdminUser(); + $result = mod_forum_external::can_add_discussion($forum->id); + $result = external_api::clean_returnvalue(mod_forum_external::can_add_discussion_returns(), $result); + $this->assertTrue($result['status']); + + } + } diff --git a/mod/forum/tests/lib_test.php b/mod/forum/tests/lib_test.php index b57c320dfbd..20b04e5e4dd 100644 --- a/mod/forum/tests/lib_test.php +++ b/mod/forum/tests/lib_test.php @@ -2014,4 +2014,104 @@ class mod_forum_lib_testcase extends advanced_testcase { self::assertCount(0, $discussions); } + + /** + * Test forum_user_can_post_discussion + */ + public function test_forum_user_can_post_discussion() { + global $CFG, $DB; + + $this->resetAfterTest(true); + + // Create course to add the module. + $course = self::getDataGenerator()->create_course(array('groupmode' => SEPARATEGROUPS, 'groupmodeforce' => 1)); + $user = self::getDataGenerator()->create_user(); + $this->getDataGenerator()->enrol_user($user->id, $course->id); + + // Forum forcing separate gropus. + $record = new stdClass(); + $record->course = $course->id; + $forum = self::getDataGenerator()->create_module('forum', $record, array('groupmode' => SEPARATEGROUPS)); + $cm = get_coursemodule_from_instance('forum', $forum->id); + $context = context_module::instance($cm->id); + + self::setUser($user); + + // The user is not enroled in any group, try to post in a forum with separate groups. + $can = forum_user_can_post_discussion($forum, null, -1, $cm, $context); + $this->assertFalse($can); + + // Create a group. + $group = $this->getDataGenerator()->create_group(array('courseid' => $course->id)); + + // Try to post in a group the user is not enrolled. + $can = forum_user_can_post_discussion($forum, $group->id, -1, $cm, $context); + $this->assertFalse($can); + + // Add the user to a group. + groups_add_member($group->id, $user->id); + + // Try to post in a group the user is not enrolled. + $can = forum_user_can_post_discussion($forum, $group->id + 1, -1, $cm, $context); + $this->assertFalse($can); + + // Now try to post in the user group. (null means it will guess the group). + $can = forum_user_can_post_discussion($forum, null, -1, $cm, $context); + $this->assertTrue($can); + + $can = forum_user_can_post_discussion($forum, $group->id, -1, $cm, $context); + $this->assertTrue($can); + + // Test all groups. + $can = forum_user_can_post_discussion($forum, -1, -1, $cm, $context); + $this->assertFalse($can); + + $this->setAdminUser(); + $can = forum_user_can_post_discussion($forum, -1, -1, $cm, $context); + $this->assertTrue($can); + + // Change forum type. + $forum->type = 'news'; + $DB->update_record('forum', $forum); + + // Admin can post news. + $can = forum_user_can_post_discussion($forum, null, -1, $cm, $context); + $this->assertTrue($can); + + // Normal users don't. + self::setUser($user); + $can = forum_user_can_post_discussion($forum, null, -1, $cm, $context); + $this->assertFalse($can); + + // Change forum type. + $forum->type = 'eachuser'; + $DB->update_record('forum', $forum); + + // I didn't post yet, so I should be able to post. + $can = forum_user_can_post_discussion($forum, null, -1, $cm, $context); + $this->assertTrue($can); + + // Post now. + $record = new stdClass(); + $record->course = $course->id; + $record->userid = $user->id; + $record->forum = $forum->id; + $discussion = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); + + // I already posted, I shouldn't be able to post. + $can = forum_user_can_post_discussion($forum, null, -1, $cm, $context); + $this->assertFalse($can); + + // Last check with no groups, normal forum and course. + $course->groupmode = NOGROUPS; + $course->groupmodeforce = 0; + $DB->update_record('course', $course); + + $forum->type = 'general'; + $forum->groupmode = NOGROUPS; + $DB->update_record('forum', $forum); + + $can = forum_user_can_post_discussion($forum, null, -1, $cm, $context); + $this->assertTrue($can); + } } diff --git a/mod/forum/version.php b/mod/forum/version.php index b19e9d04afd..2b3ff680e8f 100644 --- a/mod/forum/version.php +++ b/mod/forum/version.php @@ -24,6 +24,6 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2015111600; // The current module version (Date: YYYYMMDDXX) +$plugin->version = 2015111601; // The current module version (Date: YYYYMMDDXX) $plugin->requires = 2015111000; // Requires this Moodle version $plugin->component = 'mod_forum'; // Full name of the plugin (used for diagnostics) diff --git a/version.php b/version.php index 3e00bee66e6..b1f750ad128 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2015111600.02; // YYYYMMDD = weekly release date of this DEV branch. +$version = 2015111600.03; // YYYYMMDD = weekly release date of this DEV branch. // RR = release increments - 00 in DEV branches. // .XX = incremental changes. -- 2.43.0