From 62e20cfed624ca645edfb6fd78ffe14e769e0f93 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Mon, 4 Apr 2016 15:57:05 +0200 Subject: [PATCH] MDL-53703 wiki: New WS mod_wiki_get_subwiki_files --- mod/wiki/classes/external.php | 205 +++++++++++++++++++++++++--------- mod/wiki/db/services.php | 9 ++ mod/wiki/locallib.php | 47 ++++++++ 3 files changed, 209 insertions(+), 52 deletions(-) diff --git a/mod/wiki/classes/external.php b/mod/wiki/classes/external.php index a142b85bc52..28576ebaabb 100644 --- a/mod/wiki/classes/external.php +++ b/mod/wiki/classes/external.php @@ -433,7 +433,6 @@ class mod_wiki_external extends external_api { * @since Moodle 3.1 */ public static function get_subwiki_pages($wikiid, $groupid = -1, $userid = 0, $options = array()) { - global $USER, $DB; $returnedpages = array(); $warnings = array(); @@ -455,58 +454,15 @@ class mod_wiki_external extends external_api { $context = context_module::instance($cm->id); self::validate_context($context); - // Determine group. - $groupmode = groups_get_activity_groupmode($cm); - if ($groupmode == NOGROUPS) { - $groupid = 0; - } else if ($params['groupid'] == -1) { - // Use current group. - $groupid = groups_get_activity_group($cm); - $groupid = !empty($groupid) ? $groupid : 0; - } else { - $groupid = $params['groupid']; - } - - // Determine user. - if ($wiki->wikimode == 'collaborative') { - // Collaborative wikis don't use userid in subwikis. - $userid = 0; - } else if (empty($params['userid'])) { - // Use current user. - $userid = $USER->id; - } else { - $userid = $params['userid']; - } - - // Get subwiki based on group and user. - if (!$subwiki = wiki_get_subwiki_by_group($cm->instance, $groupid, $userid)) { - // The subwiki doesn't exist. - // Validate if user is valid. - if ($userid != 0 && $userid != $USER->id && !$user = $DB->get_record('user', array('id' => $userid))) { - throw new moodle_exception('invaliduserid', 'error'); - } + // Determine groupid and userid to use. + list($groupid, $userid) = self::determine_group_and_user($cm, $wiki, $params['groupid'], $params['userid']); - // Validate that groupid is valid. - if ($groupid != 0 && !groups_group_exists($groupid)) { - throw new moodle_exception('cannotfindgroup', 'error'); - } - - // Valid data but subwiki not found. We'll simulate a subwiki object to check if the user would be able to see it - // if it existed. If he's able to see it then we'll return an empty array because the subwiki has no pages. - $subwiki = new stdClass(); - $subwiki->wikiid = $wiki->id; - $subwiki->userid = $userid; - $subwiki->groupid = $groupid; + // Get subwiki and validate it. + $subwiki = wiki_get_subwiki_by_group_and_user_with_validation($wiki, $groupid, $userid); - // Check that the user can view the subwiki. This function checks capabilities. - if (!wiki_user_can_view($subwiki, $wiki)) { - throw new moodle_exception('cannotviewpage', 'wiki'); - } - } else { - // Check that the user can view the subwiki. This function checks capabilities. - if (!wiki_user_can_view($subwiki, $wiki)) { - throw new moodle_exception('cannotviewpage', 'wiki'); - } + if ($subwiki === false) { + throw new moodle_exception('cannotviewpage', 'wiki'); + } else if ($subwiki->id != -1) { // Set sort param. $options = $params['options']; @@ -561,7 +517,6 @@ class mod_wiki_external extends external_api { $returnedpages[] = $retpage; } - } $result = array(); @@ -711,4 +666,150 @@ class mod_wiki_external extends external_api { ); } + /** + * Describes the parameters for get_subwiki_files. + * + * @return external_function_parameters + * @since Moodle 3.1 + */ + public static function get_subwiki_files_parameters() { + return new external_function_parameters ( + array( + 'wikiid' => new external_value(PARAM_INT, 'Wiki instance ID.'), + 'groupid' => new external_value(PARAM_INT, 'Subwiki\'s group ID, -1 means current group. It will be ignored' + . ' if the wiki doesn\'t use groups.', VALUE_DEFAULT, -1), + 'userid' => new external_value(PARAM_INT, 'Subwiki\'s user ID, 0 means current user. It will be ignored' + .' in collaborative wikis.', VALUE_DEFAULT, 0) + ) + ); + } + + /** + * Returns the list of files from a specific subwiki. + * + * @param int $wikiid The wiki instance ID. + * @param int $groupid The group ID. If not defined, use current group. + * @param int $userid The user ID. If not defined, use current user. + * @return array Containing a list of warnings and a list of files. + * @since Moodle 3.1 + * @throws moodle_exception + */ + public static function get_subwiki_files($wikiid, $groupid = -1, $userid = 0) { + + $returnedfiles = array(); + $warnings = array(); + + $params = self::validate_parameters(self::get_subwiki_files_parameters(), + array( + 'wikiid' => $wikiid, + 'groupid' => $groupid, + 'userid' => $userid + ) + ); + + // Get wiki instance. + if (!$wiki = wiki_get_wiki($params['wikiid'])) { + throw new moodle_exception('incorrectwikiid', 'wiki'); + } + list($course, $cm) = get_course_and_cm_from_instance($wiki, 'wiki'); + $context = context_module::instance($cm->id); + self::validate_context($context); + + // Determine groupid and userid to use. + list($groupid, $userid) = self::determine_group_and_user($cm, $wiki, $params['groupid'], $params['userid']); + + // Get subwiki and validate it. + $subwiki = wiki_get_subwiki_by_group_and_user_with_validation($wiki, $groupid, $userid); + + // Get subwiki based on group and user. + if ($subwiki === false) { + throw new moodle_exception('cannotviewfiles', 'wiki'); + } else if ($subwiki->id != -1) { + // The subwiki exists, let's get the files. + $fs = get_file_storage(); + if ($files = $fs->get_area_files($context->id, 'mod_wiki', 'attachments', $subwiki->id, 'filename', false)) { + foreach ($files as $file) { + $filename = $file->get_filename(); + $fileurl = moodle_url::make_webservice_pluginfile_url( + $context->id, 'mod_wiki', 'attachments', $subwiki->id, '/', $filename); + + $returnedfiles[] = array( + 'filename' => $filename, + 'mimetype' => $file->get_mimetype(), + 'fileurl' => $fileurl->out(false), + 'filepath' => $file->get_filepath(), + 'filesize' => $file->get_filesize(), + 'timemodified' => $file->get_timemodified() + ); + } + } + } + + $result = array(); + $result['files'] = $returnedfiles; + $result['warnings'] = $warnings; + return $result; + } + + /** + * Describes the get_subwiki_pages return value. + * + * @return external_single_structure + * @since Moodle 3.1 + */ + public static function get_subwiki_files_returns() { + + return new external_single_structure( + array( + 'files' => new external_multiple_structure( + new external_single_structure( + array( + 'filename' => new external_value(PARAM_FILE, 'File name.'), + 'filepath' => new external_value(PARAM_PATH, 'File path.'), + 'filesize' => new external_value(PARAM_INT, 'File size.'), + 'fileurl' => new external_value(PARAM_URL, 'Downloadable file url.'), + 'timemodified' => new external_value(PARAM_INT, 'Time modified.'), + 'mimetype' => new external_value(PARAM_RAW, 'File mime type.'), + ), 'Files' + ) + ), + 'warnings' => new external_warnings(), + ) + ); + } + + /** + * Utility function for determining the groupid and userid to use. + * + * @param stdClass $cm The course module. + * @param stdClass $wiki The wiki. + * @param int $groupid Group ID. If not defined, use current group. + * @param int $userid User ID. If not defined, use current user. + * @return array Array containing the courseid and userid. + * @since Moodle 3.1 + */ + protected static function determine_group_and_user($cm, $wiki, $groupid = -1, $userid = 0) { + global $USER; + + $currentgroup = groups_get_activity_group($cm); + if ($currentgroup === false) { + // Activity doesn't use groups. + $groupid = 0; + } else if ($groupid == -1) { + // Use current group. + $groupid = !empty($currentgroup) ? $currentgroup : 0; + } + + // Determine user. + if ($wiki->wikimode == 'collaborative') { + // Collaborative wikis don't use userid in subwikis. + $userid = 0; + } else if (empty($userid)) { + // Use current user. + $userid = $USER->id; + } + + return array($groupid, $userid); + } + } diff --git a/mod/wiki/db/services.php b/mod/wiki/db/services.php index 396e572fb61..d86be2b81e1 100644 --- a/mod/wiki/db/services.php +++ b/mod/wiki/db/services.php @@ -71,6 +71,15 @@ $functions = array( 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) ), + 'mod_wiki_get_subwiki_files' => array( + 'classname' => 'mod_wiki_external', + 'methodname' => 'get_subwiki_files', + 'description' => 'Returns the list of files for a specific subwiki.', + 'type' => 'read', + 'capabilities' => 'mod/wiki:viewpage', + 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE) + ), + 'mod_wiki_get_page_contents' => array( 'classname' => 'mod_wiki_external', 'methodname' => 'get_page_contents', diff --git a/mod/wiki/locallib.php b/mod/wiki/locallib.php index 9162b384ecd..d1c04cd2f92 100644 --- a/mod/wiki/locallib.php +++ b/mod/wiki/locallib.php @@ -1687,3 +1687,50 @@ function wiki_get_visible_subwikis($wiki, $cm = null, $context = null) { return $subwikis; } + +/** + * Utility function for getting a subwiki by group and user, validating that the user can view it. + * If the subwiki doesn't exists in DB yet it'll have id -1. + * + * @param stdClass $wiki The wiki. + * @param int $groupid Group ID. 0 means the subwiki doesn't use groups. + * @param int $userid User ID. 0 means the subwiki doesn't use users. + * @return stdClass Subwiki. If it doesn't exists in DB yet it'll have id -1. If the user can't view the + * subwiki this function will return false. + * @since Moodle 3.1 + * @throws moodle_exception + */ +function wiki_get_subwiki_by_group_and_user_with_validation($wiki, $groupid, $userid) { + global $USER, $DB; + + // Get subwiki based on group and user. + if (!$subwiki = wiki_get_subwiki_by_group($wiki->id, $groupid, $userid)) { + + // The subwiki doesn't exist. + // Validate if user is valid. + if ($userid != 0) { + $user = core_user::get_user($userid, '*', MUST_EXIST); + core_user::require_active_user($user); + } + + // Validate that groupid is valid. + if ($groupid != 0 && !groups_group_exists($groupid)) { + throw new moodle_exception('cannotfindgroup', 'error'); + } + + // Valid data but subwiki not found. We'll simulate a subwiki object to check if the user would be able to see it + // if it existed. If he's able to see it then we'll return an empty array because the subwiki has no pages. + $subwiki = new stdClass(); + $subwiki->id = -1; + $subwiki->wikiid = $wiki->id; + $subwiki->userid = $userid; + $subwiki->groupid = $groupid; + } + + // Check that the user can view the subwiki. This function checks capabilities. + if (!wiki_user_can_view($subwiki, $wiki)) { + return false; + } + + return $subwiki; +} -- 2.43.0