From f2eb04c1708e0d0ea60b2f999afdf7966190ce65 Mon Sep 17 00:00:00 2001 From: "Eloy Lafuente (stronk7)" Date: Fri, 17 May 2019 20:44:48 +0200 Subject: [PATCH] MDL-65635 forum: add_discussion_post() format support changes While keeping BC as possible (format will be saved as FORMAT_HTML as default and content not modified), this commit includes these changes: - A new parameter 'messageformat', defaults to FORMAT_HTML. - A new option 'tohtml', enabling the function to convert content in other formats to FORMAT_HTML before saving them. --- mod/forum/externallib.php | 28 +++++++++++++++++++++------- mod/forum/tests/externallib_test.php | 27 ++++++++++++++++++++++++++- mod/forum/upgrade.txt | 1 + 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/mod/forum/externallib.php b/mod/forum/externallib.php index 4f5ab14048b..6f5b6613d09 100644 --- a/mod/forum/externallib.php +++ b/mod/forum/externallib.php @@ -1178,7 +1178,7 @@ class mod_forum_external extends external_api { 'postid' => new external_value(PARAM_INT, 'the post id we are going to reply to (can be the initial discussion post'), 'subject' => new external_value(PARAM_TEXT, 'new post subject'), - 'message' => new external_value(PARAM_RAW, 'new post message (only html format allowed)'), + 'message' => new external_value(PARAM_RAW, 'new post message (html assumed if messageformat is not provided)'), 'options' => new external_multiple_structure ( new external_single_structure( array( @@ -1188,12 +1188,14 @@ class mod_forum_external extends external_api { private (bool); make this reply private to the author of the parent post, default to false. inlineattachmentsid (int); the draft file area id for inline attachments attachmentsid (int); the draft file area id for attachments + tohtml (bool); convert the message & messageformat to FORMAT_HTML, defaults to false '), 'value' => new external_value(PARAM_RAW, 'the value of the option, this param is validated in the external function.' ) ) - ), 'Options', VALUE_DEFAULT, array()) + ), 'Options', VALUE_DEFAULT, array()), + 'messageformat' => new external_format_value('message', VALUE_DEFAULT) ) ); } @@ -1203,13 +1205,14 @@ class mod_forum_external extends external_api { * * @param int $postid the post id we are going to reply to * @param string $subject new post subject - * @param string $message new post message (only html format allowed) + * @param string $message new post message (html assumed if messageformat is not provided) * @param array $options optional settings + * @param string $messageformat The format of the message, defaults to FORMAT_HTML for BC * @return array of warnings and the new post id * @since Moodle 3.0 * @throws moodle_exception */ - public static function add_discussion_post($postid, $subject, $message, $options = array()) { + public static function add_discussion_post($postid, $subject, $message, $options = array(), $messageformat = FORMAT_HTML) { global $CFG, $USER; require_once($CFG->dirroot . "/mod/forum/lib.php"); @@ -1228,7 +1231,8 @@ class mod_forum_external extends external_api { 'postid' => $postid, 'subject' => $subject, 'message' => $message, - 'options' => $options + 'options' => $options, + 'messageformat' => $messageformat, ) ); @@ -1258,7 +1262,8 @@ class mod_forum_external extends external_api { 'discussionsubscribe' => true, 'private' => false, 'inlineattachmentsid' => 0, - 'attachmentsid' => null + 'attachmentsid' => null, + 'tohtml' => false ); foreach ($params['options'] as $option) { $name = trim($option['name']); @@ -1279,6 +1284,9 @@ class mod_forum_external extends external_api { $value = 0; } break; + case 'tohtml': + $value = clean_param($option['value'], PARAM_BOOL); + break; default: throw new moodle_exception('errorinvalidparam', 'webservice', '', $name); } @@ -1292,13 +1300,19 @@ class mod_forum_external extends external_api { $thresholdwarning = forum_check_throttling($forumrecord, $cm); forum_check_blocking_threshold($thresholdwarning); + // If we want to force a conversion to HTML, let's do it now. + if ($options['tohtml'] && $params['messageformat'] != FORMAT_HTML) { + $params['message'] = format_text($params['message'], $params['messageformat'], ['context' => $context]); + $params['messageformat'] = FORMAT_HTML; + } + // Create the post. $post = new stdClass(); $post->discussion = $discussion->get_id(); $post->parent = $parent->id; $post->subject = $params['subject']; $post->message = $params['message']; - $post->messageformat = FORMAT_HTML; // Force formatting for now. + $post->messageformat = $params['messageformat']; $post->messagetrust = trusttext_trusted($context); $post->itemid = $options['inlineattachmentsid']; $post->attachments = $options['attachmentsid']; diff --git a/mod/forum/tests/externallib_test.php b/mod/forum/tests/externallib_test.php index 3cfeb478d21..35696addc04 100644 --- a/mod/forum/tests/externallib_test.php +++ b/mod/forum/tests/externallib_test.php @@ -1581,11 +1581,37 @@ class mod_forum_external_testcase extends externallib_advanced_testcase { if ($createdpost['postid'] == $thispost['id']) { $this->assertEquals('some subject', $thispost['subject']); $this->assertEquals('some text here...', $thispost['message']); + $this->assertEquals(FORMAT_HTML, $thispost['messageformat']); // This is the default if format was not specified. $tested = true; } } $this->assertTrue($tested); + // Let's simulate a call with any other format, it should be stored that way. + global $DB; // Yes, we are going to use DB facilities too, because cannot rely on other functions for checking + // the format. They eat it completely (going back to FORMAT_HTML. So we only can trust DB for further + // processing. + $formats = [FORMAT_PLAIN, FORMAT_MOODLE, FORMAT_MARKDOWN, FORMAT_HTML]; + $options = []; + foreach ($formats as $format) { + $createdpost = mod_forum_external::add_discussion_post($discussion->firstpost, + 'with some format', 'some formatted here...', $options, $format); + $createdpost = external_api::clean_returnvalue(mod_forum_external::add_discussion_post_returns(), $createdpost); + $dbformat = $DB->get_field('forum_posts', 'messageformat', ['id' => $createdpost['postid']]); + $this->assertEquals($format, $dbformat); + } + + // Now let's try the 'tohtml' option. That should end with the content + // transformed and the format being FORMAT_HTML always. + $options = [['name' => 'tohtml', 'value' => true]]; + $createdpost = mod_forum_external::add_discussion_post($discussion->firstpost, + 'interesting subject', 'with some https://example.com link', $options, FORMAT_MOODLE); + $createdpost = external_api::clean_returnvalue(mod_forum_external::add_discussion_post_returns(), $createdpost); + $dbpost = $DB->get_record('forum_posts', ['id' => $createdpost['postid']]); + // Format HTML and content converted, we should get. + $this->assertEquals(FORMAT_HTML, $dbpost->messageformat); + $this->assertEquals('
with some https://example.com link
', $dbpost->message); + // Test inline and regular attachment in post // Create a file in a draft area for inline attachments. $draftidinlineattach = file_get_unused_draft_itemid(); @@ -1658,7 +1684,6 @@ class mod_forum_external_testcase extends externallib_advanced_testcase { } catch (moodle_exception $e) { $this->assertEquals('nopostforum', $e->errorcode); } - } /* diff --git a/mod/forum/upgrade.txt b/mod/forum/upgrade.txt index f4730d4ca28..50f0f2a263c 100644 --- a/mod/forum/upgrade.txt +++ b/mod/forum/upgrade.txt @@ -14,6 +14,7 @@ information provided here is intended especially for developers. * New external function mod_forum_external::get_forum_discussions returns a list of forum discussions optionally sorted and paginated. * External function mod_forum_external::get_forum_discussions_paginated has been deprecated. Use mod_forum_external::get_forum_discussions instead. + * External function mod_forum_external::add_discussion_post() has a new 'messageformat' param to be able to handle other formats different from FORMAT_HTML (that continues being the default one). Also a new 'tohtml' option enables the automatic conversion between any format and FORMAT_HTML before contents are saved. === 3.6 ===