From b1aa7dfac38653bfdb2b64fa6fa226e8b60146c2 Mon Sep 17 00:00:00 2001
From: Juan Leyva <juanleyvadelgado@gmail.com>
Date: Sat, 6 Jun 2015 00:00:56 +0200
Subject: [PATCH] MDL-50493 forum: Handle correctly qanda forums in
 get_discussion_posts

---
 mod/forum/externallib.php            | 19 ++++----
 mod/forum/tests/externallib_test.php | 69 ++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+), 9 deletions(-)

diff --git a/mod/forum/externallib.php b/mod/forum/externallib.php
index 6da22b13b06..1e0c400348f 100644
--- a/mod/forum/externallib.php
+++ b/mod/forum/externallib.php
@@ -404,6 +404,7 @@ class mod_forum_external extends external_api {
     public static function get_forum_discussion_posts($discussionid, $sortby = "created", $sortdirection = "DESC") {
         global $CFG, $DB, $USER;
 
+        $posts = array();
         $warnings = array();
 
         // Validate the parameter.
@@ -463,9 +464,9 @@ class mod_forum_external extends external_api {
         $forumtracked = forum_tp_is_tracked($forum);
 
         $sort = 'p.' . $sortby . ' ' . $sortdirection;
-        $posts = forum_get_all_discussion_posts($discussion->id, $sort, $forumtracked);
+        $allposts = forum_get_all_discussion_posts($discussion->id, $sort, $forumtracked);
 
-        foreach ($posts as $pid => $post) {
+        foreach ($allposts as $post) {
 
             if (!forum_user_can_see_post($forum, $discussion, $post, null, $cm)) {
                 $warning = array();
@@ -480,16 +481,16 @@ class mod_forum_external extends external_api {
             // Function forum_get_all_discussion_posts adds postread field.
             // Note that the value returned can be a boolean or an integer. The WS expects a boolean.
             if (empty($post->postread)) {
-                $posts[$pid]->postread = false;
+                $post->postread = false;
             } else {
-                $posts[$pid]->postread = true;
+                $post->postread = true;
             }
 
-            $posts[$pid]->canreply = $canreply;
-            if (!empty($posts[$pid]->children)) {
-                $posts[$pid]->children = array_keys($posts[$pid]->children);
+            $post->canreply = $canreply;
+            if (!empty($post->children)) {
+                $post->children = array_keys($post->children);
             } else {
-                $posts[$pid]->children = array();
+                $post->children = array();
             }
 
             $user = new stdclass();
@@ -530,7 +531,7 @@ class mod_forum_external extends external_api {
                 }
             }
 
-            $posts[$pid] = (array) $post;
+            $posts[] = $post;
         }
 
         $result = array();
diff --git a/mod/forum/tests/externallib_test.php b/mod/forum/tests/externallib_test.php
index 2fd2200744e..3bb91957e8f 100644
--- a/mod/forum/tests/externallib_test.php
+++ b/mod/forum/tests/externallib_test.php
@@ -510,6 +510,75 @@ class mod_forum_external_testcase extends externallib_advanced_testcase {
 
     }
 
+
+    /**
+     * Test get forum posts (qanda forum)
+     */
+    public function test_mod_forum_get_forum_discussion_posts_qanda() {
+        global $CFG, $DB;
+
+        $this->resetAfterTest(true);
+
+        $record = new stdClass();
+        $user1 = self::getDataGenerator()->create_user($record);
+        $user2 = 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();
+        $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
+        $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
+
+        // Forum with tracking off.
+        $record = new stdClass();
+        $record->course = $course1->id;
+        $record->type = 'qanda';
+        $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 = $user2->id;
+        $record->forum = $forum1->id;
+        $discussion1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
+
+        // Add 1 reply (not the actual user).
+        $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);
+
+        // We still see only the original post.
+        $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(1, count($posts['posts']));
+
+        // Add a new reply, the user is going to be able to see only the original post and their new post.
+        $record = new stdClass();
+        $record->discussion = $discussion1->id;
+        $record->parent = $discussion1->firstpost;
+        $record->userid = $user1->id;
+        $discussion1reply2 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
+
+        $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(2, count($posts['posts']));
+
+        // Now, we can fake the time of the user post, so he can se the rest of the discussion posts.
+        $discussion1reply2->created -= $CFG->maxeditingtime * 2;
+        $DB->update_record('forum_posts', $discussion1reply2);
+
+        $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']));
+
+    }
+
+
     /**
      * Test get forum discussions paginated
      */