// Add random questions to the offlinequiz. $structure->check_can_be_edited(); $recurse = optional_param('recurse', 0, PARAM_BOOL); $addonpage = optional_param('addonpage', 0, PARAM_INT); $categoryid = required_param('categoryid', PARAM_INT); $randomcount = required_param('randomcount', PARAM_INT); offlinequiz_add_random_questions($offlinequiz, $addonpage, $categoryid, $randomcount, $recurse); offlinequiz_delete_template_usages($offlinequiz); offlinequiz_update_sumgrades($offlinequiz); redirect($afteractionurl); } if (optional_param('savechanges', false, PARAM_BOOL) && confirm_sesskey()) { // Parameter to copy selected questions to another group. $copyselectedtogroup = optional_param('copyselectedtogrouptop', 0, PARAM_INT); if ($copyselectedtogroup) { if ($selectedquestionids && ($newgroup = offlinequiz_get_group($offlinequiz, $copyselectedtogroup))) { $fromofflinegroup = optional_param('fromofflinegroup', 0, PARAM_INT); offlinequiz_add_questionlist_to_group($selectedquestionids, $offlinequiz, $newgroup, $fromofflinegroup); offlinequiz_update_sumgrades($offlinequiz, $newgroup->id); // Delete the templates, just to be sure. offlinequiz_delete_template_usages($offlinequiz); } redirect($afteractionurl); } // If rescaling is required save the new maximum. $maxgrade = str_replace(',', '.', optional_param('maxgrade', -1, PARAM_RAW)); if (!is_numeric($maxgrade)) { $afteractionurl->param('warning', urlencode(get_string('maxgradewarning', 'offlinequiz'))); } else { $maxgrade = unformat_float($maxgrade); if ($maxgrade >= 0) {
require_once $CFG->dirroot . '/mod/offlinequiz/locallib.php'; require_once $CFG->dirroot . '/question/editlib.php'; list($thispageurl, $contexts, $cmid, $cm, $offlinequiz, $pagevars) = question_edit_setup('editq', '/mod/offlinequiz/edit.php', true); // Get the course object and related bits. $course = $DB->get_record('course', array('id' => $offlinequiz->course), '*', MUST_EXIST); require_capability('mod/offlinequiz:manage', $contexts->lowest()); // Determine groupid. $groupnumber = optional_param('groupnumber', 1, PARAM_INT); if ($groupnumber === -1 and !empty($SESSION->question_pagevars['groupnumber'])) { $groupnumber = $SESSION->question_pagevars['groupnumber']; } if ($groupnumber === -1) { $groupnumber = 1; } $offlinequiz->groupnumber = $groupnumber; $thispageurl->param('groupnumber', $offlinequiz->groupnumber); // Load the offlinequiz group and set the groupid in the offlinequiz object. if ($offlinequizgroup = offlinequiz_get_group($offlinequiz, $groupnumber)) { $offlinequiz->groupid = $offlinequizgroup->id; $groupquestions = offlinequiz_get_group_question_ids($offlinequiz); $offlinequiz->questions = $groupquestions; } else { print_error('invalidgroupnumber', 'offlinequiz'); } // Create offlinequiz question bank view. $questionbank = new mod_offlinequiz\question\bank\custom_view($contexts, $thispageurl, $course, $cm, $offlinequiz); $questionbank->set_offlinequiz_has_scanned_pages(offlinequiz_has_scanned_pages($offlinequiz->id)); // Output. $output = $PAGE->get_renderer('mod_offlinequiz', 'edit'); $contents = $output->question_bank_contents($questionbank, $pagevars); echo json_encode(array('status' => 'OK', 'contents' => $contents));
/** * Display the report. */ public function display($offlinequiz, $cm, $course) { global $CFG, $DB, $OUTPUT, $PAGE; $this->context = context_module::instance($cm->id); // Work out the display options. $download = optional_param('download', '', PARAM_ALPHA); $everything = optional_param('everything', 0, PARAM_BOOL); $recalculate = optional_param('recalculate', 0, PARAM_BOOL); // A qid paramter indicates we should display the detailed analysis of a question and subquestions. $qid = optional_param('qid', 0, PARAM_INT); $questionid = optional_param('questionid', 0, PARAM_INT); // Determine statistics mode. $statmode = optional_param('statmode', 'statsoverview', PARAM_ALPHA); $pageoptions = array(); $pageoptions['id'] = $cm->id; $pageoptions['mode'] = 'statistics'; $pageoptions['statmode'] = $statmode; // When showing big tables add the JavaScript for the double scrollbar. if ($statmode == 'questionstats' || $statmode == 'questionandanswerstats') { $module = array('name' => 'mod_offlinequiz_statistics', 'fullpath' => '/mod/offlinequiz/report/statistics/doublescroll.js', 'requires' => array(), 'strings' => array(), 'async' => false); $PAGE->requires->jquery(); $PAGE->requires->jquery_plugin('ui'); $PAGE->requires->jquery_plugin('doubleScroll', 'mod_offlinequiz'); $PAGE->requires->js_init_call('offlinequiz_statistics_init_doublescroll', null, false, $module); } if (!($groups = $DB->get_records('offlinequiz_groups', array('offlinequizid' => $offlinequiz->id), 'number', '*', 0, $offlinequiz->numgroups))) { print_error('nogroups', 'offlinequiz', $CFG->wwwroot . '/course/view.php?id=' . $COURSE->id, $scannedpage->offlinequizid); } // Determine groupid. $groupnumber = optional_param('offlinegroup', -1, PARAM_INT); if ($groupnumber === -1 and !empty($SESSION->question_pagevars['groupnumber'])) { $groupnumber = $SESSION->question_pagevars['groupnumber']; } if ($groupnumber > 0) { $pageoptions['offlinegroup'] = $groupnumber; $offlinequiz->groupnumber = $groupnumber; $offlinequiz->sumgrades = $DB->get_field('offlinequiz_groups', 'sumgrades', array('offlinequizid' => $offlinequiz->id, 'number' => $groupnumber)); if ($offlinegroup = offlinequiz_get_group($offlinequiz, $groupnumber)) { $offlinequiz->groupid = $offlinegroup->id; $groupquestions = offlinequiz_get_group_question_ids($offlinequiz); $offlinequiz->questions = $groupquestions; } else { print_error('invalidgroupnumber', 'offlinequiz'); } } else { $offlinequiz->groupid = 0; // The user wants to evaluate results from all offlinequiz groups. // Compare the sumgrades of all offlinequiz groups. First we put all sumgrades in an array. $sumgrades = array(); foreach ($groups as $group) { $sumgrades[] = round($group->sumgrades, $offlinequiz->decimalpoints); } // Now we remove duplicates. $sumgrades = array_unique($sumgrades); if (count($sumgrades) > 1) { // If the groups have different sumgrades, we can't pick one. $offlinequiz->sumgrades = -1; } else { if (count($sumgrades) == 1) { // If the groups all have the same sumgrades, we pick the first one. $offlinequiz->sumgrades = $sumgrades[0]; } else { // Pathological, there are no sumgrades, i.e. no groups... $offlinequiz->sumgrades = 0; } } // If no group has been chosen we simply take the questions from the question instances. $sql = "SELECT DISTINCT(questionid)\n FROM {offlinequiz_group_questions}\n WHERE offlinequizid = :offlinequizid"; $questionids = $DB->get_fieldset_sql($sql, array('offlinequizid' => $offlinequiz->id)); $offlinequiz->questions = $questionids; } // We warn the user if the different offlinequiz groups have different sets of questions. $differentquestions = false; if ($offlinequiz->groupid == 0 && count($groups) > 1 && $this->groups_have_different_questions($offlinequiz, $groups)) { $differentquestions = true; } $reporturl = new moodle_url('/mod/offlinequiz/report.php', $pageoptions); $useallattempts = 0; // Find out current groups mode. $currentgroup = $this->get_current_group($cm, $course, $this->context); $nostudentsingroup = false; // True if a group is selected and there is no one in it. if (empty($currentgroup)) { $currentgroup = 0; $groupstudents = array(); } else { if ($currentgroup == self::NO_GROUPS_ALLOWED) { $groupstudents = array(); $nostudentsingroup = true; } else { // All users who can attempt offlinequizzes and who are in the currently selected group. $groupstudents = get_users_by_capability($this->context, array('mod/offlinequiz:reviewmyattempts', 'mod/offlinequiz:attempt'), '', '', '', '', $currentgroup, '', false); if (!$groupstudents) { $nostudentsingroup = true; } } } // If recalculate was requested, handle that. if ($recalculate && confirm_sesskey()) { $this->clear_cached_data($offlinequiz->id, $currentgroup, $useallattempts, $offlinequiz->groupid); redirect($reporturl); } // Set up the main table. if ($statmode == 'statsoverview' || $statmode == 'questionstats') { $this->table = new offlinequiz_statistics_table(); } else { $this->table = new offlinequiz_question_answer_statistics_table(); } if ($everything) { $report = get_string('completestatsfilename', 'offlinequiz_statistics'); } else { $report = get_string('questionstatsfilename', 'offlinequiz_statistics'); } $courseshortname = format_string($course->shortname, true, array('context' => context_course::instance($course->id))); $filename = offlinequiz_report_download_filename($report, $courseshortname, $offlinequiz->name); $this->table->is_downloading($download, $filename, get_string('offlinequizstructureanalysis', 'offlinequiz_statistics')); // Load the questions. // NOTE: function is hacked to deliver question array with question IDs as keys, not the slot as before. $questions = offlinequiz_report_get_significant_questions($offlinequiz); $questionids = array_keys($questions); $fullquestions = question_load_questions($questionids); foreach ($questions as $quid => $question) { $q = $fullquestions[$quid]; $q->maxmark = $question->maxmark; $q->number = $question->number; $questions[$quid] = $q; } // Get the data to be displayed. list($offlinequizstats, $questions, $subquestions, $s) = $this->get_offlinequiz_and_questions_stats($offlinequiz, $currentgroup, $nostudentsingroup, $useallattempts, $groupstudents, $questions); $offlinequizinfo = $this->get_formatted_offlinequiz_info_data($course, $cm, $offlinequiz, $offlinequizstats); // Set up the table, if there is data. if ($s) { $this->table->statistics_setup($offlinequiz, $cm->id, $reporturl, $s); } // Print the page header stuff (if not downloading. if (!$this->table->is_downloading()) { $this->print_header_and_tabs($cm, $course, $offlinequiz, $statmode, 'statistics'); // Options for the help text popup_action. $options = array('width' => 650, 'height' => 400, 'resizable' => false, 'top' => 0, 'left' => 0, 'menubar' => false, 'location' => false, 'scrollbars' => true, 'toolbar' => false, 'status' => false, 'directories' => false, 'fullscreen' => false, 'dependent' => false); $helpfilename = 'statistics_help_'; if (current_language() == 'de') { $helpfilename .= 'de.html'; } else { $helpfilename .= 'en.html'; } $url = new moodle_url($CFG->wwwroot . '/mod/offlinequiz/report/statistics/help/' . $helpfilename); $pixicon = new pix_icon('help', get_string('statisticshelp', 'offlinequiz_statistics')); $helpaction = $OUTPUT->action_icon($url, $pixicon, new popup_action('click', $url, 'help123', $options)); echo $OUTPUT->box_start('linkbox'); echo $OUTPUT->heading(format_string($offlinequiz->name)); echo $OUTPUT->heading(get_string($statmode . 'header', 'offlinequiz_statistics') . $helpaction); echo $OUTPUT->box_end(); if (!$questionid) { $this->print_offlinequiz_group_selector($cm, $groups, $groupnumber, $pageoptions); if ($statmode == 'statsoverview') { if ($offlinequiz->sumgrades == -1 || $differentquestions) { echo $OUTPUT->box_start(); echo $OUTPUT->notification(get_string('remarks', 'offlinequiz_statistics') . ':', 'notifynote'); } if ($offlinequiz->sumgrades == -1) { echo $OUTPUT->notification('- ' . get_string('differentsumgrades', 'offlinequiz_statistics', implode(', ', $sumgrades)), 'notifynote'); } if ($differentquestions) { echo $OUTPUT->notification('- ' . get_string('differentquestions', 'offlinequiz_statistics', implode(', ', $sumgrades)), 'notifynote'); } if ($offlinequiz->sumgrades == -1 || $differentquestions) { echo $OUTPUT->box_end(); } } } if (groups_get_activity_groupmode($cm)) { groups_print_activity_menu($cm, $reporturl->out()); if ($currentgroup && !$groupstudents) { echo $OUTPUT->notification(get_string('nostudentsingroup', 'offlinequiz_statistics')); } } if (!$offlinequiz->questions) { echo offlinequiz_no_questions_message($offlinequiz, $cm, $this->context); } else { if (!$this->table->is_downloading() && $s == 0) { echo $OUTPUT->box_start('linkbox'); echo $OUTPUT->notification(get_string('noattempts', 'offlinequiz'), 'notifyproblem'); echo $OUTPUT->box_end(); echo '<br/>'; } } } if ($everything) { // Implies is downloading. // Overall report, then the analysis of each question. if ($statmode == 'statsoverview') { $this->download_offlinequiz_info_table($offlinequizinfo); } else { if ($statmode == 'questionstats') { if ($s) { $this->output_offlinequiz_structure_analysis_table($s, $questions, $subquestions); if ($this->table->is_downloading() == 'xhtml') { $this->output_statistics_graph($offlinequizstats->id, $s); } foreach ($questions as $question) { if (question_bank::get_qtype($question->qtype, false)->can_analyse_responses()) { $this->output_individual_question_response_analysis($question, $reporturl, $offlinequizstats); } else { if (!empty($question->_stats->subquestions)) { $subitemstodisplay = explode(',', $question->_stats->subquestions); foreach ($subitemstodisplay as $subitemid) { $this->output_individual_question_response_analysis($subquestions[$subitemid], $reporturl, $offlinequizstats); } } } } } } else { if ($statmode == 'questionandanswerstats') { if ($s) { $this->output_offlinequiz_structure_analysis_table($s, $questions, $subquestions); if ($this->table->is_downloading() == 'xhtml') { $this->output_statistics_graph($offlinequizstats->id, $s); } foreach ($questions as $question) { if (question_bank::get_qtype($question->qtype, false)->can_analyse_responses()) { $this->output_individual_question_response_analysis($question, $reporturl, $offlinequizstats); } else { if (!empty($question->_stats->subquestions)) { $subitemstodisplay = explode(',', $question->_stats->subquestions); foreach ($subitemstodisplay as $subitemid) { $this->output_individual_question_response_analysis($subquestions[$subitemid], $reporturl, $offlinequizstats); } } } } } } } } $this->table->export_class_instance()->finish_document(); } else { if ($questionid) { // Report on an individual question indexed by position. if (!isset($questions[$questionid])) { print_error('questiondoesnotexist', 'question'); } $this->output_individual_question_data($offlinequiz, $questions[$questionid]); $this->output_individual_question_response_analysis($questions[$questionid], $reporturl, $offlinequizstats); // Back to overview link. echo $OUTPUT->box('<a href="' . $reporturl->out() . '">' . get_string('backtoquestionsandanswers', 'offlinequiz_statistics') . '</a>', 'backtomainstats boxaligncenter backlinkbox generalbox boxwidthnormal mdl-align'); } else { if ($qid) { // Report on an individual sub-question indexed questionid. if (!isset($subquestions[$qid])) { print_error('questiondoesnotexist', 'question'); } $this->output_individual_question_data($offlinequiz, $subquestions[$qid]); $this->output_individual_question_response_analysis($subquestions[$qid], $reporturl, $offlinequizstats); // Back to overview link. echo $OUTPUT->box('<a href="' . $reporturl->out() . '">' . get_string('backtoquestionsandanswers', 'offlinequiz_statistics') . '</a>', 'boxaligncenter backlinkbox generalbox boxwidthnormal mdl-align'); } else { if ($this->table->is_downloading()) { // Downloading overview report. $this->download_offlinequiz_info_table($offlinequizinfo); if ($statmode == 'questionstats') { $this->output_offlinequiz_structure_analysis_table($s, $questions, $subquestions); } else { if ($statmode == 'questionandanswerstats') { $this->output_offlinequiz_question_answer_table($s, $questions, $subquestions, $offlinequizstats); } } $this->table->finish_output(); } else { // On-screen display of overview report. echo $this->output_caching_info($offlinequizstats, $offlinequiz->id, $currentgroup, $groupstudents, $useallattempts, $reporturl, $offlinequiz->groupid); if ($statmode == 'statsoverview') { echo $this->everything_download_options(); echo '<br/><center>'; echo $this->output_offlinequiz_info_table($offlinequizinfo); echo '</center>'; } else { if ($statmode == 'questionstats') { if ($s) { echo '<br/>'; $this->output_offlinequiz_structure_analysis_table($s, $questions, $subquestions); } } else { if ($statmode == 'questionandanswerstats') { if ($s) { echo '<br/>'; $this->output_offlinequiz_question_answer_table($s, $questions, $subquestions, $offlinequizstats); } } } } } } } } }