/**
  * Queries for all forums on a course, including additional data about unread
  * posts etc.
  * NOTE: If shared forums are in use, this will usually return the CLONE
  * forum object, which doesn't hold any data about the actual forum;
  * the exception is that unread data will be obtained from the real forum.
  * If you would like to obtain the real forum instead, please make sure
  * $realforums is set to true. This has a performance cost.
  * @param object $course Moodle course object
  * @param int $userid User ID, 0 = current user, -1 = no unread data is needed
  * @param bool $unreadasbinary If true, unread data MAY BE binary (1/0)
  *   instead of containing the full number; this improves performance but
  *   only works on some databases
  * @param array $specificids If array has no entries, returns all forums
  *   on the course; if it has at least one entry, returns only those forums 
  *   with course-module ID listed in the array
  * @param bool $realforums Set this to true to obtain real forums
  *   if any are clones; has a performance cost if shared forums are used
  * @return array Array of forum objects (keys are forum IDs; in the case of
  *   shared forums, the id is of the clone not the forum, even if
  *   $realforums is set)
  */
 static function get_course_forums($course, $userid = 0, $unread = self::UNREAD_DISCUSSIONS, $specificids = array(), $realforums = false)
 {
     global $USER, $CFG;
     $userid = forum_utils::get_real_userid($userid);
     $result = array();
     $modinfo = self::get_modinfo_special($course, $specificids);
     // Obtains extra information needed only when acquiring unread data
     $aagforums = array();
     $viewhiddenforums = array();
     $groups = array();
     if ($unread != self::UNREAD_NONE) {
         foreach ($modinfo->cms as $cmid => $cm) {
             if (count($specificids) && !in_array($cmid, $specificids)) {
                 continue;
             }
             $context = get_context_instance(CONTEXT_MODULE, $cmid);
             if ($cm->modname == 'forumng') {
                 if (has_capability('moodle/site:accessallgroups', $context, $userid)) {
                     $aagforums[] = $cm->instance;
                 }
                 if (has_capability('mod/forumng:viewallposts', $context, $userid)) {
                     $viewhiddenforums[] = $cm->instance;
                 }
             }
         }
         if ($userid == $USER->id) {
             if (array_key_exists($course->id, $USER->groupmember)) {
                 $groups = $USER->groupmember[$course->id];
             }
             // Else do nothing - groups list should be empty
         } else {
             $rs = forum_utils::get_recordset_sql("\nSELECT\n    g.id\nFROM\n    {$CFG->prefix}groups g\n    INNER JOIN {$CFG->prefix}groups_members gm ON g.id=gm.groupid\nWHERE\n    g.courseid = {$course->id}\n    AND gm.userid = {$userid}");
             while ($rec = rs_fetch_next_record($rs)) {
                 $groups[] = $rec->id;
             }
             rs_close($rs);
         }
     }
     $rows = self::query_forums($specificids, $course, $userid, $unread, $groups, $aagforums, $viewhiddenforums);
     foreach ($rows as $rec) {
         // Check course-module exists
         if (!array_key_exists($rec->cm_id, $modinfo->cms)) {
             continue;
         }
         $cm = $modinfo->cms[$rec->cm_id];
         if ($cm->modname != 'forumng') {
             continue;
         }
         // Mess about with binary setting to ensure result is same, whatever
         // the database
         if ($unread == self::UNREAD_BINARY && isset($rec->f_numunreaddiscussions)) {
             $rec->f_hasunreaddiscussions = $rec->f_numunreaddiscussions > 0 ? 1 : 0;
             unset($rec->f_numunreaddiscussions);
         }
         // Create a new forum object from the database details
         $forumfields = forum_utils::extract_subobject($rec, 'f_');
         $forum = new forum($course, $cm, get_context_instance(CONTEXT_MODULE, $cm->id), $forumfields);
         $result[$forumfields->id] = $forum;
         if ($forum->is_shared()) {
             $forum->set_clone_reference(self::CLONE_DIRECT);
         }
         // For clone forums (only pointers to genuine shared forums)
         if ($forum->is_clone()) {
             // If we are retrieving the real forum, get it individually
             if ($realforums) {
                 $othercourse = forum_utils::get_record_sql("\nSELECT\n    c.*\nFROM\n    {$CFG->prefix}course_modules cm\n    INNER JOIN {$CFG->prefix}course c ON c.id = cm.course\nWHERE\n    cm.id = {$forumfields->originalcmid}");
                 $extra = self::get_course_forums($othercourse, $userid, $unread, array($forumfields->originalcmid));
                 if (count($extra) != 1) {
                     throw new forum_exception('Unable to find shared forum ' . $forumfields->originalcmid);
                 }
                 foreach ($extra as $extraforum) {
                     $extraforum->set_clone_reference($cm->id);
                     $result[$forumfields->id] = $extraforum;
                 }
             } else {
                 if ($unread != self::UNREAD_NONE) {
                     // Even if not retrieving the real forum, we still use
                     // its undead data when unread data is on
                     $forum->init_unread_from_original($unread);
                 }
             }
         }
     }
     return $result;
 }