From 7c51b40ab135f953b9a79f21f008a97806bc9b3e Mon Sep 17 00:00:00 2001 From: Juan Leyva Date: Thu, 2 Oct 2014 12:22:43 +0200 Subject: [PATCH] MDL-46458 forum: New WS get_forum_discussions_paginated --- mod/forum/externallib.php | 233 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) diff --git a/mod/forum/externallib.php b/mod/forum/externallib.php index 98b144cd4f9..3fc4b6940ca 100644 --- a/mod/forum/externallib.php +++ b/mod/forum/externallib.php @@ -520,4 +520,237 @@ class mod_forum_external extends external_api { ); } + /** + * Describes the parameters for get_forum_discussions_paginated. + * + * @return external_external_function_parameters + * @since Moodle 2.8 + */ + public static function get_forum_discussions_paginated_parameters() { + return new external_function_parameters ( + array( + 'forumid' => new external_value(PARAM_INT, 'forum instance id', VALUE_REQUIRED), + 'sortby' => new external_value(PARAM_ALPHA, + 'sort by this element: id, timemodified, timestart or timeend', VALUE_DEFAULT, 'timemodified'), + 'sortdirection' => new external_value(PARAM_ALPHA, 'sort direction: ASC or DESC', VALUE_DEFAULT, 'DESC'), + 'page' => new external_value(PARAM_INT, 'current page', VALUE_DEFAULT, -1), + 'perpage' => new external_value(PARAM_INT, 'items per page', VALUE_DEFAULT, 0), + ) + ); + } + + /** + * Returns a list of forum discussions optionally sorted and paginated. + * + * @param int $forumid the forum instance id + * @param string $sortby sort by this element (id, timemodified, timestart or timeend) + * @param string $sortdirection sort direction: ASC or DESC + * @param int $page page number + * @param int $perpage items per page + * + * @return array the forum discussion details including warnings + * @since Moodle 2.8 + */ + public static function get_forum_discussions_paginated($forumid, $sortby = 'timemodified', $sortdirection = 'DESC', + $page = -1, $perpage = 0) { + global $CFG, $DB, $USER; + + require_once($CFG->dirroot . "/mod/forum/lib.php"); + + $warnings = array(); + + $params = self::validate_parameters(self::get_forum_discussions_paginated_parameters(), + array( + 'forumid' => $forumid, + 'sortby' => $sortby, + 'sortdirection' => $sortdirection, + 'page' => $page, + 'perpage' => $perpage + ) + ); + + // Compact/extract functions are not recommended. + $forumid = $params['forumid']; + $sortby = $params['sortby']; + $sortdirection = $params['sortdirection']; + $page = $params['page']; + $perpage = $params['perpage']; + + $sortallowedvalues = array('id', 'timemodified', 'timestart', 'timeend'); + if (!in_array($sortby, $sortallowedvalues)) { + throw new invalid_parameter_exception('Invalid value for sortby parameter (value: ' . $sortby . '),' . + 'allowed values are: ' . implode(',', $sortallowedvalues)); + } + + $sortdirection = strtoupper($sortdirection); + $directionallowedvalues = array('ASC', 'DESC'); + if (!in_array($sortdirection, $directionallowedvalues)) { + throw new invalid_parameter_exception('Invalid value for sortdirection parameter (value: ' . $sortdirection . '),' . + 'allowed values are: ' . implode(',', $directionallowedvalues)); + } + + $forum = $DB->get_record('forum', array('id' => $forumid), '*', MUST_EXIST); + $course = $DB->get_record('course', array('id' => $forum->course), '*', MUST_EXIST); + $cm = get_coursemodule_from_instance('forum', $forum->id, $course->id, false, MUST_EXIST); + + // Validate the module context. It checks everything that affects the module visibility (including groupings, etc..). + $modcontext = context_module::instance($cm->id); + self::validate_context($modcontext); + + // Check they have the view forum capability. + require_capability('mod/forum:viewdiscussion', $modcontext, null, true, 'noviewdiscussionspermission', 'forum'); + + $sort = 'd.' . $sortby . ' ' . $sortdirection; + $discussions = forum_get_discussions($cm, $sort, true, -1, -1, true, $page, $perpage); + + if ($discussions) { + $canviewfullname = has_capability('moodle/site:viewfullnames', $modcontext); + + // Get the unreads array, this takes a forum id and returns data for all discussions. + $unreads = array(); + if ($cantrack = forum_tp_can_track_forums($forum)) { + if ($forumtracked = forum_tp_is_tracked($forum)) { + $unreads = forum_get_discussions_unread($cm); + } + } + // The forum function returns the replies for all the discussions in a given forum. + $replies = forum_count_discussion_replies($forumid, $sort, -1, $page, $perpage); + + foreach ($discussions as $did => $discussion) { + // This function checks for qanda forums. + if (!forum_user_can_see_discussion($forum, $discussion, $modcontext)) { + $warning = array(); + // Function forum_get_discussions returns forum_posts ids not forum_discussions ones. + $warning['item'] = 'post'; + $warning['itemid'] = $discussion->id; + $warning['warningcode'] = '1'; + $warning['message'] = 'You can\'t see this discussion'; + $warnings[] = $warning; + continue; + } + + $discussion->numunread = 0; + if ($cantrack && $forumtracked) { + if (isset($unreads[$discussion->discussion])) { + $discussion->numunread = (int) $unreads[$discussion->discussion]; + } + } + + $discussion->numreplies = 0; + if (!empty($replies[$discussion->discussion])) { + $discussion->numreplies = (int) $replies[$discussion->discussion]->replies; + } + + // Load user objects from the results of the query. + $user = new stdclass(); + $user->id = $discussion->userid; + $user = username_load_fields_from_object($user, $discussion); + $discussion->userfullname = fullname($user, $canviewfullname); + $discussion->userpictureurl = moodle_url::make_pluginfile_url( + context_user::instance($user->id)->id, 'user', 'icon', null, '/', 'f1'); + // Fix the pluginfile.php link. + $discussion->userpictureurl = str_replace("pluginfile.php", "webservice/pluginfile.php", + $discussion->userpictureurl); + + $usermodified = new stdclass(); + $usermodified->id = $discussion->usermodified; + $usermodified = username_load_fields_from_object($usermodified, $discussion, 'um'); + $discussion->usermodifiedfullname = fullname($usermodified, $canviewfullname); + $discussion->usermodifiedpictureurl = moodle_url::make_pluginfile_url( + context_user::instance($usermodified->id)->id, 'user', 'icon', null, '/', 'f1'); + // Fix the pluginfile.php link. + $discussion->usermodifiedpictureurl = str_replace("pluginfile.php", "webservice/pluginfile.php", + $discussion->usermodifiedpictureurl); + + // Rewrite embedded images URLs. + list($discussion->message, $discussion->messageformat) = + external_format_text($discussion->message, $discussion->messageformat, + $modcontext->id, 'mod_forum', 'post', $discussion->id); + + // List attachments. + if (!empty($discussion->attachment)) { + $discussion->attachments = array(); + + $fs = get_file_storage(); + if ($files = $fs->get_area_files($modcontext->id, 'mod_forum', 'attachment', + $discussion->id, "filename", false)) { + foreach ($files as $file) { + $filename = $file->get_filename(); + + $discussion->attachments[] = array( + 'filename' => $filename, + 'mimetype' => $file->get_mimetype(), + 'fileurl' => file_encode_url($CFG->wwwroot.'/webservice/pluginfile.php', + '/'.$modcontext->id.'/mod_forum/attachment/'.$discussion->id.'/'.$filename) + ); + } + } + } + + $discussions[$did] = (array) $discussion; + } + } + + $result = array(); + $result['discussions'] = $discussions; + $result['warnings'] = $warnings; + return $result; + + } + + /** + * Describes the get_forum_discussions_paginated return value. + * + * @return external_single_structure + * @since Moodle 2.8 + */ + public static function get_forum_discussions_paginated_returns() { + return new external_single_structure( + array( + 'discussions' => new external_multiple_structure( + new external_single_structure( + array( + 'id' => new external_value(PARAM_INT, 'Post id'), + 'name' => new external_value(PARAM_TEXT, 'Discussion name'), + 'groupid' => new external_value(PARAM_INT, 'Group id'), + 'timemodified' => new external_value(PARAM_INT, 'Time modified'), + 'usermodified' => new external_value(PARAM_INT, 'The id of the user who last modified'), + 'timestart' => new external_value(PARAM_INT, 'Time discussion can start'), + 'timeend' => new external_value(PARAM_INT, 'Time discussion ends'), + 'discussion' => new external_value(PARAM_INT, 'Discussion id'), + 'parent' => new external_value(PARAM_INT, 'Parent id'), + 'userid' => new external_value(PARAM_INT, 'User who started the discussion id'), + 'created' => new external_value(PARAM_INT, 'Creation time'), + 'modified' => new external_value(PARAM_INT, 'Time modified'), + 'mailed' => new external_value(PARAM_INT, 'Mailed?'), + 'subject' => new external_value(PARAM_TEXT, 'The post subject'), + 'message' => new external_value(PARAM_RAW, 'The post message'), + 'messageformat' => new external_format_value('message'), + 'messagetrust' => new external_value(PARAM_INT, 'Can we trust?'), + 'attachment' => new external_value(PARAM_RAW, 'Has attachments?'), + 'attachments' => new external_multiple_structure( + new external_single_structure( + array ( + 'filename' => new external_value(PARAM_FILE, 'file name'), + 'mimetype' => new external_value(PARAM_RAW, 'mime type'), + 'fileurl' => new external_value(PARAM_URL, 'file download url') + ) + ), 'attachments', VALUE_OPTIONAL + ), + 'totalscore' => new external_value(PARAM_INT, 'The post message total score'), + 'mailnow' => new external_value(PARAM_INT, 'Mail now?'), + 'userfullname' => new external_value(PARAM_TEXT, 'Post author full name'), + 'usermodifiedfullname' => new external_value(PARAM_TEXT, 'Post modifier full name'), + 'userpictureurl' => new external_value(PARAM_URL, 'Post author picture.'), + 'usermodifiedpictureurl' => new external_value(PARAM_URL, 'Post modifier picture.'), + 'numreplies' => new external_value(PARAM_TEXT, 'The number of replies in the discussion'), + 'numunread' => new external_value(PARAM_INT, 'The number of unread discussions.') + ), 'post' + ) + ), + 'warnings' => new external_warnings() + ) + ); + } + }