/** * Update categories * * @param array $categories The list of categories to update * @return null * @since Moodle 2.3 */ public static function update_categories($categories) { global $CFG, $DB; require_once $CFG->dirroot . "/course/lib.php"; // Validate parameters. $params = self::validate_parameters(self::update_categories_parameters(), array('categories' => $categories)); $transaction = $DB->start_delegated_transaction(); foreach ($params['categories'] as $cat) { if (!($category = $DB->get_record('course_categories', array('id' => $cat['id'])))) { throw new moodle_exception('unknowcategory'); } $categorycontext = context_coursecat::instance($cat['id']); self::validate_context($categorycontext); require_capability('moodle/category:manage', $categorycontext); if (!empty($cat['name'])) { if (textlib::strlen($cat['name']) > 255) { throw new moodle_exception('categorytoolong'); } $category->name = $cat['name']; } if (!empty($cat['idnumber'])) { if (textlib::strlen($cat['idnumber']) > 100) { throw new moodle_exception('idnumbertoolong'); } $category->idnumber = $cat['idnumber']; } if (!empty($cat['description'])) { $category->description = $cat['description']; $category->descriptionformat = external_validate_format($cat['descriptionformat']); } if (!empty($cat['theme'])) { $category->theme = $cat['theme']; } if (!empty($cat['parent']) && $category->parent != $cat['parent']) { // First check if parent exists. if (!($parent_cat = $DB->get_record('course_categories', array('id' => $cat['parent'])))) { throw new moodle_exception('unknowcategory'); } // Then check if we have capability. self::validate_context(get_category_or_system_context((int) $cat['parent'])); require_capability('moodle/category:manage', get_category_or_system_context((int) $cat['parent'])); // Finally move the category. move_category($category, $parent_cat); $category->parent = $cat['parent']; // Get updated path by move_category(). $category->path = $DB->get_field('course_categories', 'path', array('id' => $category->id)); } $DB->update_record('course_categories', $category); } $transaction->allow_commit(); }
/** * Update categories * * @param array $categories The list of categories to update * @return null * @since Moodle 2.3 */ public static function update_categories($categories) { global $CFG, $DB; require_once($CFG->libdir . "/coursecatlib.php"); // Validate parameters. $params = self::validate_parameters(self::update_categories_parameters(), array('categories' => $categories)); $transaction = $DB->start_delegated_transaction(); foreach ($params['categories'] as $cat) { $category = coursecat::get($cat['id']); $categorycontext = context_coursecat::instance($cat['id']); self::validate_context($categorycontext); require_capability('moodle/category:manage', $categorycontext); // this will throw an exception if descriptionformat is not valid external_validate_format($cat['descriptionformat']); $category->update($cat); } $transaction->allow_commit(); }
/** * Delete Calendar events. * * @param array $events A list of events to create. * @return array array of events created. * @since Moodle 2.5 * @throws moodle_exception if user doesnt have the permission to create events. */ public static function create_calendar_events($events) { global $CFG, $DB, $USER; require_once $CFG->dirroot . "/calendar/lib.php"; // Parameter validation. $params = self::validate_parameters(self::create_calendar_events_parameters(), array('events' => $events)); $transaction = $DB->start_delegated_transaction(); $return = array(); $warnings = array(); foreach ($params['events'] as $event) { // Let us set some defaults. $event['userid'] = $USER->id; $event['modulename'] = ''; $event['instance'] = 0; $event['subscriptionid'] = null; $event['uuid'] = ''; $event['format'] = external_validate_format($event['format']); if ($event['repeats'] > 0) { $event['repeat'] = 1; } else { $event['repeat'] = 0; } $eventobj = new calendar_event($event); // Let's check if the user is allowed to delete an event. if (!calendar_add_event_allowed($eventobj)) { $warnings[] = array('item' => $event['name'], 'warningcode' => 'nopermissions', 'message' => 'you do not have permissions to create this event'); continue; } // Let's create the event. $var = $eventobj->create($event); $var = (array) $var->properties(); if ($event['repeat']) { $children = $DB->get_records('event', array('repeatid' => $var['id'])); foreach ($children as $child) { $return[] = (array) $child; } } else { $return[] = $var; } } // Everything done smoothly, let's commit. $transaction->allow_commit(); return array('events' => $return, 'warnings' => $warnings); }
/** * Send private messages from the current USER to other users * * @param array $messages An array of message to send. * @return array * @since Moodle 2.2 */ public static function send_instant_messages($messages = array()) { global $CFG, $USER, $DB; // Check if messaging is enabled. if (!$CFG->messaging) { throw new moodle_exception('disabled', 'message'); } // Ensure the current user is allowed to run this function $context = context_system::instance(); self::validate_context($context); require_capability('moodle/site:sendmessage', $context); $params = self::validate_parameters(self::send_instant_messages_parameters(), array('messages' => $messages)); //retrieve all tousers of the messages $receivers = array(); foreach ($params['messages'] as $message) { $receivers[] = $message['touserid']; } list($sqluserids, $sqlparams) = $DB->get_in_or_equal($receivers, SQL_PARAMS_NAMED, 'userid_'); $tousers = $DB->get_records_select("user", "id " . $sqluserids . " AND deleted = 0", $sqlparams); $blocklist = array(); $contactlist = array(); $sqlparams['contactid'] = $USER->id; $rs = $DB->get_recordset_sql("SELECT *\n FROM {message_contacts}\n WHERE userid {$sqluserids}\n AND contactid = :contactid", $sqlparams); foreach ($rs as $record) { if ($record->blocked) { // $record->userid is blocking current user $blocklist[$record->userid] = true; } else { // $record->userid have current user as contact $contactlist[$record->userid] = true; } } $rs->close(); $canreadallmessages = has_capability('moodle/site:readallmessages', $context); $resultmessages = array(); foreach ($params['messages'] as $message) { $resultmsg = array(); //the infos about the success of the operation //we are going to do some checking //code should match /messages/index.php checks $success = true; //check the user exists if (empty($tousers[$message['touserid']])) { $success = false; $errormessage = get_string('touserdoesntexist', 'message', $message['touserid']); } //check that the touser is not blocking the current user if ($success and !empty($blocklist[$message['touserid']]) and !$canreadallmessages) { $success = false; $errormessage = get_string('userisblockingyou', 'message'); } // Check if the user is a contact //TODO MDL-31118 performance improvement - edit the function so we can pass an array instead userid $blocknoncontacts = get_user_preferences('message_blocknoncontacts', NULL, $message['touserid']); // message_blocknoncontacts option is on and current user is not in contact list if ($success && empty($contactlist[$message['touserid']]) && !empty($blocknoncontacts)) { // The user isn't a contact and they have selected to block non contacts so this message won't be sent. $success = false; $errormessage = get_string('userisblockingyounoncontact', 'message', fullname(core_user::get_user($message['touserid']))); } //now we can send the message (at least try) if ($success) { //TODO MDL-31118 performance improvement - edit the function so we can pass an array instead one touser object $success = message_post_message($USER, $tousers[$message['touserid']], $message['text'], external_validate_format($message['textformat'])); } //build the resultmsg if (isset($message['clientmsgid'])) { $resultmsg['clientmsgid'] = $message['clientmsgid']; } if ($success) { $resultmsg['msgid'] = $success; } else { // WARNINGS: for backward compatibility we return this errormessage. // We should have thrown exceptions as these errors prevent results to be returned. // See http://docs.moodle.org/dev/Errors_handling_in_web_services#When_to_send_a_warning_on_the_server_side . $resultmsg['msgid'] = -1; $resultmsg['errormessage'] = $errormessage; } $resultmessages[] = $resultmsg; } return $resultmessages; }
/** * Update groupings * * @param array $groupings array of grouping description arrays (with keys groupname and courseid) * @return array of newly updated groupings * @since Moodle 2.3 */ public static function update_groupings($groupings) { global $CFG, $DB; require_once "{$CFG->dirroot}/group/lib.php"; $params = self::validate_parameters(self::update_groupings_parameters(), array('groupings' => $groupings)); $transaction = $DB->start_delegated_transaction(); foreach ($params['groupings'] as $grouping) { $grouping = (object) $grouping; if (trim($grouping->name) == '') { throw new invalid_parameter_exception('Invalid grouping name'); } if (!($currentgrouping = $DB->get_record('groupings', array('id' => $grouping->id)))) { throw new invalid_parameter_exception("Grouping {$grouping->id} does not exist in the course"); } // Check if the new modified grouping name already exists in the course. if ($grouping->name != $currentgrouping->name and $DB->count_records('groupings', array('courseid' => $currentgrouping->courseid, 'name' => $grouping->name))) { throw new invalid_parameter_exception('A different grouping with the same name already exists in the course'); } $grouping->courseid = $currentgrouping->courseid; // Now security checks. $context = context_course::instance($grouping->courseid); try { self::validate_context($context); } catch (Exception $e) { $exceptionparam = new stdClass(); $exceptionparam->message = $e->getMessage(); $exceptionparam->courseid = $grouping->courseid; throw new moodle_exception('errorcoursecontextnotvalid', 'webservice', '', $exceptionparam); } require_capability('moodle/course:managegroups', $context); // We must force allways FORMAT_HTML. $grouping->descriptionformat = external_validate_format($grouping->descriptionformat); // Finally update the grouping. groups_update_grouping($grouping); } $transaction->allow_commit(); return null; }
/** * Update cohorts * * @param array $cohorts * @return null * @since Moodle 2.5 */ public static function update_cohorts($cohorts) { global $CFG, $DB; require_once "{$CFG->dirroot}/cohort/lib.php"; $params = self::validate_parameters(self::update_cohorts_parameters(), array('cohorts' => $cohorts)); $transaction = $DB->start_delegated_transaction(); $syscontext = context_system::instance(); foreach ($params['cohorts'] as $cohort) { $cohort = (object) $cohort; if (trim($cohort->name) == '') { throw new invalid_parameter_exception('Invalid cohort name'); } $oldcohort = $DB->get_record('cohort', array('id' => $cohort->id), '*', MUST_EXIST); $oldcontext = context::instance_by_id($oldcohort->contextid, MUST_EXIST); require_capability('moodle/cohort:manage', $oldcontext); // Category type (context id). $categorytype = $cohort->categorytype; if (!in_array($categorytype['type'], array('idnumber', 'id', 'system'))) { throw new invalid_parameter_exception('category type must be id, idnumber or system:' . $categorytype['type']); } if ($categorytype['type'] === 'system') { $cohort->contextid = $syscontext->id; } else { if ($catid = $DB->get_field('course_categories', 'id', array($categorytype['type'] => $categorytype['value']))) { $cohort->contextid = $DB->get_field('context', 'id', array('instanceid' => $catid, 'contextlevel' => CONTEXT_COURSECAT)); } else { throw new invalid_parameter_exception('category not exists: category=' . $categorytype['value']); } } if ($cohort->contextid != $oldcohort->contextid) { $context = context::instance_by_id($cohort->contextid, MUST_EXIST); if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) { throw new invalid_parameter_exception('Invalid context'); } self::validate_context($context); require_capability('moodle/cohort:manage', $context); } if (!empty($cohort->description)) { $cohort->descriptionformat = external_validate_format($cohort->descriptionformat); } cohort_update_cohort($cohort); } $transaction->allow_commit(); return null; }
/** * Update notes about users. * * @param array $notes An array of ids for the notes to update. * @return array fail infos. * @since Moodle 2.2 */ public static function update_notes($notes = array()) { global $CFG, $DB; $params = self::validate_parameters(self::update_notes_parameters(), array('notes' => $notes)); // Check if note system is enabled. if (!$CFG->enablenotes) { throw new moodle_exception('notesdisabled', 'notes'); } $warnings = array(); foreach ($params['notes'] as $note) { $notedetails = note_load($note['id']); if (isset($notedetails->id)) { // Ensure the current user is allowed to run this function. $context = context_course::instance($notedetails->courseid); self::validate_context($context); require_capability('moodle/notes:manage', $context); $dbnote = new stdClass(); $dbnote->id = $note['id']; $dbnote->content = $note['text']; $dbnote->format = external_validate_format($note['format']); // 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: $warnings[] = array('item' => 'note', 'itemid' => $note["id"], 'warningcode' => 'badparam', 'message' => 'Provided publishstate incorrect'); break; } if (!note_save($dbnote)) { $warnings[] = array('item' => 'note', 'itemid' => $note["id"], 'warningcode' => 'savedfailed', 'message' => 'Note could not be modified'); } } else { $warnings[] = array('item' => 'note', 'itemid' => $note["id"], 'warningcode' => 'badid', 'message' => 'Note does not exist'); } } return $warnings; }
/** * 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 array $notes An array of notes to create. * @return array (success infos and fail infos) * @since Moodle 2.2 */ 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', 'error'); } 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->userid = $note['userid']; // Need to support 'html' and 'text' format values for backward compatibility. switch (strtolower($note['format'])) { case 'html': $textformat = FORMAT_HTML; break; case 'text': $textformat = FORMAT_PLAIN; default: $textformat = external_validate_format($note['format']); break; } $dbnote->content = $note['text']; $dbnote->format = $textformat; //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; } //TODO MDL-31119 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='******'#note-' . $dbnote->id, 'add note'); $success = $dbnote->id; } $resultnote['noteid'] = $success; } else { // WARNINGS: for backward compatibility we return this errormessage. // We should have thrown exceptions as these errors prevent results to be returned. // See http://docs.moodle.org/dev/Errors_handling_in_web_services#When_to_send_a_warning_on_the_server_side . $resultnote['noteid'] = -1; $resultnote['errormessage'] = $errormessage; } $resultnotes[] = $resultnote; } return $resultnotes; }
/** * Create categories * * @param array $categories - see create_categories_parameters() for the array structure * @return array - see create_categories_returns() for the array structure * */ public static function create_categories($categories) { global $CFG, $DB; require_once $CFG->libdir . "/coursecatlib.php"; $params = self::validate_parameters(self::create_categories_parameters(), array('categories' => $categories)); $transaction = $DB->start_delegated_transaction(); $createdcategories = array(); foreach ($params['categories'] as $category) { $parentCategory = $DB->get_record('course_categories', array('idnumber' => $category['parent'])); $category['parent'] = $parentCategory->id; if ($category['parent']) { if (!is_object($parentCategory)) { throw new moodle_exception('unknowcategory'); } $context = context_coursecat::instance($category['parent']); } else { $context = context_system::instance(); } self::validate_context($context); require_capability('moodle/category:manage', $context); // this will validate format and throw an exception if there are errors external_validate_format($category['descriptionformat']); $newcategory = coursecat::create($category); $createdcategories[] = array('id' => $newcategory->id, 'name' => $newcategory->name); } $transaction->allow_commit(); return $createdcategories; }