diff --git a/README.md b/README.md index 5a9db4c..a7b3b88 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,43 @@ # Moodle Plugin "sync_service" -This plugin for Moodle (type: local) adds serveral functions to the Moodle Web Service API. -Those fuctions allow users and external services to remotely create and move new course modules. -Furthermore an external service (called "Course Sync Extension Service") containing the newly added functions and other core web service functions, which are helpful to use the added functions, is added. - -The plugin is developed to work with the desktop application [MoodleSync](https://github.com/MoodleSync/sync-app), used for file synchronization between a local directory and the learning platform Moodle. - -Following functions are added: -Function | Description | Note --------- | -------- | -------- -local_course_add_new_course_module_url |Add course module URL | -local_course_add_new_course_module_resource | Add course module Resource | File needs to be uploaded with "/webservice/upload.php" web service call. -local_course_add_new_course_module_directory | Add course modul Folder | Files need to be uploaded with "/webservice/upload.php" web service call. -local_course_add_files_to_directory | Add files to existing folders | Files need to be uploaded with "/webservice/upload.php" web service call; since version 3.0.0 -local_course_move_module_to_specific_position | Move a module to a dedicated position | -local_course_add_new_section | Create and position a new course section | Since version 2.0.0 - -Usage: -* Tested on Moodle versions 3.11.4, 4.0.2, 4.1.2. and 4.2.2. -* Usage of the "REST (returning JSON)"- web service protocol. -* To install the plugin, you may use the in-build plugin installation interface. Or you can unzip the archive and copy the folder "sync_service" into the directory "\server\moodle\local". Afterwards restart Moodle, log-in as an admin and follow the installation process. -* To use the added fuctions, either enable and use the added external service (file upload and file download must be allowed) or create a new external service. -* **Be aware: the plugins setting "restrictedusers" is disabled.** +This plugin for Moodle (type: local) adds several functions to the Moodle Web Service API. +These functions allow users and external services to remotely create, move, and manage course modules with a focus on autonomous course design. + +Originally developed for [MoodleSync](https://github.com/MoodleSync/sync-app), this fork adds advanced authoring capabilities for pages and labels to support AI-driven course generation. + +## Added Functions + +The following functions are available via the Moodle Web Service API: + +| Function | Description | Note | +| -------- | ----------- | ---- | +| `local_course_add_new_course_module_url` | Add course module URL | | +| `local_course_add_new_course_module_resource` | Add course module Resource | File needs to be uploaded with "/webservice/upload.php". | +| `local_course_add_new_course_module_directory` | Add course module Folder | Files need to be uploaded with "/webservice/upload.php". | +| `local_course_add_new_course_module_page` | **Add course module Page** | Supports HTML content (PARAM_RAW). Uses CMID-First logic for stability. | +| `local_course_add_new_course_module_label` | **Add course module Label** | Supports HTML/Text labels for course structuring. | +| `local_course_add_files_to_directory` | Add files to existing folders | Since version 3.0.0. | +| `local_course_move_module_to_specific_position` | Move a module to a dedicated position | | +| `local_course_add_new_section` | Create and position a new course section | Since version 2.0.0. | + +## New in this Fork (v2024061803+) + +* **Authoring Support:** Added support for `mod_page` and `mod_label` which were previously missing from the API. +* **HTML Support:** Text parameters now use `PARAM_RAW` to allow for CSS-styled content, H5P embeds, and complex layouts. +* **CMID-First Strategy:** Internal refactoring ensures that complex modules (like Pages) are correctly linked to a Course Module ID (CMID) before instance creation, preventing "Invalid Module ID" errors. + +## Usage & Installation + +* **Compatibility:** Tested on Moodle versions 3.11.x, 4.x, and **5.2.x**. +* **Protocol:** Uses the "REST (returning JSON)" web service protocol. +* **Installation:** + 1. Unzip the archive into the directory `local/sync_service`. + 2. Log in as an admin and follow the installation process via the Notifications page. + 3. Ensure the external service "Gemini MCP" or "Course Sync Extension Service" is enabled. +* **Requirements:** File upload and download must be allowed in the web service settings. +* **Security:** The setting `restrictedusers` is disabled by default to allow flexible agent interaction. + +## License + +This plugin is licensed under the same terms as the original Moodle sync_service plugin. + diff --git a/db/services.php b/db/services.php index 5b1ca83..5250295 100644 --- a/db/services.php +++ b/db/services.php @@ -77,9 +77,25 @@ 'type' => 'write', 'ajax' => true, 'capabilities' => 'mod/folder:managefiles' + ), + 'local_course_add_new_course_module_page' => array( + 'classname' => 'local_sync_service_external', + 'methodname' => 'local_sync_service_add_new_course_module_page', + 'classpath' => 'local/sync_service/externallib.php', + 'description' => 'Add course module Page', + 'type' => 'write', + 'ajax' => true, + 'capabilities' => 'mod/page:addinstance', + ), + 'local_course_add_new_course_module_label' => array( + 'classname' => 'local_sync_service_external', + 'methodname' => 'local_sync_service_add_new_course_module_label', + 'classpath' => 'local/sync_service/externallib.php', + 'description' => 'Add course module Label', + 'type' => 'write', + 'ajax' => true, + 'capabilities' => 'mod/label:addinstance', ) - - ); $services = array( @@ -91,6 +107,8 @@ 'local_course_move_module_to_specific_position', 'local_course_add_new_course_module_directory', 'local_course_add_files_to_directory', + 'local_course_add_new_course_module_page', + 'local_course_add_new_course_module_label', 'core_course_get_contents', 'core_enrol_get_users_courses', 'core_webservice_get_site_info', diff --git a/externallib.php b/externallib.php index a365d88..16401ed 100644 --- a/externallib.php +++ b/externallib.php @@ -47,15 +47,9 @@ public static function local_sync_service_add_new_section_parameters() { /** * Creating and positioning of a new section. - * - * @param $courseid The course id. - * @param $sectionname Name of the new section. - * @param $sectionnum The position of the section inside the course, will be placed before a exisiting section with same sectionnum. - * @return $update Message: Successful. */ public static function local_sync_service_add_new_section($courseid, $sectionname, $sectionnum) { global $DB, $CFG; - // Parameter validation. $params = self::validate_parameters( self::local_sync_service_add_new_section_parameters(), array( @@ -65,45 +59,26 @@ public static function local_sync_service_add_new_section($courseid, $sectionnam ) ); - // Ensure the current user has required permission in this course. $context = context_course::instance($params['courseid']); self::validate_context($context); - - // Required permissions. require_capability('block/section_links:addinstance', $context); $cw = course_create_section($params['courseid'], $params['sectionnum'], false); - $section = $DB->get_record('course_sections', array('id' => $cw->id), '*', MUST_EXIST); $course = $DB->get_record('course', array('id' => $section->course), '*', MUST_EXIST); - $data['name'] = $params['sectionname']; - course_update_section($course, $section, $data); - $update = [ - 'message' => 'Successful', - ]; - return $update; + return ['message' => 'Successful']; } - /** - * Obtains the Parameter which will be returned. - * @return external_description - */ public static function local_sync_service_add_new_section_returns() { return new external_single_structure( - array( - 'message' => new external_value( PARAM_TEXT, 'if the execution was successful' ), - ) + array('message' => new external_value( PARAM_TEXT, 'if the execution was successful' )) ); } - /** - * Defines the necessary method parameters. - * @return external_function_parameters - */ public static function local_sync_service_add_new_course_module_url_parameters() { return new external_function_parameters( array( @@ -111,31 +86,16 @@ public static function local_sync_service_add_new_course_module_url_parameters() 'sectionnum' => new external_value( PARAM_TEXT, 'relative number of the section' ), 'urlname' => new external_value( PARAM_TEXT, 'displayed mod name' ), 'url' => new external_value( PARAM_TEXT, 'url to insert' ), - 'time' => new external_value( PARAM_TEXT, 'defines the mod. visibility', VALUE_DEFAULT, null ), 'visible' => new external_value( PARAM_TEXT, 'defines the mod. visibility' ), + 'time' => new external_value( PARAM_TEXT, 'defines the mod. visibility', VALUE_DEFAULT, null ), 'beforemod' => new external_value( PARAM_TEXT, 'mod to set before', VALUE_DEFAULT, null ), ) ); } - - /** - * Method to create a new course module containing a url. - * - * @param $courseid The course id. - * @param $sectionnum The number of the section inside the course. - * @param $urlname Displayname of the Module. - * @param $url Url to publish. - * @param $time availability time. - * @param $visible visible for course members. - * @param $beforemod Optional parameter, a Module where the new Module should be placed before. - * @return $update Message: Successful and $cmid of the new Module. - */ - public static function local_sync_service_add_new_course_module_url($courseid, $sectionnum, $urlname, $url, $time = null, $visible, $beforemod = null) { + public static function local_sync_service_add_new_course_module_url($courseid, $sectionnum, $urlname, $url, $visible, $time = null, $beforemod = null) { global $DB, $CFG; - require_once($CFG->dirroot . '/mod/' . '/url' . '/lib.php'); - - // Parameter validation. + require_once($CFG->dirroot . '/mod/url/lib.php'); $params = self::validate_parameters( self::local_sync_service_add_new_course_module_url_parameters(), array( @@ -143,17 +103,13 @@ public static function local_sync_service_add_new_course_module_url($courseid, $ 'sectionnum' => $sectionnum, 'urlname' => $urlname, 'url' => $url, - 'time' => $time, 'visible' => $visible, + 'time' => $time, 'beforemod' => $beforemod, ) ); - - // Ensure the current user has required permission in this course. $context = context_course::instance($params['courseid']); self::validate_context($context); - - // Required permissions. require_capability('mod/url:addinstance', $context); $instance = new \stdClass(); @@ -164,11 +120,9 @@ public static function local_sync_service_add_new_course_module_url($courseid, $ $instance->externalurl = $params['url']; $instance->id = url_add_instance($instance, null); - $modulename = 'url'; - $cm = new \stdClass(); $cm->course = $params['courseid']; - $cm->module = $DB->get_field( 'modules', 'id', array('name' => $modulename) ); + $cm->module = $DB->get_field( 'modules', 'id', array('name' => 'url') ); $cm->instance = $instance->id; $cm->section = $params['sectionnum']; if (!is_null($params['time'])) { @@ -176,23 +130,12 @@ public static function local_sync_service_add_new_course_module_url($courseid, $ } else if ( $params['visible'] === 'false' ) { $cm->visible = 0; } - $cm->id = add_course_module( $cm ); - $cmid = $cm->id; + course_add_cm_to_section($params['courseid'], $cm->id, $params['sectionnum'], $params['beforemod']); - course_add_cm_to_section($params['courseid'], $cmid, $params['sectionnum'], $params['beforemod']); - - $update = [ - 'message' => 'Successful', - 'id' => $cmid, - ]; - return $update; + return ['message' => 'Successful', 'id' => (string)$cm->id]; } - /** - * Obtains the Parameter which will be returned. - * @return external_description - */ public static function local_sync_service_add_new_course_module_url_returns() { return new external_single_structure( array( @@ -202,10 +145,6 @@ public static function local_sync_service_add_new_course_module_url_returns() { ); } - /** - * Defines the necessary method parameters. - * @return external_function_parameters - */ public static function local_sync_service_add_new_course_module_resource_parameters() { return new external_function_parameters( array( @@ -213,31 +152,16 @@ public static function local_sync_service_add_new_course_module_resource_paramet 'sectionnum' => new external_value( PARAM_TEXT, 'relative number of the section' ), 'itemid' => new external_value( PARAM_TEXT, 'id of the upload' ), 'displayname' => new external_value( PARAM_TEXT, 'displayed mod name' ), - 'time' => new external_value( PARAM_TEXT, 'defines the mod. availability', VALUE_DEFAULT, null ), 'visible' => new external_value( PARAM_TEXT, 'defines the mod. visibility' ), + 'time' => new external_value( PARAM_TEXT, 'defines the mod. visibility', VALUE_DEFAULT, null ), 'beforemod' => new external_value( PARAM_TEXT, 'mod to set before', VALUE_DEFAULT, null ), ) ); } - /** - * Method to create a new course module containing a file. - * - * @param $courseid The course id. - * @param $sectionnum The number of the section inside the course. - * @param $itemid File to publish. - * @param $displayname Displayname of the Module. - * @param $time availability time. - * @param $visible visible for course members. - * @param $beforemod Optional parameter, a Module where the new Module should be placed before. - * @return $update Message: Successful and $cmid of the new Module. - */ - public static function local_sync_service_add_new_course_module_resource($courseid, $sectionnum, $itemid, $displayname, $time = null, $visible, $beforemod = null) { + public static function local_sync_service_add_new_course_module_resource($courseid, $sectionnum, $itemid, $displayname, $visible, $time = null, $beforemod = null) { global $DB, $CFG; - require_once($CFG->dirroot . '/mod/' . '/resource' . '/lib.php'); - require_once($CFG->dirroot . '/availability/' . '/condition' . '/date' . '/classes' . '/condition.php'); - - // Parameter validation. + require_once($CFG->dirroot . '/mod/resource/lib.php'); $params = self::validate_parameters( self::local_sync_service_add_new_course_module_resource_parameters(), array( @@ -245,24 +169,18 @@ public static function local_sync_service_add_new_course_module_resource($course 'sectionnum' => $sectionnum, 'itemid' => $itemid, 'displayname' => $displayname, - 'time' => $time, 'visible' => $visible, + 'time' => $time, 'beforemod' => $beforemod, ) ); - - // Ensure the current user has required permission in this course. $context = context_course::instance($params['courseid']); self::validate_context($context); - - // Required permissions. require_capability('mod/resource:addinstance', $context); - $modulename = 'resource'; - $cm = new \stdClass(); $cm->course = $params['courseid']; - $cm->module = $DB->get_field('modules', 'id', array( 'name' => $modulename )); + $cm->module = $DB->get_field('modules', 'id', array( 'name' => 'resource' )); $cm->section = $params['sectionnum']; if (!is_null($params['time'])) { $cm->availability = "{\"op\":\"&\",\"c\":[{\"type\":\"date\",\"d\":\">=\",\"t\":" . $params['time'] . "}],\"showc\":[" . $params['visible'] . "]}"; @@ -270,31 +188,19 @@ public static function local_sync_service_add_new_course_module_resource($course $cm->visible = 0; } $cm->id = add_course_module($cm); - $cmid = $cm->id; - $instance = new \stdClass(); $instance->course = $params['courseid']; $instance->name = $params['displayname']; $instance->intro = null; $instance->introformat = \FORMAT_HTML; - $instance->coursemodule = $cmid; - + $instance->coursemodule = $cm->id; $instance->files = $params['itemid']; $instance->id = resource_add_instance($instance, null); + course_add_cm_to_section($params['courseid'], $cm->id, $params['sectionnum'], $params['beforemod']); - course_add_cm_to_section($params['courseid'], $cmid, $params['sectionnum'], $params['beforemod']); - - $update = [ - 'message' => 'Successful', - 'id' => $cmid, - ]; - return $update; + return ['message' => 'Successful', 'id' => (string)$cm->id]; } - /** - * Obtains the Parameter which will be returned. - * @return external_description - */ public static function local_sync_service_add_new_course_module_resource_returns() { return new external_single_structure( array( @@ -304,10 +210,6 @@ public static function local_sync_service_add_new_course_module_resource_returns ); } - /** - * Defines the necessary method parameters. - * @return external_function_parameters - */ public static function local_sync_service_move_module_to_specific_position_parameters() { return new external_function_parameters( array( @@ -318,67 +220,32 @@ public static function local_sync_service_move_module_to_specific_position_param ); } - /** - * Method to position an existing course module. - * - * @param $cmid The Module to move. - * @param $sectionid The id of the section inside the course. - * @param $beforemod Optional parameter, a Module where the new Module should be placed before. - * @return $update Message: Successful and $cmid of the new Module. - */ public static function local_sync_service_move_module_to_specific_position($cmid, $sectionid, $beforemod = null) { global $DB, $CFG; - require_once($CFG->dirroot . '/course/' . '/lib.php'); - - // Parameter validation. + require_once($CFG->dirroot . '/course/lib.php'); $params = self::validate_parameters( self::local_sync_service_move_module_to_specific_position_parameters(), - array( - 'cmid' => $cmid, - 'sectionid' => $sectionid, - 'beforemod' => $beforemod, - ) + array('cmid' => $cmid, 'sectionid' => $sectionid, 'beforemod' => $beforemod) ); - - // Ensure the current user has required permission. $modcontext = context_module::instance( $params['cmid'] ); self::validate_context( $modcontext ); - $cm = get_coursemodule_from_id('', $params['cmid']); - - // Ensure the current user has required permission in this course. $context = context_course::instance($cm->course); self::validate_context($context); - - // Required permissions. require_capability('moodle/course:movesections', $context); $section = $DB->get_record('course_sections', array( 'id' => $params['sectionid'], 'course' => $cm->course )); - moveto_module($cm, $section, $params['beforemod']); - $update = [ - 'message' => 'Successful', - ]; - return $update; + return ['message' => 'Successful']; } - /** - * Obtains the Parameter which will be returned. - * @return external_description - */ public static function local_sync_service_move_module_to_specific_position_returns() { return new external_single_structure( - array( - 'message' => new external_value( PARAM_TEXT, 'if the execution was successful' ) - ) + array('message' => new external_value( PARAM_TEXT, 'if the execution was successful' )) ); } - /** - * Defines the necessary method parameters. - * @return external_function_parameters - */ public static function local_sync_service_add_new_course_module_directory_parameters() { return new external_function_parameters( array( @@ -386,55 +253,30 @@ public static function local_sync_service_add_new_course_module_directory_parame 'sectionnum' => new external_value( PARAM_TEXT, 'relative number of the section' ), 'itemid' => new external_value( PARAM_TEXT, 'id of the upload' ), 'displayname' => new external_value( PARAM_TEXT, 'displayed mod name' ), - 'time' => new external_value( PARAM_TEXT, 'defines the mod. visibility', VALUE_DEFAULT, null ), 'visible' => new external_value( PARAM_TEXT, 'defines the mod. visibility' ), + 'time' => new external_value( PARAM_TEXT, 'defines the mod. visibility', VALUE_DEFAULT, null ), 'beforemod' => new external_value( PARAM_TEXT, 'mod to set before', VALUE_DEFAULT, null ), ) ); } - /** - * Method to create a new course module of type folder. - * - * @param $courseid The course id. - * @param $sectionnum The number of the section inside the course. - * @param $displayname Displayname of the Module. - * @param $itemid Files in same draft area to upload. - * @param $time availability time. - * @param $visible visible for course members. - * @param $beforemod Optional parameter, a Module where the new Module should be placed before. - * @return $update Message: Successful and $cmid of the new Module. - */ - public static function local_sync_service_add_new_course_module_directory($courseid, $sectionnum, $itemid, $displayname, $time = null, $visible, $beforemod = null) { + public static function local_sync_service_add_new_course_module_directory($courseid, $sectionnum, $itemid, $displayname, $visible, $time = null, $beforemod = null) { global $DB, $CFG; - require_once($CFG->dirroot . '/mod/' . '/folder' . '/lib.php'); - - // Parameter validation. + require_once($CFG->dirroot . '/mod/folder/lib.php'); $params = self::validate_parameters( self::local_sync_service_add_new_course_module_directory_parameters(), array( - 'courseid' => $courseid, - 'sectionnum' => $sectionnum, - 'itemid' => $itemid, - 'displayname' => $displayname, - 'time' => $time, - 'visible' => $visible, - 'beforemod' => $beforemod, + 'courseid' => $courseid, 'sectionnum' => $sectionnum, 'itemid' => $itemid, + 'displayname' => $displayname, 'visible' => $visible, 'time' => $time, 'beforemod' => $beforemod, ) ); - - // Ensure the current user has required permission in this course. $context = context_course::instance($params['courseid']); self::validate_context($context); - - // Required permissions. require_capability('mod/folder:addinstance', $context); - $modulename = 'folder'; - $cm = new \stdClass(); $cm->course = $params['courseid']; - $cm->module = $DB->get_field('modules', 'id', array( 'name' => $modulename )); + $cm->module = $DB->get_field('modules', 'id', array( 'name' => 'folder' )); $cm->section = $params['sectionnum']; if (!is_null($params['time'])) { $cm->availability = "{\"op\":\"&\",\"c\":[{\"type\":\"date\",\"d\":\">=\",\"t\":" . $params['time'] . "}],\"showc\":[" . $params['visible'] . "]}"; @@ -442,30 +284,19 @@ public static function local_sync_service_add_new_course_module_directory($cours $cm->visible = 0; } $cm->id = add_course_module($cm); - $cmid = $cm->id; - $instance = new \stdClass(); $instance->course = $params['courseid']; $instance->name = $params['displayname']; - $instance->coursemodule = $cmid; + $instance->coursemodule = $cm->id; $instance->introformat = FORMAT_HTML; $instance->intro = '

'.$params['displayname'].'

'; $instance->files = $params['itemid']; $instance->id = folder_add_instance($instance, null); + course_add_cm_to_section($params['courseid'], $cm->id, $params['sectionnum'], $params['beforemod']); - course_add_cm_to_section($params['courseid'], $cmid, $params['sectionnum'], $params['beforemod']); - - $update = [ - 'message' => 'Successful', - 'id' => $instance->id, - ]; - return $update; + return ['message' => 'Successful', 'id' => (string)$cm->id]; } - /** - * Obtains the Parameter which will be returned. - * @return external_description - */ public static function local_sync_service_add_new_course_module_directory_returns() { return new external_single_structure( array( @@ -475,10 +306,6 @@ public static function local_sync_service_add_new_course_module_directory_return ); } - /** - * Defines the necessary method parameters. - * @return external_function_parameters - */ public static function local_sync_service_add_files_to_directory_parameters() { return new external_function_parameters( array( @@ -489,53 +316,144 @@ public static function local_sync_service_add_files_to_directory_parameters() { ); } - /** - * This method implements the logic for the API-Call. - * - * @param $courseid The course id. - * @param $itemid File(-s) to add. - * @param $contextid Modules contextid. - * @return $update Message: Successful. - */ public static function local_sync_service_add_files_to_directory($courseid, $itemid, $contextid) { global $CFG; - require_once($CFG->dirroot . '/mod/' . '/folder' . '/lib.php'); - - // Parameter validation. + require_once($CFG->dirroot . '/mod/folder/lib.php'); $params = self::validate_parameters( self::local_sync_service_add_files_to_directory_parameters(), + array('courseid' => $courseid, 'itemid' => $itemid, 'contextid' => $contextid) + ); + $context = context_course::instance($params['courseid']); + self::validate_context($context); + require_capability('mod/folder:managefiles', $context); + file_merge_files_from_draft_area_into_filearea($params['itemid'], $params['contextid'], 'mod_folder', 'content', 0); + + return ['message' => 'Successful']; + } + + public static function local_sync_service_add_files_to_directory_returns() { + return new external_single_structure( + array('message' => new external_value( PARAM_TEXT, 'if the execution was successful' )) + ); + } + + public static function local_sync_service_add_new_course_module_page_parameters() { + return new external_function_parameters( array( - 'courseid' => $courseid, - 'itemid' => $itemid, - 'contextid' => $contextid, + 'courseid' => new external_value( PARAM_TEXT, 'id of course' ), + 'sectionnum' => new external_value( PARAM_TEXT, 'relative number of the section' ), + 'displayname' => new external_value( PARAM_TEXT, 'displayed mod name' ), + 'content' => new external_value( PARAM_RAW, 'page content' ), + 'visible' => new external_value( PARAM_TEXT, 'defines the mod. visibility' ), + 'beforemod' => new external_value( PARAM_TEXT, 'mod to set before', VALUE_DEFAULT, null ), ) ); + } - // Ensure the current user has required permission in this course. + public static function local_sync_service_add_new_course_module_page($courseid, $sectionnum, $displayname, $content, $visible, $beforemod = null) { + global $DB, $CFG; + require_once($CFG->dirroot . '/mod/page/lib.php'); + $params = self::validate_parameters( + self::local_sync_service_add_new_course_module_page_parameters(), + array('courseid' => $courseid, 'sectionnum' => $sectionnum, 'displayname' => $displayname, 'content' => $content, 'visible' => $visible, 'beforemod' => $beforemod) + ); $context = context_course::instance($params['courseid']); self::validate_context($context); + require_capability('mod/page:addinstance', $context); - // Required permissions. - require_capability('mod/folder:managefiles', $context); + // Step 1: Create placeholder Course Module + $cm = new \stdClass(); + $cm->course = $params['courseid']; + $cm->module = $DB->get_field('modules', 'id', array('name' => 'page')); + $cm->instance = 0; + $cm->section = $params['sectionnum']; + $cm->visible = ($params['visible'] === 'true' || $params['visible'] === '1') ? 1 : 0; + $cm->id = add_course_module($cm); - file_merge_files_from_draft_area_into_filearea($params['itemid'], $params['contextid'], 'mod_folder', 'content', 0); + // Step 2: Create Page Instance with cmid + $instance = new \stdClass(); + $instance->course = $params['courseid']; + $instance->coursemodule = $cm->id; + $instance->name = $params['displayname']; + $instance->intro = ''; + $instance->introformat = FORMAT_HTML; + $instance->content = $params['content']; + $instance->contentformat = FORMAT_HTML; + $instance->legacyfiles = 0; + $instance->display = 0; // Default + $instance->printintro = 0; + $instance->printlastmodified = 0; + + $instance->id = page_add_instance($instance, null); + + // Step 3: Add CM to Section + course_add_cm_to_section($params['courseid'], $cm->id, $params['sectionnum'], $params['beforemod']); + + return array('message' => 'Successful', 'id' => (string)$cm->id); + } - $update = [ - 'message' => 'Successful', - ]; - return $update; + public static function local_sync_service_add_new_course_module_page_returns() { + return new external_single_structure( + array( + 'message' => new external_value( PARAM_TEXT, 'if the execution was successful' ), + 'id' => new external_value( PARAM_TEXT, 'cmid of the new module' ), + ) + ); } - /** - * Obtains the Parameter which will be returned. - * @return external_description - */ - public static function local_sync_service_add_files_to_directory_returns() { + public static function local_sync_service_add_new_course_module_label_parameters() { + return new external_function_parameters( + array( + 'courseid' => new external_value( PARAM_TEXT, 'id of course' ), + 'sectionnum' => new external_value( PARAM_TEXT, 'relative number of the section' ), + 'intro' => new external_value( PARAM_RAW, 'label content' ), + 'visible' => new external_value( PARAM_TEXT, 'defines the mod. visibility' ), + 'beforemod' => new external_value( PARAM_TEXT, 'mod to set before', VALUE_DEFAULT, null ), + ) + ); + } + + public static function local_sync_service_add_new_course_module_label($courseid, $sectionnum, $intro, $visible, $beforemod = null) { + global $DB, $CFG; + require_once($CFG->dirroot . '/mod/label/lib.php'); + $params = self::validate_parameters( + self::local_sync_service_add_new_course_module_label_parameters(), + array('courseid' => $courseid, 'sectionnum' => $sectionnum, 'intro' => $intro, 'visible' => $visible, 'beforemod' => $beforemod) + ); + $context = context_course::instance($params['courseid']); + self::validate_context($context); + require_capability('mod/label:addinstance', $context); + + $cm = new \stdClass(); + $cm->course = $params['courseid']; + $cm->module = $DB->get_field('modules', 'id', array('name' => 'label')); + $cm->instance = 0; + $cm->section = $params['sectionnum']; + $cm->visible = ($params['visible'] === 'true' || $params['visible'] === '1') ? 1 : 0; + $cm->id = add_course_module($cm); + + $instance = new \stdClass(); + $instance->course = $params['courseid']; + $instance->coursemodule = $cm->id; + $instance->name = shorten_text(strip_tags($params['intro']), 50); + $instance->intro = $params['intro']; + $instance->introformat = FORMAT_HTML; + $instance->id = label_add_instance($instance, null); + + // Update CM instance + $DB->set_field('course_modules', 'instance', $instance->id, array('id' => $cm->id)); + + course_add_cm_to_section($params['courseid'], $cm->id, $params['sectionnum'], $params['beforemod']); + + return array('message' => 'Successful', 'id' => (string)$cm->id); + } + + public static function local_sync_service_add_new_course_module_label_returns() { return new external_single_structure( array( 'message' => new external_value( PARAM_TEXT, 'if the execution was successful' ), - ) + 'id' => new external_value( PARAM_TEXT, 'cmid of the new module' ), + ) ); } } - diff --git a/version.php b/version.php index 6e7570e..d04626b 100644 --- a/version.php +++ b/version.php @@ -23,5 +23,5 @@ */ defined('MOODLE_INTERNAL') || die(); $plugin->component = 'local_sync_service'; -$plugin->version = 2024061800; +$plugin->version = 2024061803; $plugin->requires = 2021051704.00;