/**
  * Retrieves a list of discussions.
  * @param int $groupid Group ID or ALL_GROUPS
  * @param bool $viewhidden True if user can view hidden discussions
  * @param int $page Page to retrieve (1 = first page)
  * @param int $sort Sort order (SORT_xx constant)
  * @param bool $sortreverse Reverses the chosen sort
  * @param int $userid User ID, 0 = default, -1 if unread count not required
  * @return forum_discussion_list
  */
 public function get_discussion_list($groupid = self::ALL_GROUPS, $viewhidden = false, $viewdeleted = false, $page = 1, $sort = self::SORT_DATE, $sortreverse = false, $userid = 0, $ignoreinvalidpage = true)
 {
     global $CFG;
     // Build list of SQL conditions
     ///////////////////////////////
     // Correct forum, not deleted.
     $conditions = "fd.forumid={$this->forumfields->id}";
     if (!$viewdeleted) {
         $conditions .= " AND fd.deleted=0";
     }
     // Group restriction
     if ($groupid) {
         $conditions .= " AND (fd.groupid={$groupid} OR fd.groupid IS NULL)";
     }
     // View hidden posts
     if (!$viewhidden) {
         $now = time();
         $conditions .= " AND (fd.timestart=0 OR fd.timestart <= {$now})" . " AND (fd.timeend=0 OR fd.timeend > {$now})";
     }
     // Count all discussions
     ////////////////////////
     // Get count
     $count = count_records_sql("SELECT COUNT(1) FROM {$CFG->prefix}forumng_discussions fd WHERE " . $conditions);
     // Check page index makes sense
     $pagecount = ceil($count / $CFG->forumng_discussionsperpage);
     if ($pagecount < 1) {
         $pagecount = 1;
     }
     if ($page > $pagecount || $page < 1) {
         if ($ignoreinvalidpage) {
             $page = 1;
         } else {
             throw new forum_exception("Invalid page {$page}, expecting 1..{$pagecount}");
         }
     }
     // Special case for no results
     if ($count == 0) {
         return new forum_discussion_list($page, $pagecount, $count);
     }
     // Retrieve selected discussions
     ////////////////////////////////
     // Ordering
     $orderby = 'sticky DESC';
     switch ($sort) {
         case self::SORT_DATE:
             $orderby .= ', timemodified DESC';
             break;
         case self::SORT_SUBJECT:
             $orderby .= ', subject ASC';
             break;
         case self::SORT_AUTHOR:
             // This logic is based on code in fullname().
             $override = has_capability('moodle/site:viewfullnames', $this->get_context(), $userid);
             if ($CFG->fullnamedisplay == 'firstname lastname' || $override && $CFG->fullnamedisplay == 'firstname') {
                 $orderby .= ', fu_firstname ASC, fu_lastname ASC';
             } else {
                 if ($CFG->fullnamedisplay == 'lastname firstname') {
                     $orderby .= ', fu_lastname ASC, fu_firstname ASC';
                 } else {
                     if ($CFG->fullnamedisplay == 'firstname') {
                         $orderby .= ', fu_firstname ASC';
                     }
                 }
             }
             if (!$override) {
                 if (!empty($CFG->forcefirstname)) {
                     $orderby = preg_replace('~, fu_firstname(ASC)?~', '', $orderby);
                 }
                 if (!empty($CFG->forcelastname)) {
                     $orderby = preg_replace('~, fu_lastname(ASC)?~', '', $orderby);
                 }
             }
             break;
         case self::SORT_POSTS:
             $orderby .= ', numposts DESC';
             break;
         case self::SORT_UNREAD:
             $orderby .= ', numposts-numreadposts DESC';
             break;
         case self::SORT_GROUP:
             $orderby .= ', groupname ASC';
             break;
         default:
             throw new forum_exception("Unknown SORT_xx constant {$sort}");
     }
     // swap ASC/DESC according to $sortreverse
     if ($sortreverse) {
         $orderby = str_replace('DESC', 'ASX', $orderby);
         $orderby = str_replace('ASC', 'DESC', $orderby);
         $orderby = str_replace('ASX', 'ASC', $orderby);
         $orderby = str_replace('sticky ASC', 'sticky DESC', $orderby);
     }
     // Ensure consistency by adding id ordering
     $orderby .= ', id DESC';
     // Limits
     $limitfrom = ($page - 1) * $CFG->forumng_discussionsperpage;
     $limitnum = $CFG->forumng_discussionsperpage;
     // Do query
     $rs = forum_discussion::query_discussions($conditions, $userid, $orderby, $limitfrom, $limitnum);
     $result = new forum_discussion_list($page, $pagecount, $count);
     while ($rec = rs_fetch_next_record($rs)) {
         // Create a new discussion from the database details
         $discussion = new forum_discussion($this, $rec, true, forum_utils::get_real_userid($userid));
         // Give the discussion a chance to invalidate discussion
         // cache. This is so that if the user looks at a discussion
         // list, and it shows a newer post, then they click into the
         // discussion, they don't end up not seeing it!
         $discussion->maybe_invalidate_cache();
         // Add to results
         $result->add_discussion($discussion);
     }
     rs_close($rs);
     return $result;
 }