Merge branch 'MDL-30106' of git://github.com/jleyva/moodle
This commit is contained in:
+4
-1
@@ -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,
|
||||
|
||||
@@ -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'
|
||||
)
|
||||
);
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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']));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user