/** * Display the report. */ public function display($game, $cm, $course) { global $CFG, $SESSION, $DB; // Define some strings. $strreallydel = addslashes(get_string('deleteattemptcheck', 'game')); $strtimeformat = get_string('strftimedatetime'); $strreviewquestion = get_string('reviewresponse', 'quiz'); // Only print headers if not asked to download data. if (!($download = optional_param('download', null))) { $this->print_header_and_tabs($cm, $course, $game, $reportmode = "overview"); } // Deal with actions. $action = optional_param('action', '', PARAM_ACTION); switch ($action) { case 'delete': // Some attempts need to be deleted. $attemptids = optional_param('attemptid', array(), PARAM_INT); foreach ($attemptids as $attemptid) { if ($attemptid && ($todelete = get_record('game_attempts', 'id', $attemptid))) { delete_records('game_attempts', 'id', $attemptid); delete_records('game_queries', 'attemptid', $attemptid); // Search game_attempts for other instances by this user. // If none, then delete record for this game, this user from game_grades. // else recalculate best grade. $userid = $todelete->userid; if (!record_exists('game_attempts', 'userid', $userid, 'gameid', $game->id)) { delete_records('game_grades', 'userid', $userid, 'gameid', $game->id); } else { game_save_best_score($game, $userid); } } } break; } // Print information on the number of existing attempts. if (!$download) { // Do not print notices when downloading. if ($attemptnum = count_records('game_attempts', 'gameid', $game->id)) { $a = new stdClass(); $a->attemptnum = $attemptnum; $a->studentnum = count_records_select('game_attempts', "gameid = '{$game->id}' AND preview = '0'", 'COUNT(DISTINCT userid)'); $a->studentstring = $course->students; notify(get_string('numattempts', 'game', $a)); } } $context = get_context_instance(CONTEXT_MODULE, $cm->id); // Find out current groups mode. if ($groupmode = groupmode($course, $cm)) { // Groups are being used. if (!$download) { $currentgroup = setup_and_print_groups($course, $groupmode, "report.php?id={$cm->id}&mode=overview"); } else { $currentgroup = get_and_set_current_group($course, $groupmode); } } else { $currentgroup = get_and_set_current_group($course, $groupmode); } // Set table options. $noattempts = optional_param('noattempts', 0, PARAM_INT); $detailedmarks = optional_param('detailedmarks', 0, PARAM_INT); $pagesize = optional_param('pagesize', 10, PARAM_INT); $hasfeedback = game_has_feedback($game->id) && $game->grade > 1.0E-7; if ($pagesize < 1) { $pagesize = 10; } // Now check if asked download of data. if ($download) { $filename = clean_filename("{$course->shortname} " . format_string($game->name, true)); $sort = ''; } // Define table columns. $tablecolumns = array('checkbox', 'picture', 'fullname', 'timestart', 'timefinish', 'duration'); $tableheaders = array(null, '', get_string('fullname'), get_string('startedon', 'game'), get_string('timecompleted', 'game'), get_string('attemptduration', 'game')); if ($game->grade) { $tablecolumns[] = 'grade'; $tableheaders[] = get_string('grade', 'game') . '/' . $game->grade; } if ($detailedmarks) { // We want to display marks for all questions. // Start by getting all questions. $questionlist = game_questions_in_game($game->questions); $questionids = explode(',', $questionlist); $sql = "SELECT q.*, i.score AS maxgrade, i.id AS instance" . " FROM {question} q," . " {game_queries} i" . " WHERE i.gameid = '{$game->id}' AND q.id = i.questionid" . " AND q.id IN ({$questionlist})"; if (!($questions = get_records_sql($sql))) { print_error('No questions found'); } $number = 1; foreach ($questionids as $key => $id) { if ($questions[$id]->length) { // Only print questions of non-zero length. $tablecolumns[] = '$' . $id; $tableheaders[] = '#' . $number; $questions[$id]->number = $number; $number += $questions[$id]->length; } else { // Get rid of zero length questions. unset($questions[$id]); unset($questionids[$key]); } } } if ($hasfeedback) { $tablecolumns[] = 'feedbacktext'; $tableheaders[] = get_string('feedback', 'game'); } if (!$download) { // Set up the table. $table = new flexible_table('mod-game-report-overview-report'); $table->define_columns($tablecolumns); $table->define_headers($tableheaders); $table->define_baseurl($CFG->wwwroot . '/mod/game/report.php?mode=overview&id=' . $cm->id . '&noattempts=' . $noattempts . '&detailedmarks=' . $detailedmarks . '&pagesize=' . $pagesize); $table->sortable(true); $table->collapsible(true); $table->column_suppress('picture'); $table->column_suppress('fullname'); $table->column_class('picture', 'picture'); $table->set_attribute('cellspacing', '0'); $table->set_attribute('id', 'attempts'); $table->set_attribute('class', 'generaltable generalbox'); // Start working -- this is necessary as soon as the niceties are over. $table->setup(); } else { if ($download == 'ODS') { require_once "{$CFG->libdir}/odslib.class.php"; $filename .= ".ods"; // Creating a workbook. $workbook = new MoodleODSWorkbook("-"); // Sending HTTP headers. $workbook->send($filename); // Creating the first worksheet. $sheettitle = get_string('reportoverview', 'game'); $myxls =& $workbook->add_worksheet($sheettitle); // Format types. $format =& $workbook->add_format(); $format->set_bold(0); $formatbc =& $workbook->add_format(); $formatbc->set_bold(1); $formatbc->set_align('center'); $formatb =& $workbook->add_format(); $formatb->set_bold(1); $formaty =& $workbook->add_format(); $formaty->set_bg_color('yellow'); $formatc =& $workbook->add_format(); $formatc->set_align('center'); $formatr =& $workbook->add_format(); $formatr->set_bold(1); $formatr->set_color('red'); $formatr->set_align('center'); $formatg =& $workbook->add_format(); $formatg->set_bold(1); $formatg->set_color('green'); $formatg->set_align('center'); // Here starts workshhet headers. $headers = array(get_string('fullname'), get_string('startedon', 'game'), get_string('timecompleted', 'game'), get_string('attemptduration', 'game')); if ($game->grade) { $headers[] = get_string('grade', 'game') . '/' . $game->grade; } if ($detailedmarks) { foreach ($questionids as $id) { $headers[] = '#' . $questions[$id]->number; } } if ($hasfeedback) { $headers[] = get_string('feedback', 'game'); } $colnum = 0; foreach ($headers as $item) { $myxls->write(0, $colnum, $item, $formatbc); $colnum++; } $rownum = 1; } else { if ($download == 'Excel') { require_once "{$CFG->libdir}/excellib.class.php"; $filename .= ".xls"; // Creating a workbook. $workbook = new MoodleExcelWorkbook("-"); // Sending HTTP headers. $workbook->send($filename); // Creating the first worksheet. $sheettitle = get_string('reportoverview', 'game'); $myxls =& $workbook->add_worksheet($sheettitle); // Format types. $format =& $workbook->add_format(); $format->set_bold(0); $formatbc =& $workbook->add_format(); $formatbc->set_bold(1); $formatbc->set_align('center'); $formatb =& $workbook->add_format(); $formatb->set_bold(1); $formaty =& $workbook->add_format(); $formaty->set_bg_color('yellow'); $formatc =& $workbook->add_format(); $formatc->set_align('center'); $formatr =& $workbook->add_format(); $formatr->set_bold(1); $formatr->set_color('red'); $formatr->set_align('center'); $formatg =& $workbook->add_format(); $formatg->set_bold(1); $formatg->set_color('green'); $formatg->set_align('center'); // Here starts workshhet headers. $headers = array(get_string('fullname'), get_string('startedon', 'game'), get_string('timecompleted', 'game'), get_string('attemptduration', 'game')); if ($game->grade) { $headers[] = get_string('grade', 'game') . '/' . $game->grade; } if ($detailedmarks) { foreach ($questionids as $id) { $headers[] = '#' . $questions[$id]->number; } } if ($hasfeedback) { $headers[] = get_string('feedback', 'game'); } $colnum = 0; foreach ($headers as $item) { $myxls->write(0, $colnum, $item, $formatbc); $colnum++; } $rownum = 1; } else { if ($download == 'CSV') { $filename .= ".txt"; header("Content-Type: application/download\n"); header("Content-Disposition: attachment; filename=\"{$filename}\""); header("Expires: 0"); header("Cache-Control: must-revalidate,post-check=0,pre-check=0"); header("Pragma: public"); $headers = get_string('fullname') . "\t" . get_string('startedon', 'game') . "\t" . get_string('timecompleted', 'game') . "\t" . get_string('attemptduration', 'game'); if ($game->grade) { $headers .= "\t" . get_string('grade', 'game') . "/" . $game->grade; } if ($detailedmarks) { foreach ($questionids as $id) { $headers .= "\t#" . $questions[$id]->number; } } if ($hasfeedback) { $headers .= "\t" . get_string('feedback', 'game'); } echo $headers . " \n"; } } } } $contextlists = get_related_contexts_string(get_context_instance(CONTEXT_COURSE, $course->id)); // Construct the SQL. $select = 'SELECT qa.id,' . sql_concat('u.id', '\'#\'', $db->IfNull('qa.attempt', '0')) . ' AS uniqueid, ' . 'qa.id as attemptuniqueid, qa.id AS attempt, u.id AS userid, u.firstname, u.lastname, u.picture, ' . 'qa.score, qa.timefinish, qa.timestart, qa.timefinish - qa.timestart AS duration '; if ($course->id != SITEID) { // This is too complicated, so just do it for each of the four cases. if (!empty($currentgroup) && empty($noattempts)) { // We want a particular group and we only want to see students WITH attempts. // So join on groups_members and do an inner join on attempts. $from = 'FROM {user} u JOIN {role_assignments} ra ON ra.userid = u.id ' . groups_members_join_sql() . 'JOIN {game_attempts} qa ON u.id = qa.userid AND qa.gameid = ' . $game->id; $where = ' WHERE ra.contextid ' . $contextlists . ' AND ' . groups_members_where_sql($currentgroup) . ' AND qa.preview = 0'; } else { if (!empty($currentgroup) && !empty($noattempts)) { // We want a particular group and we want to do something funky with attempts. // So join on groups_members and left join on attempts... $from = 'FROM {user} u JOIN {role_assignments} ra ON ra.userid = u.id ' . groups_members_join_sql() . 'LEFT JOIN {game_attempts} qa ON u.id = qa.userid AND qa.gameid = ' . $game->id; $where = ' WHERE ra.contextid ' . $contextlists . ' AND ' . groups_members_where_sql($currentgroup); if ($noattempts == 1) { // Noattempts = 1 means only no attempts, so make the left join ask. // For only records where the right is null (no attempts). $where .= ' AND qa.userid IS NULL'; // Show ONLY no attempts. } else { // We are including attempts, so exclude previews. $where .= ' AND qa.preview = 0'; } } else { if (empty($currentgroup)) { // We don't care about group, and we to do something funky with attempts. // So do a left join on attempts. $from = 'FROM {user} u JOIN {role_assignments} ra ON ra.userid = u.id ' . ' LEFT JOIN {game_attempts} qa ON u.id = qa.userid AND qa.gameid = ' . $game->id; $where = " WHERE ra.contextid {$contextlists}"; if (empty($noattempts)) { // Show ONLY students with attempts. $where .= ' AND qa.userid IS NOT NULL AND qa.preview = 0'; } else { if ($noattempts == 1) { // The noattempts = 1 means only no attempts,. // So make the left join ask for only records where the right is null (no attempts). // Show ONLY students without attempts. $where .= ' AND qa.userid IS NULL'; } else { if ($noattempts == 3) { // We want all attempts. $from = 'FROM {user} u JOIN {game_attempts} qa ON u.id = qa.userid '; $where = ' WHERE qa.gameid = ' . $game->id . ' AND qa.preview = 0'; } } } // The noattempts = 2 means we want all students, with or without attempts. } } } $countsql = 'SELECT COUNT(DISTINCT(' . sql_concat('u.id', '\'#\'', $db->IfNull('qa.attempt', '0')) . ')) ' . $from . $where; } else { if (empty($noattempts)) { $from = 'FROM {user} u JOIN {game_attempts} qa ON u.id = qa.userid '; $where = ' WHERE qa.gameid = ' . $game->id . ' AND qa.preview = 0'; $countsql = 'SELECT COUNT(DISTINCT(' . sql_concat('u.id', '\'#\'', $db->IfNull('qa.attempt', '0')) . ')) ' . $from . $where; } } if (!$download) { // Add extra limits due to initials bar. if ($table->get_sql_where()) { $where .= ' AND ' . $table->get_sql_where(); } // Count the records NOW, before funky question grade sorting messes up $from. if (!empty($countsql)) { $totalinitials = count_records_sql($countsql); if ($table->get_sql_where()) { $countsql .= ' AND ' . $table->get_sql_where(); } $total = count_records_sql($countsql); } // Add extra limits due to sorting by question grade. if ($sort = $table->get_sql_sort()) { $sortparts = explode(',', $sort); $newsort = array(); $questionsort = false; foreach ($sortparts as $sortpart) { $sortpart = trim($sortpart); if (substr($sortpart, 0, 1) == '$') { if (!$questionsort) { $qid = intval(substr($sortpart, 1)); $select .= ', grade '; $from .= ' LEFT JOIN {question_sessions} qns ON qns.attemptid = qa.id ' . 'LEFT JOIN {question_states} qs ON qs.id = qns.newgraded '; $where .= ' AND (' . sql_isnull('qns.questionid') . ' OR qns.questionid = ' . $qid . ')'; $newsort[] = 'grade ' . (strpos($sortpart, 'ASC') ? 'ASC' : 'DESC'); $questionsort = true; } } else { $newsort[] = $sortpart; } } // Reconstruct the sort string. $sort = ' ORDER BY ' . implode(', ', $newsort); } // Fix some wired sorting. if (empty($sort)) { $sort = ' ORDER BY qa.id'; } $table->pagesize($pagesize, $total); } // If there is feedback, include it in the query. if ($hasfeedback) { $select .= ', qf.feedbacktext '; $from .= " JOIN {game_feedback} qf ON " . "qf.gameid = {$game->id} AND qf.mingrade <= qa.score * {$game->grade} AND qa.score * {$game->grade} < qf.maxgrade"; } // Fetch the attempts. if (!empty($from)) { // If we're in the site course and displaying no attempts, it makes no sense to do the query. if (!$download) { $attempts = get_records_sql($select . $from . $where . $sort, $table->get_page_start(), $table->get_page_size()); } else { $attempts = get_records_sql($select . $from . $where . $sort); } } else { $attempts = array(); } // Build table rows. if (!$download) { $table->initialbars($totalinitials > 20); } if (!empty($attempts) || !empty($noattempts)) { if ($attempts) { foreach ($attempts as $attempt) { $picture = print_user_picture($attempt->userid, $course->id, $attempt->picture, false, true); /* Uncomment the commented lines below if you are choosing to show unenrolled users and * have uncommented the corresponding lines earlier in this script * if (in_array($attempt->userid, $unenrolledusers)) { * $userlink = '<a class="dimmed" href="'.$CFG->wwwroot. * '/user/view.php?id='.$attempt->userid.'&course='.$course->id.'">'.fullname($attempt).'</a>'; *} *else { * $userlink = '<a href="'.$CFG->wwwroot.'/user/view.php?id='. * $attempt->userid.'&course='.$course->id.'">'.fullname($attempt).'</a>'; *} */ if (!$download) { $row = array('<input type="checkbox" name="attemptid[]" value="' . $attempt->attempt . '" />', $picture, $userlink, empty($attempt->attempt) ? '-' : '<a href="review.php?q=' . $game->id . '&attempt=' . $attempt->attempt . '">' . userdate($attempt->timestart, $strtimeformat) . '</a>', empty($attempt->timefinish) ? '-' : '<a href="review.php?q=' . $game->id . '&attempt=' . $attempt->attempt . '">' . userdate($attempt->timefinish, $strtimeformat) . '</a>', empty($attempt->attempt) ? '-' : (empty($attempt->timefinish) ? get_string('unfinished', 'game') : format_time($attempt->duration))); } else { $row = array(fullname($attempt), empty($attempt->attempt) ? '-' : userdate($attempt->timestart, $strtimeformat), empty($attempt->timefinish) ? '-' : userdate($attempt->timefinish, $strtimeformat), empty($attempt->attempt) ? '-' : (empty($attempt->timefinish) ? get_string('unfinished', 'game') : format_time($attempt->duration))); } if ($game->grade) { if (!$download) { $row[] = $attempt->score === null ? '-' : '<a href="review.php?q=' . $game->id . '&attempt=' . $attempt->attempt . '">' . round($attempt->score * $game->grade, $game->decimalpoints) . '</a>'; } else { $row[] = $attempt->score === null ? '-' : round($attempt->score * $game->grade, $game->decimalpoints); } } if ($detailedmarks) { if (empty($attempt->attempt)) { foreach ($questionids as $questionid) { $row[] = '-'; } } else { foreach ($questionids as $questionid) { if ($gradedstateid = get_field('question_sessions', 'newgraded', 'attemptid', $attempt->attemptuniqueid, 'questionid', $questionid)) { $grade = round(get_field('question_states', 'grade', 'id', $gradedstateid), $game->decimalpoints); } else { $grade = '--'; } if (!$download) { $row[] = link_to_popup_window('/mod/game/reviewquestion.php?state=' . $gradedstateid . '&number=' . $questions[$questionid]->number, 'reviewquestion', $grade, 450, 650, $strreviewquestion, 'none', true); } else { $row[] = $grade; } } } } if ($hasfeedback) { if ($attempt->timefinish) { $row[] = $attempt->feedbacktext; } else { $row[] = '-'; } } if (!$download) { $table->add_data($row); } else { if ($download == 'Excel' or $download == 'ODS') { $colnum = 0; foreach ($row as $item) { $myxls->write($rownum, $colnum, $item, $format); $colnum++; } $rownum++; } else { if ($download == 'CSV') { $text = implode("\t", $row); echo $text . " \n"; } } } } } if (!$download) { // Start form. echo '<div id="tablecontainer">'; echo '<form id="attemptsform" method="post" action="report.php" ' . 'onsubmit="var menu = document.getElementById(\'menuaction\'); ' . 'return (menu.options[menu.selectedIndex].value == \'delete\' ? confirm(\'' . $strreallydel . '\') : true);">'; echo '<div>'; echo '<input type="hidden" name="id" value="' . $cm->id . '" />'; echo '<input type="hidden" name="mode" value="overview" />'; // Print table. $table->print_html(); // Print "Select all" etc.. if (!empty($attempts)) { echo '<table id="commands">'; echo '<tr><td>'; echo '<a href="javascript:select_all_in(\'DIV\',null,\'tablecontainer\');">' . get_string('selectall', 'game') . '</a> / '; echo '<a href="javascript:deselect_all_in(\'DIV\',null,\'tablecontainer\');">' . get_string('selectnone', 'game') . '</a> '; echo ' '; $options = array('delete' => get_string('delete')); echo choose_from_menu($options, 'action', '', get_string('withselected', 'game'), 'if(this.selectedIndex > 0) submitFormById(\'attemptsform\');', '', true); echo '<noscript id="noscriptmenuaction" style="display: inline;"><div>'; echo '<input type="submit" value="' . get_string('go') . '" /></div></noscript>'; echo '<script type="text/javascript">' . "\n<!--\n" . 'document.getElementById("noscriptmenuaction").style.display = "none";' . "\n-->\n" . '</script>'; echo '</td></tr></table>'; } // Close form. echo '</div>'; echo '</form></div>'; if (!empty($attempts)) { echo '<table class="boxaligncenter"><tr>'; $options = array(); $options["id"] = "{$cm->id}"; $options["q"] = "{$game->id}"; $options["mode"] = "overview"; $options['sesskey'] = sesskey(); $options["noheader"] = "yes"; $options['noattempts'] = $noattempts; $options['detailedmarks'] = $detailedmarks; echo '<td>'; $options["download"] = "ODS"; print_single_button("report.php", $options, get_string("downloadods", 'game')); echo "</td>\n"; echo '<td>'; $options["download"] = "Excel"; print_single_button("report.php", $options, get_string("downloadexcel")); echo "</td>\n"; echo '<td>'; $options["download"] = "CSV"; print_single_button('report.php', $options, get_string("downloadtext")); echo "</td>\n"; echo "<td>"; helpbutton('overviewdownload', get_string('overviewdownload', 'quiz'), 'game'); echo "</td>\n"; echo '</tr></table>'; } } else { if ($download == 'Excel' or $download == 'ODS') { $workbook->close(); exit; } else { if ($download == 'CSV') { exit; } } } } else { if (!$download) { $table->print_html(); } } // Print display options. echo '<div class="controls">'; echo '<form id="options" action="report.php" method="get">'; echo '<div>'; echo '<p>' . get_string('displayoptions', 'game') . ': </p>'; echo '<input type="hidden" name="id" value="' . $cm->id . '" />'; echo '<input type="hidden" name="q" value="' . $game->id . '" />'; echo '<input type="hidden" name="mode" value="overview" />'; echo '<input type="hidden" name="noattempts" value="0" />'; echo '<input type="hidden" name="detailedmarks" value="0" />'; echo '<table id="overview-options" class="boxaligncenter">'; echo '<tr align="left">'; echo '<td><label for="pagesize">' . get_string('pagesize', 'game') . '</label></td>'; echo '<td><input type="text" id="pagesize" name="pagesize" size="3" value="' . $pagesize . '" /></td>'; echo '</tr>'; echo '<tr align="left">'; echo '<td colspan="2">'; $options = array(0 => get_string('attemptsonly', 'game', $course->students)); if ($course->id != SITEID) { $options[1] = get_string('noattemptsonly', 'game', $course->students); $options[2] = get_string('allstudents', 'game', $course->students); $options[3] = get_string('allattempts', 'game'); } choose_from_menu($options, 'noattempts', $noattempts, ''); echo '</td></tr>'; echo '<tr align="left">'; echo '<td colspan="2"><input type="checkbox" id="checkdetailedmarks" name="detailedmarks" ' . ($detailedmarks ? 'checked="checked" ' : '') . 'value="1" /> <label for="checkdetailedmarks">' . get_string('showdetailedmarks', 'game') . '</label> '; echo '</td></tr>'; echo '<tr><td colspan="2" align="center">'; echo '<input type="submit" value="' . get_string('go') . '" />'; echo '</td></tr></table>'; echo '</div>'; echo '</form>'; echo '</div>'; echo "\n"; return true; }
require_once "{$CFG->libdir}/rsslib.php"; $id = optional_param('id', 0, PARAM_INT); // Course id $subscribe = optional_param('subscribe', null, PARAM_INT); // Subscribe/Unsubscribe all forums if ($id) { if (!($course = get_record("course", "id", $id))) { error("Course ID is incorrect"); } } else { if (!($course = get_site())) { error("Could not find a top-level course!"); } } require_course_login($course); $currentgroup = get_and_set_current_group($course, groupmode($course)); $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id); unset($SESSION->fromdiscussion); add_to_log($course->id, "forum", "view forums", "index.php?id={$course->id}"); $strforums = get_string("forums", "forum"); $strforum = get_string("forum", "forum"); $strdescription = get_string("description"); $strdiscussions = get_string("discussions", "forum"); $strsubscribed = get_string("subscribed", "forum"); $strunreadposts = get_string("unreadposts", "forum"); $strtracking = get_string('tracking', 'forum'); $strmarkallread = get_string('markallread', 'forum'); $strtrackforum = get_string('trackforum', 'forum'); $strnotrackforum = get_string('notrackforum', 'forum'); $strsubscribe = get_string('subscribe', 'forum'); $strunsubscribe = get_string('unsubscribe', 'forum');
/** * A big combination function to make it easier for modules * to set up groups. * * Terminates if the current user shouldn't be looking at this group * Otherwise returns the current group if there is one * Otherwise returns false if groups aren't relevant * * @uses SEPARATEGROUPS * @uses VISIBLEGROUPS * @param course $course A {@link $COURSE} object * @param int $groupmode Either NOGROUPS, SEPARATEGROUPS or VISIBLEGROUPS * @param string $urlroot ? * @return int|false */ function setup_and_print_groups($course, $groupmode, $urlroot) { global $USER, $SESSION; //needs his id, need to hack his groups in session $changegroup = optional_param('group', -1, PARAM_INT); $currentgroup = get_and_set_current_group($course, $groupmode, $changegroup); if ($currentgroup === false) { return false; } $context = get_context_instance(CONTEXT_COURSE, $course->id); if ($groupmode == SEPARATEGROUPS and !$currentgroup and !has_capability('moodle/site:accessallgroups', $context)) { //we are in separate groups and the current group is group 0, as last set. //this can mean that either, this guy has no group //or, this guy just came from a visible all forum, and he left when he set his current group to 0 (show all) if ($usergroups = groups_get_all_groups($course->id, $USER->id)) { //for the second situation, we need to perform the trick and get him a group. $first = reset($usergroups); $currentgroup = get_and_set_current_group($course, $groupmode, $first->id); } else { //else he has no group in this course print_heading(get_string('notingroup')); print_footer($course); exit; } } if ($groupmode == VISIBLEGROUPS or $groupmode and has_capability('moodle/site:accessallgroups', $context)) { if ($groups = groups_get_all_groups($course->id)) { echo '<div class="groupselector">'; print_group_menu($groups, $groupmode, $currentgroup, $urlroot, 1); echo '</div>'; } } else { if ($groupmode == SEPARATEGROUPS and has_capability('moodle/course:view', $context)) { //get all the groups this guy is in in this course if ($usergroups = groups_get_all_groups($course->id, $USER->id)) { echo '<div class="groupselector">'; //print them in the menu print_group_menu($usergroups, $groupmode, $currentgroup, $urlroot, 0); echo '</div>'; } } } return $currentgroup; }
$navigation = ''; } elseif (!is_callable('build_navigation')) { $navigation = array(array('title' => $course->shortname, 'url' => $CFG->wwwroot . "/course/view.php?id={$course->id}", 'type' => 'course'), array('title' => $strturnitintools, 'url' => $CFG->wwwroot . "/mod/turnitintool/index.php?id={$course->id}", 'type' => 'activity'), array('title' => format_string($turnitintool->name), 'url' => '', 'type' => 'activityinstance')); } else { $navigation = build_navigation('', $cm); } // Do not use navbar in 2.7+ if ((property_exists($CFG, 'branch') and $CFG->branch < 27) || !property_exists($CFG, 'branch')) { turnitintool_header($cm, $course, $_SERVER["REQUEST_URI"], $turnitintool->name, $SITE->fullname, $navigation, "", "", true, update_module_button($cm->id, $course->id, $strturnitintool), navmenu($course)); } else { turnitintool_header($cm, $course, $_SERVER["REQUEST_URI"], $turnitintool->name, $SITE->fullname, $navigation, "", "", true, update_module_button($cm->id, $course->id, $strturnitintool)); } /// Check to see if groups are being used and abstract for 1.8 if neccessary if (!is_callable('groups_get_activity_group')) { $changegroup = optional_param('group', -1, PARAM_INT); $cm->currentgroup = get_and_set_current_group($course, $cm->groupmode, $changegroup); setup_and_print_groups($course, $cm->groupmode, $redirectlink); } else { $groupmode = groups_get_activity_groupmode($cm); if ($groupmode) { groups_get_activity_group($cm, true); groups_print_activity_menu($cm, $redirectlink); } } // Print the main part of the page echo '<div id="turnitintool_style">'; if (!is_null($param_do)) { $do = $param_do; } else { $do = 'intro'; }
if (!($chat = get_record('chat', 'id', $id))) { error('Could not find that chat room!'); } if (!($course = get_record('course', 'id', $chat->course))) { error('Could not find the course this belongs to!'); } if (!($cm = get_coursemodule_from_instance('chat', $chat->id, $course->id))) { error('Course Module ID was incorrect'); } $context = get_context_instance(CONTEXT_MODULE, $cm->id); require_login($course->id, false, $cm); require_capability('mod/chat:chat', $context); /// Check to see if groups are being used here if ($groupmode = groupmode($course, $cm)) { // Groups are being used if ($groupid = get_and_set_current_group($course, $groupmode, $groupid)) { if (!($group = get_record('groups', 'id', $groupid))) { error("That group (id {$groupid}) doesn't exist!"); } $groupname = ': ' . $group->name; } else { $groupname = ': ' . get_string('allparticipants'); } } else { $groupid = 0; $groupname = ''; } $strchat = get_string('modulename', 'chat'); // must be before current_language() in chat_login_user() to force course language!!! $strchats = get_string('modulenameplural', 'chat'); $stridle = get_String('idle', 'chat');
/** * Display a single submission, ready for grading on a popup window * * This default method prints the teacher info and submissioncomment box at the top and * the student info and submission at the bottom. * This method also fetches the necessary data in order to be able to * provide a "Next submission" button. * Calls preprocess_submission() to give assignment type plug-ins a chance * to process submissions before they are graded * This method gets its arguments from the page parameters userid and offset */ function display_submission($extra_javascript = '') { global $CFG; $userid = required_param('userid', PARAM_INT); $offset = required_param('offset', PARAM_INT); //offset for where to start looking for student. if (!($user = get_record('user', 'id', $userid))) { error('No such user!'); } if (!($submission = $this->get_submission($user->id))) { $submission = $this->prepare_new_submission($userid); } if ($submission->timemodified > $submission->timemarked) { $subtype = 'assignmentnew'; } else { $subtype = 'assignmentold'; } /// construct SQL, using current offset to find the data of the next student $course = $this->course; $assignment = $this->assignment; $cm = $this->cm; $context = get_context_instance(CONTEXT_MODULE, $cm->id); /// Get all ppl that can submit assignments $currentgroup = get_and_set_current_group($course, groupmode($course, $cm)); $users = get_users_by_capability($context, 'mod/assignment:submit', 'u.id, u.id', '', '', '', $currentgroup, '', false); $select = 'SELECT u.id, u.firstname, u.lastname, u.picture, s.id AS submissionid, s.grade, s.submissioncomment, s.timemodified, s.timemarked, COALESCE(SIGN(SIGN(s.timemarked) + SIGN(s.timemarked - s.timemodified)), 0) AS status '; $sql = 'FROM ' . $CFG->prefix . 'user u ' . 'LEFT JOIN ' . $CFG->prefix . 'assignment_submissions s ON u.id = s.userid AND s.assignment = ' . $this->assignment->id . ' ' . 'WHERE u.id IN (' . implode(',', array_keys($users)) . ') '; require_once $CFG->libdir . '/tablelib.php'; if ($sort = flexible_table::get_sql_sort('mod-assignment-submissions')) { $sort = 'ORDER BY ' . $sort . ' '; } $nextid = 0; if (($auser = get_records_sql($select . $sql . $sort, $offset + 1, 1)) !== false) { $nextuser = array_shift($auser); /// Calculate user status $nextuser->status = $nextuser->timemarked > 0 && $nextuser->timemarked >= $nextuser->timemodified; $nextid = $nextuser->id; } print_header(get_string('feedback', 'assignment') . ':' . fullname($user, true) . ':' . format_string($this->assignment->name)); /// Print any extra javascript needed for saveandnext echo $extra_javascript; ///SOme javascript to help with setting up >.> echo '<script type="text/javascript">' . "\n"; echo 'function setNext(){' . "\n"; echo 'document.getElementById(\'submitform\').mode.value=\'next\';' . "\n"; echo 'document.getElementById(\'submitform\').userid.value="' . $nextid . '";' . "\n"; echo '}' . "\n"; echo 'function saveNext(){' . "\n"; echo 'document.getElementById(\'submitform\').mode.value=\'saveandnext\';' . "\n"; echo 'document.getElementById(\'submitform\').userid.value="' . $nextid . '";' . "\n"; echo 'document.getElementById(\'submitform\').saveuserid.value="' . $userid . '";' . "\n"; echo 'document.getElementById(\'submitform\').menuindex.value = document.getElementById(\'submitform\').grade.selectedIndex;' . "\n"; echo '}' . "\n"; echo '</script>' . "\n"; echo '<table cellspacing="0" class="feedback ' . $subtype . '" >'; ///Start of teacher info row echo '<tr>'; echo '<td class="picture teacher">'; if ($submission->teacher) { $teacher = get_record('user', 'id', $submission->teacher); } else { global $USER; $teacher = $USER; } print_user_picture($teacher->id, $this->course->id, $teacher->picture); echo '</td>'; echo '<td class="content">'; echo '<form id="submitform" action="submissions.php" method="post">'; echo '<fieldset class="invisiblefieldset">'; echo '<input type="hidden" name="offset" value="' . ($offset + 1) . '" />'; echo '<input type="hidden" name="userid" value="' . $userid . '" />'; echo '<input type="hidden" name="id" value="' . $this->cm->id . '" />'; echo '<input type="hidden" name="mode" value="grade" />'; echo '<input type="hidden" name="menuindex" value="0" />'; //selected menu index //new hidden field, initialized to -1. echo '<input type="hidden" name="saveuserid" value="-1" />'; if ($submission->timemarked) { echo '<div class="from">'; echo '<div class="fullname">' . fullname($teacher, true) . '</div>'; echo '<div class="time">' . userdate($submission->timemarked) . '</div>'; echo '</div>'; } echo '<div class="grade">' . get_string('grade') . ':'; choose_from_menu(make_grades_menu($this->assignment->grade), 'grade', $submission->grade, get_string('nograde'), '', -1); echo '</div>'; echo '<div class="clearer"></div>'; $this->preprocess_submission($submission); echo '<br />'; print_textarea($this->usehtmleditor, 14, 58, 0, 0, 'submissioncomment', $submission->submissioncomment, $this->course->id); if ($this->usehtmleditor) { echo '<input type="hidden" name="format" value="' . FORMAT_HTML . '" />'; } else { echo '<div class="format">'; choose_from_menu(format_text_menu(), "format", $submission->format, ""); helpbutton("textformat", get_string("helpformatting")); echo '</div>'; } ///Print Buttons in Single View echo '<div class="buttons">'; echo '<input type="submit" name="submit" value="' . get_string('savechanges') . '" onclick = "document.getElementById(\'submitform\').menuindex.value = document.getElementById(\'submitform\').grade.selectedIndex" />'; echo '<input type="submit" name="cancel" value="' . get_string('cancel') . '" />'; //if there are more to be graded. if ($nextid) { echo '<input type="submit" name="saveandnext" value="' . get_string('saveandnext') . '" onclick="saveNext()" />'; echo '<input type="submit" name="next" value="' . get_string('next') . '" onclick="setNext();" />'; } echo '</div>'; echo '</fieldset>'; echo '</form>'; $customfeedback = $this->custom_feedbackform($submission, true); if (!empty($customfeedback)) { echo $customfeedback; } echo '</td></tr>'; ///End of teacher info row, Start of student info row echo '<tr>'; echo '<td class="picture user">'; print_user_picture($user->id, $this->course->id, $user->picture); echo '</td>'; echo '<td class="topic">'; echo '<div class="from">'; echo '<div class="fullname">' . fullname($user, true) . '</div>'; if ($submission->timemodified) { echo '<div class="time">' . userdate($submission->timemodified) . $this->display_lateness($submission->timemodified) . '</div>'; } echo '</div>'; $this->print_user_files($user->id); echo '</td>'; echo '</tr>'; ///End of student info row echo '</table>'; if ($this->usehtmleditor) { use_html_editor(); } print_footer('none'); }
// Redirect to field entry } } if ($rid) { //editting a record, do you have access to edit this? if (!has_capability('mod/data:manageentries', $context) or !data_isowner($rid) or !confirm_sesskey()) { error(get_string('noaccess', 'data')); } } /// Print the page header $strdata = get_string('modulenameplural', 'data'); print_header_simple($data->name, "", "<a href='index.php?id={$course->id}'>{$strdata}</a> -> {$data->name}", "", "", true, "", navmenu($course)); print_heading(format_string($data->name)); /// Groups needed for Add entry tab $groupmode = groupmode($course, $cm); $currentgroup = get_and_set_current_group($course, $groupmode); /// Print the tabs $currenttab = 'add'; include 'tabs.php'; $um = new upload_manager('recordsfile', false, false, null, false, 0); if ($um->preprocess_files() && confirm_sesskey()) { $filename = $um->files['recordsfile']['tmp_name']; // Large files are likely to take their time and memory. Let PHP know // that we'll take longer, and that the process should be recycled soon // to free up memory. @set_time_limit(0); @raise_memory_limit("96M"); if (function_exists('apache_child_terminate')) { @apache_child_terminate(); } //Fix mac/dos newlines
function jclic_get_students($cm, $course, $jclicid) { global $CFG; $version_moodle = (double) substr($CFG->release, 0, 3); if ($version_moodle >= 1.7) { $context = get_context_instance(CONTEXT_MODULE, $cm->id); $currentgroup = get_and_set_current_group($course, groupmode($course, $cm)); $users = get_users_by_capability($context, 'mod/jclic:submit', 'u.id, u.id', '', '', '', $currentgroup, '', false); $dbstudents = array(); if (!empty($users)) { $select = 'SELECT u.id AS userid, u.firstname, u.lastname, u.picture '; $sql = 'FROM ' . $CFG->prefix . 'user u ' . 'LEFT JOIN ' . $CFG->prefix . 'jclic_sessions a ON u.id = a.user_id AND a.jclicid = ' . $jclicid . ' ' . 'WHERE u.id IN (' . implode(',', array_keys($users)) . ') '; $dbstudents = get_records_sql($select . $sql); } } else { $dbstudents = get_records_sql("SELECT DISTINCT us.userid, u.firstname, u.lastname\n \t\t\t\t FROM {$CFG->prefix}user u,{$CFG->prefix}user_students us, {$CFG->prefix}jclic j\n \t\t\t\t WHERE us.course=j.course AND j.id={$jclicid} AND u.id=us.userid"); } return $dbstudents; }
/** * @todo Document this function */ function forum_menu_list($course) { $menu = array(); $currentgroup = get_and_set_current_group($course, groupmode($course)); if ($forums = get_all_instances_in_course("forum", $course)) { if ($course->format == 'weeks') { $strsection = get_string('week'); } else { $strsection = get_string('topic'); } foreach ($forums as $forum) { if ($cm = get_coursemodule_from_instance('forum', $forum->id, $course->id)) { $context = get_context_instance(CONTEXT_MODULE, $cm->id); if (!isset($forum->visible)) { if (!instance_is_visible("forum", $forum) && !has_capability('moodle/course:viewhiddenactivities', $context)) { continue; } } $groupmode = groupmode($course, $cm); // Groups are being used if ($groupmode == SEPARATEGROUPS && $currentgroup === false && !has_capability('moodle/site:accessallgroups', $context)) { continue; } } $menu[$forum->id] = format_string($forum->name, true); } } return $menu; }
function get_content() { global $USER, $CFG, $COURSE; if ($this->content !== NULL) { return $this->content; } $this->content = new stdClass(); $this->content->text = ''; $this->content->footer = ''; if (empty($this->instance)) { return $this->content; } $timetoshowusers = 300; //Seconds default if (isset($CFG->block_online_users_timetosee)) { $timetoshowusers = $CFG->block_online_users_timetosee * 60; } $timefrom = 100 * floor((time() - $timetoshowusers) / 100); // Round to nearest 100 seconds for better query cache // Get context so we can check capabilities. $context = get_context_instance(CONTEXT_COURSE, $COURSE->id); //Calculate if we are in separate groups $isseparategroups = $COURSE->groupmode == SEPARATEGROUPS && $COURSE->groupmodeforce && !has_capability('moodle/site:accessallgroups', $context); //Get the user current group $currentgroup = $isseparategroups ? get_and_set_current_group($COURSE, groupmode($COURSE)) : NULL; $groupmembers = ""; $groupselect = ""; //Add this to the SQL to show only group users if ($currentgroup !== NULL) { $groupmembers = ', ' . groups_members_from_sql(); //TODO: ", {$CFG->prefix}groups_members gm "; $groupselect = ' AND ' . groups_members_where_sql($currentgroup, 'u.id'); //" AND u.id = gm.userid AND gm.groupid = '$currentgroup'"; } if ($COURSE->id == SITEID) { // Site-level $select = "SELECT u.id, u.username, u.firstname, u.lastname, u.picture, max(u.lastaccess) as lastaccess "; $from = "FROM {$CFG->prefix}user u \n {$groupmembers} "; $where = "WHERE u.lastaccess > {$timefrom}\n {$groupselect} "; $order = "ORDER BY lastaccess DESC "; } else { // Course-level $courseselect = "AND ul.courseid = '" . $COURSE->id . "'"; $select = "SELECT u.id, u.username, u.firstname, u.lastname, u.picture, max(ul.timeaccess) as lastaccess "; $from = "FROM {$CFG->prefix}user_lastaccess ul,\n {$CFG->prefix}user u\n {$groupmembers} "; $where = "WHERE ul.timeaccess > {$timefrom}\n AND u.id = ul.userid\n AND ul.courseid = {$COURSE->id}\n {$groupselect} "; $order = "ORDER BY lastaccess DESC "; } $groupby = "GROUP BY u.id, u.username, u.firstname, u.lastname, u.picture "; $SQL = $select . $from . $where . $groupby . $order; $users = array(); $pcontext = get_related_contexts_string($context); if ($pusers = get_records_sql($SQL, 0, 50)) { // We'll just take the most recent 50 maximum foreach ($pusers as $puser) { // if current user can't view hidden role assignment in this context and // user has a hidden role assigned at this context or any parent contexts, // ignore this user $SQL = "SELECT id FROM {$CFG->prefix}role_assignments\n WHERE userid = {$puser->id}\n AND contextid {$pcontext}\n AND hidden = 1"; if (!has_capability('moodle/role:viewhiddenassigns', $context) && record_exists_sql($SQL)) { // can't see this user as the current user has no capability // and this user has a hidden assignment at this context or higher continue; } $puser->fullname = fullname($puser); $users[$puser->id] = $puser; } } //Calculate minutes $minutes = floor($timetoshowusers / 60); $this->content->text = "<div class=\"info\">(" . get_string("periodnminutes", "block_online_users", $minutes) . ")</div>"; //Now, we have in users, the list of users to show //Because they are online if (!empty($users)) { //Accessibility: Don't want 'Alt' text for the user picture; DO want it for the envelope/message link (existing lang string). //Accessibility: Converted <div> to <ul>, inherit existing classes & styles. $this->content->text .= "<ul class='list'>\n"; foreach ($users as $user) { $this->content->text .= '<li class="listentry">'; $timeago = format_time(time() - $user->lastaccess); //bruno to calculate correctly on frontpage if ($user->username == 'guest') { $this->content->text .= '<div class="user">' . print_user_picture($user->id, $COURSE->id, $user->picture, 16, true, false, '', false); $this->content->text .= get_string('guestuser') . '</div>'; } else { $this->content->text .= '<div class="user"><a href="' . $CFG->wwwroot . '/user/view.php?id=' . $user->id . '&course=' . $COURSE->id . '" title="' . $timeago . '">'; $this->content->text .= print_user_picture($user->id, $COURSE->id, $user->picture, 16, true, false, '', false); $this->content->text .= $user->fullname . '</a></div>'; } if (!empty($USER->id) and $USER->id != $user->id and !empty($CFG->messaging) and !isguest() and $user->username != 'guest') { // Only when logged in and messaging active etc $this->content->text .= '<div class="message"><a title="' . get_string('messageselectadd') . '" href="' . $CFG->wwwroot . '/message/discussion.php?id=' . $user->id . '" onclick="this.target=\'message_' . $user->id . '\';return openpopup(\'/message/discussion.php?id=' . $user->id . '\', \'message_' . $user->id . '\', \'menubar=0,location=0,scrollbars,status,resizable,width=400,height=500\', 0);">' . '<img class="iconsmall" src="' . $CFG->pixpath . '/t/message.gif" alt="' . get_string('messageselectadd') . '" /></a></div>'; } $this->content->text .= "</li>\n"; } $this->content->text .= '</ul><div class="clearer"><!-- --></div>'; } else { $this->content->text .= "<div class=\"info\">" . get_string("none") . "</div>"; } return $this->content; }
function get_content() { global $CFG, $SITE, $COURSE, $USER; if (empty($CFG->bloglevel)) { $this->content->text = ''; return $this->content; } if (empty($this->config->timewithin)) { $this->config->timewithin = BLOGDEFAULTTIMEWITHIN; } if (empty($this->config->numberoftags)) { $this->config->numberoftags = BLOGDEFAULTNUMBEROFTAGS; } if (empty($this->config->sort)) { $this->config->sort = BLOGDEFAULTSORT; } if ($this->content !== NULL) { return $this->content; } if (empty($this->instance)) { $this->content = ''; return $this->content; } $this->content = new stdClass(); $this->content->text = ''; $this->content->footer = ''; /// Get a list of tags $timewithin = $this->config->timewithin * 24 * 60 * 60; /// convert to seconds $sql = 'SELECT t.id, t.type, t.text, COUNT(DISTINCT bt.id) as ct '; $sql .= "FROM {$CFG->prefix}tags t, {$CFG->prefix}blog_tag_instance bt, {$CFG->prefix}post p "; $sql .= 'WHERE t.id = bt.tagid '; $sql .= 'AND p.id = bt.entryid '; $sql .= 'AND (p.publishstate = \'site\' or p.publishstate=\'public\') '; $sql .= "AND bt.timemodified > {$timewithin} "; $sql .= 'GROUP BY t.id, t.type, t.text '; $sql .= 'ORDER BY ct DESC, t.text ASC'; if ($tags = get_records_sql($sql, 0, $this->config->numberoftags)) { /// There are 2 things to do: /// 1. tags with the same count should have the same size class /// 2. however many tags we have should be spread evenly over the /// 20 size classes $totaltags = count($tags); $currenttag = 0; $size = 20; $lasttagct = -1; $etags = array(); foreach ($tags as $tag) { $currenttag++; if ($currenttag == 1) { $lasttagct = $tag->ct; $size = 20; } else { if ($tag->ct != $lasttagct) { $lasttagct = $tag->ct; $size = 20 - (int) (($currenttag - 1) / $totaltags * 20); } } $tag->class = "{$tag->type} s{$size}"; $etags[] = $tag; } /// Now we sort the tag display order $CFG->tagsort = $this->config->sort; usort($etags, "blog_tags_sort"); /// Finally we create the output /// Accessibility: markup as a list. $this->content->text .= "\n<ul class='inline-list'>\n"; foreach ($etags as $tag) { switch ($CFG->bloglevel) { case BLOG_USER_LEVEL: $filtertype = 'user'; $filterselect = $USER->id; break; case BLOG_GROUP_LEVEL: $filtertype = 'group'; $filterselect = get_and_set_current_group($COURSE, groupmode($COURSE)); break; case BLOG_COURSE_LEVEL: $filtertype = 'course'; if (isset($COURSE->id)) { $filterselect = $COURSE->id; } else { $filterselect = $this->instance->pageid; } break; default: if (isset($COURSE->id) && $COURSE->id != SITEID) { $filtertype = 'course'; $filterselect = $COURSE->id; } else { $filtertype = 'site'; $filterselect = SITEID; } break; } $link = $CFG->wwwroot . '/blog/index.php?filtertype=' . $filtertype . '&filterselect=' . $filterselect . '&tagid=' . $tag->id; $this->content->text .= '<li><a href="' . $link . '" ' . 'class="' . $tag->class . '" ' . 'title="' . get_string('numberofentries', 'blog', $tag->ct) . '">' . $tag->text . '</a></li> '; } $this->content->text .= "\n</ul>\n"; } return $this->content; }
function get_content() { global $CFG, $USER, $COURSE; if ($this->content !== NULL) { return $this->content; } $this->content = new stdClass(); $this->content->text = ''; $this->content->footer = ''; if (empty($this->instance)) { return $this->content; } if ($COURSE->newsitems) { // Create a nice listing of recent postings require_once $CFG->dirroot . '/mod/forum/lib.php'; // We'll need this $text = ''; if (!($forum = forum_get_course_forum($COURSE->id, 'news'))) { return ''; } if (!($cm = get_coursemodule_from_instance('forum', $forum->id, $COURSE->id))) { return ''; } $context = get_context_instance(CONTEXT_MODULE, $cm->id); /// First work out whether we can post to this group and if so, include a link $groupmode = groupmode($COURSE, $cm); $currentgroup = get_and_set_current_group($COURSE, $groupmode); if (forum_user_can_post_discussion($forum, $currentgroup, $groupmode, $cm, $context)) { $text .= '<div class="newlink"><a href="' . $CFG->wwwroot . '/mod/forum/post.php?forum=' . $forum->id . '">' . get_string('addanewtopic', 'forum') . '</a>...</div>'; } /// Get all the recent discussions we're allowed to see if (!($discussions = forum_get_discussions($forum->id, 'p.modified DESC', 0, false, $currentgroup, $COURSE->newsitems))) { $text .= '(' . get_string('nonews', 'forum') . ')'; $this->content->text = $text; return $this->content; } /// Actually create the listing now $strftimerecent = get_string('strftimerecent'); $strmore = get_string('more', 'forum'); /// Accessibility: markup as a list. $text .= "\n<ul class='unlist'>\n"; foreach ($discussions as $discussion) { $discussion->subject = $discussion->name; $discussion->subject = format_string($discussion->subject, true, $forum->course); $text .= '<li class="post">' . '<div class="head">' . '<div class="date">' . userdate($discussion->modified, $strftimerecent) . '</div>' . '<div class="name">' . fullname($discussion) . '</div></div>' . '<div class="info">' . $discussion->subject . ' ' . '<a href="' . $CFG->wwwroot . '/mod/forum/discuss.php?d=' . $discussion->discussion . '">' . $strmore . '...</a></div>' . "</li>\n"; } $text .= "</ul>\n"; $this->content->text = $text; $this->content->footer = '<a href="' . $CFG->wwwroot . '/mod/forum/view.php?f=' . $forum->id . '">' . get_string('oldertopics', 'forum') . '</a> ...'; /// If RSS is activated at site and forum level and this forum has rss defined, show link if (isset($CFG->enablerssfeeds) && isset($CFG->forum_enablerssfeeds) && $CFG->enablerssfeeds && $CFG->forum_enablerssfeeds && $forum->rsstype && $forum->rssarticles) { require_once $CFG->dirroot . '/lib/rsslib.php'; // We'll need this if ($forum->rsstype == 1) { $tooltiptext = get_string('rsssubscriberssdiscussions', 'forum', format_string($forum->name)); } else { $tooltiptext = get_string('rsssubscriberssposts', 'forum', format_string($forum->name)); } if (empty($USER->id)) { $userid = 0; } else { $userid = $USER->id; } $this->content->footer .= '<br />' . rss_get_link($COURSE->id, $userid, 'forum', $forum->id, $tooltiptext); } } return $this->content; }
$header = ' (' . $header . ')'; } echo '<div class="header">' . get_string('newevent', 'calendar') . $header . '</div>'; if ($eventtype == 'select') { $courseid = optional_param('courseid', $SESSION->cal_course_referer, PARAM_INT); if ($courseid == 0) { // workaround by Dan for bug #6130 $courseid = SITEID; } if (!($course = get_record('course', 'id', $courseid))) { error('Incorrect course ID'); } if ($groupmode = groupmode($course)) { // Groups are being used $changegroup = optional_param('group', -1, PARAM_INT); $groupid = get_and_set_current_group($course, $groupmode, $changegroup); } else { $groupid = 0; } echo '<h2>' . get_string('eventkind', 'calendar') . ':</h2>'; echo '<div id="selecteventtype">'; include 'event_select.html'; echo '</div>'; } else { include 'event_new.html'; if ($usehtmleditor) { use_html_editor("description"); } } break; }
function print_section_fn(&$section, $absolute = false, $width = "100%") { /// Prints a section full of activity modules global $CFG, $USER, $THEME; static $initialised; static $groupbuttons; static $groupbuttonslink; static $isteacher, $isteacheredit; static $isediting; static $ismoving; static $strmovehere; static $strmovefull; static $strunreadpostsone; $labelformatoptions = new stdClass(); if (!isset($isteacher)) { $groupbuttons = $this->course->groupmode; $groupbuttonslink = !$this->course->groupmodeforce; $isteacher = has_capability('moodle/grade:viewall', $this->context); $isteacheredit = has_capability('moodle/course:manageactivities', $this->context); $isediting = isediting($this->course->id); $ismoving = ismoving($this->course->id); if ($ismoving) { $strmovehere = get_string("movehere"); $strmovefull = strip_tags(get_string("movefull", "", "'{$USER->activitycopyname}'")); } } if (!isset($initialised)) { include_once $CFG->dirroot . '/mod/forum/lib.php'; if ($usetracking = forum_tp_can_track_forums()) { $strunreadpostsone = get_string('unreadpostsone', 'forum'); } $initialised = true; } // Replace this with language file changes (eventually). $link_title = array('resource' => 'Lesson', 'choice' => 'Opinion', 'lesson' => 'Reading'); $labelformatoptions->noclean = true; $modinfo = unserialize($this->course->modinfo); echo "<table cellpadding=\"1\" cellspacing=\"0\" align=\"center\" width=\"{$width}\">\n"; if (!empty($section->sequence)) { $sectionmods = explode(",", $section->sequence); foreach ($sectionmods as $modnumber) { if (empty($this->mods[$modnumber])) { continue; } $mod = $this->mods[$modnumber]; /// mrc - 20042312 - Begin G8 First Nations School Customization: /// Added check for 'teacheredit' in order to hide invisible activities from /// non-editing teachers. /// if ($mod->visible or $isteacher) { if ($mod->visible or $isteacheredit) { /// mrc - 20042312 - End G8 First Nations School Customization: if (right_to_left()) { $tdalign = 'right'; } else { $tdalign = 'left'; } echo "<tr><td align=\"{$tdalign}\" class=\"activity{$mod->modname}\" width=\"{$width}\">"; if ($ismoving) { if ($mod->id == $USER->activitycopy) { continue; } echo "<a title=\"{$strmovefull}\"" . " href=\"{$CFG->wwwroot}/course/mod.php?moveto={$mod->id}&sesskey={$USER->sesskey}\">" . "<img height=\"16\" width=\"80\" src=\"{$CFG->pixpath}/movehere.gif\" " . " alt=\"{$strmovehere}\" border=\"0\"></a><br />\n"; } $instancename = urldecode($modinfo[$modnumber]->name); if (!empty($CFG->filterall)) { $instancename = filter_text("<nolink>{$instancename}</nolink>", $this->course->id); } if (!empty($modinfo[$modnumber]->extra)) { $extra = urldecode($modinfo[$modnumber]->extra); } else { $extra = ""; } if (!empty($modinfo[$modnumber]->icon)) { $icon = "{$CFG->pixpath}/" . urldecode($modinfo[$modnumber]->icon); } else { $icon = "{$CFG->modpixpath}/{$mod->modname}/icon.gif"; } if ($mod->indent) { print_spacer(12, 20 * $mod->indent, false); } // /// If the questionnaire is mandatory // if (($mod->modname == 'questionnaire') && empty($mandatorypopup)) { // $mandatorypopup = is_mod_mandatory($mod, $USER->id); // } if ($mod->modname == "label") { if (empty($this->course->usemandatory) || empty($mod->mandatory)) { if (!$mod->visible) { echo "<span class=\"dimmed_text\">"; } echo format_text($extra, FORMAT_HTML, $labelformatoptions); if (!$mod->visible) { echo "</span>"; } } else { if ($isediting) { $linkcss = $mod->visible ? "" : " class=\"dimmed\" "; $alttext = isset($link_title[$mod->modname]) ? $link_title[$mod->modname] : $mod->modfullname; echo "<img src=\"{$icon}\"" . " height=16 width=16 alt=\"{$alttext}\">" . " <font size=2><a title=\"{$alttext}\" {$linkcss} {$extra}" . " href=\"{$CFG->wwwroot}/mod/{$mod->modname}/view.php?id={$mod->id}\">{$instancename}</a></font>"; } } } else { if (!$isediting && $mod->modname == 'forum' && isset($this->course->expforumsec) && $this->course->expforumsec == $section->section) { $page = optional_param('page', 0, PARAM_INT); $changegroup = isset($_GET['group']) ? $_GET['group'] : -1; // Group change requested? $forum = get_record("forum", "id", $mod->instance); $groupmode = groupmode($this->course, $mod); // Groups are being used $currentgroup = get_and_set_current_group($this->course, $groupmode, $changegroup); forum_print_latest_discussions($this->course, $forum, $CFG->forum_manydiscussions, 'header', '', $currentgroup, $groupmode, $page); } else { // Normal activity if (!$isteacher && !empty($this->course->activitytracking)) { $act_compl = is_activity_complete($mod, $USER->id); if ($act_compl === false) { echo ' <img src="' . $CFG->wwwroot . '/course/format/' . $this->course->format . '/pix/incomplete.gif" ' . 'height="16" width="16" alt="Activity Not Completed" hspace="10" ' . 'title="Activity Not Completed">'; } else { if ($act_compl === true || is_int($act_compl) && $act_compl >= 50) { echo ' <img src="' . $CFG->wwwroot . '/course/format/' . $this->course->format . '/pix/completed.gif" ' . 'height="16" width="16" alt="Activity Completed" hspace="10" ' . 'title="Activity Completed">'; } else { if (is_int($act_compl)) { echo ' <img src="' . $CFG->wwwroot . '/course/format/' . $this->course->format . '/pix/completedpoor.gif" ' . 'height="16" width="16" alt="Activity Completed Poorly" hspace="10" ' . 'title="Activity Completed Poorly">'; } else { if ($act_compl == 'submitted') { echo ' <img src="' . $CFG->wwwroot . '/course/format/' . $this->course->format . '/pix/submitted.gif" ' . 'height="16" width="16" alt="Activity Submitted" hspace="10" ' . 'title="Activity Submitted">'; } } } } } $linkcss = $mod->visible ? "" : " class=\"dimmed\" "; $alttext = isset($link_title[$mod->modname]) ? $link_title[$mod->modname] : $mod->modfullname; echo "<img src=\"{$icon}\"" . " height=16 width=16 alt=\"{$alttext}\">" . " <font size=2><a title=\"{$alttext}\" {$linkcss} {$extra}" . " href=\"{$CFG->wwwroot}/mod/{$mod->modname}/view.php?id={$mod->id}\">{$instancename}</a></font>"; } } if ($usetracking && $mod->modname == 'forum') { if ($unread = forum_tp_count_forum_unread_posts($mod, $this->course)) { echo '<span class="unread"> <a href="' . $CFG->wwwroot . '/mod/forum/view.php?id=' . $mod->id . '">'; if ($unread == 1) { echo $strunreadpostsone; } else { print_string('unreadpostsnumber', 'forum', $unread); } echo '</a></span>'; } } if ($isediting) { // TODO: we must define this as mod property! if ($groupbuttons and $mod->modname != 'label' and $mod->modname != 'resource' and $mod->modname != 'glossary') { if (!($mod->groupmodelink = $groupbuttonslink)) { $mod->groupmode = $course->groupmode; } } else { $mod->groupmode = false; } echo " "; echo make_editing_buttons($mod, $absolute, true, $mod->indent, $section->section); // echo make_editing_buttons($mod, $absolute, true, $mod->indent); if (isadmin()) { if (empty($THEME->custompix)) { $pixpath = $CFG->wwwroot . '/pix'; } else { $pixpath = $CFG->wwwroot . '/theme/' . $CFG->theme . '/pix'; } if ($mod->hideingradebook) { echo '<a title="Show Grades" href="' . $CFG->wwwroot . '/course/view.php?id=' . $this->course->id . '&hidegrades=0&mid=' . $mod->id . '&sesskey=' . $USER->sesskey . '">' . '<img src="' . $CFG->wwwroot . '/course/format/' . $this->course->format . '/pix/hidegrades.gif" hspace="2" height="11" width="11" border="0" /></a>'; } else { echo '<a title="Hide Grades" href="' . $CFG->wwwroot . '/course/view.php?id=' . $this->course->id . '&hidegrades=1&mid=' . $mod->id . '&sesskey=' . $USER->sesskey . '">' . '<img src="' . $CFG->wwwroot . '/course/format/' . $this->course->format . '/pix/showgrades.gif" hspace="2" height="11" width="11" border="0" /></a>'; } if (!empty($this->course->usemandatory)) { if ($mod->mandatory) { echo '<a title="Mandatory off" href="' . $CFG->wwwroot . '/course/format/' . $this->course->format . '/mod.php?mandatory=0&id=' . $mod->id . '&sesskey=' . $USER->sesskey . '">' . '<img src="' . $CFG->wwwroot . '/course/format/' . $this->course->format . '/pix/lock.gif" hspace="2" height="11" width="11" border="0" /></a>'; } else { echo '<a title="Mandatory on" href="' . $CFG->wwwroot . '/course/format/' . $this->course->format . '/mod.php?mandatory=1&id=' . $mod->id . '&sesskey=' . $USER->sesskey . '">' . '<img src="' . $CFG->wwwroot . '/course/format/' . $this->course->format . '/pix/unlock.gif" hspace="2" height="11" width="11" border="0" /></a>'; } } } } echo "</td>"; echo "</tr>"; } } } if ($ismoving) { echo "<tr><td><a title=\"{$strmovefull}\"" . " href=\"mod.php?movetosection={$section->id}" . '&sesskey=' . $USER->sesskey . '">' . "<img height=\"16\" width=\"80\" src=\"{$CFG->pixpath}/movehere.gif\" " . " alt=\"{$strmovehere}\" border=\"0\"></a></td></tr>\n"; } echo "</table>\n\n"; // return $mandatorypopup; }
$SESSION->fromurl = $_SERVER["HTTP_REFERER"]; } else { $SESSION->fromurl = ''; } // Load up the $post variable. $post = new object(); $post->course = $course->id; $post->forum = $forum->id; $post->discussion = 0; // ie discussion # not defined yet $post->parent = 0; $post->subject = ''; $post->userid = $USER->id; $post->message = ''; if ($groupmode = groupmode($course, $cm)) { $post->groupid = get_and_set_current_group($course, $groupmode); if ($post->groupid == 0) { $post->groupid = -1; //TODO: why -1?? } } else { $post->groupid = -1; //TODO: why -1?? } forum_set_return(); } else { if (!empty($reply)) { // User is writing a new reply if (!($parent = forum_get_post_full($reply))) { error("Parent post ID was incorrect"); }
/** * Prints the discussion view screen for a forum. * * @param object $course The current course object. * @param object $forum Forum to be printed. * @param int $maxdiscussions The maximum number of discussions per page(optional). * @param string $displayformat The display format to use (optional). * @param string $sort Sort arguments for database query (optional). * @param int $currentgroup Group to display discussions for (optional). * @param int $groupmode Group mode of the forum (optional). * @param int $page Page mode, page to display (optional). * */ function forum_print_latest_discussions($course, $forum, $maxdiscussions = 5, $displayformat = 'plain', $sort = '', $currentgroup = -1, $groupmode = -1, $page = -1, $cm = NULL) { global $CFG, $USER; if (!$cm) { if (!($cm = get_coursemodule_from_instance('forum', $forum->id, $forum->course))) { error('Course Module ID was incorrect'); } } $context = get_context_instance(CONTEXT_MODULE, $cm->id); // Sort out some defaults if (!$maxdiscussions && $displayformat == 'plain') { $displayformat = 'header'; // Abbreviate display by default } $fullpost = false; if ($displayformat == 'plain') { $fullpost = true; } // Decide if current user is allowed to see ALL the current discussions or not // First check the group stuff $groupmode = groupmode($course, $cm); $currentgroup = get_and_set_current_group($course, $groupmode); // If the user can post discussions, then this is a good place to put the // button for it. We do not show the button if we are showing site news // and the current user is a guest. if (forum_user_can_post_discussion($forum, $currentgroup, $groupmode, $cm, $context) || $forum->type != 'news' && has_capability('moodle/legacy:guest', $context, NULL, false)) { echo '<div class="singlebutton forumaddnew">'; echo "<form id=\"newdiscussionform\" method=\"get\" action=\"{$CFG->wwwroot}/mod/forum/post.php\">"; echo '<div>'; echo "<input type=\"hidden\" name=\"forum\" value=\"{$forum->id}\" />"; echo '<input type="submit" value="'; echo $forum->type == 'news' ? get_string('addanewtopic', 'forum') : ($forum->type == 'qanda' ? get_string('addanewquestion', 'forum') : get_string('addanewdiscussion', 'forum')); echo '" />'; echo '</div>'; echo '</form>'; echo "</div>\n"; } else { if (!isguestuser() and isloggedin() and $forum->type != 'news' and $groupmode == SEPARATEGROUPS and !ismember($currentgroup)) { notify(get_string('cannotadddiscussion', 'forum')); } } // Get all the recent discussions we're allowed to see $getuserlastmodified = $displayformat == 'header'; if (!($discussions = forum_get_discussions($forum->id, $sort, 0, $fullpost, $currentgroup, 0, $getuserlastmodified))) { echo '<div class="forumnodiscuss">'; if ($forum->type == 'news') { echo '(' . get_string('nonews', 'forum') . ')'; } else { if ($forum->type == 'qanda') { echo '(' . get_string('noquestions', 'forum') . ')'; } else { echo '(' . get_string('nodiscussions', 'forum') . ')'; } } echo "</div>\n"; return; } // If no discussions then don't use paging (to avoid some divide by 0 errors) if ($maxdiscussions <= 0) { $page = -1; $maxdiscussions = 0; } // If we want paging if ($page != -1) { ///Get the number of discussions found $numdiscussions = count($discussions); ///Show the paging bar print_paging_bar($numdiscussions, $page, $maxdiscussions, "view.php?f={$forum->id}&"); //Calculate the page "window" $pagestart = $page * $maxdiscussions + 1; $pageend = $pagestart + $maxdiscussions - 1; } $replies = forum_count_discussion_replies($forum->id); $canreply = forum_user_can_post($forum); $canviewparticipants = has_capability('moodle/course:viewparticipants', $context); $discussioncount = 0; $olddiscussionlink = false; $strdatestring = get_string('strftimerecentfull'); // Check if the forum is tracked. if ($cantrack = forum_tp_can_track_forums($forum)) { $forumtracked = forum_tp_is_tracked($forum); } else { $forumtracked = false; } if ($displayformat == 'header') { echo '<table cellspacing="0" class="forumheaderlist">'; echo '<thead>'; echo '<tr>'; echo '<th class="header topic" scope="col">' . get_string('discussion', 'forum') . '</th>'; echo '<th class="header author" colspan="2" scope="col">' . get_string('startedby', 'forum') . '</th>'; if ($groupmode > 0) { echo '<th class="header group" scope="col">' . get_string('group') . '</th>'; } if (has_capability('mod/forum:viewdiscussion', $context)) { echo '<th class="header replies" scope="col">' . get_string('replies', 'forum') . '</th>'; // If the forum can be tracked, display the unread column. if ($cantrack) { echo '<th class="header replies" scope="col">' . get_string('unread', 'forum'); if ($forumtracked) { echo ' <a title="' . get_string('markallread', 'forum') . '" href="' . $CFG->wwwroot . '/mod/forum/markposts.php?f=' . $forum->id . '&mark=read&returnpage=view.php">' . '<img src="' . $CFG->pixpath . '/t/clear.gif" class="iconsmall" alt="' . get_string('markallread', 'forum') . '" /></a>'; } echo '</th>'; } } echo '<th class="header lastpost" scope="col">' . get_string('lastpost', 'forum') . '</th>'; echo '</tr>'; echo '</thead>'; echo '<tbody>'; } foreach ($discussions as $discussion) { $discussioncount++; if ($page != -1) { // We are using paging if ($discussioncount < $pagestart) { // Not there yet continue; } if ($discussioncount > $pageend) { // All done, finish the loop break; } //Without paging, old approach } else { if ($maxdiscussions && $discussioncount > $maxdiscussions) { $olddiscussionlink = true; break; } } if (!empty($replies[$discussion->discussion])) { $discussion->replies = $replies[$discussion->discussion]->replies; $discussion->lastpostid = $replies[$discussion->discussion]->lastpostid; } else { $discussion->replies = 0; } // SPECIAL CASE: The front page can display a news item post to non-logged in users. // All posts are read in this case. if (!$forumtracked) { $discussion->unread = '-'; } else { if (empty($USER)) { $discussion->unread = 0; } else { $discussion->unread = forum_tp_count_discussion_unread_posts($USER->id, $discussion->discussion); } } if (!empty($USER->id)) { $ownpost = $discussion->userid == $USER->id; } else { $ownpost = false; } // Use discussion name instead of subject of first post $discussion->subject = $discussion->name; switch ($displayformat) { case 'header': if ($groupmode > 0) { if (isset($groups[$discussion->groupid])) { $group = $groups[$discussion->groupid]; } else { $group = $groups[$discussion->groupid] = groups_get_group($discussion->groupid); //TODO: } } else { $group = -1; } forum_print_discussion_header($discussion, $forum, $group, $strdatestring, $cantrack, $forumtracked, $canviewparticipants, $context); break; default: if ($canreply or $discussion->replies) { $link = true; } else { $link = false; } $discussion->forum = $forum->id; forum_print_post($discussion, $course->id, $ownpost, $reply = 0, $link, $assessed = false); break; } } if ($displayformat == "header") { echo '</tbody>'; echo '</table>'; } if ($olddiscussionlink) { echo '<div class="forumolddiscuss">'; echo '<a href="' . $CFG->wwwroot . '/mod/forum/view.php?f=' . $forum->id . '&showall=1">'; echo get_string('olderdiscussions', 'forum') . '</a> ...</div>'; } if ($page != -1) { ///Show the paging bar print_paging_bar($numdiscussions, $page, $maxdiscussions, "view.php?f={$forum->id}&"); } }
function display($quiz, $cm, $course) { /// This function just displays the report global $CFG, $SESSION, $db, $QTYPES; $strnoquiz = get_string('noquiz', 'quiz'); $strnoattempts = get_string('noattempts', 'quiz'); /// Only print headers if not asked to download data $download = optional_param('download', NULL); if (!$download) { $this->print_header_and_tabs($cm, $course, $quiz, $reportmode = "analysis"); } /// Construct the table for this particular report if (!$quiz->questions) { print_heading($strnoattempts); return true; } /// Check to see if groups are being used in this quiz if ($groupmode = groupmode($course, $cm)) { // Groups are being used if (!$download) { $currentgroup = setup_and_print_groups($course, $groupmode, "report.php?id={$cm->id}&mode=analysis"); } else { $currentgroup = get_and_set_current_group($course, $groupmode); } } else { $currentgroup = get_and_set_current_group($course, $groupmode); } // set Table and Analysis stats options if (!isset($SESSION->quiz_analysis_table)) { $SESSION->quiz_analysis_table = array('attemptselection' => 0, 'lowmarklimit' => 0, 'pagesize' => 10); } foreach ($SESSION->quiz_analysis_table as $option => $value) { $urlparam = optional_param($option, NULL); if ($urlparam === NULL) { ${$option} = $value; } else { ${$option} = $SESSION->quiz_analysis_table[$option] = $urlparam; } } $scorelimit = $quiz->sumgrades * $lowmarklimit / 100; // ULPGC ecastro DEBUG this is here to allow for different SQL to select attempts switch ($attemptselection) { case QUIZ_ALLATTEMPTS: $limit = ''; $group = ''; break; case QUIZ_HIGHESTATTEMPT: $limit = ', max(qa.sumgrades) '; $group = ' GROUP BY qa.userid '; break; case QUIZ_FIRSTATTEMPT: $limit = ', min(qa.timemodified) '; $group = ' GROUP BY qa.userid '; break; case QUIZ_LASTATTEMPT: $limit = ', max(qa.timemodified) '; $group = ' GROUP BY qa.userid '; break; } if ($attemptselection != QUIZ_ALLATTEMPTS) { $sql = 'SELECT qa.userid ' . $limit . 'FROM ' . $CFG->prefix . 'user u LEFT JOIN ' . $CFG->prefix . 'quiz_attempts qa ON u.id = qa.userid ' . 'WHERE qa.quiz = ' . $quiz->id . ' AND qa.preview = 0 ' . $group; $usermax = get_records_sql_menu($sql); } $groupmembers = ''; $groupwhere = ''; //Add this to the SQL to show only group users if ($currentgroup) { $groupmembers = ', ' . groups_members_from_sql(); $groupwhere = ' AND ' . groups_members_where_sql($currentgroup, 'u.id'); } $sql = 'SELECT qa.* FROM ' . $CFG->prefix . 'quiz_attempts qa, ' . $CFG->prefix . 'user u ' . $groupmembers . 'WHERE u.id = qa.userid AND qa.quiz = ' . $quiz->id . ' AND qa.preview = 0 AND ( qa.sumgrades >= ' . $scorelimit . ' ) ' . $groupwhere; // ^^^^^^ es posible seleccionar aqu TODOS los quizzes, como quiere Jussi, // pero habra que llevar la cuenta ed cada quiz para restaura las preguntas (quizquestions, states) /// Fetch the attempts $attempts = get_records_sql($sql); if (empty($attempts)) { print_heading(get_string('nothingtodisplay')); $this->print_options_form($quiz, $cm, $attemptselection, $lowmarklimit, $pagesize); return true; } /// Here we rewiew all attempts and record data to construct the table $questions = array(); $statstable = array(); $questionarray = array(); foreach ($attempts as $attempt) { $questionarray[] = quiz_questions_in_quiz($attempt->layout); } $questionlist = quiz_questions_in_quiz(implode(",", $questionarray)); $questionarray = array_unique(explode(",", $questionlist)); $questionlist = implode(",", $questionarray); unset($questionarray); foreach ($attempts as $attempt) { switch ($attemptselection) { case QUIZ_ALLATTEMPTS: $userscore = 0; // can be anything, not used break; case QUIZ_HIGHESTATTEMPT: $userscore = $attempt->sumgrades; break; case QUIZ_FIRSTATTEMPT: $userscore = $attempt->timemodified; break; case QUIZ_LASTATTEMPT: $userscore = $attempt->timemodified; break; } if ($attemptselection == QUIZ_ALLATTEMPTS || $userscore == $usermax[$attempt->userid]) { $sql = "SELECT q.*, i.grade AS maxgrade, i.id AS instance" . " FROM {$CFG->prefix}question q," . " {$CFG->prefix}quiz_question_instances i" . " WHERE i.quiz = '{$quiz->id}' AND q.id = i.question" . " AND q.id IN ({$questionlist})"; if (!($quizquestions = get_records_sql($sql))) { error('No questions found'); } // Load the question type specific information if (!get_question_options($quizquestions)) { error('Could not load question options'); } // Restore the question sessions to their most recent states // creating new sessions where required if (!($states = get_question_states($quizquestions, $quiz, $attempt))) { error('Could not restore question sessions'); } $numbers = explode(',', $questionlist); $statsrow = array(); foreach ($numbers as $i) { if (!isset($quizquestions[$i]) or !isset($states[$i])) { continue; } $qtype = $quizquestions[$i]->qtype == 'random' ? $states[$i]->options->question->qtype : $quizquestions[$i]->qtype; $q = get_question_responses($quizquestions[$i], $states[$i]); if (empty($q)) { continue; } $qid = $q->id; if (!isset($questions[$qid])) { $questions[$qid]['id'] = $qid; $questions[$qid]['qname'] = $quizquestions[$i]->name; foreach ($q->responses as $answer => $r) { $r->count = 0; $questions[$qid]['responses'][$answer] = $r->answer; $questions[$qid]['rcounts'][$answer] = 0; $questions[$qid]['credits'][$answer] = $r->credit; $statsrow[$qid] = 0; } } $responses = get_question_actual_response($quizquestions[$i], $states[$i]); foreach ($responses as $resp) { if ($resp) { if ($key = array_search($resp, $questions[$qid]['responses'])) { $questions[$qid]['rcounts'][$key]++; } else { $test = new stdClass(); $test->responses = $QTYPES[$quizquestions[$i]->qtype]->get_correct_responses($quizquestions[$i], $states[$i]); if ($key = $QTYPES[$quizquestions[$i]->qtype]->check_response($quizquestions[$i], $states[$i], $test)) { $questions[$qid]['rcounts'][$key]++; } else { $questions[$qid]['responses'][] = $resp; $questions[$qid]['rcounts'][] = 1; $questions[$qid]['credits'][] = 0; } } } } $statsrow[$qid] = get_question_fraction_grade($quizquestions[$i], $states[$i]); } $attemptscores[$attempt->id] = $attempt->sumgrades; $statstable[$attempt->id] = $statsrow; } } // Statistics Data table built unset($attempts); unset($quizquestions); unset($states); // now calculate statistics and set the values in the $questions array $top = max($attemptscores); $bottom = min($attemptscores); $gap = ($top - $bottom) / 3; $top -= $gap; $bottom += $gap; foreach ($questions as $qid => $q) { $questions[$qid] = $this->report_question_stats($q, $attemptscores, $statstable, $top, $bottom); } unset($attemptscores); unset($statstable); /// Now check if asked download of data if ($download = optional_param('download', NULL)) { $filename = clean_filename("{$course->shortname} " . format_string($quiz->name, true)); switch ($download) { case "Excel": $this->Export_Excel($questions, $filename); break; case "ODS": $this->Export_ODS($questions, $filename); break; case "CSV": $this->Export_CSV($questions, $filename); break; } } /// Construct the table for this particular report $tablecolumns = array('id', 'qname', 'responses', 'credits', 'rcounts', 'rpercent', 'facility', 'qsd', 'disc_index', 'disc_coeff'); $tableheaders = array(get_string('qidtitle', 'quiz_analysis'), get_string('qtexttitle', 'quiz_analysis'), get_string('responsestitle', 'quiz_analysis'), get_string('rfractiontitle', 'quiz_analysis'), get_string('rcounttitle', 'quiz_analysis'), get_string('rpercenttitle', 'quiz_analysis'), get_string('facilitytitle', 'quiz_analysis'), get_string('stddevtitle', 'quiz_analysis'), get_string('dicsindextitle', 'quiz_analysis'), get_string('disccoefftitle', 'quiz_analysis')); $table = new flexible_table('mod-quiz-report-itemanalysis'); $table->define_columns($tablecolumns); $table->define_headers($tableheaders); $table->define_baseurl($CFG->wwwroot . '/mod/quiz/report.php?q=' . $quiz->id . '&mode=analysis'); $table->sortable(true); $table->no_sorting('rpercent'); $table->collapsible(true); $table->initialbars(false); $table->column_class('id', 'numcol'); $table->column_class('credits', 'numcol'); $table->column_class('rcounts', 'numcol'); $table->column_class('rpercent', 'numcol'); $table->column_class('facility', 'numcol'); $table->column_class('qsd', 'numcol'); $table->column_class('disc_index', 'numcol'); $table->column_class('disc_coeff', 'numcol'); $table->column_suppress('id'); $table->column_suppress('qname'); $table->column_suppress('facility'); $table->column_suppress('qsd'); $table->column_suppress('disc_index'); $table->column_suppress('disc_coeff'); $table->set_attribute('cellspacing', '0'); $table->set_attribute('id', 'itemanalysis'); $table->set_attribute('class', 'generaltable generalbox'); // Start working -- this is necessary as soon as the niceties are over $table->setup(); $tablesort = $table->get_sql_sort(); $sorts = explode(",", trim($tablesort)); if ($tablesort and is_array($sorts)) { $sortindex = array(); $sortorder = array(); foreach ($sorts as $sort) { $data = explode(" ", trim($sort)); $sortindex[] = trim($data[0]); $s = trim($data[1]); if ($s == "ASC") { $sortorder[] = SORT_ASC; } else { $sortorder[] = SORT_DESC; } } if (count($sortindex) > 0) { $sortindex[] = "id"; $sortorder[] = SORT_ASC; foreach ($questions as $qid => $row) { $index1[$qid] = $row[$sortindex[0]]; $index2[$qid] = $row[$sortindex[1]]; } array_multisort($index1, $sortorder[0], $index2, $sortorder[1], $questions); } } $format_options = new stdClass(); $format_options->para = false; $format_options->noclean = true; $format_options->newlines = false; // Now it is time to page the data, simply slice the keys in the array if (!isset($pagesize) || (int) $pagesize < 1) { $pagesize = 10; } $table->pagesize($pagesize, count($questions)); $start = $table->get_page_start(); $pagequestions = array_slice(array_keys($questions), $start, $pagesize); foreach ($pagequestions as $qnum) { $q = $questions[$qnum]; $qid = $q['id']; $question = get_record('question', 'id', $qid); if (has_capability('moodle/question:manage', get_context_instance(CONTEXT_COURSE, $course->id))) { $qnumber = " (" . link_to_popup_window('/question/question.php?id=' . $qid, '&cmid=' . $cm->id . 'editquestion', $qid, 450, 550, get_string('edit'), 'none', true) . ") "; } else { $qnumber = $qid; } $qname = '<div class="qname">' . format_text($question->name . " : ", $question->questiontextformat, $format_options, $quiz->course) . '</div>'; $qicon = print_question_icon($question, true); $qreview = quiz_question_preview_button($quiz, $question); $qtext = format_text($question->questiontext, $question->questiontextformat, $format_options, $quiz->course); $qquestion = $qname . "\n" . $qtext . "\n"; $responses = array(); foreach ($q['responses'] as $aid => $resp) { $response = new stdClass(); if ($q['credits'][$aid] <= 0) { $qclass = 'uncorrect'; } elseif ($q['credits'][$aid] == 1) { $qclass = 'correct'; } else { $qclass = 'partialcorrect'; } $response->credit = '<span class="' . $qclass . '">(' . format_float($q['credits'][$aid], 2) . ') </span>'; $response->text = '<span class="' . $qclass . '">' . format_text($resp, FORMAT_MOODLE, $format_options, $quiz->course) . ' </span>'; $count = $q['rcounts'][$aid] . '/' . $q['count']; $response->rcount = $count; $response->rpercent = '(' . format_float($q['rcounts'][$aid] / $q['count'] * 100, 0) . '%)'; $responses[] = $response; } $facility = format_float($q['facility'] * 100, 0) . "%"; $qsd = format_float($q['qsd'], 3); $di = format_float($q['disc_index'], 2); $dc = format_float($q['disc_coeff'], 2); $response = array_shift($responses); $table->add_data(array($qnumber . "\n<br />" . $qicon . "\n " . $qreview, $qquestion, $response->text, $response->credit, $response->rcount, $response->rpercent, $facility, $qsd, $di, $dc)); foreach ($responses as $response) { $table->add_data(array('', '', $response->text, $response->credit, $response->rcount, $response->rpercent, '', '', '', '')); } } print_heading_with_help(get_string("analysistitle", "quiz_analysis"), "itemanalysis", "quiz"); echo '<div id="tablecontainer">'; $table->print_html(); echo '</div>'; $this->print_options_form($quiz, $cm, $attemptselection, $lowmarklimit, $pagesize); return true; }
function data_print_header($course, $cm, $data, $currenttab = '') { global $CFG, $displaynoticegood, $displaynoticebad; $strdata = get_string('modulenameplural', 'data'); print_header_simple($data->name, '', "<a href='index.php?id={$course->id}'>{$strdata}</a> -> {$data->name}", '', '', true, update_module_button($cm->id, $course->id, get_string('modulename', 'data')), navmenu($course, $cm)); print_heading(format_string($data->name)); /// Groups needed for Add entry tab $groupmode = groupmode($course, $cm); $currentgroup = get_and_set_current_group($course, $groupmode); /// Print the tabs if ($currenttab) { include_once 'tabs.php'; } /// Print any notices if (!empty($displaynoticegood)) { notify($displaynoticegood, 'notifysuccess'); // good (usually green) } else { if (!empty($displaynoticebad)) { notify($displaynoticebad); // bad (usuually red) } } }