MDL-53703 wiki: New WS mod_wiki_get_subwiki_files
authorDani Palou <dani@moodle.com>
Mon, 4 Apr 2016 13:57:05 +0000 (15:57 +0200)
committerDani Palou <dani@moodle.com>
Mon, 11 Apr 2016 09:13:01 +0000 (11:13 +0200)
mod/wiki/classes/external.php
mod/wiki/db/services.php
mod/wiki/locallib.php

index a142b85..28576eb 100644 (file)
@@ -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);
+    }
+
 }
index 396e572..d86be2b 100644 (file)
@@ -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',
index 9162b38..d1c04cd 100644 (file)
@@ -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;
+}