mirror of
https://github.com/moodle/moodle.git
synced 2025-01-18 05:58:34 +01:00
MDL-64588 comment: New WebService core_comment_add_comment
This commit is contained in:
parent
2234b6c9dc
commit
8e4a9ed854
@ -170,4 +170,119 @@ class core_comment_external extends external_api {
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get the structure of a single comment.
|
||||
*
|
||||
* @return external_single_structure the comment structure.
|
||||
*/
|
||||
protected static function get_comment_structure() {
|
||||
return new external_single_structure(
|
||||
array(
|
||||
'id' => new external_value(PARAM_INT, 'Comment ID'),
|
||||
'content' => new external_value(PARAM_RAW, 'The content text formatted'),
|
||||
'format' => new external_format_value('content'),
|
||||
'timecreated' => new external_value(PARAM_INT, 'Time created (timestamp)'),
|
||||
'strftimeformat' => new external_value(PARAM_NOTAGS, 'Time format'),
|
||||
'profileurl' => new external_value(PARAM_URL, 'URL profile'),
|
||||
'fullname' => new external_value(PARAM_NOTAGS, 'fullname'),
|
||||
'time' => new external_value(PARAM_NOTAGS, 'Time in human format'),
|
||||
'avatar' => new external_value(PARAM_RAW, 'HTML user picture'),
|
||||
'userid' => new external_value(PARAM_INT, 'User ID'),
|
||||
'delete' => new external_value(PARAM_BOOL, 'Permission to delete=true/false', VALUE_OPTIONAL)
|
||||
), 'comment'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of method parameters for the add_comments method.
|
||||
*
|
||||
* @return external_function_parameters
|
||||
*/
|
||||
public static function add_comments_parameters() {
|
||||
return new external_function_parameters(
|
||||
[
|
||||
'comments' => new external_multiple_structure(
|
||||
new external_single_structure(
|
||||
[
|
||||
'contextlevel' => new external_value(PARAM_ALPHA, 'contextlevel system, course, user...'),
|
||||
'instanceid' => new external_value(PARAM_INT, 'the id of item associated with the contextlevel'),
|
||||
'component' => new external_value(PARAM_COMPONENT, 'component'),
|
||||
'content' => new external_value(PARAM_RAW, 'component'),
|
||||
'itemid' => new external_value(PARAM_INT, 'associated id'),
|
||||
'area' => new external_value(PARAM_AREA, 'string comment area', VALUE_DEFAULT, ''),
|
||||
]
|
||||
)
|
||||
)
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a comment or comments.
|
||||
*
|
||||
* @param array $comments the array of comments to create.
|
||||
* @return array the array containing those comments created.
|
||||
* @throws comment_exception
|
||||
*/
|
||||
public static function add_comments($comments) {
|
||||
global $CFG, $SITE;
|
||||
|
||||
if (empty($CFG->usecomments)) {
|
||||
throw new comment_exception('commentsnotenabled', 'moodle');
|
||||
}
|
||||
|
||||
$params = self::validate_parameters(self::add_comments_parameters(), ['comments' => $comments]);
|
||||
|
||||
// Validate every intended comment before creating anything, storing the validated comment for use below.
|
||||
foreach ($params['comments'] as $index => $comment) {
|
||||
$context = self::get_context_from_params($comment);
|
||||
self::validate_context($context);
|
||||
|
||||
list($context, $course, $cm) = get_context_info_array($context->id);
|
||||
if ($context->id == SYSCONTEXTID) {
|
||||
$course = $SITE;
|
||||
}
|
||||
|
||||
// Initialising comment object.
|
||||
$args = new stdClass();
|
||||
$args->context = $context;
|
||||
$args->course = $course;
|
||||
$args->cm = $cm;
|
||||
$args->component = $comment['component'];
|
||||
$args->itemid = $comment['itemid'];
|
||||
$args->area = $comment['area'];
|
||||
|
||||
$manager = new comment($args);
|
||||
if (!$manager->can_post()) {
|
||||
throw new comment_exception('nopermissiontocomment');
|
||||
}
|
||||
|
||||
$params['comments'][$index]['preparedcomment'] = $manager;
|
||||
}
|
||||
|
||||
// Create the comments.
|
||||
$results = [];
|
||||
foreach ($params['comments'] as $comment) {
|
||||
$manager = $comment['preparedcomment'];
|
||||
$newcomment = $manager->add($comment['content']);
|
||||
if (!empty($newcomment) && is_object($newcomment)) {
|
||||
$results[] = $newcomment;
|
||||
}
|
||||
$newcomment->delete = true; // USER created the comment, so they can delete it.
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of method result value for the add_comments method.
|
||||
*
|
||||
* @return external_description
|
||||
*/
|
||||
public static function add_comments_returns() {
|
||||
return new external_multiple_structure(
|
||||
self::get_comment_structure()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -45,34 +45,25 @@ class core_comment_externallib_testcase extends externallib_advanced_testcase {
|
||||
* Tests set up
|
||||
*/
|
||||
protected function setUp() {
|
||||
global $CFG;
|
||||
global $CFG, $DB;
|
||||
|
||||
require_once($CFG->dirroot . '/comment/lib.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get_comments
|
||||
*/
|
||||
public function test_get_comments() {
|
||||
global $DB, $CFG;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$CFG->usecomments = true;
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$course = $this->getDataGenerator()->create_course(array('enablecomment' => 1));
|
||||
$this->student = $this->getDataGenerator()->create_user();
|
||||
$this->course = $this->getDataGenerator()->create_course(array('enablecomment' => 1));
|
||||
$studentrole = $DB->get_record('role', array('shortname' => 'student'));
|
||||
$this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id);
|
||||
$this->getDataGenerator()->enrol_user($this->student->id, $this->course->id, $studentrole->id);
|
||||
|
||||
$record = new stdClass();
|
||||
$record->course = $course->id;
|
||||
$record->course = $this->course->id;
|
||||
$record->name = "Mod data test";
|
||||
$record->intro = "Some intro of some sort";
|
||||
$record->comments = 1;
|
||||
|
||||
$module = $this->getDataGenerator()->create_module('data', $record);
|
||||
$field = data_get_field_new('text', $module);
|
||||
$this->module = $this->getDataGenerator()->create_module('data', $record);
|
||||
$field = data_get_field_new('text', $this->module);
|
||||
|
||||
$fielddetail = new stdClass();
|
||||
$fielddetail->name = 'Name';
|
||||
@ -80,28 +71,37 @@ class core_comment_externallib_testcase extends externallib_advanced_testcase {
|
||||
|
||||
$field->define_field($fielddetail);
|
||||
$field->insert_field();
|
||||
$recordid = data_add_record($module);
|
||||
$this->recordid = data_add_record($this->module);
|
||||
|
||||
$datacontent = array();
|
||||
$datacontent['fieldid'] = $field->field->id;
|
||||
$datacontent['recordid'] = $recordid;
|
||||
$datacontent['recordid'] = $this->recordid;
|
||||
$datacontent['content'] = 'Asterix';
|
||||
|
||||
$contentid = $DB->insert_record('data_content', $datacontent);
|
||||
$cm = get_coursemodule_from_instance('data', $module->id, $course->id);
|
||||
$this->cm = get_coursemodule_from_instance('data', $this->module->id, $this->course->id);
|
||||
|
||||
$context = context_module::instance($module->cmid);
|
||||
$this->context = context_module::instance($this->module->cmid);
|
||||
}
|
||||
|
||||
$this->setUser($user);
|
||||
/**
|
||||
* Test get_comments
|
||||
*/
|
||||
public function test_get_comments() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$this->setUser($this->student);
|
||||
|
||||
// We need to add the comments manually, the comment API uses the global OUTPUT and this is going to make the WS to fail.
|
||||
$newcmt = new stdClass;
|
||||
$newcmt->contextid = $context->id;
|
||||
$newcmt->contextid = $this->context->id;
|
||||
$newcmt->commentarea = 'database_entry';
|
||||
$newcmt->itemid = $recordid;
|
||||
$newcmt->itemid = $this->recordid;
|
||||
$newcmt->content = 'New comment';
|
||||
$newcmt->format = 0;
|
||||
$newcmt->userid = $user->id;
|
||||
$newcmt->userid = $this->student->id;
|
||||
$newcmt->timecreated = time();
|
||||
$cmtid1 = $DB->insert_record('comments', $newcmt);
|
||||
|
||||
@ -110,9 +110,9 @@ class core_comment_externallib_testcase extends externallib_advanced_testcase {
|
||||
$cmtid2 = $DB->insert_record('comments', $newcmt);
|
||||
|
||||
$contextlevel = 'module';
|
||||
$instanceid = $cm->id;
|
||||
$instanceid = $this->cm->id;
|
||||
$component = 'mod_data';
|
||||
$itemid = $recordid;
|
||||
$itemid = $this->recordid;
|
||||
$area = 'database_entry';
|
||||
$page = 0;
|
||||
|
||||
@ -127,8 +127,8 @@ class core_comment_externallib_testcase extends externallib_advanced_testcase {
|
||||
$this->assertEquals(15, $result['perpage']);
|
||||
$this->assertTrue($result['canpost']);
|
||||
|
||||
$this->assertEquals($user->id, $result['comments'][0]['userid']);
|
||||
$this->assertEquals($user->id, $result['comments'][1]['userid']);
|
||||
$this->assertEquals($this->student->id, $result['comments'][0]['userid']);
|
||||
$this->assertEquals($this->student->id, $result['comments'][1]['userid']);
|
||||
|
||||
$this->assertEquals($cmtid2, $result['comments'][0]['id']); // Default ordering newer first.
|
||||
$this->assertEquals($cmtid1, $result['comments'][1]['id']);
|
||||
@ -154,4 +154,180 @@ class core_comment_externallib_testcase extends externallib_advanced_testcase {
|
||||
$this->assertEquals($CFG->commentsperpage, $result['perpage']);
|
||||
$this->assertEquals($cmtid2, $result['comments'][0]['id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test add_comments not enabled site level
|
||||
*/
|
||||
public function test_add_comments_not_enabled_site_level() {
|
||||
global $CFG;
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$CFG->usecomments = false;
|
||||
$this->setUser($this->student);
|
||||
$this->expectException(comment_exception::class);
|
||||
core_comment_external::add_comments([
|
||||
[
|
||||
'contextlevel' => 'module',
|
||||
'instanceid' => $this->cm->id,
|
||||
'component' => 'mod_data',
|
||||
'content' => 'abc',
|
||||
'itemid' => $this->recordid,
|
||||
'area' => 'database_entry'
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test add_comments not enabled module level
|
||||
*/
|
||||
public function test_add_comments_not_enabled_module_level() {
|
||||
global $DB;
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$DB->set_field('data', 'comments', 0, array('id' => $this->module->id));
|
||||
$this->setUser($this->student);
|
||||
$this->expectException(comment_exception::class);
|
||||
core_comment_external::add_comments([
|
||||
[
|
||||
'contextlevel' => 'module',
|
||||
'instanceid' => $this->cm->id,
|
||||
'component' => 'mod_data',
|
||||
'content' => 'abc',
|
||||
'itemid' => $this->recordid,
|
||||
'area' => 'database_entry'
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test add_comments
|
||||
*/
|
||||
public function test_add_comments_single() {
|
||||
$this->resetAfterTest(true);
|
||||
$this->setUser($this->student);
|
||||
|
||||
$result = core_comment_external::add_comments([
|
||||
[
|
||||
'contextlevel' => 'module',
|
||||
'instanceid' => $this->cm->id,
|
||||
'component' => 'mod_data',
|
||||
'content' => 'abc',
|
||||
'itemid' => $this->recordid,
|
||||
'area' => 'database_entry'
|
||||
]
|
||||
]);
|
||||
$result = external_api::clean_returnvalue(core_comment_external::add_comments_returns(), $result);
|
||||
|
||||
$expectedkeys = [
|
||||
'id',
|
||||
'content',
|
||||
'format',
|
||||
'timecreated',
|
||||
'strftimeformat',
|
||||
'profileurl',
|
||||
'fullname',
|
||||
'time',
|
||||
'avatar',
|
||||
'userid',
|
||||
'delete',
|
||||
];
|
||||
|
||||
// Verify the result contains 1 result having the correct structure.
|
||||
$this->assertCount(1, $result);
|
||||
foreach ($expectedkeys as $key) {
|
||||
$this->assertArrayHasKey($key, $result[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test add_comments when one of the comments contains invalid data and cannot be created.
|
||||
*
|
||||
* This simply verifies that the entire operation fails.
|
||||
*/
|
||||
public function test_add_comments_multiple_contains_invalid() {
|
||||
$this->resetAfterTest(true);
|
||||
$this->setUser($this->student);
|
||||
|
||||
$this->expectException(comment_exception::class);
|
||||
core_comment_external::add_comments([
|
||||
[
|
||||
'contextlevel' => 'module',
|
||||
'instanceid' => $this->cm->id,
|
||||
'component' => 'mod_data',
|
||||
'content' => 'abc',
|
||||
'itemid' => $this->recordid,
|
||||
'area' => 'database_entry'
|
||||
],
|
||||
[
|
||||
'contextlevel' => 'module',
|
||||
'instanceid' => $this->cm->id,
|
||||
'component' => 'mod_data',
|
||||
'content' => 'abc',
|
||||
'itemid' => $this->recordid,
|
||||
'area' => 'areanotfound'
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test add_comments when one of the comments contains invalid data and cannot be created.
|
||||
*
|
||||
* This simply verifies that the entire operation fails.
|
||||
*/
|
||||
public function test_add_comments_multiple_all_valid() {
|
||||
$this->resetAfterTest(true);
|
||||
$this->setUser($this->student);
|
||||
|
||||
$inputdata = [
|
||||
[
|
||||
'contextlevel' => 'module',
|
||||
'instanceid' => $this->cm->id,
|
||||
'component' => 'mod_data',
|
||||
'content' => 'cat',
|
||||
'itemid' => $this->recordid,
|
||||
'area' => 'database_entry'
|
||||
],
|
||||
[
|
||||
'contextlevel' => 'module',
|
||||
'instanceid' => $this->cm->id,
|
||||
'component' => 'mod_data',
|
||||
'content' => 'dog',
|
||||
'itemid' => $this->recordid,
|
||||
'area' => 'database_entry'
|
||||
]
|
||||
];
|
||||
$result = core_comment_external::add_comments($inputdata);
|
||||
$result = external_api::clean_returnvalue(core_comment_external::add_comments_returns(), $result);
|
||||
|
||||
// Two comments should have been created.
|
||||
$this->assertCount(2, $result);
|
||||
|
||||
// The content for each comment should come back formatted.
|
||||
foreach ($result as $index => $comment) {
|
||||
$formatoptions = array('overflowdiv' => true, 'blanktarget' => true);
|
||||
$expectedcontent = format_text($inputdata[$index]['content'], FORMAT_MOODLE, $formatoptions);
|
||||
$this->assertEquals($expectedcontent, $comment['content']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test add_comments invalid area
|
||||
*/
|
||||
public function test_add_comments_invalid_area() {
|
||||
$this->resetAfterTest(true);
|
||||
$this->setUser($this->student);
|
||||
|
||||
$comments = [
|
||||
[
|
||||
'contextlevel' => 'module',
|
||||
'instanceid' => $this->cm->id,
|
||||
'component' => 'mod_data',
|
||||
'content' => 'abc',
|
||||
'itemid' => $this->recordid,
|
||||
'area' => 'rhomboid'
|
||||
]
|
||||
];
|
||||
$this->expectException(comment_exception::class);
|
||||
core_comment_external::add_comments($comments);
|
||||
}
|
||||
}
|
||||
|
@ -334,6 +334,13 @@ $functions = array(
|
||||
'capabilities' => 'moodle/comment:view',
|
||||
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
|
||||
),
|
||||
'core_comment_add_comments' => array(
|
||||
'classname' => 'core_comment_external',
|
||||
'methodname' => 'add_comments',
|
||||
'description' => 'Adds a comment or comments.',
|
||||
'type' => 'write',
|
||||
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
|
||||
),
|
||||
'core_completion_get_activities_completion_status' => array(
|
||||
'classname' => 'core_completion_external',
|
||||
'methodname' => 'get_activities_completion_status',
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$version = 2019092700.00; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
$version = 2019092700.01; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
// RR = release increments - 00 in DEV branches.
|
||||
// .XX = incremental changes.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user