diff --git a/lang/en/notes.php b/lang/en/notes.php index f8520faf9c5..7dc95e2150f 100644 --- a/lang/en/notes.php +++ b/lang/en/notes.php @@ -37,7 +37,9 @@ $string['deletenotes'] = 'Delete all notes'; $string['editnote'] = 'Edit note'; $string['enablenotes'] = 'Enable notes'; $string['groupaddnewnote'] = 'Add a common note'; +$string['invalidcourseid'] = 'Invalid course id: {$a}'; $string['invalidid'] = 'Invalid note ID specified'; +$string['invaliduserid'] = 'Invalid user id: {$a}'; $string['nocontent'] = 'Note content can not be empty'; $string['nonotes'] = 'There are no notes of this type yet'; $string['nopermissiontodelete'] = 'You may not delete this note'; diff --git a/lib/db/services.php b/lib/db/services.php index 51cf05bae67..1d27d63d995 100644 --- a/lib/db/services.php +++ b/lib/db/services.php @@ -206,4 +206,15 @@ $functions = array( 'capabilities'=> 'moodle/course:create,moodle/course:visibility', ), + // === notes related functions === + + 'moodle_notes_create_notes' => array( + 'classname' => 'moodle_notes_external', + 'methodname' => 'create_notes', + 'classpath' => 'notes/externallib.php', + 'description' => 'Create notes', + 'type' => 'write', + 'capabilities'=> 'moodle/notes:manage', + ), + ); diff --git a/notes/externallib.php b/notes/externallib.php new file mode 100644 index 00000000000..143cfa53dc1 --- /dev/null +++ b/notes/externallib.php @@ -0,0 +1,186 @@ +. + +/** + * External notes API + * + * @package moodlecore + * @subpackage notes + * @copyright 2011 Moodle Pty Ltd (http://moodle.com) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +require_once("$CFG->libdir/externallib.php"); + +class moodle_notes_external extends external_api { + + /** + * Returns description of method parameters + * @return external_function_parameters + */ + public static function create_notes_parameters() { + return new external_function_parameters( + array( + 'notes' => new external_multiple_structure( + new external_single_structure( + array( + 'userid' => new external_value(PARAM_INT, 'id of the user the note is about'), + 'publishstate' => new external_value(PARAM_ALPHA, '\'personal\', \'course\' or \'site\''), + 'courseid' => new external_value(PARAM_INT, 'course id of the note (in Moodle a note can only be created into a course, even for site and personal notes)'), + 'text' => new external_value(PARAM_RAW, 'the text of the message - text or HTML'), + 'format' => new external_value(PARAM_ALPHA, '\'text\' or \'html\'', VALUE_DEFAULT, 'text'), + 'clientnoteid' => new external_value(PARAM_ALPHANUMEXT, 'your own client id for the note. If this id is provided, the fail message id will be returned to you', VALUE_OPTIONAL), + ) + ) + ) + ) + ); + } + + /** + * Create notes about some users + * Note: code should be matching the /notes/edit.php checks + * and the /user/addnote.php checks. (they are similar cheks) + * @param $notes An array of notes to create. + * @return array (success infos and fail infos) + */ + public static function create_notes($notes = array()) { + global $CFG, $DB; + require_once($CFG->dirroot . "/notes/lib.php"); + + $params = self::validate_parameters(self::create_notes_parameters(), array('notes' => $notes)); + + //check if note system is enabled + if (!$CFG->enablenotes) { + throw new moodle_exception('notesdisabled', 'notes'); + } + + //retrieve all courses + $courseids = array(); + foreach($params['notes'] as $note) { + $courseids[] = $note['courseid']; + } + $courses = $DB->get_records_list("course", "id", $courseids); + + //retrieve all users of the notes + $userids = array(); + foreach($params['notes'] as $note) { + $userids[] = $note['userid']; + } + list($sqluserids, $sqlparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED, 'userid_'); + $users = $DB->get_records_select("user", "id " . $sqluserids . " AND deleted = 0", $sqlparams); + + $resultnotes = array(); + foreach ($params['notes'] as $note) { + + $success = true; + $resultnote = array(); //the infos about the success of the operation + + //check the course exists + if (empty($courses[$note['courseid']])) { + $success = false; + $errormessage = get_string('invalidcourseid', 'notes', $note['courseid']); + } else { + // Ensure the current user is allowed to run this function + $context = get_context_instance(CONTEXT_COURSE, $note['courseid']); + self::validate_context($context); + require_capability('moodle/notes:manage', $context); + } + + //check the user exists + if (empty($users[$note['userid']])) { + $success = false; + $errormessage = get_string('invaliduserid', 'notes', $note['userid']); + } + + //build the resultnote + if (isset($note['clientnoteid'])) { + $resultnote['clientnoteid'] = $note['clientnoteid']; + } + + if ($success) { + //now we can create the note + $dbnote = new stdClass(); + $dbnote->courseid = $note['courseid']; + $dbnote->format = FORMAT_PLAIN; + //clean param text + switch (strtolower($note['format'])) { + case 'html': + $note['text'] = clean_param($note['text'], PARAM_CLEANHTML); + break; + case 'text': + $note['text'] = clean_param($note['text'], PARAM_TEXT); + break; + default: + $note['text'] = clean_param($note['text'], PARAM_TEXT); + break; + } + + $dbnote->content = $note['text']; + //get the state ('personal', 'course', 'site') + switch ($note['publishstate']) { + case 'personal': + $dbnote->publishstate = NOTES_STATE_DRAFT; + break; + case 'course': + $dbnote->publishstate = NOTES_STATE_PUBLIC; + break; + case 'site': + $dbnote->publishstate = NOTES_STATE_SITE; + $dbnote->courseid = SITEID; + break; + default: + break; + } + $dbnote->userid = $note['userid']; + + //TODO: performance improvement - if possible create a bulk functions for saving multiple notes at once + if (note_save($dbnote)) { //note_save attribut an id in case of success + add_to_log($dbnote->courseid, 'notes', 'add', + 'index.php?course='.$dbnote->courseid.'&user='.$dbnote->userid + . '#note-' . $dbnote->id , 'add note'); + $success = $dbnote->id; + } + + $resultnote['noteid'] = $success; + } else { + $resultnote['noteid'] = -1; + $resultnote['errormessage'] = $errormessage; + } + + $resultnotes[] = $resultnote; + } + + return $resultnotes; + } + + /** + * Returns description of method result value + * @return external_description + */ + public static function create_notes_returns() { + return new external_multiple_structure( + new external_single_structure( + array( + 'clientnoteid' => new external_value(PARAM_ALPHANUMEXT, 'your own id for the note', VALUE_OPTIONAL), + 'noteid' => new external_value(PARAM_INT, 'test this to know if it success: id of the created note when successed, -1 when failed'), + 'errormessage' => new external_value(PARAM_TEXT, 'error message - if failed', VALUE_OPTIONAL) + ) + ) + ); + } + +} diff --git a/version.php b/version.php index caaa6ff2258..b3c5afd200e 100644 --- a/version.php +++ b/version.php @@ -30,7 +30,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2011060200.00; // YYYYMMDD = weekly release date of this DEV branch +$version = 2011060200.038; // YYYYMMDD = weekly release date of this DEV branch // RR = release increments - 00 in DEV branches // .XX = incremental changes diff --git a/webservice/simpletest/testwebservice.php b/webservice/simpletest/testwebservice.php index cbc299cd2c3..ffd0cc91f5e 100644 --- a/webservice/simpletest/testwebservice.php +++ b/webservice/simpletest/testwebservice.php @@ -88,7 +88,8 @@ class webservice_test extends UnitTestCase { 'moodle_group_delete_groupmembers' => false, 'moodle_group_create_groups' => false, 'moodle_group_delete_groups' => false, - 'moodle_enrol_manual_enrol_users' => false + 'moodle_enrol_manual_enrol_users' => false, + 'moodle_notes_create_notes' => false ); //performance testing: number of time the web service are run @@ -1485,4 +1486,35 @@ class webservice_test extends UnitTestCase { } + function moodle_notes_create_notes($client) { + global $DB, $CFG; + + $note1 = array(); + $note1['userid'] = 2; //about who is the note + $note1['publishstate'] = 'personal'; //can be course, site, personal + $note1['courseid'] = 2; //in Moodle a notes is always created into a course, even a site note. + $note1['text'] = 'This is a personal note about the user'; + $note1['clientnoteid'] = 'note_1'; + + $note2 = array(); + $note2['userid'] = 40000; //mostl likely going to fail + $note2['publishstate'] = 'course'; + $note2['courseid'] = 2; + $note2['text'] = 'This is a teacher note about the user'; + $note2['clientnoteid'] = 'note_2'; + + $note3 = array(); + $note3['userid'] = 2; + $note3['publishstate'] = 'site'; + $note3['courseid'] = 30000; //most likely going to fail + $note3['text'] = 'This is a teacher site-wide note about the user'; + $note3['clientnoteid'] = 'note_3'; + + $function = 'moodle_notes_create_notes'; + $params = array('notes' => array($note1, $note2, $note3)); + $notes = $client->call($function, $params); + + $this->assertEqual(3, count($notes)); //1 info is a success, 2 others should be failed + } + }