diff --git a/mod/forum/classes/local/vaults/post.php b/mod/forum/classes/local/vaults/post.php index 186457a73b5..83264055303 100644 --- a/mod/forum/classes/local/vaults/post.php +++ b/mod/forum/classes/local/vaults/post.php @@ -437,19 +437,28 @@ class post extends db_table_vault { 'where' => $privatewhere, 'params' => $privateparams, ] = $this->get_private_reply_sql($user, $canseeprivatereplies, "mp"); + [ + 'where' => $privatewhere2, + 'params' => $privateparams2, + ] = $this->get_private_reply_sql($user, $canseeprivatereplies, "p"); $sql = " - SELECT p.* - FROM {" . self::TABLE . "} p + SELECT posts.* + FROM {" . self::TABLE . "} posts JOIN ( - SELECT mp.discussion, mp.created, MAX(mp.id) AS latestpostid - FROM {" . self::TABLE . "} mp - WHERE mp.discussion {$insql} {$privatewhere} - GROUP BY mp.discussion, mp.created - HAVING mp.created = MAX(mp.created) - ) lp on lp.discussion = p.discussion AND lp.latestpostid = p.id"; + SELECT p.discussion, MAX(p.id) as latestpostid + FROM {" . self::TABLE . "} p + JOIN ( + SELECT mp.discussion, MAX(mp.created) AS created + FROM {" . self::TABLE . "} mp + WHERE mp.discussion {$insql} {$privatewhere} + GROUP BY mp.discussion + ) lp ON lp.discussion = p.discussion AND lp.created = p.created + WHERE 1=1 {$privatewhere2} + GROUP BY p.discussion + ) plp on plp.discussion = posts.discussion AND plp.latestpostid = posts.id"; - $records = $this->get_db()->get_records_sql($sql, array_merge($params, $privateparams)); + $records = $this->get_db()->get_records_sql($sql, array_merge($params, $privateparams, $privateparams2)); $entities = $this->transform_db_records_to_entities($records); return array_reduce($entities, function($carry, $entity) { @@ -469,10 +478,10 @@ class post extends db_table_vault { $params = []; $privatewhere = ''; if (!$canseeprivatereplies) { - $privatewhere = " AND ({$posttablealias}.privatereplyto = :privatereplyto OR " . - "{$posttablealias}.userid = :privatereplyfrom OR {$posttablealias}.privatereplyto = 0)"; - $params['privatereplyto'] = $user->id; - $params['privatereplyfrom'] = $user->id; + $privatewhere = " AND ({$posttablealias}.privatereplyto = :{$posttablealias}_privatereplyto OR " . + "{$posttablealias}.userid = :{$posttablealias}_privatereplyfrom OR {$posttablealias}.privatereplyto = 0)"; + $params[$posttablealias . '_privatereplyto'] = $user->id; + $params[$posttablealias . '_privatereplyfrom'] = $user->id; } return [ @@ -496,15 +505,19 @@ class post extends db_table_vault { list($insql, $params) = $this->get_db()->get_in_or_equal($discussionids, SQL_PARAMS_NAMED); $sql = " - SELECT p.* - FROM {" . self::TABLE . "} p + SELECT posts.* + FROM {" . self::TABLE . "} posts JOIN ( - SELECT mp.discussion, mp.created, MIN(mp.id) AS firstpostid - FROM {" . self::TABLE . "} mp - WHERE mp.discussion {$insql} - GROUP BY mp.discussion, mp.created - HAVING mp.created = MIN(mp.created) - ) fp ON fp.discussion = p.discussion AND fp.firstpostid = p.id"; + SELECT p.discussion, MIN(p.id) as firstpostid + FROM {" . self::TABLE . "} p + JOIN ( + SELECT mp.discussion, MIN(mp.created) AS created + FROM {" . self::TABLE . "} mp + WHERE mp.discussion {$insql} + GROUP BY mp.discussion + ) lp ON lp.discussion = p.discussion AND lp.created = p.created + GROUP BY p.discussion + ) plp on plp.discussion = posts.discussion AND plp.firstpostid = posts.id"; $records = $this->get_db()->get_records_sql($sql, $params); return $this->transform_db_records_to_entities($records); diff --git a/mod/forum/tests/vaults_post_test.php b/mod/forum/tests/vaults_post_test.php index 540715a3839..bd489047be6 100644 --- a/mod/forum/tests/vaults_post_test.php +++ b/mod/forum/tests/vaults_post_test.php @@ -793,15 +793,18 @@ final class vaults_post_test extends \advanced_testcase { $course = $datagenerator->create_course(); [$teacher, $otherteacher] = $this->helper_create_users($course, 2, 'teacher'); [$user, $user2] = $this->helper_create_users($course, 2, 'student'); + $now = time(); $forum = $datagenerator->create_module('forum', ['course' => $course->id]); [$discussion1, $post1] = $this->helper_post_to_forum($forum, $user); - $post2 = $this->helper_reply_to_post($post1, $user); - $post3 = $this->helper_reply_to_post($post1, $user); - $post4 = $this->helper_reply_to_post($post2, $user); + $post2 = $this->helper_reply_to_post($post1, $user, ['created' => $now + 100]); + $post3 = $this->helper_reply_to_post($post1, $user, ['created' => $now + 101]); + $post4 = $this->helper_reply_to_post($post2, $user, ['created' => $now + 102]); [$discussion2, $post5] = $this->helper_post_to_forum($forum, $user); $post6 = $this->helper_reply_to_post($post5, $user); - [$discussion3, $post7] = $this->helper_post_to_forum($forum, $user); - $post8 = $this->helper_post_to_discussion($forum, $discussion3, $teacher, [ + $post7 = $this->helper_reply_to_post($post5, $user); + $post8 = $this->helper_reply_to_post($post6, $user); + [$discussion3, $post9] = $this->helper_post_to_forum($forum, $user); + $post10 = $this->helper_post_to_discussion($forum, $discussion3, $teacher, [ 'privatereplyto' => $user->id, ]); @@ -813,22 +816,22 @@ final class vaults_post_test extends \advanced_testcase { [$discussion1->id, $discussion2->id], false); $this->assertCount(2, $ids); $this->assertEquals($post4->id, $ids[$discussion1->id]->get_id()); - $this->assertEquals($post6->id, $ids[$discussion2->id]->get_id()); + $this->assertEquals($post8->id, $ids[$discussion2->id]->get_id()); $ids = $this->vault->get_latest_posts_for_discussion_ids($user, [$discussion1->id, $discussion2->id, $discussion3->id], false); $this->assertCount(3, $ids); $this->assertEquals($post4->id, $ids[$discussion1->id]->get_id()); - $this->assertEquals($post6->id, $ids[$discussion2->id]->get_id()); - $this->assertEquals($post8->id, $ids[$discussion3->id]->get_id()); + $this->assertEquals($post8->id, $ids[$discussion2->id]->get_id()); + $this->assertEquals($post10->id, $ids[$discussion3->id]->get_id()); // Checks the user who doesn't have access to the private reply. $ids = $this->vault->get_latest_posts_for_discussion_ids($user2, [$discussion1->id, $discussion2->id, $discussion3->id], false); $this->assertCount(3, $ids); $this->assertEquals($post4->id, $ids[$discussion1->id]->get_id()); - $this->assertEquals($post6->id, $ids[$discussion2->id]->get_id()); - $this->assertEquals($post7->id, $ids[$discussion3->id]->get_id()); + $this->assertEquals($post8->id, $ids[$discussion2->id]->get_id()); + $this->assertEquals($post9->id, $ids[$discussion3->id]->get_id()); // Checks the user with the private reply to. $ids = $this->vault->get_latest_posts_for_discussion_ids($user, [ @@ -839,8 +842,8 @@ final class vaults_post_test extends \advanced_testcase { ], false); $this->assertCount(3, $ids); $this->assertEquals($post4->id, $ids[$discussion1->id]->get_id()); - $this->assertEquals($post6->id, $ids[$discussion2->id]->get_id()); - $this->assertEquals($post8->id, $ids[$discussion3->id]->get_id()); + $this->assertEquals($post8->id, $ids[$discussion2->id]->get_id()); + $this->assertEquals($post10->id, $ids[$discussion3->id]->get_id()); } /** @@ -871,13 +874,16 @@ final class vaults_post_test extends \advanced_testcase { $user = $datagenerator->create_user(); $course = $datagenerator->create_course(); $forum = $datagenerator->create_module('forum', ['course' => $course->id]); + $now = time(); [$discussion1, $post1] = $this->helper_post_to_forum($forum, $user); - $post2 = $this->helper_reply_to_post($post1, $user); - $post3 = $this->helper_reply_to_post($post1, $user); - $post4 = $this->helper_reply_to_post($post2, $user); + $post2 = $this->helper_reply_to_post($post1, $user, ['created' => $now + 100]); + $post3 = $this->helper_reply_to_post($post1, $user, ['created' => $now + 101]); + $post4 = $this->helper_reply_to_post($post2, $user, ['created' => $now + 102]); [$discussion2, $post5] = $this->helper_post_to_forum($forum, $user); $post6 = $this->helper_reply_to_post($post5, $user); - [$discussion3, $post7] = $this->helper_post_to_forum($forum, $user); + $post7 = $this->helper_reply_to_post($post5, $user); + $post8 = $this->helper_reply_to_post($post6, $user); + [$discussion3, $post9] = $this->helper_post_to_forum($forum, $user); $firstposts = $this->vault->get_first_post_for_discussion_ids([$discussion1->id]); $this->assertCount(1, $firstposts); @@ -892,7 +898,7 @@ final class vaults_post_test extends \advanced_testcase { $this->assertCount(3, $firstposts); $this->assertEquals($post1->id, $firstposts[$post1->id]->get_id()); $this->assertEquals($post5->id, $firstposts[$post5->id]->get_id()); - $this->assertEquals($post7->id, $firstposts[$post7->id]->get_id()); + $this->assertEquals($post9->id, $firstposts[$post9->id]->get_id()); $firstposts = $this->vault->get_first_post_for_discussion_ids([ $discussion1->id, @@ -903,7 +909,7 @@ final class vaults_post_test extends \advanced_testcase { $this->assertCount(3, $firstposts); $this->assertEquals($post1->id, $firstposts[$post1->id]->get_id()); $this->assertEquals($post5->id, $firstposts[$post5->id]->get_id()); - $this->assertEquals($post7->id, $firstposts[$post7->id]->get_id()); + $this->assertEquals($post9->id, $firstposts[$post9->id]->get_id()); } /**