Permalink
Browse files

MDL-28646 Web service: core_course_get_contents()

1. Implement core_course_get_contents web service
2. Implement callbacks in folder, resource, page and url modules
3. Implement download script for web service
  • Loading branch information...
1 parent 1de9151 commit ec0d6ea2a9e5ebd1a457e51e2cf639f27ca082a8 @dcai dcai committed with mouneyrac Nov 25, 2011
View
@@ -33,6 +33,209 @@
*/
class core_course_external extends external_api {
+ /**
+ * Returns description of method parameters
+ * @return external_function_parameters
+ */
+ public static function get_course_contents_parameters() {
+ return new external_function_parameters(
+ array('courseid' => new external_value(PARAM_INT, 'course id'),
+ 'options' => new external_multiple_structure (
+ new external_single_structure(
+ array('name' => new external_value(PARAM_ALPHANUM, 'option name'),
+ 'value' => new external_value(PARAM_RAW, 'the value of the option, this param is personaly validated in the external function.')
+ )
+ ), 'Options, not used yet, might be used in later version', VALUE_DEFAULT, array())
+ )
+ );
+ }
+
+ /**
+ * Get course contents
+ * @param int $courseid
+ * @param array $options, not used yet, might be used in later version
+ * @return array
+ */
+ public static function get_course_contents($courseid, $options) {
+ global $CFG, $DB;
+ require_once($CFG->dirroot . "/course/lib.php");
+
+ //validate parameter
+ $params = self::validate_parameters(self::get_course_contents_parameters(),
+ array('courseid' => $courseid, 'options' => $options));
+
+ //retrieve the course
+ $course = $DB->get_record('course', array('id' => $params['courseid']), '*', MUST_EXIST);
+
+ //check course format exist
+ if (!file_exists($CFG->dirroot . '/course/format/' . $course->format . '/lib.php')) {
+ throw new moodle_exception('cannotgetcoursecontents', 'webservice', '', null, get_string('courseformatnotfound', 'error', '', $course->format));
+ } else {
+ require_once($CFG->dirroot . '/course/format/' . $course->format . '/lib.php');
+ }
+
+ // 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('errorcoursecontextnotvalid', 'webservice', '', $exceptionparam);
+ }
+
+ $canupdatecourse = has_capability('moodle/course:update', $context);
+
+ //create return value
+ $coursecontents = array();
+
+ if ($canupdatecourse or $course->visible
+ or has_capability('moodle/course:viewhiddencourses', $context)) {
+
+ //retrieve sections
+ $modinfo = get_fast_modinfo($course);
+ $sections = get_all_sections($course->id);
+
+ //for each sections (first displayed to last displayed)
+ foreach ($sections as $key => $section) {
+
+ $showsection = (has_capability('moodle/course:viewhiddensections', $context) or $section->visible or !$course->hiddensections);
+ if (!$showsection) {
+ continue;
+ }
+
+ // reset $sectioncontents
+ $sectionvalues = array();
+ $sectionvalues['id'] = $section->id;
+ $sectionvalues['name'] = get_section_name($course, $section);
+ $summary = file_rewrite_pluginfile_urls($section->summary, 'webservice/pluginfile.php', $context->id, 'course', 'section', $section->id);
+ $sectionvalues['visible'] = $section->visible;
+ $sectionvalues['summary'] = format_text($summary, $section->summaryformat);
+ $sectioncontents = array();
+
+ //for each module of the section
+ foreach ($modinfo->sections[$section->section] as $cmid) { //matching /course/lib.php:print_section() logic
+ $cm = $modinfo->cms[$cmid];
+
+ // stop here if the module is not visible to the user
+ if (!$cm->uservisible) {
+ continue;
+ }
+
+ $module = array();
+
+ //common info (for people being able to see the module or availability dates)
+ $module['id'] = $cm->id;
+ $module['name'] = format_string($cm->name, true);
+ $module['modname'] = $cm->modname;
+ $module['modplural'] = $cm->modplural;
+ $module['modicon'] = $cm->get_icon_url()->out(false);
+ $module['indent'] = $cm->indent;
+
+ $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
+
+ if (!empty($cm->showdescription)) {
+ $module['description'] = $cm->get_content();
+ }
+
+ //url of the module
+ $url = $cm->get_url();
+ if ($url) { //labels don't have url
+ $module['url'] = $cm->get_url()->out();
+ }
+
+ $canviewhidden = has_capability('moodle/course:viewhiddenactivities',
+ get_context_instance(CONTEXT_MODULE, $cm->id));
+ //user that can view hidden module should know about the visibility
+ $module['visible'] = $cm->visible;
+
+ //availability date (also send to user who can see hidden module when the showavailabilyt is ON)
+ if ($canupdatecourse or ($CFG->enableavailability && $canviewhidden && $cm->showavailability)) {
+ $module['availablefrom'] = $cm->availablefrom;
+ $module['availableuntil'] = $cm->availableuntil;
+ }
+
+ $baseurl = 'webservice/pluginfile.php';
+
+ //call $modulename_export_contents
+ //(each module callback take care about checking the capabilities)
+ require_once($CFG->dirroot . '/mod/' . $cm->modname . '/lib.php');
+ $getcontentfunction = $cm->modname.'_export_contents';
+ if (function_exists($getcontentfunction)) {
+ if ($contents = $getcontentfunction($cm, $baseurl)) {
+ $module['contents'] = $contents;
+ }
+ }
+
+ //assign result to $sectioncontents
+ $sectioncontents[] = $module;
+
+ }
+ $sectionvalues['modules'] = $sectioncontents;
+
+ // assign result to $coursecontents
+ $coursecontents[] = $sectionvalues;
+ }
+ }
+ return $coursecontents;
+ }
+
+ /**
+ * Returns description of method result value
+ * @return external_description
+ */
+ public static function get_course_contents_returns() {
+ return new external_multiple_structure(
+ new external_single_structure(
+ array(
+ 'id' => new external_value(PARAM_INT, 'Section ID'),
+ 'name' => new external_value(PARAM_TEXT, 'Section name'),
+ 'visible' => new external_value(PARAM_INT, 'is the section visible', VALUE_OPTIONAL),
+ 'summary' => new external_value(PARAM_RAW, 'Section description'),
+ 'modules' => new external_multiple_structure(
+ new external_single_structure(
+ array(
+ 'id' => new external_value(PARAM_INT, 'activity id'),
+ 'url' => new external_value(PARAM_URL, 'activity url', VALUE_OPTIONAL),
+ 'name' => new external_value(PARAM_TEXT, 'activity module name'),
+ 'description' => new external_value(PARAM_RAW, 'activity description', VALUE_OPTIONAL),
+ 'visible' => new external_value(PARAM_INT, 'is the module visible', VALUE_OPTIONAL),
+ 'modicon' => new external_value(PARAM_URL, 'activity icon url'),
+ 'modname' => new external_value(PARAM_PLUGIN, 'activity module type'),
+ 'modplural' => new external_value(PARAM_TEXT, 'activity module plural name'),
+ 'availablefrom' => new external_value(PARAM_INT, 'module availability start date', VALUE_OPTIONAL),
+ 'availableuntil' => new external_value(PARAM_INT, 'module availability en date', VALUE_OPTIONAL),
+ 'indent' => new external_value(PARAM_INT, 'number of identation in the site'),
+ 'contents' => new external_multiple_structure(
+ new external_single_structure(
+ array(
+ // content info
+ 'type'=> new external_value(PARAM_TEXT, 'a file or a folder or external link'),
+ 'filename'=> new external_value(PARAM_FILE, 'filename'),
+ 'filepath'=> new external_value(PARAM_PATH, 'filepath'),
+ 'filesize'=> new external_value(PARAM_INT, 'filesize'),
+ 'fileurl' => new external_value(PARAM_URL, 'downloadable file url', VALUE_OPTIONAL),
+ 'content' => new external_value(PARAM_RAW, 'Raw content, will be used when type is content', VALUE_OPTIONAL),
+ 'timecreated' => new external_value(PARAM_INT, 'Time created'),
+ 'timemodified' => new external_value(PARAM_INT, 'Time modified'),
+ 'sortorder' => new external_value(PARAM_INT, 'Content sort order'),
+
+ // copyright related info
+ 'userid' => new external_value(PARAM_INT, 'User who added this content to moodle'),
+ 'author' => new external_value(PARAM_TEXT, 'Content owner'),
+ 'license' => new external_value(PARAM_TEXT, 'Content license'),
+ )
+ ), VALUE_DEFAULT, array()
+ )
+ )
+ ), 'list of module'
+ )
+ )
+ )
+ );
+ }
+
/**
* Returns description of method parameters
* @return external_function_parameters
@@ -430,4 +633,4 @@ public static function create_courses_returns() {
return core_course_external::create_courses_returns();
}
-}
+}
View
@@ -164,6 +164,7 @@
$string['couldnotupdatenoexistinguser'] = 'Cannot update the user - user doesn\'t exist';
$string['countriesphpempty'] = 'Error: The file countries.php in language pack {$a} is empty or missing.';
$string['coursedoesnotbelongtocategory'] = 'The course doesn\'t belong to this category';
+$string['courseformatnotfound'] = 'The course format \'{$a}\' doesn\'t exist or is not recognized';
$string['coursegroupunknown'] = 'Course corresponding to group {$a} not specified';
$string['courseidnotfound'] = 'Course id doesn\'t exist';
$string['coursemisconf'] = 'Course is misconfigured';
View
@@ -43,6 +43,7 @@
$string['arguments'] = 'Arguments';
$string['authmethod'] = 'Authentication method';
$string['cannotcreatetoken'] = 'No permission to create web service token for the service {$a}.';
+$string['cannotgetcoursecontents'] = 'Cannot get course contents';
$string['configwebserviceplugins'] = 'For security reasons, only protocols that are in use should be enabled.';
$string['context'] = 'Context';
$string['createservicedescription'] = 'A service is a set of web service functions. You will allow the user to access to a new service. On the <strong>Add service</strong> page check \'Enable\' and \'Authorised users\' options. Select \'No required capability\'.';
@@ -74,6 +75,7 @@
$string['enableprotocolsdescription'] = 'At least one protocol should be enabled. For security reasons, only protocols that are to be used should be enabled.';
$string['enablews'] = 'Enable web services';
$string['enablewsdescription'] = 'Web services must be enabled in Advanced features.';
+$string['enabledirectdownload'] = 'Web service file downloading must be enabled in external service settings';
$string['entertoken'] = 'Enter a security key/token:';
$string['error'] = 'Error: {$a}';
$string['errorcatcontextnotvalid'] = 'You cannot execute functions in the category context (category id:{$a->catid}). The context error message was: {$a->message}';
@@ -177,6 +179,7 @@
$string['tokenauthlog'] = 'Token authentication';
$string['tokencreatedbyadmin'] = 'Can only be reset by administrator (*)';
$string['tokencreator'] = 'Creator';
+$string['unknownoptionkey'] = 'Unknown option key ({$a})';
$string['updateusersettings'] = 'Update';
$string['userasclients'] = 'Users as clients with token';
$string['userasclientsdescription'] = 'The following steps help you to set up the Moodle web service for users as clients. These steps also help to set up the recommended token (security keys) authentication method. In this use case, the user will generate his token from the security keys page via My profile settings.';
View
@@ -404,6 +404,15 @@
'capabilities'=> 'moodle/course:create,moodle/course:visibility',
),
+ 'core_course_get_contents' => array(
+ 'classname' => 'core_course_external',
+ 'methodname' => 'get_course_contents',
+ 'classpath' => 'course/externallib.php',
+ 'description' => 'Get course contents',
+ 'type' => 'read',
+ 'capabilities'=> 'moodle/course:update,moodle/course:viewhiddencourses',
+ ),
+
// === message related functions ===
'moodle_message_send_instantmessages' => array(
@@ -474,7 +483,8 @@
'moodle_notes_create_notes',
'moodle_user_get_course_participants_by_id',
'moodle_user_get_users_by_courseid',
- 'moodle_message_send_instantmessages'),
+ 'moodle_message_send_instantmessages',
+ 'core_course_get_contents'),
'enabled' => 0,
'restrictedusers' => 0,
'shortname' => MOODLE_OFFICIAL_MOBILE_SERVICE,
Oops, something went wrong.

0 comments on commit ec0d6ea

Please sign in to comment.