[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/mod/forum/ -> externallib.php (source)

   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  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1