Example #1
0
    public function display($quiz, $cm, $course) {
        global $CFG, $DB, $OUTPUT;

        list($currentgroup, $students, $groupstudents, $allowed) =
                $this->init('responses', 'quiz_responses_settings_form', $quiz, $cm, $course);
        $options = new quiz_responses_options('responses', $quiz, $cm, $course);

        if ($fromform = $this->form->get_data()) {
            $options->process_settings_from_form($fromform);

        } else {
            $options->process_settings_from_params();
        }

        $this->form->set_data($options->get_initial_form_data());

        if ($options->attempts == self::ALL_WITH) {
            // This option is only available to users who can access all groups in
            // groups mode, so setting allowed to empty (which means all quiz attempts
            // are accessible, is not a security porblem.
            $allowed = array();
        }

        // Load the required questions.
        $questions = quiz_report_get_significant_questions($quiz);

        // Prepare for downloading, if applicable.
        $courseshortname = format_string($course->shortname, true,
                array('context' => context_course::instance($course->id)));
        $table = new quiz_responses_table($quiz, $this->context, $this->qmsubselect,
                $options, $groupstudents, $students, $questions, $this->get_base_url());
        $filename = quiz_report_download_filename(get_string('responsesfilename', 'quiz_responses'),
                $courseshortname, $quiz->name);
        $table->is_downloading($options->download, $filename,
                $courseshortname . ' ' . format_string($quiz->name, true));
        if ($table->is_downloading()) {
            raise_memory_limit(MEMORY_EXTRA);
        }

        $this->process_actions($quiz, $cm, $currentgroup, $groupstudents, $allowed, $options->get_url());

        // Start output.
        if (!$table->is_downloading()) {
            // Only print headers if not asked to download data.
            $this->print_header_and_tabs($cm, $course, $quiz, $this->mode);
        }

        if ($groupmode = groups_get_activity_groupmode($cm)) {
            // Groups are being used, so output the group selector if we are not downloading.
            if (!$table->is_downloading()) {
                groups_print_activity_menu($cm, $options->get_url());
            }
        }

        // Print information on the number of existing attempts.
        if (!$table->is_downloading()) {
            // Do not print notices when downloading.
            if ($strattemptnum = quiz_num_attempt_summary($quiz, $cm, true, $currentgroup)) {
                echo '<div class="quizattemptcounts">' . $strattemptnum . '</div>';
            }
        }

        $hasquestions = quiz_questions_in_quiz($quiz->questions);
        if (!$table->is_downloading()) {
            if (!$hasquestions) {
                echo quiz_no_questions_message($quiz, $cm, $this->context);
            } else if (!$students) {
                echo $OUTPUT->notification(get_string('nostudentsyet'));
            } else if ($currentgroup && !$groupstudents) {
                echo $OUTPUT->notification(get_string('nostudentsingroup'));
            }

            // Print the display options.
            $this->form->display();
        }

        $hasstudents = $students && (!$currentgroup || $groupstudents);
        if ($hasquestions && ($hasstudents || $options->attempts == self::ALL_WITH)) {

            list($fields, $from, $where, $params) = $table->base_sql($allowed);

            $table->set_count_sql("SELECT COUNT(1) FROM $from WHERE $where", $params);

            $table->set_sql($fields, $from, $where, $params);

            if (!$table->is_downloading()) {
                // Print information on the grading method.
                if ($strattempthighlight = quiz_report_highlighting_grading_method(
                        $quiz, $this->qmsubselect, $options->onlygraded)) {
                    echo '<div class="quizattemptcounts">' . $strattempthighlight . '</div>';
                }
            }

            // Define table columns.
            $columns = array();
            $headers = array();

            if (!$table->is_downloading() && $options->checkboxcolumn) {
                $columns[] = 'checkbox';
                $headers[] = null;
            }

            $this->add_user_columns($table, $columns, $headers);
            $this->add_state_column($columns, $headers);

            if ($table->is_downloading()) {
                $this->add_time_columns($columns, $headers);
            }

            $this->add_grade_columns($quiz, $options->usercanseegrades, $columns, $headers);

            foreach ($questions as $id => $question) {
                if ($options->showqtext) {
                    $columns[] = 'question' . $id;
                    $headers[] = get_string('questionx', 'question', $question->number);
                }
                if ($options->showresponses) {
                    $columns[] = 'response' . $id;
                    $headers[] = get_string('responsex', 'quiz_responses', $question->number);
                }
                if ($options->showright) {
                    $columns[] = 'right' . $id;
                    $headers[] = get_string('rightanswerx', 'quiz_responses', $question->number);
                }
            }

            $table->define_columns($columns);
            $table->define_headers($headers);
            $table->sortable(true, 'uniqueid');

            // Set up the table.
            $table->define_baseurl($options->get_url());

            $this->configure_user_columns($table);

            $table->no_sorting('feedbacktext');
            $table->column_class('sumgrades', 'bold');

            $table->set_attribute('id', 'attempts');

            $table->collapsible(true);

            $table->out($options->pagesize, true);
        }
        return true;
    }
Example #2
0
 public function display($quiz, $cm, $course)
 {
     global $CFG, $COURSE, $DB, $OUTPUT;
     $this->context = get_context_instance(CONTEXT_MODULE, $cm->id);
     $download = optional_param('download', '', PARAM_ALPHA);
     list($currentgroup, $students, $groupstudents, $allowed) = $this->load_relevant_students($cm);
     $pageoptions = array();
     $pageoptions['id'] = $cm->id;
     $pageoptions['mode'] = 'overview';
     $reporturl = new moodle_url('/mod/quiz/report.php', $pageoptions);
     $qmsubselect = quiz_report_qm_filter_select($quiz);
     $mform = new mod_quiz_report_overview_settings($reporturl, array('qmsubselect' => $qmsubselect, 'quiz' => $quiz, 'currentgroup' => $currentgroup, 'context' => $this->context));
     if ($fromform = $mform->get_data()) {
         $regradeall = false;
         $regradealldry = false;
         $regradealldrydo = false;
         $attemptsmode = $fromform->attemptsmode;
         if ($qmsubselect) {
             $qmfilter = $fromform->qmfilter;
         } else {
             $qmfilter = 0;
         }
         $regradefilter = !empty($fromform->regradefilter);
         set_user_preference('quiz_report_overview_detailedmarks', $fromform->detailedmarks);
         set_user_preference('quiz_report_pagesize', $fromform->pagesize);
         $detailedmarks = $fromform->detailedmarks;
         $pagesize = $fromform->pagesize;
     } else {
         $regradeall = optional_param('regradeall', 0, PARAM_BOOL);
         $regradealldry = optional_param('regradealldry', 0, PARAM_BOOL);
         $regradealldrydo = optional_param('regradealldrydo', 0, PARAM_BOOL);
         $attemptsmode = optional_param('attemptsmode', null, PARAM_INT);
         if ($qmsubselect) {
             $qmfilter = optional_param('qmfilter', 0, PARAM_INT);
         } else {
             $qmfilter = 0;
         }
         $regradefilter = optional_param('regradefilter', 0, PARAM_INT);
         $detailedmarks = get_user_preferences('quiz_report_overview_detailedmarks', 1);
         $pagesize = get_user_preferences('quiz_report_pagesize', 0);
     }
     $this->validate_common_options($attemptsmode, $pagesize, $course, $currentgroup);
     $displayoptions = array();
     $displayoptions['attemptsmode'] = $attemptsmode;
     $displayoptions['qmfilter'] = $qmfilter;
     $displayoptions['regradefilter'] = $regradefilter;
     $mform->set_data($displayoptions + array('detailedmarks' => $detailedmarks, 'pagesize' => $pagesize));
     if (!$this->should_show_grades($quiz)) {
         $detailedmarks = 0;
     }
     // We only want to show the checkbox to delete attempts
     // if the user has permissions and if the report mode is showing attempts.
     $candelete = has_capability('mod/quiz:deleteattempts', $this->context) && $attemptsmode != QUIZ_REPORT_ATTEMPTS_STUDENTS_WITH_NO;
     if ($attemptsmode == QUIZ_REPORT_ATTEMPTS_ALL) {
         // This option is only available to users who can access all groups in
         // groups mode, so setting allowed to empty (which means all quiz attempts
         // are accessible, is not a security porblem.
         $allowed = array();
     }
     $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
     $courseshortname = format_string($course->shortname, true, array('context' => $coursecontext));
     $displaycoursecontext = get_context_instance(CONTEXT_COURSE, $COURSE->id);
     $displaycourseshortname = format_string($COURSE->shortname, true, array('context' => $displaycoursecontext));
     // Load the required questions.
     $questions = quiz_report_get_significant_questions($quiz);
     $table = new quiz_report_overview_table($quiz, $this->context, $qmsubselect, $groupstudents, $students, $detailedmarks, $questions, $candelete, $reporturl, $displayoptions);
     $filename = quiz_report_download_filename(get_string('overviewfilename', 'quiz_overview'), $courseshortname, $quiz->name);
     $table->is_downloading($download, $filename, $displaycourseshortname . ' ' . format_string($quiz->name, true));
     if ($table->is_downloading()) {
         raise_memory_limit(MEMORY_EXTRA);
     }
     // Process actions.
     if (empty($currentgroup) || $groupstudents) {
         if (optional_param('delete', 0, PARAM_BOOL) && confirm_sesskey()) {
             if ($attemptids = optional_param('attemptid', array(), PARAM_INT)) {
                 require_capability('mod/quiz:deleteattempts', $this->context);
                 $this->delete_selected_attempts($quiz, $cm, $attemptids, $allowed);
                 redirect($reporturl->out(false, $displayoptions));
             }
         } else {
             if (optional_param('regrade', 0, PARAM_BOOL) && confirm_sesskey()) {
                 if ($attemptids = optional_param('attemptid', array(), PARAM_INT)) {
                     require_capability('mod/quiz:regrade', $this->context);
                     $this->regrade_attempts($quiz, false, $groupstudents, $attemptids);
                     redirect($reporturl->out(false, $displayoptions));
                 }
             }
         }
     }
     if ($regradeall && confirm_sesskey()) {
         require_capability('mod/quiz:regrade', $this->context);
         $this->regrade_attempts($quiz, false, $groupstudents);
         redirect($reporturl->out(false, $displayoptions), '', 5);
     } else {
         if ($regradealldry && confirm_sesskey()) {
             require_capability('mod/quiz:regrade', $this->context);
             $this->regrade_attempts($quiz, true, $groupstudents);
             redirect($reporturl->out(false, $displayoptions), '', 5);
         } else {
             if ($regradealldrydo && confirm_sesskey()) {
                 require_capability('mod/quiz:regrade', $this->context);
                 $this->regrade_attempts_needing_it($quiz, $groupstudents);
                 redirect($reporturl->out(false, $displayoptions), '', 5);
             }
         }
     }
     // Start output.
     if (!$table->is_downloading()) {
         // Only print headers if not asked to download data
         $this->print_header_and_tabs($cm, $course, $quiz, 'overview');
     }
     if ($groupmode = groups_get_activity_groupmode($cm)) {
         // Groups are being used
         if (!$table->is_downloading()) {
             groups_print_activity_menu($cm, $reporturl->out(true, $displayoptions));
         }
     }
     // Print information on the number of existing attempts
     if (!$table->is_downloading()) {
         //do not print notices when downloading
         if ($strattemptnum = quiz_num_attempt_summary($quiz, $cm, true, $currentgroup)) {
             echo '<div class="quizattemptcounts">' . $strattemptnum . '</div>';
         }
     }
     $hasquestions = quiz_questions_in_quiz($quiz->questions);
     if (!$table->is_downloading()) {
         if (!$hasquestions) {
             echo quiz_no_questions_message($quiz, $cm, $this->context);
         } else {
             if (!$students) {
                 echo $OUTPUT->notification(get_string('nostudentsyet'));
             } else {
                 if ($currentgroup && !$groupstudents) {
                     echo $OUTPUT->notification(get_string('nostudentsingroup'));
                 }
             }
         }
         // Print display options
         $mform->display();
     }
     $hasstudents = $students && (!$currentgroup || $groupstudents);
     if ($hasquestions && ($hasstudents || $attemptsmode == QUIZ_REPORT_ATTEMPTS_ALL)) {
         // Construct the SQL
         $fields = $DB->sql_concat('u.id', "'#'", 'COALESCE(quiza.attempt, 0)') . ' AS uniqueid, ';
         if ($qmsubselect) {
             $fields .= "(CASE " . "   WHEN {$qmsubselect} THEN 1" . "   ELSE 0 " . "END) AS gradedattempt, ";
         }
         list($fields, $from, $where, $params) = $this->base_sql($quiz, $qmsubselect, $qmfilter, $attemptsmode, $allowed);
         $table->set_count_sql("SELECT COUNT(1) FROM {$from} WHERE {$where}", $params);
         // Test to see if there are any regraded attempts to be listed.
         $fields .= ", COALESCE((\n                                SELECT MAX(qqr.regraded)\n                                  FROM {quiz_overview_regrades} qqr\n                                 WHERE qqr.questionusageid = quiza.uniqueid\n                          ), -1) AS regraded";
         if ($regradefilter) {
             $where .= " AND COALESCE((\n                                    SELECT MAX(qqr.regraded)\n                                      FROM {quiz_overview_regrades} qqr\n                                     WHERE qqr.questionusageid = quiza.uniqueid\n                                ), -1) <> -1";
         }
         $table->set_sql($fields, $from, $where, $params);
         if (!$table->is_downloading()) {
             // Regrade buttons
             if (has_capability('mod/quiz:regrade', $this->context)) {
                 $regradesneeded = $this->count_question_attempts_needing_regrade($quiz, $groupstudents);
                 if ($currentgroup) {
                     $a = new stdClass();
                     $a->groupname = groups_get_group_name($currentgroup);
                     $a->coursestudents = get_string('participants');
                     $a->countregradeneeded = $regradesneeded;
                     $regradealldrydolabel = get_string('regradealldrydogroup', 'quiz_overview', $a);
                     $regradealldrylabel = get_string('regradealldrygroup', 'quiz_overview', $a);
                     $regradealllabel = get_string('regradeallgroup', 'quiz_overview', $a);
                 } else {
                     $regradealldrydolabel = get_string('regradealldrydo', 'quiz_overview', $regradesneeded);
                     $regradealldrylabel = get_string('regradealldry', 'quiz_overview');
                     $regradealllabel = get_string('regradeall', 'quiz_overview');
                 }
                 $displayurl = new moodle_url($reporturl, $displayoptions + array('sesskey' => sesskey()));
                 echo '<div class="mdl-align">';
                 echo '<form action="' . $displayurl->out_omit_querystring() . '">';
                 echo '<div>';
                 echo html_writer::input_hidden_params($displayurl);
                 echo '<input type="submit" name="regradeall" value="' . $regradealllabel . '"/>';
                 echo '<input type="submit" name="regradealldry" value="' . $regradealldrylabel . '"/>';
                 if ($regradesneeded) {
                     echo '<input type="submit" name="regradealldrydo" value="' . $regradealldrydolabel . '"/>';
                 }
                 echo '</div>';
                 echo '</form>';
                 echo '</div>';
             }
             // Print information on the grading method
             if ($strattempthighlight = quiz_report_highlighting_grading_method($quiz, $qmsubselect, $qmfilter)) {
                 echo '<div class="quizattemptcounts">' . $strattempthighlight . '</div>';
             }
         }
         // Define table columns
         $columns = array();
         $headers = array();
         if (!$table->is_downloading() && $candelete) {
             $columns[] = 'checkbox';
             $headers[] = null;
         }
         $this->add_user_columns($table, $columns, $headers);
         $this->add_time_columns($columns, $headers);
         if ($detailedmarks) {
             foreach ($questions as $slot => $question) {
                 // Ignore questions of zero length
                 $columns[] = 'qsgrade' . $slot;
                 $header = get_string('qbrief', 'quiz', $question->number);
                 if (!$table->is_downloading()) {
                     $header .= '<br />';
                 } else {
                     $header .= ' ';
                 }
                 $header .= '/' . quiz_rescale_grade($question->maxmark, $quiz, 'question');
                 $headers[] = $header;
             }
         }
         if (!$table->is_downloading() && has_capability('mod/quiz:regrade', $this->context) && $this->has_regraded_questions($from, $where, $params)) {
             $columns[] = 'regraded';
             $headers[] = get_string('regrade', 'quiz_overview');
         }
         $this->add_grade_columns($quiz, $columns, $headers);
         $this->set_up_table_columns($table, $columns, $headers, $reporturl, $displayoptions, false);
         $table->set_attribute('class', 'generaltable generalbox grades');
         $table->out($pagesize, true);
     }
     if (!$table->is_downloading() && $this->should_show_grades($quiz)) {
         if ($currentgroup && $groupstudents) {
             list($usql, $params) = $DB->get_in_or_equal($groupstudents);
             $params[] = $quiz->id;
             if ($DB->record_exists_select('quiz_grades', "userid {$usql} AND quiz = ?", $params)) {
                 $imageurl = new moodle_url('/mod/quiz/report/overview/overviewgraph.php', array('id' => $quiz->id, 'groupid' => $currentgroup));
                 $graphname = get_string('overviewreportgraphgroup', 'quiz_overview', groups_get_group_name($currentgroup));
                 echo $OUTPUT->heading($graphname);
                 echo html_writer::tag('div', html_writer::empty_tag('img', array('src' => $imageurl, 'alt' => $graphname)), array('class' => 'graph'));
             }
         }
         if ($DB->record_exists('quiz_grades', array('quiz' => $quiz->id))) {
             $graphname = get_string('overviewreportgraph', 'quiz_overview');
             $imageurl = new moodle_url('/mod/quiz/report/overview/overviewgraph.php', array('id' => $quiz->id));
             echo $OUTPUT->heading($graphname);
             echo html_writer::tag('div', html_writer::empty_tag('img', array('src' => $imageurl, 'alt' => $graphname)), array('class' => 'graph'));
         }
     }
     return true;
 }
Example #3
0
 public function display($quiz, $cm, $course)
 {
     global $CFG, $DB, $PAGE;
     $this->quiz = $quiz;
     $this->cm = $cm;
     $this->course = $course;
     // Get the URL options.
     $slot = optional_param('slot', null, PARAM_INT);
     $questionid = optional_param('qid', null, PARAM_INT);
     $grade = optional_param('grade', null, PARAM_ALPHA);
     $includeauto = optional_param('includeauto', false, PARAM_BOOL);
     if (!in_array($grade, array('all', 'needsgrading', 'autograded', 'manuallygraded'))) {
         $grade = null;
     }
     $pagesize = optional_param('pagesize', self::DEFAULT_PAGE_SIZE, PARAM_INT);
     $page = optional_param('page', 0, PARAM_INT);
     $order = optional_param('order', self::DEFAULT_ORDER, PARAM_ALPHA);
     // Assemble the options requried to reload this page.
     $optparams = array('includeauto', 'page');
     foreach ($optparams as $param) {
         if (${$param}) {
             $this->viewoptions[$param] = ${$param};
         }
     }
     if ($pagesize != self::DEFAULT_PAGE_SIZE) {
         $this->viewoptions['pagesize'] = $pagesize;
     }
     if ($order != self::DEFAULT_ORDER) {
         $this->viewoptions['order'] = $order;
     }
     // Check permissions.
     $this->context = context_module::instance($cm->id);
     require_capability('mod/quiz:grade', $this->context);
     $shownames = has_capability('quiz/grading:viewstudentnames', $this->context);
     $showidnumbers = has_capability('quiz/grading:viewidnumber', $this->context);
     // Validate order.
     if (!in_array($order, array('random', 'date', 'studentfirstname', 'studentlastname', 'idnumber'))) {
         $order = self::DEFAULT_ORDER;
     } else {
         if (!$shownames && ($order == 'studentfirstname' || $order == 'studentlastname')) {
             $order = self::DEFAULT_ORDER;
         } else {
             if (!$showidnumbers && $order == 'idnumber') {
                 $order = self::DEFAULT_ORDER;
             }
         }
     }
     if ($order == 'random') {
         $page = 0;
     }
     // Get the list of questions in this quiz.
     $this->questions = quiz_report_get_significant_questions($quiz);
     if ($slot && !array_key_exists($slot, $this->questions)) {
         throw new moodle_exception('unknownquestion', 'quiz_grading');
     }
     // Process any submitted data.
     if ($data = data_submitted() && confirm_sesskey() && $this->validate_submitted_marks()) {
         $this->process_submitted_data();
         redirect($this->grade_question_url($slot, $questionid, $grade, $page + 1));
     }
     // Get the group, and the list of significant users.
     $this->currentgroup = $this->get_current_group($cm, $course, $this->context);
     if ($this->currentgroup == self::NO_GROUPS_ALLOWED) {
         $this->users = array();
     } else {
         $this->users = get_users_by_capability($this->context, array('mod/quiz:reviewmyattempts', 'mod/quiz:attempt'), '', '', '', '', $this->currentgroup, '', false);
     }
     $hasquestions = quiz_has_questions($quiz->id);
     $counts = null;
     if ($slot && $hasquestions) {
         // Make sure there is something to do.
         $statecounts = $this->get_question_state_summary(array($slot));
         foreach ($statecounts as $record) {
             if ($record->questionid == $questionid) {
                 $counts = $record;
                 break;
             }
         }
         // If not, redirect back to the list.
         if (!$counts || $counts->{$grade} == 0) {
             redirect($this->list_questions_url(), get_string('alldoneredirecting', 'quiz_grading'));
         }
     }
     // Start output.
     $this->print_header_and_tabs($cm, $course, $quiz, 'grading');
     // What sort of page to display?
     if (!$hasquestions) {
         echo quiz_no_questions_message($quiz, $cm, $this->context);
     } else {
         if (!$slot) {
             $this->display_index($includeauto);
         } else {
             $this->display_grading_interface($slot, $questionid, $grade, $pagesize, $page, $shownames, $showidnumbers, $order, $counts);
         }
     }
     return true;
 }
Example #4
0
    /**
     * Display the report.
     */
    public function display($quiz, $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.
        $qid = optional_param('qid', 0, PARAM_INT);
        $slot = optional_param('slot', 0, PARAM_INT);

        $pageoptions = array();
        $pageoptions['id'] = $cm->id;
        $pageoptions['mode'] = 'statistics';

        $reporturl = new moodle_url('/mod/quiz/report.php', $pageoptions);

        $mform = new quiz_statistics_settings_form($reporturl);
        if ($fromform = $mform->get_data()) {
            $useallattempts = $fromform->useallattempts;
            if ($fromform->useallattempts) {
                set_user_preference('quiz_report_statistics_useallattempts',
                        $fromform->useallattempts);
            } else {
                unset_user_preference('quiz_report_statistics_useallattempts');
            }

        } else {
            $useallattempts = get_user_preferences('quiz_report_statistics_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 quizzes and who are in the currently selected group.
            $groupstudents = get_users_by_capability($this->context,
                    array('mod/quiz:reviewmyattempts', 'mod/quiz:attempt'),
                    '', '', '', '', $currentgroup, '', false);
            if (!$groupstudents) {
                $nostudentsingroup = true;
            }
        }

        // If recalculate was requested, handle that.
        if ($recalculate && confirm_sesskey()) {
            $this->clear_cached_data($quiz->id, $currentgroup, $useallattempts);
            redirect($reporturl);
        }

        // Set up the main table.
        $this->table = new quiz_statistics_table();
        if ($everything) {
            $report = get_string('completestatsfilename', 'quiz_statistics');
        } else {
            $report = get_string('questionstatsfilename', 'quiz_statistics');
        }
        $courseshortname = format_string($course->shortname, true,
                array('context' => context_course::instance($course->id)));
        $filename = quiz_report_download_filename($report, $courseshortname, $quiz->name);
        $this->table->is_downloading($download, $filename,
                get_string('quizstructureanalysis', 'quiz_statistics'));

        // Load the questions.
        $questions = quiz_report_get_significant_questions($quiz);
        $questionids = array();
        foreach ($questions as $question) {
            $questionids[] = $question->id;
        }
        $fullquestions = question_load_questions($questionids);
        foreach ($questions as $qno => $question) {
            $q = $fullquestions[$question->id];
            $q->maxmark = $question->maxmark;
            $q->slot = $qno;
            $q->number = $question->number;
            $questions[$qno] = $q;
        }

        // Get the data to be displayed.
        list($quizstats, $questions, $subquestions, $s) =
                $this->get_quiz_and_questions_stats($quiz, $currentgroup,
                        $nostudentsingroup, $useallattempts, $groupstudents, $questions);
        $quizinfo = $this->get_formatted_quiz_info_data($course, $cm, $quiz, $quizstats);

        // Set up the table, if there is data.
        if ($s) {
            $this->table->statistics_setup($quiz, $cm->id, $reporturl, $s);
        }

        // Print the page header stuff (if not downloading.
        if (!$this->table->is_downloading()) {
            $this->print_header_and_tabs($cm, $course, $quiz, 'statistics');

            if (groups_get_activity_groupmode($cm)) {
                groups_print_activity_menu($cm, $reporturl->out());
                if ($currentgroup && !$groupstudents) {
                    $OUTPUT->notification(get_string('nostudentsingroup', 'quiz_statistics'));
                }
            }

            if (!quiz_questions_in_quiz($quiz->questions)) {
                echo quiz_no_questions_message($quiz, $cm, $this->context);
            } else if (!$this->table->is_downloading() && $s == 0) {
                echo $OUTPUT->notification(get_string('noattempts', 'quiz'));
            }

            // Print display options form.
            $mform->set_data(array('useallattempts' => $useallattempts));
            $mform->display();
        }

        if ($everything) { // Implies is downloading.
            // Overall report, then the analysis of each question.
            $this->download_quiz_info_table($quizinfo);

            if ($s) {
                $this->output_quiz_structure_analysis_table($s, $questions, $subquestions);

                if ($this->table->is_downloading() == 'xhtml') {
                    $this->output_statistics_graph($quizstats->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, $quizstats);

                    } else if (!empty($question->_stats->subquestions)) {
                        $subitemstodisplay = explode(',', $question->_stats->subquestions);
                        foreach ($subitemstodisplay as $subitemid) {
                            $this->output_individual_question_response_analysis(
                                    $subquestions[$subitemid], $reporturl, $quizstats);
                        }
                    }
                }
            }

            $this->table->export_class_instance()->finish_document();

        } else if ($slot) {
            // Report on an individual question indexed by position.
            if (!isset($questions[$slot])) {
                print_error('questiondoesnotexist', 'question');
            }

            $this->output_individual_question_data($quiz, $questions[$slot]);
            $this->output_individual_question_response_analysis(
                    $questions[$slot], $reporturl, $quizstats);

            // Back to overview link.
            echo $OUTPUT->box('<a href="' . $reporturl->out() . '">' .
                    get_string('backtoquizreport', 'quiz_statistics') . '</a>',
                    'backtomainstats boxaligncenter 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($quiz, $subquestions[$qid]);
            $this->output_individual_question_response_analysis(
                    $subquestions[$qid], $reporturl, $quizstats);

            // Back to overview link.
            echo $OUTPUT->box('<a href="' . $reporturl->out() . '">' .
                    get_string('backtoquizreport', 'quiz_statistics') . '</a>',
                    'boxaligncenter generalbox boxwidthnormal mdl-align');

        } else if ($this->table->is_downloading()) {
            // Downloading overview report.
            $this->download_quiz_info_table($quizinfo);
            $this->output_quiz_structure_analysis_table($s, $questions, $subquestions);
            $this->table->finish_output();

        } else {
            // On-screen display of overview report.
            echo $OUTPUT->heading(get_string('quizinformation', 'quiz_statistics'));
            echo $this->output_caching_info($quizstats, $quiz->id, $currentgroup,
                    $groupstudents, $useallattempts, $reporturl);
            echo $this->everything_download_options();
            echo $this->output_quiz_info_table($quizinfo);
            if ($s) {
                echo $OUTPUT->heading(get_string('quizstructureanalysis', 'quiz_statistics'));
                $this->output_quiz_structure_analysis_table($s, $questions, $subquestions);
                $this->output_statistics_graph($quizstats->id, $s);
            }
        }

        return true;
    }
Example #5
0
 public function display($quiz, $cm, $course)
 {
     global $CFG, $COURSE, $DB, $PAGE, $OUTPUT;
     $this->context = get_context_instance(CONTEXT_MODULE, $cm->id);
     $download = optional_param('download', '', PARAM_ALPHA);
     list($currentgroup, $students, $groupstudents, $allowed) = $this->load_relevant_students($cm);
     $pageoptions = array();
     $pageoptions['id'] = $cm->id;
     $pageoptions['mode'] = 'responses';
     $reporturl = new moodle_url('/mod/quiz/report.php', $pageoptions);
     $qmsubselect = quiz_report_qm_filter_select($quiz);
     $mform = new mod_quiz_report_responses_settings($reporturl, array('qmsubselect' => $qmsubselect, 'quiz' => $quiz, 'currentgroup' => $currentgroup, 'context' => $this->context));
     if ($fromform = $mform->get_data()) {
         $attemptsmode = $fromform->attemptsmode;
         if ($qmsubselect) {
             $qmfilter = $fromform->qmfilter;
         } else {
             $qmfilter = 0;
         }
         set_user_preference('quiz_report_responses_qtext', $fromform->qtext);
         set_user_preference('quiz_report_responses_resp', $fromform->resp);
         set_user_preference('quiz_report_responses_right', $fromform->right);
         set_user_preference('quiz_report_pagesize', $fromform->pagesize);
         $includeqtext = $fromform->qtext;
         $includeresp = $fromform->resp;
         $includeright = $fromform->right;
         $pagesize = $fromform->pagesize;
     } else {
         $attemptsmode = optional_param('attemptsmode', null, PARAM_INT);
         if ($qmsubselect) {
             $qmfilter = optional_param('qmfilter', 0, PARAM_INT);
         } else {
             $qmfilter = 0;
         }
         $includeqtext = get_user_preferences('quiz_report_responses_qtext', 0);
         $includeresp = get_user_preferences('quiz_report_responses_resp', 1);
         $includeright = get_user_preferences('quiz_report_responses_right', 0);
         $pagesize = get_user_preferences('quiz_report_pagesize', 0);
     }
     $this->validate_common_options($attemptsmode, $pagesize, $course, $currentgroup);
     if (!$includeqtext && !$includeresp && !$includeright) {
         $includeresp = 1;
         set_user_preference('quiz_report_responses_resp', 1);
     }
     // We only want to show the checkbox to delete attempts
     // if the user has permissions and if the report mode is showing attempts.
     $candelete = has_capability('mod/quiz:deleteattempts', $this->context) && $attemptsmode != QUIZ_REPORT_ATTEMPTS_STUDENTS_WITH_NO;
     $displayoptions = array();
     $displayoptions['attemptsmode'] = $attemptsmode;
     $displayoptions['qmfilter'] = $qmfilter;
     $displayoptions['qtext'] = $includeqtext;
     $displayoptions['resp'] = $includeresp;
     $displayoptions['right'] = $includeright;
     $mform->set_data($displayoptions + array('pagesize' => $pagesize));
     if ($attemptsmode == QUIZ_REPORT_ATTEMPTS_ALL) {
         // This option is only available to users who can access all groups in
         // groups mode, so setting allowed to empty (which means all quiz attempts
         // are accessible, is not a security porblem.
         $allowed = array();
     }
     $attemptids = optional_param_array('attemptid', array(), PARAM_INT);
     if ($attemptids && confirm_sesskey()) {
         require_capability('mod/quiz:deleteattempts', $this->context);
         $this->delete_selected_attempts($quiz, $cm, $attemptids, $allowed);
         redirect($reporturl->out(false, $displayoptions));
     }
     // Load the required questions.
     $questions = quiz_report_get_significant_questions($quiz);
     $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
     $courseshortname = format_string($course->shortname, true, array('context' => $coursecontext));
     $displaycoursecontext = get_context_instance(CONTEXT_COURSE, $COURSE->id);
     $displaycourseshortname = format_string($COURSE->shortname, true, array('context' => $displaycoursecontext));
     $table = new quiz_report_responses_table($quiz, $this->context, $qmsubselect, $groupstudents, $students, $questions, $candelete, $reporturl, $displayoptions);
     $filename = quiz_report_download_filename(get_string('responsesfilename', 'quiz_responses'), $courseshortname, $quiz->name);
     $table->is_downloading($download, $filename, $displaycourseshortname . ' ' . format_string($quiz->name, true));
     if ($table->is_downloading()) {
         raise_memory_limit(MEMORY_EXTRA);
     }
     if (!$table->is_downloading()) {
         // Only print headers if not asked to download data
         $this->print_header_and_tabs($cm, $course, $quiz, 'responses');
     }
     if ($groupmode = groups_get_activity_groupmode($cm)) {
         // Groups are being used
         if (!$table->is_downloading()) {
             groups_print_activity_menu($cm, $reporturl->out(true, $displayoptions));
         }
     }
     // Print information on the number of existing attempts
     if (!$table->is_downloading()) {
         //do not print notices when downloading
         if ($strattemptnum = quiz_num_attempt_summary($quiz, $cm, true, $currentgroup)) {
             echo '<div class="quizattemptcounts">' . $strattemptnum . '</div>';
         }
     }
     $hasquestions = quiz_questions_in_quiz($quiz->questions);
     if (!$table->is_downloading()) {
         if (!$hasquestions) {
             echo quiz_no_questions_message($quiz, $cm, $this->context);
         } else {
             if (!$students) {
                 echo $OUTPUT->notification(get_string('nostudentsyet'));
             } else {
                 if ($currentgroup && !$groupstudents) {
                     echo $OUTPUT->notification(get_string('nostudentsingroup'));
                 }
             }
         }
         // Print display options
         $mform->display();
     }
     $hasstudents = $students && (!$currentgroup || $groupstudents);
     if ($hasquestions && ($hasstudents || $attemptsmode == QUIZ_REPORT_ATTEMPTS_ALL)) {
         // Print information on the grading method and whether we are displaying
         if (!$table->is_downloading()) {
             //do not print notices when downloading
             if ($strattempthighlight = quiz_report_highlighting_grading_method($quiz, $qmsubselect, $qmfilter)) {
                 echo '<div class="quizattemptcounts">' . $strattempthighlight . '</div>';
             }
         }
         list($fields, $from, $where, $params) = $this->base_sql($quiz, $qmsubselect, $qmfilter, $attemptsmode, $allowed);
         $table->set_count_sql("SELECT COUNT(1) FROM {$from} WHERE {$where}", $params);
         $table->set_sql($fields, $from, $where, $params);
         // Define table columns
         $columns = array();
         $headers = array();
         if (!$table->is_downloading() && $candelete) {
             $columns[] = 'checkbox';
             $headers[] = null;
         }
         $this->add_user_columns($table, $columns, $headers);
         if ($table->is_downloading()) {
             $this->add_time_columns($columns, $headers);
         }
         $this->add_grade_columns($quiz, $columns, $headers);
         foreach ($questions as $id => $question) {
             if ($displayoptions['qtext']) {
                 $columns[] = 'question' . $id;
                 $headers[] = get_string('questionx', 'question', $question->number);
             }
             if ($displayoptions['resp']) {
                 $columns[] = 'response' . $id;
                 $headers[] = get_string('responsex', 'quiz_responses', $question->number);
             }
             if ($displayoptions['right']) {
                 $columns[] = 'right' . $id;
                 $headers[] = get_string('rightanswerx', 'quiz_responses', $question->number);
             }
         }
         $table->define_columns($columns);
         $table->define_headers($headers);
         $table->sortable(true, 'uniqueid');
         // Set up the table
         $table->define_baseurl($reporturl->out(true, $displayoptions));
         $this->configure_user_columns($table);
         $table->no_sorting('feedbacktext');
         $table->column_class('sumgrades', 'bold');
         $table->set_attribute('id', 'attempts');
         $table->collapsible(true);
         $table->out($pagesize, true);
     }
     return true;
 }
Example #6
0
 public function display($quiz, $cm, $course)
 {
     global $CFG, $DB, $OUTPUT, $PAGE;
     list($currentgroup, $students, $groupstudents, $allowed) = $this->init('overview', 'quiz_overview_settings_form', $quiz, $cm, $course);
     $options = new quiz_overview_options('overview', $quiz, $cm, $course);
     if ($fromform = $this->form->get_data()) {
         $options->process_settings_from_form($fromform);
     } else {
         $options->process_settings_from_params();
     }
     $this->form->set_data($options->get_initial_form_data());
     if ($options->attempts == self::ALL_WITH) {
         // This option is only available to users who can access all groups in
         // groups mode, so setting allowed to empty (which means all quiz attempts
         // are accessible, is not a security porblem.
         $allowed = array();
     }
     // Load the required questions.
     $questions = quiz_report_get_significant_questions($quiz);
     // Prepare for downloading, if applicable.
     $courseshortname = format_string($course->shortname, true, array('context' => context_course::instance($course->id)));
     $table = new quiz_overview_table($quiz, $this->context, $this->qmsubselect, $options, $groupstudents, $students, $questions, $options->get_url());
     $filename = quiz_report_download_filename(get_string('overviewfilename', 'quiz_overview'), $courseshortname, $quiz->name);
     $table->is_downloading($options->download, $filename, $courseshortname . ' ' . format_string($quiz->name, true));
     if ($table->is_downloading()) {
         raise_memory_limit(MEMORY_EXTRA);
     }
     $this->course = $course;
     // Hack to make this available in process_actions.
     $this->process_actions($quiz, $cm, $currentgroup, $groupstudents, $allowed, $options->get_url());
     // Start output.
     if (!$table->is_downloading()) {
         // Only print headers if not asked to download data.
         $this->print_header_and_tabs($cm, $course, $quiz, $this->mode);
     }
     if ($groupmode = groups_get_activity_groupmode($cm)) {
         // Groups are being used, so output the group selector if we are not downloading.
         if (!$table->is_downloading()) {
             groups_print_activity_menu($cm, $options->get_url());
         }
     }
     // Print information on the number of existing attempts.
     if (!$table->is_downloading()) {
         // Do not print notices when downloading.
         if ($strattemptnum = quiz_num_attempt_summary($quiz, $cm, true, $currentgroup)) {
             echo '<div class="quizattemptcounts">' . $strattemptnum . '</div>';
         }
     }
     $hasquestions = quiz_questions_in_quiz($quiz->questions);
     if (!$table->is_downloading()) {
         if (!$hasquestions) {
             echo quiz_no_questions_message($quiz, $cm, $this->context);
         } else {
             if (!$students) {
                 echo $OUTPUT->notification(get_string('nostudentsyet'));
             } else {
                 if ($currentgroup && !$groupstudents) {
                     echo $OUTPUT->notification(get_string('nostudentsingroup'));
                 }
             }
         }
         // Print the display options.
         $this->form->display();
     }
     $hasstudents = $students && (!$currentgroup || $groupstudents);
     if ($hasquestions && ($hasstudents || $options->attempts == self::ALL_WITH)) {
         // Construct the SQL.
         $fields = $DB->sql_concat('u.id', "'#'", 'COALESCE(quiza.attempt, 0)') . ' AS uniqueid, ';
         if ($this->qmsubselect) {
             $fields .= "(CASE " . "   WHEN {$this->qmsubselect} THEN 1" . "   ELSE 0 " . "END) AS gradedattempt, ";
         }
         list($fields, $from, $where, $params) = $table->base_sql($allowed);
         $table->set_count_sql("SELECT COUNT(1) FROM {$from} WHERE {$where}", $params);
         // Test to see if there are any regraded attempts to be listed.
         $fields .= ", COALESCE((\n                                SELECT MAX(qqr.regraded)\n                                  FROM {quiz_overview_regrades} qqr\n                                 WHERE qqr.questionusageid = quiza.uniqueid\n                          ), -1) AS regraded";
         if ($options->onlyregraded) {
             $where .= " AND COALESCE((\n                                    SELECT MAX(qqr.regraded)\n                                      FROM {quiz_overview_regrades} qqr\n                                     WHERE qqr.questionusageid = quiza.uniqueid\n                                ), -1) <> -1";
         }
         $table->set_sql($fields, $from, $where, $params);
         if (!$table->is_downloading()) {
             // Output the regrade buttons.
             if (has_capability('mod/quiz:regrade', $this->context)) {
                 $regradesneeded = $this->count_question_attempts_needing_regrade($quiz, $groupstudents);
                 if ($currentgroup) {
                     $a = new stdClass();
                     $a->groupname = groups_get_group_name($currentgroup);
                     $a->coursestudents = get_string('participants');
                     $a->countregradeneeded = $regradesneeded;
                     $regradealldrydolabel = get_string('regradealldrydogroup', 'quiz_overview', $a);
                     $regradealldrylabel = get_string('regradealldrygroup', 'quiz_overview', $a);
                     $regradealllabel = get_string('regradeallgroup', 'quiz_overview', $a);
                 } else {
                     $regradealldrydolabel = get_string('regradealldrydo', 'quiz_overview', $regradesneeded);
                     $regradealldrylabel = get_string('regradealldry', 'quiz_overview');
                     $regradealllabel = get_string('regradeall', 'quiz_overview');
                 }
                 $displayurl = new moodle_url($options->get_url(), array('sesskey' => sesskey()));
                 echo '<div class="mdl-align">';
                 echo '<form action="' . $displayurl->out_omit_querystring() . '">';
                 echo '<div>';
                 echo html_writer::input_hidden_params($displayurl);
                 echo '<input type="submit" name="regradeall" value="' . $regradealllabel . '"/>';
                 echo '<input type="submit" name="regradealldry" value="' . $regradealldrylabel . '"/>';
                 if ($regradesneeded) {
                     echo '<input type="submit" name="regradealldrydo" value="' . $regradealldrydolabel . '"/>';
                 }
                 echo '</div>';
                 echo '</form>';
                 echo '</div>';
             }
             // Print information on the grading method.
             if ($strattempthighlight = quiz_report_highlighting_grading_method($quiz, $this->qmsubselect, $options->onlygraded)) {
                 echo '<div class="quizattemptcounts">' . $strattempthighlight . '</div>';
             }
         }
         // Define table columns.
         $columns = array();
         $headers = array();
         if (!$table->is_downloading() && $options->checkboxcolumn) {
             $columns[] = 'checkbox';
             $headers[] = null;
         }
         $this->add_user_columns($table, $columns, $headers);
         $this->add_state_column($columns, $headers);
         $this->add_time_columns($columns, $headers);
         $this->add_grade_columns($quiz, $options->usercanseegrades, $columns, $headers, false);
         if (!$table->is_downloading() && has_capability('mod/quiz:regrade', $this->context) && $this->has_regraded_questions($from, $where, $params)) {
             $columns[] = 'regraded';
             $headers[] = get_string('regrade', 'quiz_overview');
         }
         if ($options->slotmarks) {
             foreach ($questions as $slot => $question) {
                 // Ignore questions of zero length.
                 $columns[] = 'qsgrade' . $slot;
                 $header = get_string('qbrief', 'quiz', $question->number);
                 if (!$table->is_downloading()) {
                     $header .= '<br />';
                 } else {
                     $header .= ' ';
                 }
                 $header .= '/' . quiz_rescale_grade($question->maxmark, $quiz, 'question');
                 $headers[] = $header;
             }
         }
         $this->set_up_table_columns($table, $columns, $headers, $this->get_base_url(), $options, false);
         $table->set_attribute('class', 'generaltable generalbox grades');
         $table->out($options->pagesize, true);
     }
     if (!$table->is_downloading() && $options->usercanseegrades) {
         $output = $PAGE->get_renderer('mod_quiz');
         if ($currentgroup && $groupstudents) {
             list($usql, $params) = $DB->get_in_or_equal($groupstudents);
             $params[] = $quiz->id;
             if ($DB->record_exists_select('quiz_grades', "userid {$usql} AND quiz = ?", $params)) {
                 $imageurl = new moodle_url('/mod/quiz/report/overview/overviewgraph.php', array('id' => $quiz->id, 'groupid' => $currentgroup));
                 $graphname = get_string('overviewreportgraphgroup', 'quiz_overview', groups_get_group_name($currentgroup));
                 echo $output->graph($imageurl, $graphname);
             }
         }
         if ($DB->record_exists('quiz_grades', array('quiz' => $quiz->id))) {
             $imageurl = new moodle_url('/mod/quiz/report/overview/overviewgraph.php', array('id' => $quiz->id));
             $graphname = get_string('overviewreportgraph', 'quiz_overview');
             echo $output->graph($imageurl, $graphname);
         }
     }
     return true;
 }
Example #7
0
 /**
  * Display the report.
  */
 public function display($quiz, $cm, $course)
 {
     global $OUTPUT;
     raise_memory_limit(MEMORY_HUGE);
     $this->context = context_module::instance($cm->id);
     if (!quiz_has_questions($quiz->id)) {
         $this->print_header_and_tabs($cm, $course, $quiz, 'statistics');
         echo quiz_no_questions_message($quiz, $cm, $this->context);
         return true;
     }
     // 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 sub question.
     $qid = optional_param('qid', 0, PARAM_INT);
     $slot = optional_param('slot', 0, PARAM_INT);
     $variantno = optional_param('variant', null, PARAM_INT);
     $whichattempts = optional_param('whichattempts', $quiz->grademethod, PARAM_INT);
     $whichtries = optional_param('whichtries', question_attempt::LAST_TRY, PARAM_ALPHA);
     $pageoptions = array();
     $pageoptions['id'] = $cm->id;
     $pageoptions['mode'] = 'statistics';
     $reporturl = new moodle_url('/mod/quiz/report.php', $pageoptions);
     $mform = new quiz_statistics_settings_form($reporturl, compact('quiz'));
     $mform->set_data(array('whichattempts' => $whichattempts, 'whichtries' => $whichtries));
     if ($whichattempts != $quiz->grademethod) {
         $reporturl->param('whichattempts', $whichattempts);
     }
     if ($whichtries != question_attempt::LAST_TRY) {
         $reporturl->param('whichtries', $whichtries);
     }
     // 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 quizzes and who are in the currently selected group.
             $groupstudents = get_users_by_capability($this->context, array('mod/quiz:reviewmyattempts', 'mod/quiz:attempt'), '', '', '', '', $currentgroup, '', false);
             if (!$groupstudents) {
                 $nostudentsingroup = true;
             }
         }
     }
     $qubaids = quiz_statistics_qubaids_condition($quiz->id, $groupstudents, $whichattempts);
     // If recalculate was requested, handle that.
     if ($recalculate && confirm_sesskey()) {
         $this->clear_cached_data($qubaids);
         redirect($reporturl);
     }
     // Set up the main table.
     $this->table = new quiz_statistics_table();
     if ($everything) {
         $report = get_string('completestatsfilename', 'quiz_statistics');
     } else {
         $report = get_string('questionstatsfilename', 'quiz_statistics');
     }
     $courseshortname = format_string($course->shortname, true, array('context' => context_course::instance($course->id)));
     $filename = quiz_report_download_filename($report, $courseshortname, $quiz->name);
     $this->table->is_downloading($download, $filename, get_string('quizstructureanalysis', 'quiz_statistics'));
     $questions = $this->load_and_initialise_questions_for_calculations($quiz);
     // Print the page header stuff (if not downloading.
     if (!$this->table->is_downloading()) {
         $this->print_header_and_tabs($cm, $course, $quiz, 'statistics');
     }
     if (!$nostudentsingroup) {
         // Get the data to be displayed.
         $progress = $this->get_progress_trace_instance();
         list($quizstats, $questionstats) = $this->get_all_stats_and_analysis($quiz, $whichattempts, $whichtries, $groupstudents, $questions, $progress);
     } else {
         // Or create empty stats containers.
         $quizstats = new \quiz_statistics\calculated($whichattempts);
         $questionstats = new \core_question\statistics\questions\all_calculated_for_qubaid_condition();
     }
     // Set up the table, if there is data.
     if ($quizstats->s()) {
         $this->table->statistics_setup($quiz, $cm->id, $reporturl, $quizstats->s());
     }
     // Print the rest of the page header stuff (if not downloading.
     if (!$this->table->is_downloading()) {
         if (groups_get_activity_groupmode($cm)) {
             groups_print_activity_menu($cm, $reporturl->out());
             if ($currentgroup && !$groupstudents) {
                 $OUTPUT->notification(get_string('nostudentsingroup', 'quiz_statistics'));
             }
         }
         if (!$this->table->is_downloading() && $quizstats->s() == 0) {
             echo $OUTPUT->notification(get_string('noattempts', 'quiz'));
         }
         foreach ($questionstats->any_error_messages() as $errormessage) {
             echo $OUTPUT->notification($errormessage);
         }
         // Print display options form.
         $mform->display();
     }
     if ($everything) {
         // Implies is downloading.
         // Overall report, then the analysis of each question.
         $quizinfo = $quizstats->get_formatted_quiz_info_data($course, $cm, $quiz);
         $this->download_quiz_info_table($quizinfo);
         if ($quizstats->s()) {
             $this->output_quiz_structure_analysis_table($questionstats);
             if ($this->table->is_downloading() == 'xhtml' && $quizstats->s() != 0) {
                 $this->output_statistics_graph($quiz->id, $currentgroup, $whichattempts);
             }
             $this->output_all_question_response_analysis($qubaids, $questions, $questionstats, $reporturl, $whichtries);
         }
         $this->table->export_class_instance()->finish_document();
     } else {
         if ($qid) {
             // Report on an individual sub-question indexed questionid.
             if (is_null($questionstats->for_subq($qid, $variantno))) {
                 print_error('questiondoesnotexist', 'question');
             }
             $this->output_individual_question_data($quiz, $questionstats->for_subq($qid, $variantno));
             $this->output_individual_question_response_analysis($questionstats->for_subq($qid, $variantno)->question, $variantno, $questionstats->for_subq($qid, $variantno)->s, $reporturl, $qubaids, $whichtries);
             // Back to overview link.
             echo $OUTPUT->box('<a href="' . $reporturl->out() . '">' . get_string('backtoquizreport', 'quiz_statistics') . '</a>', 'boxaligncenter generalbox boxwidthnormal mdl-align');
         } else {
             if ($slot) {
                 // Report on an individual question indexed by position.
                 if (!isset($questions[$slot])) {
                     print_error('questiondoesnotexist', 'question');
                 }
                 if ($variantno === null && ($questionstats->for_slot($slot)->get_sub_question_ids() || $questionstats->for_slot($slot)->get_variants())) {
                     if (!$this->table->is_downloading()) {
                         $number = $questionstats->for_slot($slot)->question->number;
                         echo $OUTPUT->heading(get_string('slotstructureanalysis', 'quiz_statistics', $number), 3);
                     }
                     $this->table->define_baseurl(new moodle_url($reporturl, array('slot' => $slot)));
                     $this->table->format_and_add_array_of_rows($questionstats->structure_analysis_for_one_slot($slot));
                 } else {
                     $this->output_individual_question_data($quiz, $questionstats->for_slot($slot, $variantno));
                     $this->output_individual_question_response_analysis($questions[$slot], $variantno, $questionstats->for_slot($slot, $variantno)->s, $reporturl, $qubaids, $whichtries);
                 }
                 if (!$this->table->is_downloading()) {
                     // Back to overview link.
                     echo $OUTPUT->box('<a href="' . $reporturl->out() . '">' . get_string('backtoquizreport', 'quiz_statistics') . '</a>', 'backtomainstats boxaligncenter generalbox boxwidthnormal mdl-align');
                 } else {
                     $this->table->finish_output();
                 }
             } else {
                 if ($this->table->is_downloading()) {
                     // Downloading overview report.
                     $quizinfo = $quizstats->get_formatted_quiz_info_data($course, $cm, $quiz);
                     $this->download_quiz_info_table($quizinfo);
                     if ($quizstats->s()) {
                         $this->output_quiz_structure_analysis_table($questionstats);
                     }
                     $this->table->finish_output();
                 } else {
                     // On-screen display of overview report.
                     echo $OUTPUT->heading(get_string('quizinformation', 'quiz_statistics'), 3);
                     echo $this->output_caching_info($quizstats->timemodified, $quiz->id, $groupstudents, $whichattempts, $reporturl);
                     echo $this->everything_download_options();
                     $quizinfo = $quizstats->get_formatted_quiz_info_data($course, $cm, $quiz);
                     echo $this->output_quiz_info_table($quizinfo);
                     if ($quizstats->s()) {
                         echo $OUTPUT->heading(get_string('quizstructureanalysis', 'quiz_statistics'), 3);
                         $this->output_quiz_structure_analysis_table($questionstats);
                         $this->output_statistics_graph($quiz->id, $currentgroup, $whichattempts);
                     }
                 }
             }
         }
     }
     return true;
 }
 /**
  * Displays the papercopy report for a given quiz.
  *
  * @param stdClass     $quiz       An associative array of quiz data, for which this report should be rendered.
  * @param stdClass     $cm         A data set representing the given course-module.
  * @param stdClass     $course     A data set representing the given course.
  */
 public function display($quiz, $cm, $course)
 {
     //access the global configuration, database, and page renderer
     global $CFG, $DB, $PAGE;
     //store local copies of the quiz, course, module and context
     $this->quiz = $quiz;
     $this->cm = $cm;
     $this->course = $course;
     $this->context = context_module::instance($cm->id);
     //get a reference to the current quiz
     $this->quizobj = $this->get_quiz_object();
     //and load the questions into memory
     $this->quizobj->preload_questions();
     $this->quizobj->load_questions();
     //get the current action, if one has been specified
     $action = optional_param('action', false, PARAM_ALPHA);
     //start output
     $this->print_header_and_tabs($cm, $course, $quiz, 'grading');
     //--- display the report:
     //if there are no questions in the quiz, display an error message
     if (!$this->quizobj->get_questions()) {
         echo quiz_no_questions_message($quiz, $cm, $this->context);
         //otherwise, if we have no action, display the index page
     } else {
         if (!$action) {
             $this->maintain_batches();
             $this->display_index();
         } else {
             switch ($action) {
                 //create new copies based on the upload data
                 case 'create':
                     //ensure we have a valid session; i.e. prevent CSRF
                     confirm_sesskey();
                     //and handle the create action
                     $this->handle_action_create();
                     break;
                     //upload a file, and determine how to use it to get response content
                 //upload a file, and determine how to use it to get response content
                 case 'upload':
                     //ensure we have a valid session; i.e. prevent CSRF
                     confirm_sesskey();
                     //and handle the upload
                     $this->handle_action_upload();
                     break;
                 case 'associate':
                     //ensure we have a valid sesseion
                     confirm_sesskey();
                     //handle associations
                     $this->handle_action_associate();
                     //roll through to view/edit
                 //roll through to view/edit
                 case 'viewedit':
                     $this->maintain_batches();
                     $this->handle_action_view_edit();
                     break;
                 case 'deletebatches':
                     //ensure we have a valid session
                     confirm_sesskey();
                     $this->handle_action_delete_batches();
                     $this->maintain_batches();
                     //roll into the index display
                 //roll into the index display
                 default:
                     $this->display_index();
             }
         }
     }
     return true;
 }
Example #9
0
    public function display($quiz, $cm, $course) {
        global $CFG, $DB, $PAGE;

        $this->quiz = $quiz;
        $this->cm = $cm;
        $this->course = $course;

        // Get the URL options.
        $slot = optional_param('slot', null, PARAM_INT);
        $questionid = optional_param('qid', null, PARAM_INT);
        $grade = optional_param('grade', null, PARAM_ALPHA);

        $includeauto = optional_param('includeauto', false, PARAM_BOOL);
        if (!in_array($grade, array('all', 'needsgrading', 'autograded', 'manuallygraded'))) {
            $grade = null;
        }
        $pagesize = optional_param('pagesize', self::DEFAULT_PAGE_SIZE, PARAM_INT);
        $page = optional_param('page', 0, PARAM_INT);
        $order = optional_param('order', self::DEFAULT_ORDER, PARAM_ALPHA);

        // Assemble the options requried to reload this page.
        $optparams = array('includeauto', 'page');
        foreach ($optparams as $param) {
            if ($$param) {
                $this->viewoptions[$param] = $$param;
            }
        }
        if ($pagesize != self::DEFAULT_PAGE_SIZE) {
            $this->viewoptions['pagesize'] = $pagesize;
        }
        if ($order != self::DEFAULT_ORDER) {
            $this->viewoptions['order'] = $order;
        }

        // Check permissions
        $this->context = get_context_instance(CONTEXT_MODULE, $cm->id);
        require_capability('mod/quiz:grade', $this->context);
        $shownames = has_capability('quiz/grading:viewstudentnames', $this->context);
        $showidnumbers = has_capability('quiz/grading:viewidnumber', $this->context);

        // Validate order.
        if (!in_array($order, array('random', 'date', 'student', 'idnumber'))) {
            $order = self::DEFAULT_ORDER;
        } else if (!$shownames && $order == 'student') {
            $order = self::DEFAULT_ORDER;
        } else if (!$showidnumbers && $order == 'idnumber') {
            $order = self::DEFAULT_ORDER;
        }
        if ($order == 'random') {
            $page = 0;
        }

        // Get the list of questions in this quiz.
        $this->questions = quiz_report_get_significant_questions($quiz);
        if ($slot && !array_key_exists($slot, $this->questions)) {
            throw new moodle_exception('unknownquestion', 'quiz_grading');
        }

        // Process any submitted data.
        if ($data = data_submitted() && confirm_sesskey() && $this->validate_submitted_marks()) {
            $this->process_submitted_data();

            redirect($this->grade_question_url($slot, $questionid, $grade, $page + 1));
        }

        // Get the group, and the list of significant users.
        $this->currentgroup = groups_get_activity_group($this->cm, true);
        $this->users = get_users_by_capability($this->context,
                array('mod/quiz:reviewmyattempts', 'mod/quiz:attempt'), '', '', '', '',
                $this->currentgroup, '', false);

        // Start output.
        $this->print_header_and_tabs($cm, $course, $quiz, 'grading');

        // What sort of page to display?
        if (!quiz_questions_in_quiz($quiz->questions)) {
            echo quiz_no_questions_message($quiz, $cm, $this->context);

        } else if (!$slot) {
            $this->display_index($includeauto);

        } else {
            $this->display_grading_interface($slot, $questionid, $grade,
                    $pagesize, $page, $shownames, $showidnumbers, $order);
        }
        return true;
    }
Example #10
0
    /**
     * Generates the view attempt button
     *
     * @param int $course The course ID
     * @param array $quiz Array containging quiz date
     * @param int $cm The Course Module ID
     * @param int $context The page Context ID
     * @param mod_quiz_view_object $viewobj
     * @param string $buttontext
     */
    public function view_attempt_button($course, $quiz, $cm, $context, $viewobj,
            $buttontext, $preventmessages) {
        $output = '';
        // Determine if we should be showing a start/continue attempt button,
        // or a button to go back to the course page.
        $output .= $this->box_start('quizattempt');

        // Now actually print the appropriate button.
        if (!quiz_clean_layout($quiz->questions, true)) {
            $output .= quiz_no_questions_message($quiz, $cm, $context);
        }

        if ($preventmessages) {
            $output .= $this->access_messages($preventmessages);
        }

        if ($buttontext) {
            $output .= $viewobj->accessmanager->print_start_attempt_button($viewobj->canpreview,
                    $buttontext, $viewobj->unfinished);
        } else if ($buttontext === '') {
            $output .= $this->single_button(new moodle_url('/course/view.php',
                    array('id' => $course->id)), get_string('backtocourse', 'quiz'), 'get',
                    array('class' => 'continuebutton'));
        }
        $output .= $this->box_end();

        return $output;
    }
 public function display($quiz, $cm, $course)
 {
     global $CFG, $PAGE, $OUTPUT;
     $PAGE->set_pagelayout('print');
     $PAGE->requires->js('/mod/quiz/report/categorygrades/categorygrades.js');
     $this->quiz = $quiz;
     $this->cm = $cm;
     $this->course = $course;
     // Get the URL options.
     $group = optional_param('group', null, PARAM_INT);
     $pagesize = optional_param('pagesize', self::DEFAULT_PAGE_SIZE, PARAM_INT);
     $page = optional_param('page', 0, PARAM_INT);
     $order = optional_param('order', self::DEFAULT_ORDER, PARAM_ALPHA);
     $qubaid = optional_param('qubaid', null, PARAM_INT);
     // Assemble the options required to reload this page.
     $optparams = array('page');
     foreach ($optparams as $param) {
         if (${$param}) {
             $this->viewoptions[$param] = ${$param};
         }
     }
     if ($pagesize != self::DEFAULT_PAGE_SIZE) {
         $this->viewoptions['pagesize'] = $pagesize;
     }
     if ($order != self::DEFAULT_ORDER) {
         $this->viewoptions['order'] = $order;
     }
     // Check permissions.
     $this->context = context_module::instance($cm->id);
     require_capability('mod/quiz:grade', $this->context);
     $shownames = has_capability('quiz/grading:viewstudentnames', $this->context);
     $showidnumbers = has_capability('quiz/grading:viewidnumber', $this->context);
     // Validate order.
     if (!in_array($order, array('random', 'date', 'firstname', 'lastname', 'idnumber'))) {
         $order = self::DEFAULT_ORDER;
     } else {
         if (!$shownames && ($order == 'firstname' || $order == 'lastname')) {
             $order = self::DEFAULT_ORDER;
         } else {
             if (!$showidnumbers && $order == 'idnumber') {
                 $order = self::DEFAULT_ORDER;
             }
         }
     }
     if ($order == 'random') {
         $page = 0;
     }
     // Get the group, and the list of significant users.
     $this->currentgroup = $this->get_current_group($cm, $course, $this->context);
     if ($this->currentgroup == self::NO_GROUPS_ALLOWED) {
         $this->users = array();
     } else {
         $this->users = get_users_by_capability($this->context, array('mod/quiz:reviewmyattempts', 'mod/quiz:attempt'), '', '', '', '', $this->currentgroup, '', false);
     }
     $hasquestions = quiz_has_questions($quiz->id);
     // Start output.
     $this->print_header_and_tabs($cm, $course, $quiz, 'categorygrades');
     echo $OUTPUT->heading(get_string('categorygrades', 'quiz_categorygrades'), 2, 'cg_heading');
     echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css\">\n";
     // What sort of page to display?
     if (!$hasquestions) {
         echo quiz_no_questions_message($quiz, $cm, $this->context);
     } else {
         if (!isset($group)) {
             $group = $this->currentgroup;
         }
     }
     if ($groupmode = groups_get_activity_groupmode($this->cm)) {
         // Groups is being used.
         groups_print_activity_menu($this->cm, $PAGE->url, false, true);
     }
     $this->display_attempts($pagesize, $page, $shownames, $showidnumbers, $order, $group, $qubaid);
     return true;
 }