diff --git a/plugins/QnA/class.qna.plugin.php b/plugins/QnA/class.qna.plugin.php index 3cc6a6146..1a686ad8a 100644 --- a/plugins/QnA/class.qna.plugin.php +++ b/plugins/QnA/class.qna.plugin.php @@ -1189,6 +1189,20 @@ public function fullQuestionMetaDataSchema() { ], 'dateAccepted:dt|n' => 'When an answer was accepted.', 'dateAnswered:dt|n' => 'When the last answer was inserted.', + "acceptedAnswers" => [ + "object" => "Accepted answers.", + "type" => "array", + "items" => Schema::parse([ + "commentID" => [ + "type" => "integer", + "description" => "Unique ID of the accepted answer's comment row." + ], + "body?" => [ + "type" => "string", + "description" => "Rendered content of the answer." + ], + ]), + ] ]); } @@ -1205,6 +1219,18 @@ public function discussionSchema_init(Schema $schema) { ])); } + /** + * Update the schema when getting a specific discussion from the API. + * + * @param Schema $schema + */ + public function discussionGetSchema_init(Schema $schema) { + // Add expanding a discussion's accepted answer content. + $expand = $schema->getField("properties.expand.items.enum"); + $expand[] = "acceptedAnswers"; + $schema->setField("properties.expand.items.enum", $expand); + } + /** * Add question meta data to discussion record. * @@ -1222,10 +1248,27 @@ public function discussionsApiController_normalizeOutput( return $discussion; } + $expandAnswers = $discussionsApiController->isExpandField("acceptedAnswers", $options["expand"] ?? []); + $acceptedAnswers = []; + $acceptedAnswerRows = $this->commentModel->getWhere([ + "DiscussionID" => $discussion["discussionID"], + "Qna" => "Accepted" + ])->resultArray(); + foreach ($acceptedAnswerRows as $comment) { + $answer = [ + "commentID" => $comment["CommentID"], + ]; + if ($expandAnswers) { + $answer["body"] = Gdn_Format::to($comment["Body"], $comment["Format"]); + } + $acceptedAnswers[] = $answer; + } + $discussion['attributes']['question'] = [ 'status' => strtolower($discussion['qnA']), 'dateAccepted' => $discussion['dateAccepted'], 'dateAnswered' => $discussion['dateOfAnswer'], + "acceptedAnswers" => $acceptedAnswers, ]; return $discussion; diff --git a/plugins/QnA/tests/APIv2/DiscussionsQuestionTest.php b/plugins/QnA/tests/APIv2/DiscussionsQuestionTest.php index 942f0b087..df7f9b246 100644 --- a/plugins/QnA/tests/APIv2/DiscussionsQuestionTest.php +++ b/plugins/QnA/tests/APIv2/DiscussionsQuestionTest.php @@ -112,4 +112,39 @@ public function testDiscussionsIndexQuestion() { } } + /** + * Verify accepted answer comment IDs are returned in a discussion response. + */ + public function testAcceptedAnswersInDiscussion() { + // Create the question. + $question = $this->testGetQuestion(); + + // Create a few answers. + $answers = []; + for ($i = 1; $i <= 5; $i++) { + $answers[] = $this->api()->post("comments", [ + "body" => "Hello world.", + "discussionID" => $question["discussionID"], + "format" => "Markdown", + ])->getBody(); + } + + // FLag the first two answers as accepted. + $this->api()->patch("comments/answer/".$answers[0]["commentID"], ["status" => "accepted"]); + $this->api()->patch("comments/answer/".$answers[1]["commentID"], ["status" => "accepted"]); + + $discussion = $this->api()->get("discussions/".$question['discussionID'])->getBody(); + + // Verify we have accepted answers. + $this->assertArrayHasKey("acceptedAnswers", $discussion["attributes"]["question"], "No accepted answers."); + $acceptedAnswers = $discussion["attributes"]["question"]["acceptedAnswers"]; + + // Verify we have exactly two accepted answers. + $this->assertEquals(2, count($acceptedAnswers), "Unexpected number of answers."); + + // Verify we have the correct two answers. + $commentIDs = array_column($acceptedAnswers, "commentID"); + $this->assertContains($answers[0]["commentID"], $commentIDs); + $this->assertContains($answers[1]["commentID"], $commentIDs); + } }