From 9857381dc335dcff02986acecfb5f8c6dde646f6 Mon Sep 17 00:00:00 2001 From: Costantino Cito Date: Fri, 20 Mar 2015 12:56:32 +0100 Subject: [PATCH 1/2] MDL-49330 core_notes: New external function core_notes_get_course_notes --- lib/db/services.php | 11 ++- notes/externallib.php | 168 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 178 insertions(+), 1 deletion(-) diff --git a/lib/db/services.php b/lib/db/services.php index 47eb28c3cb8..c23624c3887 100644 --- a/lib/db/services.php +++ b/lib/db/services.php @@ -312,6 +312,14 @@ $functions = array( 'capabilities' => 'moodle/course:managegroups', ), + 'core_notes_get_course_notes' => array( + 'classname' => 'core_notes_external', + 'methodname' => 'get_course_notes', + 'description' => 'Returns all notes in specified course (or site) for the specified user.', + 'type' => 'read', + 'capabilities' => 'moodle/notes:view', + ), + // === file related functions === 'moodle_file_get_files' => array( @@ -1023,7 +1031,8 @@ $services = array( 'core_user_remove_user_device', 'core_course_get_courses', 'core_completion_update_activity_completion_status_manually', - 'mod_data_get_databases_by_courses' + 'mod_data_get_databases_by_courses', + 'core_notes_get_course_notes', ), 'enabled' => 0, 'restrictedusers' => 0, diff --git a/notes/externallib.php b/notes/externallib.php index d06d98270e7..957a07de5b5 100644 --- a/notes/externallib.php +++ b/notes/externallib.php @@ -463,6 +463,174 @@ class core_notes_external extends external_api { 'When errorcode is badid, the note does not exist', 'errorcode can be badparam (incorrect parameter), savedfailed (could not be modified), or badid (note does not exist)'); } + + /** + * Returns description of method parameters + * + * @return external_function_parameters + * @since Moodle 2.9 + */ + public static function get_course_notes_parameters() { + return new external_function_parameters( + array( + 'courseid' => new external_value(PARAM_INT, 'course id, 0 for SITE'), + 'userid' => new external_value(PARAM_INT, 'user id', VALUE_OPTIONAL), + ) + ); + } + + /** + * Create a notes list + * + * @param int $courseid ID of the Course + * @param stdClass $context context object + * @param int $userid ID of the User + * @param int $state + * @param int $author + * @return array of notes + * @since Moodle 2.9 + */ + protected static function create_note_list($courseid, $context, $userid, $state, $author = 0) { + $results = array(); + $notes = note_list($courseid, $userid, $state, $author); + foreach ($notes as $key => $note) { + $note = (array)$note; + list($note['content'], $note['format']) = external_format_text($note['content'], + $note['format'], + $context->id, + '', + '', + 0); + $results[$key] = $note; + } + return $results; + } + + /** + * Get a list of course notes + * + * @param int $courseid ID of the Course + * @param int $userid ID of the User + * @return array of site, course and personal notes and warnings + * @since Moodle 2.9 + * @throws moodle_exception + */ + public static function get_course_notes($courseid, $userid = 0) { + global $CFG, $USER; + + if (empty($CFG->enablenotes)) { + throw new moodle_exception('notesdisabled', 'notes'); + } + + $warnings = array(); + $arrayparams = array( + 'courseid' => $courseid, + 'userid' => $userid, + ); + $params = self::validate_parameters(self::get_course_notes_parameters(), $arrayparams); + + if (empty($params['courseid'])) { + $params['courseid'] = SITEID; + } + $user = null; + if (!empty($params['userid'])) { + $user = core_user::get_user($params['userid'], 'id', MUST_EXIST); + } + + $course = get_course($params['courseid']); + + if ($course->id == SITEID) { + $context = context_system::instance(); + } else { + $context = context_course::instance($course->id); + } + self::validate_context($context); + + $sitenotes = array(); + $coursenotes = array(); + $personalnotes = array(); + + if ($course->id != SITEID) { + + require_capability('moodle/notes:view', $context); + $sitenotes = self::create_note_list($course->id, $context, $params['userid'], NOTES_STATE_SITE); + $coursenotes = self::create_note_list($course->id, $context, $params['userid'], NOTES_STATE_PUBLIC); + $personalnotes = self::create_note_list($course->id, $context, $params['userid'], NOTES_STATE_DRAFT, + $USER->id); + } else { + if (has_capability('moodle/notes:view', $context)) { + $sitenotes = self::create_note_list(0, $context, $params['userid'], NOTES_STATE_SITE); + } + // It returns notes only for a specific user! + if (!empty($user)) { + $usercourses = enrol_get_users_courses($user->id, true); + foreach ($usercourses as $c) { + // All notes at course level, only if we have capability on every course. + if (has_capability('moodle/notes:view', context_course::instance($c->id))) { + $coursenotes += self::create_note_list($c->id, $context, $params['userid'], NOTES_STATE_PUBLIC); + } + } + } + } + + $results = array( + 'sitenotes' => $sitenotes, + 'coursenotes' => $coursenotes, + 'personalnotes' => $personalnotes, + 'warnings' => $warnings + ); + return $results; + + } + + /** + * Returns array of note structure + * + * @return external_description + * @since Moodle 2.9 + */ + protected static function get_note_structure() { + return array( + 'id' => new external_value(PARAM_INT, 'id of this note'), + 'courseid' => new external_value(PARAM_INT, 'id of the course'), + 'userid' => new external_value(PARAM_INT, 'user id'), + 'content' => new external_value(PARAM_RAW, 'the content text formated'), + 'format' => new external_format_value('content'), + 'created' => new external_value(PARAM_INT, 'time created (timestamp)'), + 'lastmodified' => new external_value(PARAM_INT, 'time of last modification (timestamp)'), + 'usermodified' => new external_value(PARAM_INT, 'user id of the creator of this note'), + 'publishstate' => new external_value(PARAM_ALPHA, "state of the note (i.e. draft, public, site) ") + ); + } + + /** + * Returns description of method result value + * + * @return external_description + * @since Moodle 2.9 + */ + public static function get_course_notes_returns() { + return new external_single_structure( + array( + 'sitenotes' => new external_multiple_structure( + new external_single_structure( + self::get_note_structure() , '' + ), 'site notes', VALUE_OPTIONAL + ), + 'coursenotes' => new external_multiple_structure( + new external_single_structure( + self::get_note_structure() , '' + ), 'couse notes', VALUE_OPTIONAL + ), + 'personalnotes' => new external_multiple_structure( + new external_single_structure( + self::get_note_structure() , '' + ), 'personal notes', VALUE_OPTIONAL + ), + 'warnings' => new external_warnings() + ), 'notes' + ); + } } /** From 12068d65cb30f01af9a0426e16835703ea0c6378 Mon Sep 17 00:00:00 2001 From: Costantino Cito Date: Mon, 23 Mar 2015 15:31:33 +0100 Subject: [PATCH 2/2] MDL-49330 core_notes: Unit tests for get_course_notes --- notes/tests/externallib_test.php | 117 +++++++++++++++++++++++++++++++ version.php | 2 +- 2 files changed, 118 insertions(+), 1 deletion(-) diff --git a/notes/tests/externallib_test.php b/notes/tests/externallib_test.php index 72af7f91e1f..7005466e3d0 100644 --- a/notes/tests/externallib_test.php +++ b/notes/tests/externallib_test.php @@ -240,4 +240,121 @@ class core_notes_externallib_testcase extends externallib_advanced_testcase { $notes2 = array($note2); $updatednotes = core_notes_external::update_notes($notes2); } + + /** + * Test get_course_notes + */ + public function test_get_course_notes() { + global $DB, $CFG; + + $this->resetAfterTest(true); + $CFG->enablenotes = true; + + // Take role definitions. + $studentrole = $DB->get_record('role', array('shortname' => 'student')); + $teacherrole = $DB->get_record('role', array('shortname' => 'teacher')); + + // Create students and teachers. + $student1 = $this->getDataGenerator()->create_user(); + $student2 = $this->getDataGenerator()->create_user(); + $teacher1 = $this->getDataGenerator()->create_user(); + $teacher2 = $this->getDataGenerator()->create_user(); + $course1 = $this->getDataGenerator()->create_course(); + $course2 = $this->getDataGenerator()->create_course(); + + // Enroll students and teachers to COURSE-1. + $this->getDataGenerator()->enrol_user($student1->id, $course1->id, $studentrole->id); + $this->getDataGenerator()->enrol_user($student2->id, $course1->id, $studentrole->id); + $this->getDataGenerator()->enrol_user($teacher1->id, $course1->id, $teacherrole->id); + $this->getDataGenerator()->enrol_user($teacher2->id, $course1->id, $teacherrole->id); + // Enroll students and teachers to COURSE-2 (teacher1 is not enrolled in Course 2). + $this->getDataGenerator()->enrol_user($student1->id, $course2->id, $studentrole->id); + $this->getDataGenerator()->enrol_user($student2->id, $course2->id, $studentrole->id); + + $this->getDataGenerator()->enrol_user($teacher2->id, $course2->id, $teacherrole->id); + + // Generate notes. + $gen = $this->getDataGenerator()->get_plugin_generator('core_notes'); + + $this->setUser($teacher1); + + // NoteA1: on student1 (Course1) by Teacher1. + $params = array('courseid' => $course1->id, 'userid' => $student1->id, 'publishstate' => NOTES_STATE_PUBLIC, + 'usermodified' => $teacher1->id); + $notea1 = $gen->create_instance($params); + // NoteA2: on student1 (Course1) by Teacher1. + $params = array('courseid' => $course1->id, 'userid' => $student1->id, 'publishstate' => NOTES_STATE_PUBLIC, + 'usermodified' => $teacher1->id); + $notea2 = $gen->create_instance($params); + // NoteS1: on student1 SITE-LEVEL by teacher1. + $params = array('courseid' => $course1->id, 'userid' => $student1->id, 'publishstate' => NOTES_STATE_SITE, + 'usermodified' => $teacher1->id); + $notes1 = $gen->create_instance($params); + // NoteP1: on student1 PERSONAL by teacher1. + $params = array('courseid' => $course1->id, 'userid' => $student1->id, 'publishstate' => NOTES_STATE_DRAFT, + 'usermodified' => $teacher1->id); + $notep1 = $gen->create_instance($params); + // NoteB1: on student1 (Course2) by teacher1. + $params = array('courseid' => $course2->id, 'userid' => $student1->id, 'publishstate' => NOTES_STATE_PUBLIC, + 'usermodified' => $teacher1->id); + $noteb1 = $gen->create_instance($params); + + // Retrieve notes, normal case. + $result = core_notes_external::get_course_notes($course1->id, $student1->id); + $result = external_api::clean_returnvalue(core_notes_external::get_course_notes_returns(), $result); + $this->assertEquals($notes1->id, $result['sitenotes'][0]['id']); + $this->assertEquals($notea1->id, $result['coursenotes'][0]['id']); + $this->assertEquals($notep1->id, $result['personalnotes'][0]['id']); + + // Try to get notes from a course the user is not enrolled. + try { + $result = core_notes_external::get_course_notes($course2->id, $student1->id); + $this->fail('the user is not enrolled in the course'); + } catch (require_login_exception $e) { + $this->assertEquals('requireloginerror', $e->errorcode); + } + + $result = core_notes_external::get_course_notes(0, $student1->id); + $result = external_api::clean_returnvalue(core_notes_external::get_course_notes_returns(), $result); + $this->assertEmpty($result['sitenotes']); + $this->assertEquals($notea1->id, $result['coursenotes'][0]['id']); + $this->assertEquals($notea2->id, $result['coursenotes'][1]['id']); + $this->assertCount(2, $result['coursenotes']); + + $this->setAdminUser(); + $result = core_notes_external::get_course_notes(0, $student1->id); + $result = external_api::clean_returnvalue(core_notes_external::get_course_notes_returns(), $result); + $this->assertEquals($notes1->id, $result['sitenotes'][0]['id']); + $this->assertCount(1, $result['sitenotes']); + + $this->setUser($teacher1); + $result = core_notes_external::get_course_notes(0, 0); + $result = external_api::clean_returnvalue(core_notes_external::get_course_notes_returns(), $result); + $this->assertEmpty($result['sitenotes']); + $this->assertEmpty($result['coursenotes']); + $this->assertEmpty($result['personalnotes']); + + $this->setUser($teacher2); + $result = core_notes_external::get_course_notes($course1->id, $student1->id); + $result = external_api::clean_returnvalue(core_notes_external::get_course_notes_returns(), $result); + $this->assertEquals($notes1->id, $result['sitenotes'][0]['id']); + $this->assertEquals($notea1->id, $result['coursenotes'][0]['id']); + $this->assertCount(1, $result['sitenotes']); + $this->assertCount(2, $result['coursenotes']); + + $result = core_notes_external::get_course_notes($course1->id, 0); + $result = external_api::clean_returnvalue(core_notes_external::get_course_notes_returns(), $result); + $this->assertEquals($notes1->id, $result['sitenotes'][0]['id']); + $this->assertEquals($notea1->id, $result['coursenotes'][0]['id']); + $this->assertEquals($notea2->id, $result['coursenotes'][1]['id']); + $this->assertCount(1, $result['sitenotes']); + $this->assertCount(2, $result['coursenotes']); + + $this->setUser($teacher1); + $result = core_notes_external::get_course_notes($course1->id, 0); + $result = external_api::clean_returnvalue(core_notes_external::get_course_notes_returns(), $result); + $this->assertEquals($notep1->id, $result['personalnotes'][0]['id']); + $this->assertCount(1, $result['personalnotes']); + + } } diff --git a/version.php b/version.php index 9495a9cdcef..9172a176a33 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2015032600.00; // YYYYMMDD = weekly release date of this DEV branch. +$version = 2015032600.01; // YYYYMMDD = weekly release date of this DEV branch. // RR = release increments - 00 in DEV branches. // .XX = incremental changes.