Merge branch 'MDL-30106' of git://github.com/jleyva/moodle

This commit is contained in:
Dan Poltawski
2014-05-06 10:25:48 +08:00
7 changed files with 333 additions and 3 deletions
+4 -1
View File
@@ -947,7 +947,10 @@ $services = array(
'message_airnotifier_is_system_configured',
'message_airnotifier_are_notification_preferences_configured',
'core_grades_get_grades',
'core_grades_update_grades'),
'core_grades_update_grades',
'mod_forum_get_forums_by_courses',
'mod_forum_get_forum_discussions',
'mod_forum_get_forum_discussion_posts'),
'enabled' => 0,
'restrictedusers' => 0,
'shortname' => MOODLE_OFFICIAL_MOBILE_SERVICE,
+9
View File
@@ -43,5 +43,14 @@ $functions = array(
'description' => 'Returns a list of forum discussions contained within a given set of forums.',
'type' => 'read',
'capabilities' => 'mod/forum:viewdiscussion, mod/forum:viewqandawithoutposting'
),
'mod_forum_get_forum_discussion_posts' => array(
'classname' => 'mod_forum_external',
'methodname' => 'get_forum_discussion_posts',
'classpath' => 'mod/forum/externallib.php',
'description' => 'Returns a list of forum posts for a discussion.',
'type' => 'read',
'capabilities' => 'mod/forum:viewdiscussion, mod/forum:viewqandawithoutposting'
)
);
+166
View File
@@ -354,4 +354,170 @@ class mod_forum_external extends external_api {
)
);
}
/**
* Describes the parameters for get_forum_discussion_posts.
*
* @return external_external_function_parameters
* @since Moodle 2.7
*/
public static function get_forum_discussion_posts_parameters() {
return new external_function_parameters (
array(
'discussionid' => new external_value(PARAM_INT, 'discussion ID', VALUE_REQUIRED),
'sortby' => new external_value(PARAM_ALPHA,
'sort by this element: id, created or modified', VALUE_DEFAULT, 'created'),
'sortdirection' => new external_value(PARAM_ALPHA, 'sort direction: ASC or DESC', VALUE_DEFAULT, 'DESC')
)
);
}
/**
* Returns a list of forum posts for a discussion
*
* @param int $discussionid the post ids
* @param string $sortby sort by this element (id, created or modified)
* @param string $sortdirection sort direction: ASC or DESC
*
* @return array the forum post details
* @since Moodle 2.7
*/
public static function get_forum_discussion_posts($discussionid, $sortby = "created", $sortdirection = "DESC") {
global $CFG, $DB, $USER;
$warnings = array();
// Validate the parameter.
$params = self::validate_parameters(self::get_forum_discussion_posts_parameters(),
array(
'discussionid' => $discussionid,
'sortby' => $sortby,
'sortdirection' => $sortdirection));
// Compact/extract functions are not recommended.
$discussionid = $params['discussionid'];
$sortby = $params['sortby'];
$sortdirection = $params['sortdirection'];
$sortallowedvalues = array('id', 'created', 'modified');
if (!in_array($sortby, $sortallowedvalues)) {
throw new invalid_parameter_exception('Invalid value for sortby parameter (value: ' . $sortby . '),' .
'allowed values are: ' . implode(',', $sortallowedvalues));
}
$sortdirection = strtoupper($sortdirection);
$directionallowedvalues = array('ASC', 'DESC');
if (!in_array($sortdirection, $directionallowedvalues)) {
throw new invalid_parameter_exception('Invalid value for sortdirection parameter (value: ' . $sortdirection . '),' .
'allowed values are: ' . implode(',', $directionallowedvalues));
}
$discussion = $DB->get_record('forum_discussions', array('id' => $discussionid), '*', MUST_EXIST);
$forum = $DB->get_record('forum', array('id' => $discussion->forum), '*', MUST_EXIST);
$course = $DB->get_record('course', array('id' => $forum->course), '*', MUST_EXIST);
$cm = get_coursemodule_from_instance('forum', $forum->id, $course->id, false, MUST_EXIST);
// Validate the module context. It checks everything that affects the module visibility (including groupings, etc..).
$modcontext = context_module::instance($cm->id);
self::validate_context($modcontext);
// This require must be here, see mod/forum/discuss.php.
require_once($CFG->dirroot . "/mod/forum/lib.php");
// Check they have the view forum capability.
require_capability('mod/forum:viewdiscussion', $modcontext, null, true, 'noviewdiscussionspermission', 'forum');
if (! $post = forum_get_post_full($discussion->firstpost)) {
throw new moodle_exception('notexists', 'forum');
}
// This function check groups, qanda, timed discussions, etc.
if (!forum_user_can_see_post($forum, $discussion, $post, null, $cm)) {
throw new moodle_exception('noviewdiscussionspermission', 'forum');
}
$canviewfullname = has_capability('moodle/site:viewfullnames', $modcontext);
// We will add this field in the response.
$canreply = forum_user_can_post($forum, $discussion, $USER, $cm, $course, $modcontext);
$forumtracked = forum_tp_is_tracked($forum);
$sort = 'p.' . $sortby . ' ' . $sortdirection;
$posts = forum_get_all_discussion_posts($discussion->id, $sort, $forumtracked);
foreach ($posts as $pid => $post) {
if (!forum_user_can_see_post($forum, $discussion, $post, null, $cm)) {
$warning = array();
$warning['item'] = 'post';
$warning['itemid'] = $post->id;
$warning['warningcode'] = '1';
$warning['message'] = 'You can\'t see this post';
$warnings[] = $warning;
continue;
}
// Function forum_get_all_discussion_posts adds postread field.
if (!isset($post->postread)) {
$posts[$pid]->postread = false;
}
$posts[$pid]->canreply = $canreply;
if (!empty($posts[$pid]->children)) {
$posts[$pid]->children = array_keys($posts[$pid]->children);
} else {
$posts[$pid]->children = array();
}
$user = new stdclass();
$user = username_load_fields_from_object($user, $post);
$posts[$pid]->userfullname = fullname($user, $canviewfullname);
$posts[$pid] = (array) $post;
}
$result = array();
$result['posts'] = $posts;
$result['warnings'] = $warnings;
return $result;
}
/**
* Describes the get_forum_discussion_posts return value.
*
* @return external_single_structure
* @since Moodle 2.7
*/
public static function get_forum_discussion_posts_returns() {
return new external_single_structure(
array(
'posts' => new external_multiple_structure(
new external_single_structure(
array(
'id' => new external_value(PARAM_INT, 'Post id'),
'discussion' => new external_value(PARAM_INT, 'Discussion id'),
'parent' => new external_value(PARAM_INT, 'Parent id'),
'userid' => new external_value(PARAM_INT, 'User id'),
'created' => new external_value(PARAM_INT, 'Creation time'),
'modified' => new external_value(PARAM_INT, 'Time modified'),
'mailed' => new external_value(PARAM_INT, 'Mailed?'),
'subject' => new external_value(PARAM_TEXT, 'The post subject'),
'message' => new external_value(PARAM_RAW, 'The post message'),
'messageformat' => new external_value(PARAM_INT, 'The post message format'),
'messagetrust' => new external_value(PARAM_INT, 'Can we trust?'),
'attachment' => new external_value(PARAM_RAW, 'Attachments'),
'totalscore' => new external_value(PARAM_INT, 'The post message total score'),
'mailnow' => new external_value(PARAM_INT, 'Mail now?'),
'children' => new external_multiple_structure(new external_value(PARAM_INT, 'children post id')),
'canreply' => new external_value(PARAM_BOOL, 'The user can reply to posts?'),
'postread' => new external_value(PARAM_BOOL, 'The post was read'),
'userfullname' => new external_value(PARAM_TEXT, 'Post author full name')
), 'post'
)
),
'warnings' => new external_warnings()
)
);
}
}
+128
View File
@@ -384,4 +384,132 @@ class mod_forum_external_testcase extends externallib_advanced_testcase {
$this->assertEquals('requireloginerror', $e->errorcode);
}
}
/**
* Test get forum posts
*/
public function test_mod_forum_get_forum_discussion_posts() {
global $CFG;
$this->resetAfterTest(true);
// Set the CFG variable to allow track forums.
$CFG->forum_trackreadposts = true;
// Create a user who can track forums.
$record = new stdClass();
$record->trackforums = true;
$user1 = self::getDataGenerator()->create_user($record);
// Create a bunch of other users to post.
$user2 = self::getDataGenerator()->create_user();
$user3 = self::getDataGenerator()->create_user();
// Set the first created user to the test user.
self::setUser($user1);
// Create course to add the module.
$course1 = self::getDataGenerator()->create_course();
// Forum with tracking off.
$record = new stdClass();
$record->course = $course1->id;
$record->trackingtype = FORUM_TRACKING_OFF;
$forum1 = self::getDataGenerator()->create_module('forum', $record);
$forum1context = context_module::instance($forum1->cmid);
// Add discussions to the forums.
$record = new stdClass();
$record->course = $course1->id;
$record->userid = $user1->id;
$record->forum = $forum1->id;
$discussion1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
$record = new stdClass();
$record->course = $course1->id;
$record->userid = $user2->id;
$record->forum = $forum1->id;
$discussion2 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
// Add 2 replies to the discussion 1 from different users.
$record = new stdClass();
$record->discussion = $discussion1->id;
$record->parent = $discussion1->firstpost;
$record->userid = $user2->id;
$discussion1reply1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
$record->parent = $discussion1reply1->id;
$record->userid = $user3->id;
$discussion1reply2 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
// Enrol the user in the course.
$enrol = enrol_get_plugin('manual');
// Following line enrol and assign default role id to the user.
// So the user automatically gets mod/forum:viewdiscussion on all forums of the course.
$this->getDataGenerator()->enrol_user($user1->id, $course1->id);
$this->getDataGenerator()->enrol_user($user2->id, $course1->id);
$this->getDataGenerator()->enrol_user($user3->id, $course1->id);
// Create what we expect to be returned when querying the discussion.
$expectedposts = array(
'posts' => array(),
'warnings' => array(),
);
$expectedposts['posts'][] = array(
'id' => $discussion1reply2->id,
'discussion' => $discussion1reply2->discussion,
'parent' => $discussion1reply2->parent,
'userid' => $discussion1reply2->userid,
'created' => $discussion1reply2->created,
'modified' => $discussion1reply2->modified,
'mailed' => $discussion1reply2->mailed,
'subject' => $discussion1reply2->subject,
'message' => file_rewrite_pluginfile_urls($discussion1reply2->message, 'pluginfile.php',
$forum1context->id, 'mod_forum', 'post', $discussion1reply2->id),
'messageformat' => $discussion1reply2->messageformat,
'messagetrust' => $discussion1reply2->messagetrust,
'attachment' => $discussion1reply2->attachment,
'totalscore' => $discussion1reply2->totalscore,
'mailnow' => $discussion1reply2->mailnow,
'children' => array(),
'canreply' => true,
'postread' => false,
'userfullname' => fullname($user3)
);
$expectedposts['posts'][] = array(
'id' => $discussion1reply1->id,
'discussion' => $discussion1reply1->discussion,
'parent' => $discussion1reply1->parent,
'userid' => $discussion1reply1->userid,
'created' => $discussion1reply1->created,
'modified' => $discussion1reply1->modified,
'mailed' => $discussion1reply1->mailed,
'subject' => $discussion1reply1->subject,
'message' => file_rewrite_pluginfile_urls($discussion1reply1->message, 'pluginfile.php',
$forum1context->id, 'mod_forum', 'post', $discussion1reply1->id),
'messageformat' => $discussion1reply1->messageformat,
'messagetrust' => $discussion1reply1->messagetrust,
'attachment' => $discussion1reply1->attachment,
'totalscore' => $discussion1reply1->totalscore,
'mailnow' => $discussion1reply1->mailnow,
'children' => array(4),
'canreply' => true,
'postread' => false,
'userfullname' => fullname($user2)
);
// Test a discussion with two additional posts (total 3 posts).
$posts = mod_forum_external::get_forum_discussion_posts($discussion1->id, 'modified', 'DESC');
$posts = external_api::clean_returnvalue(mod_forum_external::get_forum_discussion_posts_returns(), $posts);
$this->assertEquals(3, count($posts['posts']));
// Unset the initial discussion post.
array_pop($posts['posts']);
$this->assertEquals($expectedposts, $posts);
// Test discussion without additional posts. There should be only one post (the one created by the discussion).
$posts = mod_forum_external::get_forum_discussion_posts($discussion2->id, 'modified', 'DESC');
$posts = external_api::clean_returnvalue(mod_forum_external::get_forum_discussion_posts_returns(), $posts);
$this->assertEquals(1, count($posts['posts']));
}
}
+24
View File
@@ -198,6 +198,30 @@ class mod_forum_generator extends testing_module_generator {
$record['modified'] = $time;
}
if (!isset($record['mailed'])) {
$record['mailed'] = 0;
}
if (!isset($record['messageformat'])) {
$record['messageformat'] = 0;
}
if (!isset($record['messagetrust'])) {
$record['messagetrust'] = 0;
}
if (!isset($record['attachment'])) {
$record['attachment'] = "";
}
if (!isset($record['totalscore'])) {
$record['totalscore'] = 0;
}
if (!isset($record['mailnow'])) {
$record['mailnow'] = 0;
}
$record = (object) $record;
// Add the post.
+1 -1
View File
@@ -24,7 +24,7 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2014042200; // The current module version (Date: YYYYMMDDXX)
$plugin->version = 2014042201; // The current module version (Date: YYYYMMDDXX)
$plugin->requires = 2013110500; // Requires this Moodle version
$plugin->component = 'mod_forum'; // Full name of the plugin (used for diagnostics)
$plugin->cron = 60;
+1 -1
View File
@@ -29,7 +29,7 @@
defined('MOODLE_INTERNAL') || die();
$version = 2014050200.00; // YYYYMMDD = weekly release date of this DEV branch.
$version = 2014050200.01; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.