[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 3 // This file is part of Moodle - http://moodle.org/ 4 // 5 // Moodle is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // Moodle is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 17 18 /** 19 * External forum API 20 * 21 * @package mod_forum 22 * @copyright 2012 Mark Nelson <markn@moodle.com> 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 defined('MOODLE_INTERNAL') || die; 27 28 require_once("$CFG->libdir/externallib.php"); 29 30 class mod_forum_external extends external_api { 31 32 /** 33 * Describes the parameters for get_forum. 34 * 35 * @return external_external_function_parameters 36 * @since Moodle 2.5 37 */ 38 public static function get_forums_by_courses_parameters() { 39 return new external_function_parameters ( 40 array( 41 'courseids' => new external_multiple_structure(new external_value(PARAM_INT, 'course ID', 42 VALUE_REQUIRED, '', NULL_NOT_ALLOWED), 'Array of Course IDs', VALUE_DEFAULT, array()), 43 ) 44 ); 45 } 46 47 /** 48 * Returns a list of forums in a provided list of courses, 49 * if no list is provided all forums that the user can view 50 * will be returned. 51 * 52 * @param array $courseids the course ids 53 * @return array the forum details 54 * @since Moodle 2.5 55 */ 56 public static function get_forums_by_courses($courseids = array()) { 57 global $CFG; 58 59 require_once($CFG->dirroot . "/mod/forum/lib.php"); 60 61 $params = self::validate_parameters(self::get_forums_by_courses_parameters(), array('courseids' => $courseids)); 62 63 $courses = array(); 64 if (empty($params['courseids'])) { 65 $courses = enrol_get_my_courses(); 66 $params['courseids'] = array_keys($courses); 67 } 68 69 // Array to store the forums to return. 70 $arrforums = array(); 71 $warnings = array(); 72 73 // Ensure there are courseids to loop through. 74 if (!empty($params['courseids'])) { 75 76 list($courses, $warnings) = external_util::validate_courses($params['courseids'], $courses); 77 78 // Get the forums in this course. This function checks users visibility permissions. 79 $forums = get_all_instances_in_courses("forum", $courses); 80 foreach ($forums as $forum) { 81 82 $course = $courses[$forum->course]; 83 $cm = get_coursemodule_from_instance('forum', $forum->id, $course->id); 84 $context = context_module::instance($cm->id); 85 86 // Skip forums we are not allowed to see discussions. 87 if (!has_capability('mod/forum:viewdiscussion', $context)) { 88 continue; 89 } 90 91 $forum->name = external_format_string($forum->name, $context->id); 92 // Format the intro before being returning using the format setting. 93 list($forum->intro, $forum->introformat) = external_format_text($forum->intro, $forum->introformat, 94 $context->id, 'mod_forum', 'intro', 0); 95 $forum->introfiles = external_util::get_area_files($context->id, 'mod_forum', 'intro', false, false); 96 // Discussions count. This function does static request cache. 97 $forum->numdiscussions = forum_count_discussions($forum, $cm, $course); 98 $forum->cmid = $forum->coursemodule; 99 $forum->cancreatediscussions = forum_user_can_post_discussion($forum, null, -1, $cm, $context); 100 101 // Add the forum to the array to return. 102 $arrforums[$forum->id] = $forum; 103 } 104 } 105 106 return $arrforums; 107 } 108 109 /** 110 * Describes the get_forum return value. 111 * 112 * @return external_single_structure 113 * @since Moodle 2.5 114 */ 115 public static function get_forums_by_courses_returns() { 116 return new external_multiple_structure( 117 new external_single_structure( 118 array( 119 'id' => new external_value(PARAM_INT, 'Forum id'), 120 'course' => new external_value(PARAM_INT, 'Course id'), 121 'type' => new external_value(PARAM_TEXT, 'The forum type'), 122 'name' => new external_value(PARAM_RAW, 'Forum name'), 123 'intro' => new external_value(PARAM_RAW, 'The forum intro'), 124 'introformat' => new external_format_value('intro'), 125 'introfiles' => new external_files('Files in the introduction text', VALUE_OPTIONAL), 126 'assessed' => new external_value(PARAM_INT, 'Aggregate type'), 127 'assesstimestart' => new external_value(PARAM_INT, 'Assess start time'), 128 'assesstimefinish' => new external_value(PARAM_INT, 'Assess finish time'), 129 'scale' => new external_value(PARAM_INT, 'Scale'), 130 'maxbytes' => new external_value(PARAM_INT, 'Maximum attachment size'), 131 'maxattachments' => new external_value(PARAM_INT, 'Maximum number of attachments'), 132 'forcesubscribe' => new external_value(PARAM_INT, 'Force users to subscribe'), 133 'trackingtype' => new external_value(PARAM_INT, 'Subscription mode'), 134 'rsstype' => new external_value(PARAM_INT, 'RSS feed for this activity'), 135 'rssarticles' => new external_value(PARAM_INT, 'Number of RSS recent articles'), 136 'timemodified' => new external_value(PARAM_INT, 'Time modified'), 137 'warnafter' => new external_value(PARAM_INT, 'Post threshold for warning'), 138 'blockafter' => new external_value(PARAM_INT, 'Post threshold for blocking'), 139 'blockperiod' => new external_value(PARAM_INT, 'Time period for blocking'), 140 'completiondiscussions' => new external_value(PARAM_INT, 'Student must create discussions'), 141 'completionreplies' => new external_value(PARAM_INT, 'Student must post replies'), 142 'completionposts' => new external_value(PARAM_INT, 'Student must post discussions or replies'), 143 'cmid' => new external_value(PARAM_INT, 'Course module id'), 144 'numdiscussions' => new external_value(PARAM_INT, 'Number of discussions in the forum', VALUE_OPTIONAL), 145 'cancreatediscussions' => new external_value(PARAM_BOOL, 'If the user can create discussions', VALUE_OPTIONAL), 146 ), 'forum' 147 ) 148 ); 149 } 150 151 /** 152 * Describes the parameters for get_forum_discussion_posts. 153 * 154 * @return external_external_function_parameters 155 * @since Moodle 2.7 156 */ 157 public static function get_forum_discussion_posts_parameters() { 158 return new external_function_parameters ( 159 array( 160 'discussionid' => new external_value(PARAM_INT, 'discussion ID', VALUE_REQUIRED), 161 'sortby' => new external_value(PARAM_ALPHA, 162 'sort by this element: id, created or modified', VALUE_DEFAULT, 'created'), 163 'sortdirection' => new external_value(PARAM_ALPHA, 'sort direction: ASC or DESC', VALUE_DEFAULT, 'DESC') 164 ) 165 ); 166 } 167 168 /** 169 * Returns a list of forum posts for a discussion 170 * 171 * @param int $discussionid the post ids 172 * @param string $sortby sort by this element (id, created or modified) 173 * @param string $sortdirection sort direction: ASC or DESC 174 * 175 * @return array the forum post details 176 * @since Moodle 2.7 177 */ 178 public static function get_forum_discussion_posts($discussionid, $sortby = "created", $sortdirection = "DESC") { 179 global $CFG, $DB, $USER, $PAGE; 180 181 $posts = array(); 182 $warnings = array(); 183 184 // Validate the parameter. 185 $params = self::validate_parameters(self::get_forum_discussion_posts_parameters(), 186 array( 187 'discussionid' => $discussionid, 188 'sortby' => $sortby, 189 'sortdirection' => $sortdirection)); 190 191 // Compact/extract functions are not recommended. 192 $discussionid = $params['discussionid']; 193 $sortby = $params['sortby']; 194 $sortdirection = $params['sortdirection']; 195 196 $sortallowedvalues = array('id', 'created', 'modified'); 197 if (!in_array($sortby, $sortallowedvalues)) { 198 throw new invalid_parameter_exception('Invalid value for sortby parameter (value: ' . $sortby . '),' . 199 'allowed values are: ' . implode(',', $sortallowedvalues)); 200 } 201 202 $sortdirection = strtoupper($sortdirection); 203 $directionallowedvalues = array('ASC', 'DESC'); 204 if (!in_array($sortdirection, $directionallowedvalues)) { 205 throw new invalid_parameter_exception('Invalid value for sortdirection parameter (value: ' . $sortdirection . '),' . 206 'allowed values are: ' . implode(',', $directionallowedvalues)); 207 } 208 209 $discussion = $DB->get_record('forum_discussions', array('id' => $discussionid), '*', MUST_EXIST); 210 $forum = $DB->get_record('forum', array('id' => $discussion->forum), '*', MUST_EXIST); 211 $course = $DB->get_record('course', array('id' => $forum->course), '*', MUST_EXIST); 212 $cm = get_coursemodule_from_instance('forum', $forum->id, $course->id, false, MUST_EXIST); 213 214 // Validate the module context. It checks everything that affects the module visibility (including groupings, etc..). 215 $modcontext = context_module::instance($cm->id); 216 self::validate_context($modcontext); 217 218 // This require must be here, see mod/forum/discuss.php. 219 require_once($CFG->dirroot . "/mod/forum/lib.php"); 220 221 // Check they have the view forum capability. 222 require_capability('mod/forum:viewdiscussion', $modcontext, null, true, 'noviewdiscussionspermission', 'forum'); 223 224 if (! $post = forum_get_post_full($discussion->firstpost)) { 225 throw new moodle_exception('notexists', 'forum'); 226 } 227 228 // This function check groups, qanda, timed discussions, etc. 229 if (!forum_user_can_see_post($forum, $discussion, $post, null, $cm)) { 230 throw new moodle_exception('noviewdiscussionspermission', 'forum'); 231 } 232 233 $canviewfullname = has_capability('moodle/site:viewfullnames', $modcontext); 234 235 // We will add this field in the response. 236 $canreply = forum_user_can_post($forum, $discussion, $USER, $cm, $course, $modcontext); 237 238 $forumtracked = forum_tp_is_tracked($forum); 239 240 $sort = 'p.' . $sortby . ' ' . $sortdirection; 241 $allposts = forum_get_all_discussion_posts($discussion->id, $sort, $forumtracked); 242 243 foreach ($allposts as $post) { 244 245 if (!forum_user_can_see_post($forum, $discussion, $post, null, $cm)) { 246 $warning = array(); 247 $warning['item'] = 'post'; 248 $warning['itemid'] = $post->id; 249 $warning['warningcode'] = '1'; 250 $warning['message'] = 'You can\'t see this post'; 251 $warnings[] = $warning; 252 continue; 253 } 254 255 // Function forum_get_all_discussion_posts adds postread field. 256 // Note that the value returned can be a boolean or an integer. The WS expects a boolean. 257 if (empty($post->postread)) { 258 $post->postread = false; 259 } else { 260 $post->postread = true; 261 } 262 263 $post->canreply = $canreply; 264 if (!empty($post->children)) { 265 $post->children = array_keys($post->children); 266 } else { 267 $post->children = array(); 268 } 269 270 $user = new stdclass(); 271 $user->id = $post->userid; 272 $user = username_load_fields_from_object($user, $post, null, array('picture', 'imagealt', 'email')); 273 $post->userfullname = fullname($user, $canviewfullname); 274 275 $userpicture = new user_picture($user); 276 $userpicture->size = 1; // Size f1. 277 $post->userpictureurl = $userpicture->get_url($PAGE)->out(false); 278 279 $post->subject = external_format_string($post->subject, $modcontext->id); 280 // Rewrite embedded images URLs. 281 list($post->message, $post->messageformat) = 282 external_format_text($post->message, $post->messageformat, $modcontext->id, 'mod_forum', 'post', $post->id); 283 284 // List attachments. 285 if (!empty($post->attachment)) { 286 $post->attachments = external_util::get_area_files($modcontext->id, 'mod_forum', 'attachment', $post->id); 287 } 288 289 $posts[] = $post; 290 } 291 292 $result = array(); 293 $result['posts'] = $posts; 294 $result['warnings'] = $warnings; 295 return $result; 296 } 297 298 /** 299 * Describes the get_forum_discussion_posts return value. 300 * 301 * @return external_single_structure 302 * @since Moodle 2.7 303 */ 304 public static function get_forum_discussion_posts_returns() { 305 return new external_single_structure( 306 array( 307 'posts' => new external_multiple_structure( 308 new external_single_structure( 309 array( 310 'id' => new external_value(PARAM_INT, 'Post id'), 311 'discussion' => new external_value(PARAM_INT, 'Discussion id'), 312 'parent' => new external_value(PARAM_INT, 'Parent id'), 313 'userid' => new external_value(PARAM_INT, 'User id'), 314 'created' => new external_value(PARAM_INT, 'Creation time'), 315 'modified' => new external_value(PARAM_INT, 'Time modified'), 316 'mailed' => new external_value(PARAM_INT, 'Mailed?'), 317 'subject' => new external_value(PARAM_TEXT, 'The post subject'), 318 'message' => new external_value(PARAM_RAW, 'The post message'), 319 'messageformat' => new external_format_value('message'), 320 'messagetrust' => new external_value(PARAM_INT, 'Can we trust?'), 321 'attachment' => new external_value(PARAM_RAW, 'Has attachments?'), 322 'attachments' => new external_files('attachments', VALUE_OPTIONAL), 323 'totalscore' => new external_value(PARAM_INT, 'The post message total score'), 324 'mailnow' => new external_value(PARAM_INT, 'Mail now?'), 325 'children' => new external_multiple_structure(new external_value(PARAM_INT, 'children post id')), 326 'canreply' => new external_value(PARAM_BOOL, 'The user can reply to posts?'), 327 'postread' => new external_value(PARAM_BOOL, 'The post was read'), 328 'userfullname' => new external_value(PARAM_TEXT, 'Post author full name'), 329 'userpictureurl' => new external_value(PARAM_URL, 'Post author picture.', VALUE_OPTIONAL) 330 ), 'post' 331 ) 332 ), 333 'warnings' => new external_warnings() 334 ) 335 ); 336 } 337 338 /** 339 * Describes the parameters for get_forum_discussions_paginated. 340 * 341 * @return external_external_function_parameters 342 * @since Moodle 2.8 343 */ 344 public static function get_forum_discussions_paginated_parameters() { 345 return new external_function_parameters ( 346 array( 347 'forumid' => new external_value(PARAM_INT, 'forum instance id', VALUE_REQUIRED), 348 'sortby' => new external_value(PARAM_ALPHA, 349 'sort by this element: id, timemodified, timestart or timeend', VALUE_DEFAULT, 'timemodified'), 350 'sortdirection' => new external_value(PARAM_ALPHA, 'sort direction: ASC or DESC', VALUE_DEFAULT, 'DESC'), 351 'page' => new external_value(PARAM_INT, 'current page', VALUE_DEFAULT, -1), 352 'perpage' => new external_value(PARAM_INT, 'items per page', VALUE_DEFAULT, 0), 353 ) 354 ); 355 } 356 357 /** 358 * Returns a list of forum discussions optionally sorted and paginated. 359 * 360 * @param int $forumid the forum instance id 361 * @param string $sortby sort by this element (id, timemodified, timestart or timeend) 362 * @param string $sortdirection sort direction: ASC or DESC 363 * @param int $page page number 364 * @param int $perpage items per page 365 * 366 * @return array the forum discussion details including warnings 367 * @since Moodle 2.8 368 */ 369 public static function get_forum_discussions_paginated($forumid, $sortby = 'timemodified', $sortdirection = 'DESC', 370 $page = -1, $perpage = 0) { 371 global $CFG, $DB, $USER, $PAGE; 372 373 require_once($CFG->dirroot . "/mod/forum/lib.php"); 374 375 $warnings = array(); 376 $discussions = array(); 377 378 $params = self::validate_parameters(self::get_forum_discussions_paginated_parameters(), 379 array( 380 'forumid' => $forumid, 381 'sortby' => $sortby, 382 'sortdirection' => $sortdirection, 383 'page' => $page, 384 'perpage' => $perpage 385 ) 386 ); 387 388 // Compact/extract functions are not recommended. 389 $forumid = $params['forumid']; 390 $sortby = $params['sortby']; 391 $sortdirection = $params['sortdirection']; 392 $page = $params['page']; 393 $perpage = $params['perpage']; 394 395 $sortallowedvalues = array('id', 'timemodified', 'timestart', 'timeend'); 396 if (!in_array($sortby, $sortallowedvalues)) { 397 throw new invalid_parameter_exception('Invalid value for sortby parameter (value: ' . $sortby . '),' . 398 'allowed values are: ' . implode(',', $sortallowedvalues)); 399 } 400 401 $sortdirection = strtoupper($sortdirection); 402 $directionallowedvalues = array('ASC', 'DESC'); 403 if (!in_array($sortdirection, $directionallowedvalues)) { 404 throw new invalid_parameter_exception('Invalid value for sortdirection parameter (value: ' . $sortdirection . '),' . 405 'allowed values are: ' . implode(',', $directionallowedvalues)); 406 } 407 408 $forum = $DB->get_record('forum', array('id' => $forumid), '*', MUST_EXIST); 409 $course = $DB->get_record('course', array('id' => $forum->course), '*', MUST_EXIST); 410 $cm = get_coursemodule_from_instance('forum', $forum->id, $course->id, false, MUST_EXIST); 411 412 // Validate the module context. It checks everything that affects the module visibility (including groupings, etc..). 413 $modcontext = context_module::instance($cm->id); 414 self::validate_context($modcontext); 415 416 // Check they have the view forum capability. 417 require_capability('mod/forum:viewdiscussion', $modcontext, null, true, 'noviewdiscussionspermission', 'forum'); 418 419 $sort = 'd.pinned DESC, d.' . $sortby . ' ' . $sortdirection; 420 $alldiscussions = forum_get_discussions($cm, $sort, true, -1, -1, true, $page, $perpage, FORUM_POSTS_ALL_USER_GROUPS); 421 422 if ($alldiscussions) { 423 $canviewfullname = has_capability('moodle/site:viewfullnames', $modcontext); 424 425 // Get the unreads array, this takes a forum id and returns data for all discussions. 426 $unreads = array(); 427 if ($cantrack = forum_tp_can_track_forums($forum)) { 428 if ($forumtracked = forum_tp_is_tracked($forum)) { 429 $unreads = forum_get_discussions_unread($cm); 430 } 431 } 432 // The forum function returns the replies for all the discussions in a given forum. 433 $replies = forum_count_discussion_replies($forumid, $sort, -1, $page, $perpage); 434 435 foreach ($alldiscussions as $discussion) { 436 437 // This function checks for qanda forums. 438 // Note that the forum_get_discussions returns as id the post id, not the discussion id so we need to do this. 439 $discussionrec = clone $discussion; 440 $discussionrec->id = $discussion->discussion; 441 if (!forum_user_can_see_discussion($forum, $discussionrec, $modcontext)) { 442 $warning = array(); 443 // Function forum_get_discussions returns forum_posts ids not forum_discussions ones. 444 $warning['item'] = 'post'; 445 $warning['itemid'] = $discussion->id; 446 $warning['warningcode'] = '1'; 447 $warning['message'] = 'You can\'t see this discussion'; 448 $warnings[] = $warning; 449 continue; 450 } 451 452 $discussion->numunread = 0; 453 if ($cantrack && $forumtracked) { 454 if (isset($unreads[$discussion->discussion])) { 455 $discussion->numunread = (int) $unreads[$discussion->discussion]; 456 } 457 } 458 459 $discussion->numreplies = 0; 460 if (!empty($replies[$discussion->discussion])) { 461 $discussion->numreplies = (int) $replies[$discussion->discussion]->replies; 462 } 463 464 $picturefields = explode(',', user_picture::fields()); 465 466 // Load user objects from the results of the query. 467 $user = new stdclass(); 468 $user->id = $discussion->userid; 469 $user = username_load_fields_from_object($user, $discussion, null, $picturefields); 470 // Preserve the id, it can be modified by username_load_fields_from_object. 471 $user->id = $discussion->userid; 472 $discussion->userfullname = fullname($user, $canviewfullname); 473 474 $userpicture = new user_picture($user); 475 $userpicture->size = 1; // Size f1. 476 $discussion->userpictureurl = $userpicture->get_url($PAGE)->out(false); 477 478 $usermodified = new stdclass(); 479 $usermodified->id = $discussion->usermodified; 480 $usermodified = username_load_fields_from_object($usermodified, $discussion, 'um', $picturefields); 481 // Preserve the id (it can be overwritten due to the prefixed $picturefields). 482 $usermodified->id = $discussion->usermodified; 483 $discussion->usermodifiedfullname = fullname($usermodified, $canviewfullname); 484 485 $userpicture = new user_picture($usermodified); 486 $userpicture->size = 1; // Size f1. 487 $discussion->usermodifiedpictureurl = $userpicture->get_url($PAGE)->out(false); 488 489 $discussion->name = external_format_string($discussion->name, $modcontext->id); 490 $discussion->subject = external_format_string($discussion->subject, $modcontext->id); 491 // Rewrite embedded images URLs. 492 list($discussion->message, $discussion->messageformat) = 493 external_format_text($discussion->message, $discussion->messageformat, 494 $modcontext->id, 'mod_forum', 'post', $discussion->id); 495 496 // List attachments. 497 if (!empty($discussion->attachment)) { 498 $discussion->attachments = external_util::get_area_files($modcontext->id, 'mod_forum', 'attachment', 499 $discussion->id); 500 } 501 502 $discussions[] = $discussion; 503 } 504 } 505 506 $result = array(); 507 $result['discussions'] = $discussions; 508 $result['warnings'] = $warnings; 509 return $result; 510 511 } 512 513 /** 514 * Describes the get_forum_discussions_paginated return value. 515 * 516 * @return external_single_structure 517 * @since Moodle 2.8 518 */ 519 public static function get_forum_discussions_paginated_returns() { 520 return new external_single_structure( 521 array( 522 'discussions' => new external_multiple_structure( 523 new external_single_structure( 524 array( 525 'id' => new external_value(PARAM_INT, 'Post id'), 526 'name' => new external_value(PARAM_TEXT, 'Discussion name'), 527 'groupid' => new external_value(PARAM_INT, 'Group id'), 528 'timemodified' => new external_value(PARAM_INT, 'Time modified'), 529 'usermodified' => new external_value(PARAM_INT, 'The id of the user who last modified'), 530 'timestart' => new external_value(PARAM_INT, 'Time discussion can start'), 531 'timeend' => new external_value(PARAM_INT, 'Time discussion ends'), 532 'discussion' => new external_value(PARAM_INT, 'Discussion id'), 533 'parent' => new external_value(PARAM_INT, 'Parent id'), 534 'userid' => new external_value(PARAM_INT, 'User who started the discussion id'), 535 'created' => new external_value(PARAM_INT, 'Creation time'), 536 'modified' => new external_value(PARAM_INT, 'Time modified'), 537 'mailed' => new external_value(PARAM_INT, 'Mailed?'), 538 'subject' => new external_value(PARAM_TEXT, 'The post subject'), 539 'message' => new external_value(PARAM_RAW, 'The post message'), 540 'messageformat' => new external_format_value('message'), 541 'messagetrust' => new external_value(PARAM_INT, 'Can we trust?'), 542 'attachment' => new external_value(PARAM_RAW, 'Has attachments?'), 543 'attachments' => new external_files('attachments', VALUE_OPTIONAL), 544 'totalscore' => new external_value(PARAM_INT, 'The post message total score'), 545 'mailnow' => new external_value(PARAM_INT, 'Mail now?'), 546 'userfullname' => new external_value(PARAM_TEXT, 'Post author full name'), 547 'usermodifiedfullname' => new external_value(PARAM_TEXT, 'Post modifier full name'), 548 'userpictureurl' => new external_value(PARAM_URL, 'Post author picture.'), 549 'usermodifiedpictureurl' => new external_value(PARAM_URL, 'Post modifier picture.'), 550 'numreplies' => new external_value(PARAM_TEXT, 'The number of replies in the discussion'), 551 'numunread' => new external_value(PARAM_INT, 'The number of unread discussions.'), 552 'pinned' => new external_value(PARAM_BOOL, 'Is the discussion pinned') 553 ), 'post' 554 ) 555 ), 556 'warnings' => new external_warnings() 557 ) 558 ); 559 } 560 561 /** 562 * Returns description of method parameters 563 * 564 * @return external_function_parameters 565 * @since Moodle 2.9 566 */ 567 public static function view_forum_parameters() { 568 return new external_function_parameters( 569 array( 570 'forumid' => new external_value(PARAM_INT, 'forum instance id') 571 ) 572 ); 573 } 574 575 /** 576 * Trigger the course module viewed event and update the module completion status. 577 * 578 * @param int $forumid the forum instance id 579 * @return array of warnings and status result 580 * @since Moodle 2.9 581 * @throws moodle_exception 582 */ 583 public static function view_forum($forumid) { 584 global $DB, $CFG; 585 require_once($CFG->dirroot . "/mod/forum/lib.php"); 586 587 $params = self::validate_parameters(self::view_forum_parameters(), 588 array( 589 'forumid' => $forumid 590 )); 591 $warnings = array(); 592 593 // Request and permission validation. 594 $forum = $DB->get_record('forum', array('id' => $params['forumid']), '*', MUST_EXIST); 595 list($course, $cm) = get_course_and_cm_from_instance($forum, 'forum'); 596 597 $context = context_module::instance($cm->id); 598 self::validate_context($context); 599 600 require_capability('mod/forum:viewdiscussion', $context, null, true, 'noviewdiscussionspermission', 'forum'); 601 602 // Call the forum/lib API. 603 forum_view($forum, $course, $cm, $context); 604 605 $result = array(); 606 $result['status'] = true; 607 $result['warnings'] = $warnings; 608 return $result; 609 } 610 611 /** 612 * Returns description of method result value 613 * 614 * @return external_description 615 * @since Moodle 2.9 616 */ 617 public static function view_forum_returns() { 618 return new external_single_structure( 619 array( 620 'status' => new external_value(PARAM_BOOL, 'status: true if success'), 621 'warnings' => new external_warnings() 622 ) 623 ); 624 } 625 626 /** 627 * Returns description of method parameters 628 * 629 * @return external_function_parameters 630 * @since Moodle 2.9 631 */ 632 public static function view_forum_discussion_parameters() { 633 return new external_function_parameters( 634 array( 635 'discussionid' => new external_value(PARAM_INT, 'discussion id') 636 ) 637 ); 638 } 639 640 /** 641 * Trigger the discussion viewed event. 642 * 643 * @param int $discussionid the discussion id 644 * @return array of warnings and status result 645 * @since Moodle 2.9 646 * @throws moodle_exception 647 */ 648 public static function view_forum_discussion($discussionid) { 649 global $DB, $CFG; 650 require_once($CFG->dirroot . "/mod/forum/lib.php"); 651 652 $params = self::validate_parameters(self::view_forum_discussion_parameters(), 653 array( 654 'discussionid' => $discussionid 655 )); 656 $warnings = array(); 657 658 $discussion = $DB->get_record('forum_discussions', array('id' => $params['discussionid']), '*', MUST_EXIST); 659 $forum = $DB->get_record('forum', array('id' => $discussion->forum), '*', MUST_EXIST); 660 list($course, $cm) = get_course_and_cm_from_instance($forum, 'forum'); 661 662 // Validate the module context. It checks everything that affects the module visibility (including groupings, etc..). 663 $modcontext = context_module::instance($cm->id); 664 self::validate_context($modcontext); 665 666 require_capability('mod/forum:viewdiscussion', $modcontext, null, true, 'noviewdiscussionspermission', 'forum'); 667 668 // Call the forum/lib API. 669 forum_discussion_view($modcontext, $forum, $discussion); 670 671 $result = array(); 672 $result['status'] = true; 673 $result['warnings'] = $warnings; 674 return $result; 675 } 676 677 /** 678 * Returns description of method result value 679 * 680 * @return external_description 681 * @since Moodle 2.9 682 */ 683 public static function view_forum_discussion_returns() { 684 return new external_single_structure( 685 array( 686 'status' => new external_value(PARAM_BOOL, 'status: true if success'), 687 'warnings' => new external_warnings() 688 ) 689 ); 690 } 691 692 /** 693 * Returns description of method parameters 694 * 695 * @return external_function_parameters 696 * @since Moodle 3.0 697 */ 698 public static function add_discussion_post_parameters() { 699 return new external_function_parameters( 700 array( 701 'postid' => new external_value(PARAM_INT, 'the post id we are going to reply to 702 (can be the initial discussion post'), 703 'subject' => new external_value(PARAM_TEXT, 'new post subject'), 704 'message' => new external_value(PARAM_RAW, 'new post message (only html format allowed)'), 705 'options' => new external_multiple_structure ( 706 new external_single_structure( 707 array( 708 'name' => new external_value(PARAM_ALPHANUM, 709 'The allowed keys (value format) are: 710 discussionsubscribe (bool); subscribe to the discussion?, default to true 711 inlineattachmentsid (int); the draft file area id for inline attachments 712 attachmentsid (int); the draft file area id for attachments 713 '), 714 'value' => new external_value(PARAM_RAW, 'the value of the option, 715 this param is validated in the external function.' 716 ) 717 ) 718 ), 'Options', VALUE_DEFAULT, array()) 719 ) 720 ); 721 } 722 723 /** 724 * Create new posts into an existing discussion. 725 * 726 * @param int $postid the post id we are going to reply to 727 * @param string $subject new post subject 728 * @param string $message new post message (only html format allowed) 729 * @param array $options optional settings 730 * @return array of warnings and the new post id 731 * @since Moodle 3.0 732 * @throws moodle_exception 733 */ 734 public static function add_discussion_post($postid, $subject, $message, $options = array()) { 735 global $DB, $CFG, $USER; 736 require_once($CFG->dirroot . "/mod/forum/lib.php"); 737 738 $params = self::validate_parameters(self::add_discussion_post_parameters(), 739 array( 740 'postid' => $postid, 741 'subject' => $subject, 742 'message' => $message, 743 'options' => $options 744 )); 745 // Validate options. 746 $options = array( 747 'discussionsubscribe' => true, 748 'inlineattachmentsid' => 0, 749 'attachmentsid' => null 750 ); 751 foreach ($params['options'] as $option) { 752 $name = trim($option['name']); 753 switch ($name) { 754 case 'discussionsubscribe': 755 $value = clean_param($option['value'], PARAM_BOOL); 756 break; 757 case 'inlineattachmentsid': 758 $value = clean_param($option['value'], PARAM_INT); 759 break; 760 case 'attachmentsid': 761 $value = clean_param($option['value'], PARAM_INT); 762 break; 763 default: 764 throw new moodle_exception('errorinvalidparam', 'webservice', '', $name); 765 } 766 $options[$name] = $value; 767 } 768 769 $warnings = array(); 770 771 if (!$parent = forum_get_post_full($params['postid'])) { 772 throw new moodle_exception('invalidparentpostid', 'forum'); 773 } 774 775 if (!$discussion = $DB->get_record("forum_discussions", array("id" => $parent->discussion))) { 776 throw new moodle_exception('notpartofdiscussion', 'forum'); 777 } 778 779 // Request and permission validation. 780 $forum = $DB->get_record('forum', array('id' => $discussion->forum), '*', MUST_EXIST); 781 list($course, $cm) = get_course_and_cm_from_instance($forum, 'forum'); 782 783 $context = context_module::instance($cm->id); 784 self::validate_context($context); 785 786 if (!forum_user_can_post($forum, $discussion, $USER, $cm, $course, $context)) { 787 throw new moodle_exception('nopostforum', 'forum'); 788 } 789 790 $thresholdwarning = forum_check_throttling($forum, $cm); 791 forum_check_blocking_threshold($thresholdwarning); 792 793 // Create the post. 794 $post = new stdClass(); 795 $post->discussion = $discussion->id; 796 $post->parent = $parent->id; 797 $post->subject = $params['subject']; 798 $post->message = $params['message']; 799 $post->messageformat = FORMAT_HTML; // Force formatting for now. 800 $post->messagetrust = trusttext_trusted($context); 801 $post->itemid = $options['inlineattachmentsid']; 802 $post->attachments = $options['attachmentsid']; 803 $fakemform = $post->attachments; 804 if ($postid = forum_add_new_post($post, $fakemform)) { 805 806 $post->id = $postid; 807 808 // Trigger events and completion. 809 $params = array( 810 'context' => $context, 811 'objectid' => $post->id, 812 'other' => array( 813 'discussionid' => $discussion->id, 814 'forumid' => $forum->id, 815 'forumtype' => $forum->type, 816 ) 817 ); 818 $event = \mod_forum\event\post_created::create($params); 819 $event->add_record_snapshot('forum_posts', $post); 820 $event->add_record_snapshot('forum_discussions', $discussion); 821 $event->trigger(); 822 823 // Update completion state. 824 $completion = new completion_info($course); 825 if ($completion->is_enabled($cm) && 826 ($forum->completionreplies || $forum->completionposts)) { 827 $completion->update_state($cm, COMPLETION_COMPLETE); 828 } 829 830 $settings = new stdClass(); 831 $settings->discussionsubscribe = $options['discussionsubscribe']; 832 forum_post_subscription($settings, $forum, $discussion); 833 } else { 834 throw new moodle_exception('couldnotadd', 'forum'); 835 } 836 837 $result = array(); 838 $result['postid'] = $postid; 839 $result['warnings'] = $warnings; 840 return $result; 841 } 842 843 /** 844 * Returns description of method result value 845 * 846 * @return external_description 847 * @since Moodle 3.0 848 */ 849 public static function add_discussion_post_returns() { 850 return new external_single_structure( 851 array( 852 'postid' => new external_value(PARAM_INT, 'new post id'), 853 'warnings' => new external_warnings() 854 ) 855 ); 856 } 857 858 /** 859 * Returns description of method parameters 860 * 861 * @return external_function_parameters 862 * @since Moodle 3.0 863 */ 864 public static function add_discussion_parameters() { 865 return new external_function_parameters( 866 array( 867 'forumid' => new external_value(PARAM_INT, 'Forum instance ID'), 868 'subject' => new external_value(PARAM_TEXT, 'New Discussion subject'), 869 'message' => new external_value(PARAM_RAW, 'New Discussion message (only html format allowed)'), 870 'groupid' => new external_value(PARAM_INT, 'The group, default to -1', VALUE_DEFAULT, -1), 871 'options' => new external_multiple_structure ( 872 new external_single_structure( 873 array( 874 'name' => new external_value(PARAM_ALPHANUM, 875 'The allowed keys (value format) are: 876 discussionsubscribe (bool); subscribe to the discussion?, default to true 877 discussionpinned (bool); is the discussion pinned, default to false 878 inlineattachmentsid (int); the draft file area id for inline attachments 879 attachmentsid (int); the draft file area id for attachments 880 '), 881 'value' => new external_value(PARAM_RAW, 'The value of the option, 882 This param is validated in the external function.' 883 ) 884 ) 885 ), 'Options', VALUE_DEFAULT, array()) 886 ) 887 ); 888 } 889 890 /** 891 * Add a new discussion into an existing forum. 892 * 893 * @param int $forumid the forum instance id 894 * @param string $subject new discussion subject 895 * @param string $message new discussion message (only html format allowed) 896 * @param int $groupid the user course group 897 * @param array $options optional settings 898 * @return array of warnings and the new discussion id 899 * @since Moodle 3.0 900 * @throws moodle_exception 901 */ 902 public static function add_discussion($forumid, $subject, $message, $groupid = -1, $options = array()) { 903 global $DB, $CFG; 904 require_once($CFG->dirroot . "/mod/forum/lib.php"); 905 906 $params = self::validate_parameters(self::add_discussion_parameters(), 907 array( 908 'forumid' => $forumid, 909 'subject' => $subject, 910 'message' => $message, 911 'groupid' => $groupid, 912 'options' => $options 913 )); 914 // Validate options. 915 $options = array( 916 'discussionsubscribe' => true, 917 'discussionpinned' => false, 918 'inlineattachmentsid' => 0, 919 'attachmentsid' => null 920 ); 921 foreach ($params['options'] as $option) { 922 $name = trim($option['name']); 923 switch ($name) { 924 case 'discussionsubscribe': 925 $value = clean_param($option['value'], PARAM_BOOL); 926 break; 927 case 'discussionpinned': 928 $value = clean_param($option['value'], PARAM_BOOL); 929 break; 930 case 'inlineattachmentsid': 931 $value = clean_param($option['value'], PARAM_INT); 932 break; 933 case 'attachmentsid': 934 $value = clean_param($option['value'], PARAM_INT); 935 break; 936 default: 937 throw new moodle_exception('errorinvalidparam', 'webservice', '', $name); 938 } 939 $options[$name] = $value; 940 } 941 942 $warnings = array(); 943 944 // Request and permission validation. 945 $forum = $DB->get_record('forum', array('id' => $params['forumid']), '*', MUST_EXIST); 946 list($course, $cm) = get_course_and_cm_from_instance($forum, 'forum'); 947 948 $context = context_module::instance($cm->id); 949 self::validate_context($context); 950 951 // Normalize group. 952 if (!groups_get_activity_groupmode($cm)) { 953 // Groups not supported, force to -1. 954 $groupid = -1; 955 } else { 956 // Check if we receive the default or and empty value for groupid, 957 // in this case, get the group for the user in the activity. 958 if ($groupid === -1 or empty($params['groupid'])) { 959 $groupid = groups_get_activity_group($cm); 960 } else { 961 // Here we rely in the group passed, forum_user_can_post_discussion will validate the group. 962 $groupid = $params['groupid']; 963 } 964 } 965 966 if (!forum_user_can_post_discussion($forum, $groupid, -1, $cm, $context)) { 967 throw new moodle_exception('cannotcreatediscussion', 'forum'); 968 } 969 970 $thresholdwarning = forum_check_throttling($forum, $cm); 971 forum_check_blocking_threshold($thresholdwarning); 972 973 // Create the discussion. 974 $discussion = new stdClass(); 975 $discussion->course = $course->id; 976 $discussion->forum = $forum->id; 977 $discussion->message = $params['message']; 978 $discussion->messageformat = FORMAT_HTML; // Force formatting for now. 979 $discussion->messagetrust = trusttext_trusted($context); 980 $discussion->itemid = $options['inlineattachmentsid']; 981 $discussion->groupid = $groupid; 982 $discussion->mailnow = 0; 983 $discussion->subject = $params['subject']; 984 $discussion->name = $discussion->subject; 985 $discussion->timestart = 0; 986 $discussion->timeend = 0; 987 $discussion->attachments = $options['attachmentsid']; 988 989 if (has_capability('mod/forum:pindiscussions', $context) && $options['discussionpinned']) { 990 $discussion->pinned = FORUM_DISCUSSION_PINNED; 991 } else { 992 $discussion->pinned = FORUM_DISCUSSION_UNPINNED; 993 } 994 $fakemform = $options['attachmentsid']; 995 if ($discussionid = forum_add_discussion($discussion, $fakemform)) { 996 997 $discussion->id = $discussionid; 998 999 // Trigger events and completion. 1000 1001 $params = array( 1002 'context' => $context, 1003 'objectid' => $discussion->id, 1004 'other' => array( 1005 'forumid' => $forum->id, 1006 ) 1007 ); 1008 $event = \mod_forum\event\discussion_created::create($params); 1009 $event->add_record_snapshot('forum_discussions', $discussion); 1010 $event->trigger(); 1011 1012 $completion = new completion_info($course); 1013 if ($completion->is_enabled($cm) && 1014 ($forum->completiondiscussions || $forum->completionposts)) { 1015 $completion->update_state($cm, COMPLETION_COMPLETE); 1016 } 1017 1018 $settings = new stdClass(); 1019 $settings->discussionsubscribe = $options['discussionsubscribe']; 1020 forum_post_subscription($settings, $forum, $discussion); 1021 } else { 1022 throw new moodle_exception('couldnotadd', 'forum'); 1023 } 1024 1025 $result = array(); 1026 $result['discussionid'] = $discussionid; 1027 $result['warnings'] = $warnings; 1028 return $result; 1029 } 1030 1031 /** 1032 * Returns description of method result value 1033 * 1034 * @return external_description 1035 * @since Moodle 3.0 1036 */ 1037 public static function add_discussion_returns() { 1038 return new external_single_structure( 1039 array( 1040 'discussionid' => new external_value(PARAM_INT, 'New Discussion ID'), 1041 'warnings' => new external_warnings() 1042 ) 1043 ); 1044 } 1045 1046 /** 1047 * Returns description of method parameters 1048 * 1049 * @return external_function_parameters 1050 * @since Moodle 3.1 1051 */ 1052 public static function can_add_discussion_parameters() { 1053 return new external_function_parameters( 1054 array( 1055 'forumid' => new external_value(PARAM_INT, 'Forum instance ID'), 1056 'groupid' => new external_value(PARAM_INT, 'The group to check, default to active group. 1057 Use -1 to check if the user can post in all the groups.', VALUE_DEFAULT, null) 1058 ) 1059 ); 1060 } 1061 1062 /** 1063 * Check if the current user can add discussions in the given forum (and optionally for the given group). 1064 * 1065 * @param int $forumid the forum instance id 1066 * @param int $groupid the group to check, default to active group. Use -1 to check if the user can post in all the groups. 1067 * @return array of warnings and the status (true if the user can add discussions) 1068 * @since Moodle 3.1 1069 * @throws moodle_exception 1070 */ 1071 public static function can_add_discussion($forumid, $groupid = null) { 1072 global $DB, $CFG; 1073 require_once($CFG->dirroot . "/mod/forum/lib.php"); 1074 1075 $params = self::validate_parameters(self::can_add_discussion_parameters(), 1076 array( 1077 'forumid' => $forumid, 1078 'groupid' => $groupid, 1079 )); 1080 $warnings = array(); 1081 1082 // Request and permission validation. 1083 $forum = $DB->get_record('forum', array('id' => $params['forumid']), '*', MUST_EXIST); 1084 list($course, $cm) = get_course_and_cm_from_instance($forum, 'forum'); 1085 1086 $context = context_module::instance($cm->id); 1087 self::validate_context($context); 1088 1089 $status = forum_user_can_post_discussion($forum, $params['groupid'], -1, $cm, $context); 1090 1091 $result = array(); 1092 $result['status'] = $status; 1093 $result['warnings'] = $warnings; 1094 return $result; 1095 } 1096 1097 /** 1098 * Returns description of method result value 1099 * 1100 * @return external_description 1101 * @since Moodle 3.1 1102 */ 1103 public static function can_add_discussion_returns() { 1104 return new external_single_structure( 1105 array( 1106 'status' => new external_value(PARAM_BOOL, 'True if the user can add discussions, false otherwise.'), 1107 'warnings' => new external_warnings() 1108 ) 1109 ); 1110 } 1111 1112 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |