/**
 * This page (list.php) lists the users with in alphabetical order of their
 * last-name with number of discussions and replies. If there are any 
 * discussions and/or replies a link is printed for displaying all the posts
 * from that a given user depending on chosen group
 * @copyright © July 2010 The Open University
 * @author Mahmoud Kassaei m.kassaei@open.ac.uk
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @package forumNG
 */
require_once '../../../../config.php';
require_once $CFG->dirroot . '/mod/forumng/forum.php';
$cmid = required_param('id', PARAM_INT);
$cloneid = optional_param('clone', 0, PARAM_INT);
try {
    $forum = forum::get_from_cmid($cmid, $cloneid);
    $course = $forum->get_course();
    $cm = $forum->get_course_module();
    $context = $forum->get_context();
    if ($forum->is_shared() || $forum->is_clone()) {
        throw new forum_exception("<strong>View post by user</strong> doesn't work for a shared forum.");
    }
    // Check forum access (using forum group, if required)
    $forumgroupid = forum::get_activity_group($cm, false);
    $forum->require_view($forumgroupid);
    // TODO: Use/define a more accurate capability. This will do for now.
    require_capability('mod/forumng:viewallposts', $forum->get_context());
    // Print page header
    $forum->print_subpage_header(get_string('userposts', 'forumng'));
    // This section uses custom groups rather than the normal forum groups.
    // We are using the groups that are set for the course and not the ones
/**
 * Obtains the automatic completion state for this forum based on any conditions
 * in forum settings.
 *
 * @param object $course Course
 * @param object $cm Course-module
 * @param int $userid User ID
 * @param bool $type Type of comparison (or/and; can be used as return value if no conditions)
 * @return bool True if completed, false if not. (If no conditions, then return
 *   value depends on comparison type)
 */
function forumng_get_completion_state($course, $cm, $userid, $type)
{
    // Use forum object to handle this request
    $forum = forum::get_from_cmid($cm->id, forum::CLONE_DIRECT);
    return $forum->get_completion_state($userid, $type);
}
<?php

require_once '../../../../config.php';
require_once $CFG->dirroot . '/mod/forumng/forum.php';
$d = required_param('d', PARAM_INT);
$target = required_param('target', PARAM_INT);
$cloneid = optional_param('clone', 0, PARAM_INT);
if (!$target) {
    print_error('move_notselected', 'forumng');
}
try {
    $discussion = forum_discussion::get_from_id($d, $cloneid);
    // Get target forum
    $targetforum = forum::get_from_cmid($target, forum::CLONE_DIRECT);
    // If it is a clone, find the original
    $targetforum = $targetforum->get_real_forum();
    // Check permission for move
    $discussion->require_view();
    require_capability('mod/forumng:movediscussions', $discussion->get_forum()->get_context());
    require_capability('mod/forumng:movediscussions', $targetforum->get_context());
    $aag = has_capability('moodle/site:accessallgroups', $targetforum->get_context());
    // Work out target group for move
    $targetgroup = $discussion->get_group_id();
    if ($targetforum->get_group_mode() == 0 || !$targetgroup && $aag && $discussion->get_forum()->get_group_mode() != 0) {
        // Either target forum doesn't have groups, or it does have groups but
        // so does the source forum and this is already an all-groups post,
        // and you have access all groups, so it can be all-groups
        $targetgroup = null;
    } else {
        // Target forum has groups :( Need to decide a group
        if ($targetgroup && $targetforum->get_grouping() != $discussion->get_forum()->get_grouping()) {
 /**
  * Internal method. Queries for a number of forums, including additional
  * data about unread posts etc. Returns the database result.
  * @param array $cmids If specified, array of course-module IDs of desired
  *   forums
  * @param object $course If specified, course object
  * @param int $userid User ID, 0 = current user
  * @param int $unread Type of unread data to obtain (UNREAD_xx constant).
  * @param array $groups Array of group IDs to which the given user belongs
  *   (may be null if unread data not required)
  * @param array $aagforums Array of forums in which the user has
  *   'access all groups' (may be null if unread data not required)
  * @param array $viewhiddenforums Array of forums in which the user has
  *   'view hidden discussions' (may be null if unread data not required)
  * @return array Array of row objects
  */
 private static function query_forums($cmids = array(), $course = null, $userid, $unread, $groups, $aagforums, $viewhiddenforums)
 {
     global $CFG, $USER;
     if (!count($cmids) && !$course) {
         throw new forum_exception("forum::query_forums requires course id or cmids");
     }
     if (count($cmids)) {
         $conditions = "cm.id " . forum_utils::in_or_equals($cmids);
     } else {
         $conditions = "f.course = {$course->id}";
     }
     $singleforum = count($cmids) == 1 ? reset($cmids) : false;
     $inviewhiddenforums = forum_utils::in_or_equals($viewhiddenforums);
     // This array of additional results is used later if combining
     // standard results with single-forum calls.
     $plusresult = array();
     // For read tracking, we get a count of total number of posts in
     // forum, and total number of read posts in the forum (this
     // is so we can display the number of UNread posts, but the query
     // works that way around because it will return 0 if no read
     // information is stored).
     if ($unread != self::UNREAD_NONE && forum::enabled_read_tracking()) {
         // Work out when unread status ends
         $endtime = time() - $CFG->forumng_readafterdays * 24 * 3600;
         if (!$userid) {
             $userid = $USER->id;
         }
         $ingroups = forum_utils::in_or_equals($groups);
         $inaagforums = forum_utils::in_or_equals($aagforums);
         $restrictionsql = '';
         if ($singleforum) {
             // If it is for a single forum, get the restriction from the
             // forum type
             $forum = forum::get_from_cmid($singleforum, forum::CLONE_DIRECT);
             $type = $forum->get_type();
             if ($type->has_unread_restriction()) {
                 $value = $type->get_unread_restriction_sql($forum);
                 if ($value) {
                     $restrictionsql = 'AND ' . $value;
                 }
             }
         } else {
             // When it is not for a single forum, we can only group together
             // results for types that do not place restrictions on the
             // unread count.
             $modinfo = self::get_modinfo_special($course, $cmids);
             $okayids = array();
             if (array_key_exists('forumng', $modinfo->instances)) {
                 foreach ($modinfo->instances['forumng'] as $info) {
                     if (count($cmids) && !in_array($info->id, $cmids)) {
                         continue;
                     }
                     $type = self::get_type_from_modinfo_info($info);
                     if (forum_type::get_new($type)->has_unread_restriction()) {
                         // This one's a problem! Do it individually
                         $problemresults = self::query_forums(array($info->id), null, $userid, $unread, $groups, $aagforums, $viewhiddenforums);
                         foreach ($problemresults as $problemresult) {
                             $plusresult[$problemresult->f_id] = $problemresult;
                         }
                     } else {
                         $okayids[] = $info->id;
                     }
                 }
             }
             if (count($okayids) == 0) {
                 // There are no 'normal' forums, so return result so far
                 // after sorting it
                 uasort($plusresult, 'forum::sort_forum_result');
                 return $plusresult;
             } else {
                 // Fall through to normal calculation, but change conditions
                 // to include only the 'normal' forums
                 $conditions .= " AND cm.id " . forum_utils::in_or_equals($okayids);
             }
         }
         // NOTE fpfirst is used only by forum types, not here
         $now = time();
         $sharedquerypart = "\nFROM\n    {$CFG->prefix}forumng_discussions fd\n    INNER JOIN {$CFG->prefix}forumng_posts fplast ON fd.lastpostid = fplast.id\n    INNER JOIN {$CFG->prefix}forumng_posts fpfirst ON fd.postid = fpfirst.id\n    LEFT JOIN {$CFG->prefix}forumng_read fr ON fd.id = fr.discussionid AND fr.userid={$userid}\nWHERE\n    fd.forumid=f.id AND fplast.modified>{$endtime}\n    AND (\n        (fd.groupid IS NULL)\n        OR (fd.groupid {$ingroups})\n        OR cm.groupmode=" . VISIBLEGROUPS . "\n        OR (fd.forumid {$inaagforums})\n    )\n    AND fd.deleted=0\n    AND (\n        ((fd.timestart=0 OR fd.timestart <= {$now})\n        AND (fd.timeend=0 OR fd.timeend > {$now}))\n        OR (fd.forumid {$inviewhiddenforums})\n    )\n    AND ((fplast.edituserid IS NOT NULL AND fplast.edituserid<>{$userid})\n        OR fplast.userid<>{$userid})\n    AND (fr.time IS NULL OR fplast.modified>fr.time)\n    {$restrictionsql}";
         // Note: There is an unusual case in which this number can
         // be inaccurate. It is to do with ignoring messages the user
         // posted. We consider a discussion as 'not unread' if the last
         // message is by current user. In actual fact, a discussion could
         // contain unread messages if messages were posted by other users
         // after this user viewed the forum last, but before they posted
         // their reply. Since this should be an infrequent occurrence I
         // believe this behaviour is acceptable.
         if ($unread == self::UNREAD_BINARY && ($CFG->dbtype == 'postgres7' || $CFG->dbtype == 'mysql')) {
             // Query to get 0/1 unread discussions count
             $readtracking = "\n(SELECT\n    COUNT(1)\nFROM (\n    SELECT\n        1\n    {$sharedquerypart}\n    LIMIT 1) innerquery\n) AS f_hasunreaddiscussions";
         } else {
             // Query to get full unread discussions count
             $readtracking = "\n(SELECT\n    COUNT(1)\n{$sharedquerypart}\n) AS f_numunreaddiscussions";
         }
     } else {
         $readtracking = "NULL AS numreadposts, NULL AS timeread";
     }
     $now = time();
     $orderby = "LOWER(f.name)";
     // Main query. This retrieves:
     // - Full forum fields
     // - Basic course-module and course data (not whole tables)
     // - Discussion count
     // - Unread data, if enabled
     // - User subscription data
     $rs = get_recordset_sql($sql = "\nSELECT\n    " . forum_utils::select_forum_fields('f') . ",\n    " . forum_utils::select_course_module_fields('cm') . ",\n    " . forum_utils::select_course_fields('c') . ",\n    (SELECT COUNT(1)\n        FROM {$CFG->prefix}forumng_discussions cfd\n        WHERE cfd.forumid=f.id AND cfd.deleted=0\n        AND (\n            ((cfd.timestart=0 OR cfd.timestart <= {$now})\n            AND (cfd.timeend=0 OR cfd.timeend > {$now}))\n            OR (cfd.forumid {$inviewhiddenforums})\n        )\n        ) AS f_numdiscussions,\n    {$readtracking}\nFROM\n    {$CFG->prefix}forumng f\n    INNER JOIN {$CFG->prefix}course_modules cm ON cm.instance=f.id\n        AND cm.module=(SELECT id from {$CFG->prefix}modules WHERE name='forumng')\n    INNER JOIN {$CFG->prefix}course c ON c.id=f.course\nWHERE\n    {$conditions}\nORDER BY\n    {$orderby}");
     if (!$rs) {
         throw new forum_exception("Failed to retrieve forums");
     }
     $result = recordset_to_array($rs);
     rs_close($rs);
     if (count($plusresult) > 0) {
         foreach ($plusresult as $key => $value) {
             $result[$key] = $value;
         }
         uasort($result, 'forum::sort_forum_result');
     }
     return $result;
 }