? patch.txt Index: externallib.php =================================================================== RCS file: /cvsroot/moodle/moodle/course/externallib.php,v retrieving revision 1.2 diff -u -r1.2 externallib.php --- externallib.php 21 Jun 2010 15:30:52 -0000 1.2 +++ externallib.php 3 Aug 2010 08:30:48 -0000 @@ -16,11 +16,11 @@ // along with Moodle. If not, see . /** - * External user API + * External course API * * @package core * @subpackage course - * @copyright 2009 Moodle Pty Ltd (http://moodle.com) + * @copyright 2010 Moodle Pty Ltd (http://moodle.com) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -30,4 +30,333 @@ class moodle_course_external extends external_api { + /** + * Returns description of method parameters + * @return external_function_parameters + */ + public static function get_courses_parameters() { + return new external_function_parameters( + array('options' => new external_single_structure( + array('ids' => new external_multiple_structure( + new external_value(PARAM_INT, 'Course id') + , 'List of course id. If empty return all courses + except front page course.', + VALUE_OPTIONAL) + ), 'options - operator OR is used', VALUE_DEFAULT, array()) + ) + ); + } + + /** + * Get courses + * @param array $options + * @return array + */ + public static function get_courses($options) { + global $CFG, $DB; + require_once($CFG->dirroot . "/course/lib.php"); + + //validate parameter + $params = self::validate_parameters(self::get_courses_parameters(), + array('options' => $options)); + + //retrieve courses + if (!key_exists('ids', $params['options']) + or empty($params['options']['ids'])) { + $where = 'id NOT IN (' . SITEID . ')'; + $courses = $DB->get_records_select('course', $where); + } else { + $courses = $DB->get_records_list('course', 'id', $params['options']['ids']); + } + + //create return value + $coursesinfo = array(); + foreach ($courses as $course) { + + // now security checks + $context = get_context_instance(CONTEXT_COURSE, $course->id); + try { + self::validate_context($context); + } catch (Exception $e) { + $exceptionparam = new stdClass(); + $exceptionparam->message = $e->getMessage(); + $exceptionparam->courseid = $course->id; + throw new moodle_exception( + get_string('errorcoursecontextnotvalid', 'webservice', $exceptionparam)); + } + require_capability('moodle/course:view', $context); + + $courseinfo = array(); + $courseinfo['id'] = $course->id; + $courseinfo['fullname'] = $course->fullname; + $courseinfo['shortname'] = $course->shortname; + $courseinfo['categoryid'] = $course->category; + $courseinfo['summary'] = $course->summary; + $courseinfo['summaryformat'] = $course->summaryformat; + $courseinfo['format'] = $course->format; + $courseinfo['startdate'] = $course->startdate; + $courseinfo['numsections'] = $course->numsections; + + //some field should be returned only if the user has update permission + if (has_capability('moodle/course:update', $context)) { + $courseinfo['categorysortorder'] = $course->sortorder; + $courseinfo['idnumber'] = $course->idnumber; + $courseinfo['showgrades'] = $course->showgrades; + $courseinfo['showreports'] = $course->showreports; + $courseinfo['newsitems'] = $course->newsitems; + $courseinfo['visible'] = $course->visible; + $courseinfo['maxbytes'] = $course->maxbytes; + $courseinfo['hiddensections'] = $course->hiddensections; + $courseinfo['groupmode'] = $course->groupmode; + $courseinfo['groupmodeforce'] = $course->groupmodeforce; + $courseinfo['defaultgroupingid'] = $course->defaultgroupingid; + $courseinfo['lang'] = $course->lang; + $courseinfo['timecreated'] = $course->timecreated; + $courseinfo['timemodified'] = $course->timemodified; + $courseinfo['forcetheme'] = $course->theme; + $courseinfo['enablecompletion'] = $course->enablecompletion; + $courseinfo['completionstartonenrol'] = $course->completionstartonenrol; + $courseinfo['completionnotify'] = $course->completionnotify; + } + + $coursesinfo[] = $courseinfo; + } + + return $coursesinfo; + } + + /** + * Returns description of method result value + * @return external_description + */ + public static function get_courses_returns() { + return new external_multiple_structure( + new external_single_structure( + array( + 'id' => new external_value(PARAM_INT, 'course id'), + 'shortname' => new external_value(PARAM_TEXT, 'course short name'), + 'categoryid' => new external_value(PARAM_INT, 'category id'), + 'categorysortorder' => new external_value(PARAM_INT, + 'sort order into the category', VALUE_OPTIONAL), + 'fullname' => new external_value(PARAM_TEXT, 'full name'), + 'idnumber' => new external_value(PARAM_RAW, 'id number', VALUE_OPTIONAL), + 'summary' => new external_value(PARAM_RAW, 'summary'), + 'summaryformat' => new external_value(PARAM_INT, + 'the summary text Moodle format'), + 'format' => new external_value(PARAM_ALPHANUMEXT, + 'course format: weeks, topics, social, site,..'), + 'showgrades' => new external_value(PARAM_INT, + '1 if grades are shown, otherwise 0', VALUE_OPTIONAL), + 'newsitems' => new external_value(PARAM_INT, + 'number of recent items appearing on the course page', VALUE_OPTIONAL), + 'startdate' => new external_value(PARAM_INT, + 'timestamp when the course start'), + 'numsections' => new external_value(PARAM_INT, 'number of weeks/topics'), + 'maxbytes' => new external_value(PARAM_INT, + 'largest size of file that can be uploaded into the course', + VALUE_OPTIONAL), + 'showreports' => new external_value(PARAM_INT, + 'are activity report shown (yes = 1, no =0)', VALUE_OPTIONAL), + 'visible' => new external_value(PARAM_INT, + '1: available to student, 0:not available', VALUE_OPTIONAL), + 'hiddensections' => new external_value(PARAM_INT, + 'How the hidden sections in the course are displayed to students', + VALUE_OPTIONAL), + 'groupmode' => new external_value(PARAM_INT, 'no group, separate, visible', + VALUE_OPTIONAL), + 'groupmodeforce' => new external_value(PARAM_INT, '1: yes, 0: no', + VALUE_OPTIONAL), + 'defaultgroupingid' => new external_value(PARAM_INT, 'default grouping id', + VALUE_OPTIONAL), + 'timecreated' => new external_value(PARAM_INT, + 'timestamp when the course have been created', VALUE_OPTIONAL), + 'timemodified' => new external_value(PARAM_INT, + 'timestamp when the course have been modified', VALUE_OPTIONAL), + 'enablecompletion' => new external_value(PARAM_INT, + 'Enabled, control via completion and activity settings. Disbaled, + not shown in activity settings.', + VALUE_OPTIONAL), + 'completionstartonenrol' => new external_value(PARAM_INT, + '1: begin tracking a student\'s progress in course completion + after course enrolment. 0: does not', + VALUE_OPTIONAL), + 'completionnotify' => new external_value(PARAM_INT, + '1: yes 0: no', VALUE_OPTIONAL), + 'lang' => new external_value(PARAM_ALPHANUMEXT, + 'forced course language', VALUE_OPTIONAL), + 'forcetheme' => new external_value(PARAM_ALPHANUMEXT, + 'name of the force theme', VALUE_OPTIONAL), + ), 'course' + ) + ); + } + + /** + * Returns description of method parameters + * @return external_function_parameters + */ + public static function create_courses_parameters() { + $courseconfig = get_config('moodlecourse'); //needed for many default values + return new external_function_parameters( + array( + 'courses' => new external_multiple_structure( + new external_single_structure( + array( + 'fullname' => new external_value(PARAM_TEXT, 'full name'), + 'shortname' => new external_value(PARAM_TEXT, 'course short name'), + 'categoryid' => new external_value(PARAM_INT, 'category id'), + 'idnumber' => new external_value(PARAM_RAW, 'id number', VALUE_OPTIONAL), + 'summary' => new external_value(PARAM_RAW, 'summary', VALUE_OPTIONAL), + 'summaryformat' => new external_value(PARAM_INT, + 'the summary text Moodle format', VALUE_DEFAULT, FORMAT_MOODLE), + 'format' => new external_value(PARAM_ALPHANUMEXT, + 'course format: weeks, topics, social, site,..', + VALUE_DEFAULT, $courseconfig->format), + 'showgrades' => new external_value(PARAM_INT, + '1 if grades are shown, otherwise 0', VALUE_DEFAULT, + $courseconfig->showgrades), + 'newsitems' => new external_value(PARAM_INT, + 'number of recent items appearing on the course page', + VALUE_DEFAULT, $courseconfig->newsitems), + 'startdate' => new external_value(PARAM_INT, + 'timestamp when the course start', VALUE_OPTIONAL), + 'numsections' => new external_value(PARAM_INT, 'number of weeks/topics', + VALUE_DEFAULT, $courseconfig->numsections), + 'maxbytes' => new external_value(PARAM_INT, + 'largest size of file that can be uploaded into the course', + VALUE_DEFAULT, $courseconfig->maxbytes), + 'showreports' => new external_value(PARAM_INT, + 'are activity report shown (yes = 1, no =0)', VALUE_DEFAULT, + $courseconfig->showreports), + 'visible' => new external_value(PARAM_INT, + '1: available to student, 0:not available', VALUE_OPTIONAL), + 'hiddensections' => new external_value(PARAM_INT, + 'How the hidden sections in the course are displayed to students', + VALUE_DEFAULT, $courseconfig->hiddensections), + 'groupmode' => new external_value(PARAM_INT, 'no group, separate, visible', + VALUE_DEFAULT, $courseconfig->groupmode), + 'groupmodeforce' => new external_value(PARAM_INT, '1: yes, 0: no', + VALUE_DEFAULT, $courseconfig->groupmodeforce), + 'defaultgroupingid' => new external_value(PARAM_INT, 'default grouping id', + VALUE_DEFAULT, 0), + 'enablecompletion' => new external_value(PARAM_INT, + 'Enabled, control via completion and activity settings. Disbaled, + not shown in activity settings.', + VALUE_OPTIONAL), + 'completionstartonenrol' => new external_value(PARAM_INT, + '1: begin tracking a student\'s progress in course completion after + course enrolment. 0: does not', + VALUE_OPTIONAL), + 'completionnotify' => new external_value(PARAM_INT, + '1: yes 0: no', VALUE_OPTIONAL), + 'lang' => new external_value(PARAM_ALPHANUMEXT, + 'forced course language', VALUE_OPTIONAL), + 'forcetheme' => new external_value(PARAM_ALPHANUMEXT, + 'name of the force theme', VALUE_OPTIONAL), + ) + ), 'courses to create' + ) + ) + ); + } + + /** + * Create courses + * @param array $courses + * @return array courses (id and shortname only) + */ + public static function create_courses($courses) { + global $CFG, $DB; + require_once($CFG->dirroot . "/course/lib.php"); + require_once($CFG->libdir . '/completionlib.php'); + + + $params = self::validate_parameters(self::create_courses_parameters(), + array('courses' => $courses)); + + $availablethemes = get_plugin_list('theme'); + $availablelangs = get_string_manager()->get_list_of_translations(); + + $transaction = $DB->start_delegated_transaction(); + + foreach ($params['courses'] as $course) { + + // Ensure the current user is allowed to run this function + $context = get_context_instance(CONTEXT_COURSECAT, $course['categoryid']); + try { + self::validate_context($context); + } catch (Exception $e) { + $exceptionparam = new stdClass(); + $exceptionparam->message = $e->getMessage(); + $exceptionparam->catid = $course['categoryid']; + throw new moodle_exception( + get_string('errorcatcontextnotvalid', 'webservice', $exceptionparam)); + } + require_capability('moodle/course:create', $context); + + // Make sure lang is valid + if (key_exists('lang', $course) and empty($availablelangs[$course['lang']])) { + throw new moodle_exception( + get_string('courselangnotsupported', 'error', $course['lang'])); + } + + // Make sure theme is valid + if (key_exists('forcetheme', $course)) { + if (!empty($CFG->allowcoursethemes)) { + if (empty($availablethemes[$course['forcetheme']])) { + throw new moodle_exception( + get_string('coursethemenotsupported', 'error', $course['forcetheme'])); + } else { + $course['theme'] = $course['forcetheme']; + } + } + } + + //force visibility if ws user doesn't have the permission to set it + $category = $DB->get_record('course_categories', array('id' => $course['categoryid'])); + if (!has_capability('moodle/course:visibility', $context)) { + $course['visible'] = $category->visible; + } + + //set default value for completion + if (completion_info::is_enabled_for_site()) { + if (!key_exists('enablecompletion', $course)) { + $course['enablecompletion'] = $courseconfig->enablecompletion; + } + if (!key_exists('completionstartonenrol', $course)) { + $course['completionstartonenrol'] = $courseconfig->completionstartonenrol; + } + } else { + $course['enablecompletion'] = 0; + $course['completionstartonenrol'] = 0; + } + + $course['category'] = $course['categoryid']; + + //Note: create_course() core function check shortname, idnumber, category + $course['id'] = create_course((object) $course)->id; + + $resultcourses[] = array('id' => $course['id'], 'shortname' => $course['shortname']); + } + + $transaction->allow_commit(); + + return $resultcourses; + } + + /** + * Returns description of method result value + * @return external_description + */ + public static function create_courses_returns() { + return new external_multiple_structure( + new external_single_structure( + array( + 'id' => new external_value(PARAM_INT, 'course id'), + 'shortname' => new external_value(PARAM_TEXT, 'short name'), + ) + ) + ); + } + } \ No newline at end of file