コード例 #1
0
 /**
  * Tests getting forum object from id and cmid, inc clones.
  */
 public function test_get_forum()
 {
     $this->resetAfterTest();
     $course = $this->get_new_course();
     // Test get_from_id using test lib.
     $forum = $this->get_new_forumng($course->id, array('name' => 'TEST', 'intro' => 'abc123'));
     $cm = get_coursemodule_from_instance('forumng', $forum->get_id());
     // Check.
     $this->check_forum_settings($forum, $course, $cm);
     // Check get_from_cmid also works.
     $forum = mod_forumng::get_from_cmid($cm->id, mod_forumng::CLONE_DIRECT);
     $this->check_forum_settings($forum, $course, $cm);
     // Check clone.
     $forum1 = $this->get_new_forumng($course->id, array('name' => 'TEST', 'intro' => 'abc123', 'shared' => true, 'cmidnumber' => 'SF1'));
     $this->assertEmpty($forum1->get_clone_details());
     $this->assertTrue($forum1->is_shared());
     $course2 = $this->get_new_course();
     $forum2 = $this->get_new_forumng($course2->id, array('name' => 'TEST', 'usesharedgroup' => array('useshared' => true, 'originalcmidnumber' => 'SF1')));
     $this->assertTrue($forum2->is_shared());
     $this->assertEquals($forum1->get_course_module_id(), $forum2->get_course_module_id(true));
     $this->assertEquals($forum1->get_context()->id, $forum2->get_context(true)->id);
     $this->assertEquals($course2->id, $forum2->get_course()->id);
     $this->assertEquals($course->id, $forum2->get_course(true)->id);
     // Discrepancy between get_course_id() [returns original] and get_course()[returns clone].
     $this->assertEquals($course->id, $forum2->get_course_id());
     // Use another instance without clone set to test it knows it is a clone.
     $forum3 = mod_forumng::get_from_cmid($forum2->get_course_module_id(), mod_forumng::CLONE_DIRECT);
     $this->assertTrue($forum3->is_clone());
     $this->assertArrayHasKey($forum3->get_context()->id, $forum1->get_clone_details());
     $this->assertEquals($course2->id, $forum3->get_course_id());
 }
コード例 #2
0
function forumngfeature_usage_show_mostreaders($params, $forum = null)
{
    global $DB, $PAGE;
    $cloneid = empty($params['clone']) ? 0 : $params['clone'];
    if ($forum == null) {
        if (empty($params['id'])) {
            throw new moodle_exception('Missing forum id param');
        }
        $forum = mod_forumng::get_from_cmid($params['id'], $cloneid);
    }
    $groupwhere = '';
    $groupparams = array();
    $groupid = 0;
    if (!empty($params['group']) && $params['group'] != mod_forumng::NO_GROUPS && $params['group'] != mod_forumng::ALL_GROUPS) {
        $groupwhere = 'AND (fd.groupid = :groupid OR fd.groupid IS NULL)';
        $groupid = $params['group'];
        $groupparams = array('groupid' => $groupid);
    }
    if (has_capability('mod/forumng:viewreadinfo', $forum->get_context())) {
        if (!$PAGE->has_set_url()) {
            // Set context when called via ajax.
            $PAGE->set_context($forum->get_context());
        }
        $renderer = $PAGE->get_renderer('forumngfeature_usage');
        // Only get enrolled users - speeds up query significantly on large forums.
        list($sql, $params) = get_enrolled_sql($forum->get_context(), '', $groupid, true);
        // View discussions read.
        $readers = $DB->get_recordset_sql("\n                SELECT COUNT(fr.userid) AS count, fr.discussionid\n                  FROM {forumng_discussions} fd\n            RIGHT JOIN (\n\t\t                SELECT discussionid, userid\n\t\t                  FROM (\n\t\t                        SELECT * FROM {forumng_read}\n\t\t                     UNION ALL\n\t\t                        SELECT frp.id, frp.userid, fp.discussionid, frp.time\n                                  FROM {forumng_posts} fp\n                            RIGHT JOIN {forumng_read_posts} frp ON fp.id = frp.postid\n                                 WHERE fp.deleted = 0 AND fp.oldversion = 0\n                        ) frp GROUP BY discussionid, userid\n                ) fr ON fr.discussionid = fd.id\n                 WHERE fd.forumngid = :courseid\n                   AND fd.deleted = 0\n                {$groupwhere}\n                   AND fr.userid IN({$sql})\n              GROUP BY fr.discussionid\n              ORDER BY count desc, fr.discussionid desc", array_merge(array('courseid' => $forum->get_id()), $groupparams, $params), 0, 5);
        $readerlist = array();
        foreach ($readers as $discuss) {
            $discussion = mod_forumng_discussion::get_from_id($discuss->discussionid, $cloneid);
            list($content, $user) = $renderer->render_usage_discussion_info($forum, $discussion);
            $readerlist[] = $renderer->render_usage_list_item($forum, $discuss->count, $user, $content);
        }
        return $renderer->render_usage_list($readerlist, 'mostreaders', false);
    }
}
コード例 #3
0
 * Each item displayed may also check capabilities for display.
 * @package forumngfeature_usage
 * @copyright 2013 The Open University
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
require_once '../../../../config.php';
require_once $CFG->dirroot . '/mod/forumng/mod_forumng.php';
require_once $CFG->dirroot . '/mod/forumng/feature/usage/locallib.php';
$cmid = required_param('id', PARAM_INT);
$cloneid = optional_param('clone', 0, PARAM_INT);
$ratings = optional_param('ratings', 0, PARAM_INT);
$pageparams = array('id' => $cmid);
if ($cloneid) {
    $pageparams['clone'] = $cloneid;
}
$forum = mod_forumng::get_from_cmid($cmid, $cloneid);
$course = $forum->get_course();
$cm = $forum->get_course_module();
$context = $forum->get_context();
$groupid = mod_forumng::get_activity_group($cm, true);
if ($groupid != mod_forumng::NO_GROUPS && $groupid != mod_forumng::ALL_GROUPS) {
    $pageparams['group'] = $groupid;
    $groupwhere = 'AND (fd.groupid = ? OR fd.groupid IS NULL)';
    $groupparams = array($groupid);
} else {
    $groupwhere = '';
    $groupparams = array();
}
$ajaxparams = $pageparams;
// Check access.
$forum->require_view($groupid);
コード例 #4
0
$id = required_param('id', PARAM_INT);
$clone = optional_param('clone', 0, PARAM_INT);
$multigroups = optional_param('multigroups', 0, PARAM_INT);
$directmove = optional_param('directmove', 0, PARAM_INT);
// Get the forum the discussions are being moved from.
$forum = mod_forumng::get_from_cmid($id, $clone);
// Check for cancel and if cancelled redirect back to forum view page.
if (!empty($cancel)) {
    redirect('../../view.php?' . $forum->get_link_params(mod_forumng::PARAM_PLAIN));
}
$targetgroup = optional_param('group', 0, PARAM_INT);
$target = optional_param('forum', 0, PARAM_INT);
if ($target == 0) {
    $target = required_param('target', PARAM_INT);
}
$targetforum = mod_forumng::get_from_cmid($target, mod_forumng::CLONE_DIRECT);
// Sets up chosen target group.
$chosentargetgroup = optional_param('chosengroup', 0, PARAM_INT);
if (!$targetgroup) {
    $targetgroup = $chosentargetgroup;
}
if (!$targetgroup) {
    $cm = $forum->get_course_module();
    $targetgroup = mod_forumng::get_activity_group($cm, false);
}
// Security check against user and their capabilities.
$forum->require_view($targetgroup);
check_move_permissions($forum, $targetforum);
// If it is a clone, find the original.
$targetforum = $targetforum->get_real_forum();
$targetgroupmode = $targetforum->get_group_mode();
コード例 #5
0
 * @copyright 2012 The Open University
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
require_once dirname(__FILE__) . '/../../../../config.php';
require_once $CFG->dirroot . '/mod/forumng/lib.php';
require_once $CFG->dirroot . '/mod/forumng/mod_forumng.php';
require_once $CFG->dirroot . '/mod/forumng/feature/userposts/locallib.php';
$id = required_param('id', PARAM_INT);
// Course Module ID.
$groupid = optional_param('group', 0, PARAM_INT);
$userid = optional_param('user', 0, PARAM_INT);
$params = array();
$params['id'] = $id;
$params['group'] = $groupid;
$url = new moodle_url('/mod/forumng/feature/userposts/savegrades.php');
$forum = mod_forumng::get_from_cmid($id, mod_forumng::CLONE_DIRECT);
if (!($cm = $forum->get_course_module())) {
    print_error('invalidcoursemodule');
}
$PAGE->set_cm($cm);
$course = $forum->get_course();
$context = get_context_instance(CONTEXT_MODULE, $cm->id);
require_course_login($course, true, $cm);
// Grading capability check.
if (!$forum->can_grade()) {
    print_error('nopermissiontoshow');
}
$mode = '';
if (!empty($_POST['menu'])) {
    $mode = 'bulk';
    $gradeinfo = $_POST['menu'];
コード例 #6
0
ファイル: lib.php プロジェクト: unikent/moodle-mod_forumng
/**
 * Provides a link for managing OU alerts reports
 * @param settings_navigation $settings
 * @param navigation_node $node
 */
function forumng_extend_settings_navigation(settings_navigation $settings, navigation_node $node)
{
    global $PAGE, $CFG, $COURSE;
    require_once $CFG->dirroot . '/mod/forumng/mod_forumng.php';
    $forum = mod_forumng::get_from_cmid($PAGE->cm->id, mod_forumng::CLONE_DIRECT);
    $context = $forum->get_context();
    if ($forum->oualerts_enabled() && has_capability('report/oualerts:managealerts', $PAGE->cm->context) && count($forum->get_reportingemails()) > 0) {
        $managelevelnode = $node->add(get_string('managepostalerts', 'forumng'), new moodle_url('/report/oualerts/manage.php', array('coursename' => $COURSE->id, 'contextcourseid' => $COURSE->id, 'cmid' => $PAGE->cm->id)));
    }
}
コード例 #7
0
/**
 * 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 = mod_forumng::get_from_cmid($cm->id, mod_forumng::CLONE_DIRECT);
    return $forum->get_completion_state($userid, $type);
}
コード例 #8
0
 /**
  * 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 $DB, $CFG, $USER;
     if (!count($cmids) && !$course) {
         throw new coding_exception("mod_forumng::query_forums requires course id or cmids");
     }
     if (count($cmids)) {
         list($in, $conditionsparams) = mod_forumng_utils::get_in_array_sql('cm.id', $cmids);
         $conditions = $in;
     } else {
         $conditions = "f.course = ?";
         $conditionsparams = array($course->id);
     }
     $singleforum = count($cmids) == 1 ? reset($cmids) : false;
     list($inviewhiddenforums, $inviewhiddenforumsparams) = mod_forumng_utils::get_in_array_sql('fd.forumngid', $viewhiddenforums);
     list($cfdinviewhiddenforums, $inviewhiddenforumsparams) = mod_forumng_utils::get_in_array_sql('cfd.forumngid', $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 && mod_forumng::enabled_read_tracking()) {
         // Work out when unread status ends
         $endtime = time() - $CFG->forumng_readafterdays * 24 * 3600;
         if (!$userid) {
             $userid = $USER->id;
         }
         list($ingroups, $ingroupsparams) = mod_forumng_utils::get_in_array_sql('fd.groupid', $groups);
         list($inaagforums, $inaagforumsparams) = mod_forumng_utils::get_in_array_sql('fd.forumngid', $aagforums);
         $restrictionsql = '';
         $restrictionparams = array();
         if ($singleforum) {
             // If it is for a single forum, get the restriction from the
             // forum type
             $forum = mod_forumng::get_from_cmid($singleforum, mod_forumng::CLONE_DIRECT);
             $type = $forum->get_type();
             if ($type->has_unread_restriction()) {
                 list($value, $restrictionparams) = $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 = get_fast_modinfo($course);
             $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 (forumngtype::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, 'mod_forumng::sort_mod_forumng_result');
                 return $plusresult;
             } else {
                 // Fall through to normal calculation, but change conditions
                 // to include only the 'normal' forums
                 list($in, $inparams) = mod_forumng_utils::get_in_array_sql('cm.id', $okayids);
                 $conditions .= " AND " . $in;
                 $conditionsparams = array_merge($conditionsparams, $inparams);
             }
         }
         // NOTE fpfirst is used only by forum types, not here
         $now = time();
         $sharedquerypart = "\nFROM\n    {forumng_discussions} fd\n    INNER JOIN {forumng_posts} fplast ON fd.lastpostid = fplast.id\n    INNER JOIN {forumng_posts} fpfirst ON fd.postid = fpfirst.id\n    LEFT JOIN {forumng_read} fr ON fd.id = fr.discussionid AND fr.userid = ?\nWHERE\n    fd.forumngid = f.id AND fplast.modified>?\n    AND (\n        (fd.groupid IS NULL)\n        OR ({$ingroups})\n        OR cm.groupmode = " . VISIBLEGROUPS . "\n        OR ({$inaagforums})\n    )\n    AND fd.deleted = 0\n    AND (\n        ((fd.timestart = 0 OR fd.timestart <= ?)\n        AND (fd.timeend = 0 OR fd.timeend > ?))\n        OR ({$inviewhiddenforums})\n    )\n    AND ((fplast.edituserid IS NOT NULL AND fplast.edituserid<>?)\n        OR fplast.userid<>?)\n    AND (fr.time IS NULL OR fplast.modified>fr.time)\n    {$restrictionsql}";
         $sharedqueryparams = array_merge(array($userid, $endtime), $ingroupsparams, $inaagforumsparams, array($now, $now), $inviewhiddenforumsparams, array($userid, $userid), $restrictionparams);
         // 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) {
             // Query to get 0/1 unread discussions count
             $readtracking = self::select_exists("SELECT 1 {$sharedquerypart}") . "AS f_hasunreaddiscussions";
             $readtrackingparams = $sharedqueryparams;
         } else {
             // Query to get full unread discussions count
             $readtracking = "\n(SELECT\n    COUNT(1)\n{$sharedquerypart}\n) AS f_numunreaddiscussions";
             $readtrackingparams = $sharedqueryparams;
         }
     } else {
         $readtracking = "NULL AS numreadposts, NULL AS timeread";
         $readtrackingparams = array();
     }
     $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
     $result = $DB->get_records_sql($sql = "\nSELECT\n    " . mod_forumng_utils::select_mod_forumng_fields('f') . ",\n    " . mod_forumng_utils::select_course_module_fields('cm') . ",\n    " . mod_forumng_utils::select_course_fields('c') . ",\n    (SELECT COUNT(1)\n        FROM {forumng_discussions} cfd\n        WHERE cfd.forumngid = f.id AND cfd.deleted = 0\n        AND (\n            ((cfd.timestart = 0 OR cfd.timestart <= ?)\n            AND (cfd.timeend = 0 OR cfd.timeend > ?))\n            OR ({$cfdinviewhiddenforums})\n        )\n        ) AS f_numdiscussions,\n    {$readtracking}\nFROM\n    {forumng} f\n    INNER JOIN {course_modules} cm ON cm.instance = f.id\n        AND cm.module = (SELECT id from {modules} WHERE name = 'forumng')\n    INNER JOIN {course} c ON c.id = f.course\nWHERE\n    {$conditions}\nORDER BY\n    {$orderby}", array_merge(array($now, $now), $inviewhiddenforumsparams, $readtrackingparams, $conditionsparams));
     if (count($plusresult) > 0) {
         foreach ($plusresult as $key => $value) {
             $result[$key] = $value;
         }
         uasort($result, 'mod_forumng::sort_mod_forumng_result');
     }
     return $result;
 }
コード例 #9
0
 public function heading_summary()
 {
     $forum = mod_forumng::get_from_cmid($this->cm->id, $this->cloneid);
     return get_string('exportingcontentfrom', 'portfolio', strtolower(get_string('forum', 'forumng')) . ': ' . $forum->get_name());
 }
 /**
  * This function handles all aspects of page processing and then calls
  * methods in $selector at the appropriate moments.
  * @param post_selector $selector Object that extends this base class
  */
 public static function go($selector)
 {
     global $PAGE, $FULLME, $SESSION;
     $id = required_param('id', PARAM_INT);
     $cloneid = optional_param('clone', 0, PARAM_INT);
     $fromselect = optional_param('fromselect', 0, PARAM_INT);
     $all = optional_param('all', '', PARAM_RAW);
     $select = optional_param('select', '', PARAM_RAW);
     $isform = optional_param('postselectform', 0, PARAM_INT);
     $PAGE->set_url($FULLME);
     // Get basic objects.
     $forum = mod_forumng::get_from_cmid($id, $cloneid);
     $forumngid = $forum->get_id();
     $params = array_merge($_REQUEST, $forum->get_link_params_array());
     if (optional_param('cancel', '', PARAM_RAW)) {
         // CALL TYPE 6.
         redirect('../../view.php?' . $forum->get_link_params(mod_forumng::PARAM_PLAIN));
     }
     $cm = $forum->get_course_module();
     $course = $forum->get_course();
     $groupid = mod_forumng::get_activity_group($cm, true);
     // Page name and permissions.
     $pagename = $selector->get_page_name();
     $buttonname = $selector->get_button_name();
     $forum->require_view($groupid);
     $selector->require_capability($forum->get_context(), $forum);
     if (!($fromselect || $isform || $all)) {
         // Either an initial request (non-JS) to display the 'dialog' box,
         // or a request to show the list of posts with checkboxes for selection.
         // Both types share same navigation.
         $out = $forum->init_page(new moodle_url('/mod/forumng/view.php', $forum->get_link_params_array()));
         print $out->header();
         if (!$select) {
             // Show initial dialog.
             print $out->box_start();
             print html_writer::tag('h2', $buttonname);
             print html_writer::start_tag('form', array('action' => $_SERVER['PHP_SELF'], 'method' => 'get', 'id' => 'discsel'));
             print html_writer::start_tag('div');
             foreach ($params as $param => $paramval) {
                 print html_writer::empty_tag('input', array('name' => $param, 'type' => 'hidden', 'value' => $paramval));
             }
             print html_writer::tag('p', get_string('selectordiscall', 'forumng'));
             print html_writer::start_tag('div', array('class' => 'forumng-buttons'));
             print html_writer::empty_tag('input', array('name' => 'all', 'type' => 'submit', 'value' => get_string('selectoralldisc', 'forumng')));
             print html_writer::empty_tag('input', array('name' => 'select', 'type' => 'submit', 'value' => get_string('selectorselecteddisc', 'forumng')));
             print html_writer::empty_tag('input', array('name' => 'cancel', 'type' => 'submit', 'value' => get_string('cancel')));
             print html_writer::end_tag('div');
             print html_writer::end_tag('div');
             print html_writer::end_tag('form');
             print $out->box_end();
         } else {
             // Show list of posts to select.
             print html_writer::start_tag('div', array('class' => 'forumng-selectintro'));
             print html_writer::tag('p', get_string('selectdiscintro', 'forumng'));
             print html_writer::end_tag('div');
             print html_writer::start_tag('form', array('action' => $_SERVER['PHP_SELF'], 'method' => 'post', 'id' => 'discsel'));
             print html_writer::start_tag('div');
             print $forum->get_link_params(mod_forumng::PARAM_FORM);
             print html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'fromselect', 'value' => '1'));
             foreach ($params as $param => $paramval) {
                 print html_writer::empty_tag('input', array('name' => $param, 'type' => 'hidden', 'value' => $paramval));
             }
             // Now show discussions, allow for override at type level if following is no good.
             if (method_exists($forum->get_type(), 'print_select_page')) {
                 print $forum->get_type()->print_select_page($forum, $groupid);
             } else {
                 // Use default processing, get view and hack in selectors.
                 ob_start();
                 $forum->get_type()->print_view_page($forum, $groupid);
                 $discussionhtml = ob_get_contents();
                 ob_end_clean();
                 // Try and hack into the discussion list - must be xhtml...
                 $doc = new DOMDocument('1.0', 'utf-8');
                 @$doc->loadHTML($discussionhtml);
                 $docnew = new DOMDocument('1.0', 'utf-8');
                 $xpath = new DOMXPath($doc);
                 $lists = $xpath->query("//table[contains(concat(' ',normalize-space(@class),' '),' forumng-discussionlist ')]");
                 // Remove all links.
                 foreach ($lists as $list) {
                     $links = $xpath->query("//a|//form", $list);
                     foreach ($links as $node) {
                         if ($node->nodeName == 'a') {
                             // Disable links.
                             $node->removeAttribute('href');
                         } else {
                             // Remove any forms.
                             $node->parentNode->removeChild($node);
                         }
                     }
                     // Add in discussion select.
                     $rows = $xpath->query("//table[@class='generaltable forumng-discussionlist']\n                                //tr[not(@class) or @class!='forumng-divider']", $list);
                     for ($a = 0, $len = $rows->length; $a < $len; $a++) {
                         // Add in select options for each row, checking types.
                         $row = $rows->item($a);
                         if ($a == 0) {
                             $newcell = $doc->createElement('th', get_string('selectorselectdisc', 'mod_forumng'));
                             $newcell->setAttribute('class', 'header');
                             $newcell->setAttribute('scope', 'col');
                             $row->appendChild($newcell);
                         } else {
                             $id = $row->getAttribute('id');
                             if (strpos($id, 'discrow') === false) {
                                 continue;
                             }
                             // Get discussion id from row id as added by renderer.
                             $id = str_replace('discrow_', '', $id);
                             // Check if we include checkbox or not.
                             $classar = explode(' ', $row->getAttribute('class'));
                             $includematches = array_intersect($selector->only_discussion_types(), $classar);
                             $excludematches = array_intersect($selector->exclude_discussion_types(), $classar);
                             if ((count($selector->only_discussion_types()) == 0 || count($includematches) > 0) && count($excludematches) == 0) {
                                 // OK to include, add checkbox and label.
                                 $select = $doc->createElement('input');
                                 $select->setAttribute('type', 'checkbox');
                                 $select->setAttribute('name', "selectd{$id}");
                                 $select->setAttribute('id', "selectd{$id}");
                                 $label = $doc->createElement('label', get_string('selectorselectdisc', 'mod_forumng'));
                                 $label->setAttribute('for', "selectd{$id}");
                                 $label->setAttribute('class', 'accesshide');
                                 $newcell = $doc->createElement('td');
                                 $newcell->setAttribute('class', 'dselect');
                                 $newcell->appendChild($select);
                                 $newcell->appendChild($label);
                                 $row->appendChild($newcell);
                             } else {
                                 $newcell = $doc->createElement('td', '&nbsp;');
                                 $row->appendChild($newcell);
                             }
                         }
                     }
                     // Keep only discussion list by moving to new xml doc.
                     $newnode = $docnew->importNode($list, true);
                     $docnew->appendChild($newnode);
                 }
                 print $docnew->saveHTML();
             }
             print html_writer::start_tag('div', array('class' => 'forumng-selectoutro'));
             print html_writer::empty_tag('input', array('type' => 'submit', 'value' => get_string('confirmselection', 'forumng')));
             print html_writer::empty_tag('input', array('type' => 'submit', 'name' => 'cancel', 'value' => get_string('cancel')));
             print html_writer::end_tag('div');
             print html_writer::end_tag('div');
             print html_writer::end_tag('form');
         }
         // Display footer.
         print $out->footer();
     } else {
         // Call types 3, 4, and 5 use the form (and may include list of postids).
         $postids = array();
         $selectedids = array();
         foreach ($_POST as $field => $value) {
             $matches = array();
             if (!is_array($value) && (string) $value !== '0' && preg_match('~^selectd([0-9]+)$~', $field, $matches)) {
                 $selectedids[] = $matches[1];
             }
         }
         if (!empty($selectedids)) {
             // Check access.
             foreach ($selectedids as $id) {
                 $discuss = mod_forumng_discussion::get_from_id($id, $cloneid);
                 if ($forum->get_type()->can_view_discussion($discuss)) {
                     $postids[] = $id;
                 }
             }
         } else {
             if (!$all) {
                 // No slections made.
                 redirect('../../view.php?' . $forum->get_link_params(mod_forumng::PARAM_PLAIN));
             }
             // Work out discussion list for this page (e.g. selected All).
             $sortorder = optional_param('sort', 'd', PARAM_ALPHA);
             if (isset($SESSION->forumng_discussionlist[$forumngid]->sort)) {
                 $sortorder = $SESSION->forumng_discussionlist[$forumngid]->sort;
             }
             $page = optional_param('page', 1, PARAM_INT);
             if (isset($SESSION->forumng_discussionlist[$forumngid]->page)) {
                 $page = $SESSION->forumng_discussionlist[$forumngid]->page;
             }
             $sortchar = substr($sortorder, 0, 1);
             if (strlen($sortorder) == 2) {
                 $sortreverse = substr($sortorder, 1, 1) == 'r' ? true : false;
             } else {
                 $sortreverse = false;
             }
             $sort = mod_forumng::get_sort_code($sortchar);
             $list = $forum->get_discussion_list($groupid, $forum->can_view_hidden(), $page, $sort, $sortreverse);
             $discussionsarr = array_merge($list->get_sticky_discussions(), $list->get_normal_discussions());
             // Double check ID is valid and user can view.
             for ($a = 0; $a < count($discussionsarr); $a++) {
                 if ($forum->get_type()->can_view_discussion($discussionsarr[$a])) {
                     $postids[] = $discussionsarr[$a]->get_id();
                 }
             }
         }
         $out = $forum->init_page(new moodle_url('/mod/forumng/view.php', $forum->get_link_params_array()), $pagename);
         // Get form to use.
         $mform = $selector->get_form($forum, $all, $postids);
         if (!$mform) {
             // Some options do not need a confirmation form; in that case,
             // just apply the action immediately.
             $selector->apply($forum, $all, $postids, null);
             exit;
         }
         // Check cancel.
         if ($mform->is_cancelled()) {
             redirect('../../view.php?' . $forum->get_link_params(mod_forumng::PARAM_PLAIN));
         }
         if ($fromform = $mform->get_data()) {
             // User submitted form to confirm process, which should now be
             // applied by selector.
             $selector->apply($forum, $all, $postids, $fromform);
             exit;
         } else {
             print $out->header();
             // User requested form either via JavaScript or the other way, and
             // either with all messages or the whole discussion.
             // Print form.
             print $mform->display();
             // Print optional content that goes after form.
             print $selector->get_content_after_form($forum, $all, $postids, $fromform);
             // Display footer.
             print $out->footer();
         }
     }
 }