Skip to content

Commit

Permalink
MDL-64588 comment: New WebService core_comment_delete_comment
Browse files Browse the repository at this point in the history
  • Loading branch information
jleyva authored and snake committed Oct 1, 2019
1 parent 8e4a9ed commit 09899ab
Show file tree
Hide file tree
Showing 3 changed files with 210 additions and 2 deletions.
87 changes: 87 additions & 0 deletions comment/classes/external.php
Original file line number Diff line number Diff line change
Expand Up @@ -285,4 +285,91 @@ public static function add_comments_returns() {
self::get_comment_structure()
);
}

/**
* Returns description of method parameters for the delete_comments() method.
*
* @return external_function_parameters
*/
public static function delete_comments_parameters() {
return new external_function_parameters(
[
'comments' => new external_multiple_structure(
new external_value(PARAM_INT, 'id of the comment', VALUE_DEFAULT, 0)
)
]
);
}

/**
* Deletes a comment or comments.
*
* @param array $comments array of comment ids to be deleted
* @return array
* @throws comment_exception
*/
public static function delete_comments(array $comments) {
global $CFG, $DB, $USER, $SITE;

if (empty($CFG->usecomments)) {
throw new comment_exception('commentsnotenabled', 'moodle');
}

$params = self::validate_parameters(self::delete_comments_parameters(), ['comments' => $comments]);
$commentids = $params['comments'];

list($insql, $inparams) = $DB->get_in_or_equal($commentids);
$commentrecords = $DB->get_records_select('comments', "id {$insql}", $inparams);

// If one or more of the records could not be found, report this and fail early.
if (count($commentrecords) != count($comments)) {
$invalidcomments = array_diff($commentids, array_column($commentrecords, 'id'));
$invalidcommentsstr = implode(',', $invalidcomments);
throw new comment_exception("One or more comments could not be found by id: $invalidcommentsstr");
}

// Make sure we can delete every one of the comments before actually doing so.
$comments = []; // Holds the comment objects, for later deletion.
foreach ($commentrecords as $commentrecord) {
// Validate the context.
list($context, $course, $cm) = get_context_info_array($commentrecord->contextid);
if ($context->id == SYSCONTEXTID) {
$course = $SITE;
}
self::validate_context($context);

// Make sure the user is allowed to delete the comment.
$args = new stdClass;
$args->context = $context;
$args->course = $course;
$args->cm = $cm;
$args->component = $commentrecord->component;
$args->itemid = $commentrecord->itemid;
$args->area = $commentrecord->commentarea;
$manager = new comment($args);

if ($commentrecord->userid != $USER->id && !$manager->can_delete($commentrecord->id)) {
throw new comment_exception('nopermissiontodelentry');
}

// User is allowed to delete it, so store the comment object, for use below in final deletion.
$comments[$commentrecord->id] = $manager;
}

// All comments can be deleted by the user. Make it so.
foreach ($comments as $commentid => $comment) {
$comment->delete($commentid);
}

return [];
}

/**
* Returns description of method result value for the delete_comments() method.
*
* @return external_description
*/
public static function delete_comments_returns() {
return new external_warnings();
}
}
118 changes: 116 additions & 2 deletions comment/tests/externallib_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ protected function setUp() {

$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($this->student->id, $this->course->id, $studentrole->id);
$this->studentrole = $DB->get_record('role', array('shortname' => 'student'));
$this->getDataGenerator()->enrol_user($this->student->id, $this->course->id, $this->studentrole->id);

$record = new stdClass();
$record->course = $this->course->id;
Expand Down Expand Up @@ -330,4 +330,118 @@ public function test_add_comments_invalid_area() {
$this->expectException(comment_exception::class);
core_comment_external::add_comments($comments);
}

/**
* Test delete_comment invalid comment.
*/
public function test_delete_comments_invalid_comments() {
$this->resetAfterTest(true);
$this->setUser($this->student);

$this->expectException(comment_exception::class);
core_comment_external::delete_comments([-1, 0]);
}

/**
* Test delete_comment own user.
*/
public function test_delete_comments_own_user() {
$this->resetAfterTest(true);
$this->setUser($this->student);

// Create a few comments.
$result = 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' => 'def',
'itemid' => $this->recordid,
'area' => 'database_entry'
]
]);
$result = external_api::clean_returnvalue(core_comment_external::add_comments_returns(), $result);


// Delete those comments we just created.
$result = core_comment_external::delete_comments([$result[0]['id'], $result[1]['id']]);
$result = external_api::clean_returnvalue(core_comment_external::delete_comments_returns(), $result);
$this->assertEquals([], $result);
}

/**
* Test delete_comment other student.
*/
public function test_delete_comment_other_student() {
$this->resetAfterTest(true);
$this->setUser($this->student);

// Create a comment as student 1.
$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);

$this->assertNotEquals(0, $result[0]['id']);

// Create another student.
$otherstudent = $this->getDataGenerator()->create_user();
$this->getDataGenerator()->enrol_user($otherstudent->id, $this->course->id, $this->studentrole->id);

$this->setUser($otherstudent);
$this->expectException(comment_exception::class);
core_comment_external::delete_comments([$result[0]['id']]);
}

/**
* Test delete_comment as teacher.
*/
public function test_delete_comments_as_teacher() {
global $DB;
$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);

$this->assertNotEquals(0, $result[0]['id']);

// Create teacher.
$teacher = $this->getDataGenerator()->create_user();
$teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
$this->getDataGenerator()->enrol_user($teacher->id, $this->course->id, $teacherrole->id);

$this->setUser($teacher);
$result = external_api::clean_returnvalue(
core_comment_external::delete_comments_returns(),
core_comment_external::delete_comments([$result[0]['id']])
);

$this->assertEquals([], $result);

}
}
7 changes: 7 additions & 0 deletions lib/db/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,13 @@
'type' => 'write',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
),
'core_comment_delete_comments' => array(
'classname' => 'core_comment_external',
'methodname' => 'delete_comments',
'description' => 'Deletes 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',
Expand Down

0 comments on commit 09899ab

Please sign in to comment.