public function test_quiz_format_grade()
 {
     $quiz = new stdClass();
     $quiz->decimalpoints = 2;
     $this->assertEquals(quiz_format_grade($quiz, 0.12345678), format_float(0.12, 2));
     $this->assertEquals(quiz_format_grade($quiz, 0), format_float(0, 2));
     $this->assertEquals(quiz_format_grade($quiz, 1.0), format_float(1, 2));
     $quiz->decimalpoints = 0;
     $this->assertEquals(quiz_format_grade($quiz, 0.12345678), '0');
 }
Example #2
0
    function build_table(){
        global $CFG, $DB;
        if ($this->rawdata) {
            // Define some things we need later to process raw data from db.
            $this->strtimeformat = str_replace(',', '', get_string('strftimedatetime'));
            parent::build_table();
            //end of adding data from attempts data to table / download
            //now add averages at bottom of table :
            $params = array($this->quiz->id);
            $averagesql = "SELECT AVG(qg.grade) AS grade " .
                    "FROM {quiz_grades} qg " .
                    "WHERE quiz=?";

            $this->add_separator();
            if ($this->is_downloading()){
                $namekey = 'lastname';
            } else {
                $namekey = 'fullname';
            }
            if ($this->groupstudents){
                list($g_usql, $g_params) = $DB->get_in_or_equal($this->groupstudents);

                $groupaveragesql = $averagesql." AND qg.userid $g_usql";
                $groupaverage = $DB->get_record_sql($groupaveragesql, array_merge($params, $g_params));
                $groupaveragerow = array($namekey => get_string('groupavg', 'grades'),
                        'sumgrades' => quiz_format_grade($this->quiz, $groupaverage->grade),
                        'feedbacktext'=> strip_tags(quiz_report_feedback_for_grade($groupaverage->grade, $this->quiz->id, $this->context)));
                if($this->detailedmarks && ($this->qmsubselect || $this->quiz->attempts == 1)) {
                    $avggradebyq = quiz_get_average_grade_for_questions($this->quiz, $this->groupstudents);
                    $groupaveragerow += quiz_format_average_grade_for_questions($avggradebyq, $this->questions, $this->quiz, $this->is_downloading());
                }
                $this->add_data_keyed($groupaveragerow);
            }

            if ($this->students) {
                list($s_usql, $s_params) = $DB->get_in_or_equal($this->students);
                $overallaverage = $DB->get_record_sql($averagesql." AND qg.userid $s_usql", array_merge($params, $s_params));
                $overallaveragerow = array($namekey => get_string('overallaverage', 'grades'),
                            'sumgrades' => quiz_format_grade($this->quiz, $overallaverage->grade),
                            'feedbacktext'=> strip_tags(quiz_report_feedback_for_grade($overallaverage->grade, $this->quiz->id, $this->context)));
                if($this->detailedmarks && ($this->qmsubselect || $this->quiz->attempts == 1)) {
                    $avggradebyq = quiz_get_average_grade_for_questions($this->quiz, $this->students);
                    $overallaveragerow += quiz_format_average_grade_for_questions($avggradebyq, $this->questions, $this->quiz, $this->is_downloading());
                }
                $this->add_data_keyed($overallaveragerow);
            }
        }
    }
Example #3
0
/**
 * Convert the raw grade stored in $attempt into a grade out of the maximum
 * grade for this quiz.
 *
 * @param float $rawgrade the unadjusted grade, fof example $attempt->sumgrades
 * @param object $quiz the quiz object. Only the fields grade, sumgrades and decimalpoints are used.
 * @param bool|string $format whether to format the results for display
 *      or 'question' to format a question grade (different number of decimal places.
 * @return float|string the rescaled grade, or null/the lang string 'notyetgraded'
 *      if the $grade is null.
 */
function quiz_rescale_grade($rawgrade, $quiz, $format = true) {
    if (is_null($rawgrade)) {
        $grade = null;
    } else if ($quiz->sumgrades >= 0.000005) {
        $grade = $rawgrade * $quiz->grade / $quiz->sumgrades;
    } else {
        $grade = 0;
    }
    if ($format === 'question') {
        $grade = quiz_format_question_grade($quiz, $grade);
    } else if ($format) {
        $grade = quiz_format_grade($quiz, $grade);
    }
    return $grade;
}
 /**
  * Add all the grade and feedback columns, if applicable, to the $columns
  * and $headers arrays.
  * @param object $quiz the quiz settings.
  * @param array $columns the list of columns. Added to.
  * @param array $headers the columns headings. Added to.
  */
 protected function add_grade_columns($quiz, &$columns, &$headers)
 {
     if ($this->should_show_grades($quiz)) {
         $columns[] = 'sumgrades';
         $headers[] = get_string('grade', 'quiz') . '/' . quiz_format_grade($quiz, $quiz->grade);
     }
     if (quiz_has_feedback($quiz)) {
         $columns[] = 'feedbacktext';
         $headers[] = get_string('feedback', 'quiz');
     }
 }
Example #5
0
                        foreach ($slots as $slot) {
                            $json[$slot->slot] = array('id' => $slot->id, 'slot' => $slot->slot, 'page' => $slot->page);
                        }
                        echo json_encode(array('slots' => $json));
                        break;
                    case 'updatedependency':
                        require_capability('mod/quiz:manage', $modcontext);
                        $slot = $structure->get_slot_by_id($id);
                        $value = (bool) $value;
                        $structure->update_question_dependency($slot->id, $value);
                        echo json_encode(array('requireprevious' => $value));
                        break;
                }
                break;
        }
        break;
    case 'DELETE':
        switch ($class) {
            case 'resource':
                require_capability('mod/quiz:manage', $modcontext);
                if (!($slot = $DB->get_record('quiz_slots', array('quizid' => $quiz->id, 'id' => $id)))) {
                    throw new moodle_exception('AJAX commands.php: Bad slot ID ' . $id);
                }
                $structure->remove_slot($quiz, $slot->slot);
                quiz_delete_previews($quiz);
                quiz_update_sumgrades($quiz);
                echo json_encode(array('newsummarks' => quiz_format_grade($quiz, $quiz->sumgrades), 'deleted' => true, 'newnumquestions' => $structure->get_question_count()));
                break;
        }
        break;
}
Example #6
0
        $bands = $bands * 5;
    } else {
        if ($bands <= 10) {
            $bands = $bands * 2;
        }
    }
}
$bandwidth = $quiz->grade / $bands;
$bands = ceil($bands);
$bandlabels = array();
for ($i = 0; $i < $quiz->grade; $i += $bandwidth) {
    $label = quiz_format_grade($quiz, $i) . ' - ';
    if ($quiz->grade > $i + $bandwidth) {
        $label .= quiz_format_grade($quiz, $i + $bandwidth);
    } else {
        $label .= quiz_format_grade($quiz, $quiz->grade);
    }
    $bandlabels[] = $label;
}
$line->x_data = $bandlabels;
$line->y_format['allusers'] = array('colour' => 'red', 'bar' => 'fill', 'shadow_offset' => 1, 'legend' => get_string('allparticipants'));
$line->y_data['allusers'] = quiz_report_grade_bands($bandwidth, $bands, $quizid, $groupusers);
$line->y_order = array('allusers');
$line->parameter['y_min_left'] = 0;
// start at 0
$line->parameter['y_max_left'] = max($line->y_data['allusers']);
$line->parameter['y_decimal_left'] = 0;
// 2 decimal places for y axis.
//pick a sensible number of gridlines depending on max value on graph.
$gridlines = max($line->y_data['allusers']);
while ($gridlines >= 10) {
Example #7
0
 /**
  * Display the report.
  */
 function display($quiz, $cm, $course)
 {
     global $CFG, $COURSE, $DB, $PAGE, $OUTPUT;
     $context = get_context_instance(CONTEXT_MODULE, $cm->id);
     // Work out some display options - whether there is feedback, and whether scores should be shown.
     $hasfeedback = quiz_has_feedback($quiz);
     $fakeattempt = new stdClass();
     $fakeattempt->preview = false;
     $fakeattempt->timefinish = $quiz->timeopen;
     $fakeattempt->userid = 0;
     $reviewoptions = quiz_get_reviewoptions($quiz, $fakeattempt, $context);
     $showgrades = quiz_has_grades($quiz) && $reviewoptions->scores;
     $download = optional_param('download', '', PARAM_ALPHA);
     if ($attemptids = optional_param('attemptid', array(), PARAM_INT)) {
         //attempts need to be deleted
         require_capability('mod/quiz:deleteattempts', $context);
         $attemptids = optional_param('attemptid', array(), PARAM_INT);
         foreach ($attemptids as $attemptid) {
             add_to_log($course->id, 'quiz', 'delete attempt', 'report.php?id=' . $cm->id, $attemptid, $cm->id);
             quiz_delete_attempt($attemptid, $quiz);
         }
         //No need for a redirect, any attemptids that do not exist are ignored.
         //So no problem if the user refreshes and tries to delete the same attempts
         //twice.
     }
     $pageoptions = array();
     $pageoptions['id'] = $cm->id;
     $pageoptions['q'] = $quiz->id;
     $pageoptions['mode'] = 'responses';
     $reporturl = new moodle_url($CFG->wwwroot . '/mod/quiz/report.php', $pageoptions);
     $qmsubselect = quiz_report_qm_filter_select($quiz);
     /// find out current groups mode
     $currentgroup = groups_get_activity_group($cm, true);
     $mform = new mod_quiz_report_responses_settings($reporturl, array('qmsubselect' => $qmsubselect, 'quiz' => $quiz, 'currentgroup' => $currentgroup));
     if ($fromform = $mform->get_data()) {
         $attemptsmode = $fromform->attemptsmode;
         if ($qmsubselect) {
             //control is not on the form if
             //the grading method is not set
             //to grade one attempt per user eg. for average attempt grade.
             $qmfilter = $fromform->qmfilter;
         } else {
             $qmfilter = 0;
         }
         set_user_preference('quiz_report_pagesize', $fromform->pagesize);
         $pagesize = $fromform->pagesize;
     } else {
         $qmfilter = optional_param('qmfilter', 0, PARAM_INT);
         $attemptsmode = optional_param('attemptsmode', null, PARAM_INT);
         if ($attemptsmode === null) {
             //default
             $attemptsmode = QUIZ_REPORT_ATTEMPTS_ALL;
         } else {
             if ($currentgroup) {
                 //default for when a group is selected
                 if ($attemptsmode === null || $attemptsmode == QUIZ_REPORT_ATTEMPTS_ALL) {
                     $attemptsmode = QUIZ_REPORT_ATTEMPTS_STUDENTS_WITH;
                 }
             } else {
                 if (!$currentgroup && $course->id == SITEID) {
                     //force report on front page to show all, unless a group is selected.
                     $attemptsmode = QUIZ_REPORT_ATTEMPTS_ALL;
                 }
             }
         }
         $pagesize = get_user_preferences('quiz_report_pagesize', 0);
     }
     if ($pagesize < 1) {
         $pagesize = QUIZ_REPORT_DEFAULT_PAGE_SIZE;
     }
     // 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', $context) && $attemptsmode != QUIZ_REPORT_ATTEMPTS_STUDENTS_WITH_NO;
     $displayoptions = array();
     $displayoptions['attemptsmode'] = $attemptsmode;
     $displayoptions['qmfilter'] = $qmfilter;
     //work out the sql for this table.
     if (!($students = get_users_by_capability($context, array('mod/quiz:reviewmyattempts', 'mod/quiz:attempt'), '', '', '', '', '', '', false))) {
         $students = array();
     } else {
         $students = array_keys($students);
     }
     if (empty($currentgroup)) {
         // all users who can attempt quizzes
         $allowed = $students;
         $groupstudents = array();
     } else {
         // all users who can attempt quizzes and who are in the currently selected group
         if (!($groupstudents = get_users_by_capability($context, array('mod/quiz:reviewmyattempts', 'mod/quiz:attempt'), '', '', '', '', $currentgroup, '', false))) {
             $groupstudents = array();
         } else {
             $groupstudents = array_keys($groupstudents);
         }
         $allowed = $groupstudents;
     }
     $questions = quiz_report_load_questions($quiz);
     $table = new quiz_report_responses_table($quiz, $qmsubselect, $groupstudents, $students, $questions, $candelete, $reporturl, $displayoptions);
     $table->is_downloading($download, get_string('reportresponses', 'quiz_responses'), "{$COURSE->shortname} " . format_string($quiz->name, true));
     if (!$table->is_downloading()) {
         // Only print headers if not asked to download data
         $PAGE->requires->css('mod/quiz/report/responses/styles.css');
         $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(false, $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>';
         }
     }
     $nostudents = false;
     if (!$students) {
         echo $OUTPUT->notification(get_string('nostudentsyet'));
         $nostudents = true;
     } else {
         if ($currentgroup && !$groupstudents) {
             echo $OUTPUT->notification(get_string('nostudentsingroup'));
             $nostudents = true;
         }
     }
     if (!$table->is_downloading()) {
         // Print display options
         $mform->set_data($displayoptions + compact('pagesize'));
         $mform->display();
     }
     if (!$nostudents || $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>';
             }
         }
         $showgrades = quiz_has_grades($quiz) && $reviewoptions->scores;
         $hasfeedback = quiz_has_feedback($quiz);
         // Construct the SQL
         $fields = $DB->sql_concat('u.id', '\'#\'', 'COALESCE(qa.attempt, \'0\')') . ' AS concattedid, ';
         if ($qmsubselect) {
             $fields .= "(CASE " . "   WHEN {$qmsubselect} THEN 1" . "   ELSE 0 " . "END) AS gradedattempt, ";
         }
         $fields .= 'qa.uniqueid, qa.id AS attempt, u.id AS userid, u.idnumber, u.firstname,' . ' u.lastname, u.institution, u.department, u.email, u.picture, u.imagealt, ' . 'qa.sumgrades, qa.timefinish, qa.timestart, qa.timefinish - qa.timestart AS duration, ' . 'qa.layout ';
         // This part is the same for all cases - join users and quiz_attempts tables
         $from = '{user} u ';
         $from .= 'LEFT JOIN {quiz_attempts} qa ON qa.userid = u.id AND qa.quiz = :quizid';
         $params = array('quizid' => $quiz->id);
         if ($qmsubselect && $qmfilter) {
             $from .= ' AND ' . $qmsubselect;
         }
         switch ($attemptsmode) {
             case QUIZ_REPORT_ATTEMPTS_ALL:
                 // Show all attempts, including students who are no longer in the course
                 $where = 'qa.id IS NOT NULL AND qa.preview = 0';
                 break;
             case QUIZ_REPORT_ATTEMPTS_STUDENTS_WITH:
                 // Show only students with attempts
                 list($allowed_usql, $allowed_params) = $DB->get_in_or_equal($allowed, SQL_PARAMS_NAMED, 'u0000');
                 $params += $allowed_params;
                 $where = "u.id {$allowed_usql} AND qa.preview = 0 AND qa.id IS NOT NULL";
                 break;
             case QUIZ_REPORT_ATTEMPTS_STUDENTS_WITH_NO:
                 // Show only students without attempts
                 list($allowed_usql, $allowed_params) = $DB->get_in_or_equal($allowed, SQL_PARAMS_NAMED, 'u0000');
                 $params += $allowed_params;
                 $where = "u.id {$allowed_usql} AND qa.id IS NULL";
                 break;
             case QUIZ_REPORT_ATTEMPTS_ALL_STUDENTS:
                 // Show all students with or without attempts
                 list($allowed_usql, $allowed_params) = $DB->get_in_or_equal($allowed, SQL_PARAMS_NAMED, 'u0000');
                 $params += $allowed_params;
                 $where = "u.id {$allowed_usql} AND (qa.preview = 0 OR qa.preview IS NULL)";
                 break;
         }
         $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;
         }
         if (!$table->is_downloading() && $CFG->grade_report_showuserimage) {
             $columns[] = 'picture';
             $headers[] = '';
         }
         if (!$table->is_downloading()) {
             $columns[] = 'fullname';
             $headers[] = get_string('name');
         } else {
             $columns[] = 'lastname';
             $headers[] = get_string('lastname');
             $columns[] = 'firstname';
             $headers[] = get_string('firstname');
         }
         if ($CFG->grade_report_showuseridnumber) {
             $columns[] = 'idnumber';
             $headers[] = get_string('idnumber');
         }
         if ($table->is_downloading()) {
             $columns[] = 'institution';
             $headers[] = get_string('institution');
             $columns[] = 'department';
             $headers[] = get_string('department');
             $columns[] = 'email';
             $headers[] = get_string('email');
             $columns[] = 'timestart';
             $headers[] = get_string('startedon', 'quiz');
             $columns[] = 'timefinish';
             $headers[] = get_string('timecompleted', 'quiz');
             $columns[] = 'duration';
             $headers[] = get_string('attemptduration', 'quiz');
         }
         if ($showgrades) {
             $columns[] = 'sumgrades';
             $headers[] = get_string('grade', 'quiz') . '/' . quiz_format_grade($quiz, $quiz->grade);
         }
         if ($hasfeedback) {
             $columns[] = 'feedbacktext';
             $headers[] = get_string('feedback', 'quiz');
         }
         // we want to display responses for all questions
         foreach ($questions as $id => $question) {
             // Ignore questions of zero length
             $columns[] = 'qsanswer' . $id;
             $headers[] = '#' . $question->number;
             $question->formattedname = strip_tags(format_string($question->name));
         }
         // Load the question type specific information
         if (!get_question_options($questions)) {
             print_error('cannotloadoptions', 'quiz_responses');
         }
         $table->define_columns($columns);
         $table->define_headers($headers);
         $table->sortable(true, 'concattedid');
         // Set up the table
         $table->define_baseurl($reporturl->out(false, $displayoptions));
         $table->collapsible(true);
         $table->column_suppress('picture');
         $table->column_suppress('fullname');
         $table->column_suppress('idnumber');
         $table->no_sorting('feedbacktext');
         $table->column_class('picture', 'picture');
         $table->column_class('lastname', 'bold');
         $table->column_class('firstname', 'bold');
         $table->column_class('fullname', 'bold');
         $table->column_class('sumgrades', 'bold');
         $table->set_attribute('id', 'attempts');
         $table->out($pagesize, true);
     }
     return true;
 }
Example #8
0
 /**
  * Get the overall quiz grade formatted for display.
  * @return string the maximum grade for this quiz.
  */
 public function formatted_quiz_grade()
 {
     return quiz_format_grade($this->get_quiz(), $this->get_quiz()->grade);
 }
 public function grade_by_category($uniqueattemptid, $catid)
 {
     $qcount = 0;
     $totalpossiblemark = 0;
     $totalactualmark = 0;
     foreach ($this->lateststeps[$uniqueattemptid] as $lateststep) {
         if (isset($this->qidtocatidhash[$lateststep->questionid])) {
             if ($this->qidtocatidhash[$lateststep->questionid] == $catid) {
                 $totalpossiblemark += $lateststep->maxmark;
                 $totalactualmark += $lateststep->fraction * $lateststep->maxmark;
                 $qcount++;
             }
         }
     }
     if ($totalpossiblemark > 0) {
         $grade = quiz_format_grade($this->quiz, $totalactualmark / $totalpossiblemark * 100);
     } else {
         $grade = '--';
     }
     return "{$grade} ({$qcount})";
 }
            $bands /= 2;
        }
    }
    if ($bands < 4) {
        $bands *= 5;
    } else {
        if ($bands <= 10) {
            $bands *= 2;
        }
    }
}
$bands = ceil($bands);
$bandwidth = $quiz->grade / $bands;
$bandlabels = array();
for ($i = 1; $i <= $bands; $i++) {
    $bandlabels[] = quiz_format_grade($quiz, ($i - 1) * $bandwidth) . ' - ' . quiz_format_grade($quiz, $i * $bandwidth);
}
$line->x_data = $bandlabels;
$line->y_format['allusers'] = array('colour' => 'red', 'bar' => 'fill', 'shadow_offset' => 1, 'legend' => get_string('allparticipants'));
$line->y_data['allusers'] = quiz_report_grade_bands($bandwidth, $bands, $quizid, $groupusers);
$line->y_order = array('allusers');
$ymax = max($line->y_data['allusers']);
$line->parameter['y_min_left'] = 0;
// start at 0
$line->parameter['y_max_left'] = $ymax;
$line->parameter['y_decimal_left'] = 0;
// 2 decimal places for y axis.
//pick a sensible number of gridlines depending on max value on graph.
$gridlines = $ymax;
while ($gridlines >= 10) {
    if ($gridlines >= 50) {
Example #11
0
    /**
     * Display the report.
     */
    function display($quiz, $cm, $course) {
        global $CFG, $COURSE, $DB, $OUTPUT;

        $this->context = get_context_instance(CONTEXT_MODULE, $cm->id);

        // Work out some display options - whether there is feedback, and whether scores should be shown.
        $hasfeedback = quiz_has_feedback($quiz);
        $fakeattempt = new stdClass();
        $fakeattempt->preview = false;
        $fakeattempt->timefinish = $quiz->timeopen;
        $fakeattempt->userid = 0;
        $reviewoptions = quiz_get_reviewoptions($quiz, $fakeattempt, $this->context);
        $showgrades = quiz_has_grades($quiz) && $reviewoptions->scores;

        $download = optional_param('download', '', PARAM_ALPHA);

        /// find out current groups mode
        $currentgroup = groups_get_activity_group($cm, true);
        if (!$students = get_users_by_capability($this->context, array('mod/quiz:reviewmyattempts', 'mod/quiz:attempt'),'u.id,1','','','','','',false)) {
            $students = array();
        } else {
            $students = array_keys($students);
        }

        if (empty($currentgroup)) {
            // all users who can attempt quizzes
            $allowed = $students;
            $groupstudents = array();
        } else {
            // all users who can attempt quizzes and who are in the currently selected group
            if (!$groupstudents = get_users_by_capability($this->context, array('mod/quiz:reviewmyattempts', 'mod/quiz:attempt'),'u.id,1','','','',$currentgroup,'',false)) {
                $groupstudents = array();
            } else {
                $groupstudents = array_keys($groupstudents);
            }
            $allowed = $groupstudents;
        }

        $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) {
                //control is not on the form if
                //the grading method is not set
                //to grade one attempt per user eg. for average attempt grade.
                $qmfilter = $fromform->qmfilter;
            } else {
                $qmfilter = 0;
            }
            $regradefilter = $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);
        }
        if ($currentgroup) {
            //default for when a group is selected
            if ($attemptsmode === null  || $attemptsmode == QUIZ_REPORT_ATTEMPTS_ALL) {
                $attemptsmode = QUIZ_REPORT_ATTEMPTS_STUDENTS_WITH;
            }
        } else if (!$currentgroup && $course->id == SITEID) {
            //force report on front page to show all, unless a group is selected.
            $attemptsmode = QUIZ_REPORT_ATTEMPTS_ALL;
        } else if ($attemptsmode === null) {
            //default
            $attemptsmode = QUIZ_REPORT_ATTEMPTS_ALL;
        }
        if (!$reviewoptions->scores) {
            $detailedmarks = 0;
        }
        if ($pagesize < 1) {
            $pagesize = QUIZ_REPORT_DEFAULT_PAGE_SIZE;
        }
        // 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['regradefilter'] = $regradefilter;

        if ($attemptsmode == QUIZ_REPORT_ATTEMPTS_ALL) {
            $allowed = array();
        }

        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, $groupstudents);
                    redirect($reporturl->out(false, $displayoptions));
                }
            } else if (optional_param('regrade', 0, PARAM_BOOL) && confirm_sesskey()) {
                if ($attemptids = optional_param('attemptid', array(), PARAM_INT)) {
                    $this->regrade_selected_attempts($quiz, $attemptids, $groupstudents);
                    redirect($reporturl->out(false, $displayoptions));
                }
            }
        }

        //work out the sql for this table.
        if ($detailedmarks) {
            $questions = quiz_report_load_questions($quiz);
        } else {
            $questions = array();
        }
        $table = new quiz_report_overview_table($quiz , $qmsubselect, $groupstudents,
                $students, $detailedmarks, $questions, $candelete, $reporturl,
                $displayoptions, $this->context);
        $table->is_downloading($download, get_string('reportoverview','quiz'),
                    "$COURSE->shortname ".format_string($quiz->name,true));
        if (!$table->is_downloading()) {
            // Only print headers if not asked to download data
            $this->print_header_and_tabs($cm, $course, $quiz, "overview");
        }

        if ($regradeall && confirm_sesskey()) {
            $this->regrade_all(false, $quiz, $groupstudents);
        } else if ($regradealldry && confirm_sesskey()) {
            $this->regrade_all(true, $quiz, $groupstudents);
        } else if ($regradealldrydo && confirm_sesskey()) {
            $this->regrade_all_needed($quiz, $groupstudents);
        }
        if ($regradeall || $regradealldry || $regradealldrydo) {
            redirect($reporturl->out(false, $displayoptions), '', 5);
        }

        if ($groupmode = groups_get_activity_groupmode($cm)) {   // Groups are being used
            if (!$table->is_downloading()) {
                groups_print_activity_menu($cm, $reporturl->out(true, $displayoptions));
            }
        }

        $nostudents = false;
        if (!$students) {
            if (!$table->is_downloading()) {
                echo $OUTPUT->notification(get_string('nostudentsyet'));
            }
            $nostudents = true;
        } else if ($currentgroup && !$groupstudents) {
            if (!$table->is_downloading()) {
                echo $OUTPUT->notification(get_string('nostudentsingroup'));
            }
            $nostudents = true;
        }
        if (!$table->is_downloading()) {
            // Print display options
            $mform->set_data($displayoptions +compact('detailedmarks', 'pagesize'));
            $mform->display();

            // Print information on the number of existing attempts
            if ($strattemptnum = quiz_num_attempt_summary($quiz, $cm, true, $currentgroup)) {
                echo '<div class="quizattemptcounts">' . $strattemptnum . '</div>';
            }
        }

        if (!$nostudents || ($attemptsmode == QUIZ_REPORT_ATTEMPTS_ALL)) {

            // Construct the SQL
            $fields = $DB->sql_concat('u.id', "'#'", 'COALESCE(qa.attempt, 0)') . ' AS uniqueid,';
            if ($qmsubselect) {
                $fields .= "\n(CASE WHEN $qmsubselect THEN 1 ELSE 0 END) AS gradedattempt,";
            }

            $fields .= '
                    qa.uniqueid AS attemptuniqueid,
                    qa.id AS attempt,
                    u.id AS userid,
                    u.idnumber,
                    u.firstname,
                    u.lastname,
                    u.picture,
                    u.imagealt,
                    u.email,
                    qa.sumgrades,
                    qa.timefinish,
                    qa.timestart,
                    CASE WHEN qa.timefinish = 0 THEN null
                         WHEN qa.timefinish > qa.timestart THEN qa.timefinish - qa.timestart
                         ELSE 0 END AS duration';
            // To explain that last bit, in MySQL, qa.timestart and qa.timefinish
            // are unsigned. Since MySQL 5.5.5, when they introduced strict mode,
            // subtracting a larger unsigned int from a smaller one gave an error.
            // Therefore, we avoid doing that. timefinish can be non-zero and less
            // than timestart when you have two load-balanced servers with very
            // badly synchronised clocks, and a student does a really quick attempt.

            // This part is the same for all cases - join users and quiz_attempts tables
            $from = '{user} u ';
            $from .= 'LEFT JOIN {quiz_attempts} qa ON qa.userid = u.id AND qa.quiz = :quizid';
            $params = array('quizid' => $quiz->id);

            if ($qmsubselect && $qmfilter) {
                $from .= ' AND '.$qmsubselect;
            }
            switch ($attemptsmode) {
                 case QUIZ_REPORT_ATTEMPTS_ALL:
                     // Show all attempts, including students who are no longer in the course
                    $where = 'qa.id IS NOT NULL AND qa.preview = 0';
                     break;
                 case QUIZ_REPORT_ATTEMPTS_STUDENTS_WITH:
                     // Show only students with attempts
                     list($allowed_usql, $allowed_params) = $DB->get_in_or_equal($allowed, SQL_PARAMS_NAMED, 'u0000');
                     $params += $allowed_params;
                    $where = "u.id $allowed_usql AND qa.preview = 0 AND qa.id IS NOT NULL";
                     break;
                 case QUIZ_REPORT_ATTEMPTS_STUDENTS_WITH_NO:
                     // Show only students without attempts
                     list($allowed_usql, $allowed_params) = $DB->get_in_or_equal($allowed, SQL_PARAMS_NAMED, 'u0000');
                     $params += $allowed_params;
                    $where = "u.id $allowed_usql AND qa.id IS NULL";
                     break;
                 case QUIZ_REPORT_ATTEMPTS_ALL_STUDENTS:
                     // Show all students with or without attempts
                     list($allowed_usql, $allowed_params) = $DB->get_in_or_equal($allowed, SQL_PARAMS_NAMED, 'u0000');
                     $params += $allowed_params;
                    $where = "u.id $allowed_usql AND (qa.preview = 0 OR qa.preview IS NULL)";
                     break;
             }

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

            $sqlobject = new stdClass();
            $sqlobject->from = $from;
            $sqlobject->where = $where;
            $sqlobject->params = $params;
            //test to see if there are any regraded attempts to be listed.
            if (quiz_get_regraded_qs($sqlobject, 0, 1)) {
                $regradedattempts = true;
            } else {
                $regradedattempts = false;
            }
            $fields .= ', COALESCE((SELECT MAX(qqr.regraded) FROM {quiz_question_regrade} qqr WHERE qqr.attemptid = qa.uniqueid),-1) AS regraded';
            if ($regradefilter) {
                $where .= ' AND COALESCE((SELECT MAX(qqr.regraded) FROM {quiz_question_regrade} qqr WHERE qqr.attemptid = qa.uniqueid),-1) !=\'-1\'';
            }
            $table->set_sql($fields, $from, $where, $params);

            // Define table columns
            $columns = array();
            $headers = array();
            if (!$table->is_downloading()) { //do not print notices when downloading
                //regrade buttons
                if (has_capability('mod/quiz:regrade', $this->context)) {
                    $countregradeneeded = $this->count_regrade_all_needed($quiz, $groupstudents);
                    if ($currentgroup) {
                        $a= new stdClass();
                        $a->groupname = groups_get_group_name($currentgroup);
                        $a->coursestudents = get_string('participants');
                        $a->countregradeneeded = $countregradeneeded;
                        $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', $countregradeneeded);
                        $regradealldrylabel = get_string('regradealldry', 'quiz_overview');
                        $regradealllabel = get_string('regradeall', 'quiz_overview');
                    }
                    $displayurl = new moodle_url($reporturl, $displayoptions);
                    echo '<div class="mdl-align">';
                    echo '<form action="'.$displayurl->out_omit_querystring().'">';
                    echo '<div>';
                    echo html_writer::input_hidden_params($displayurl);
                    echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey())) . "\n";
                    echo '<input type="submit" name="regradeall" value="'.$regradealllabel.'"/>';
                    echo '<input type="submit" name="regradealldry" value="'.$regradealldrylabel.'"/>';
                    if ($countregradeneeded) {
                        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>';
                }
            }

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

            if (!$table->is_downloading() && $CFG->grade_report_showuserimage) {
                $columns[]= 'picture';
                $headers[]= '';
            }
            if (!$table->is_downloading()) {
                $columns[]= 'fullname';
                $headers[]= get_string('name');
             } else {
                $columns[]= 'lastname';
                $headers[]= get_string('lastname');
                $columns[]= 'firstname';
                $headers[]= get_string('firstname');
             }

            if ($CFG->grade_report_showuseridnumber) {
                $columns[]= 'idnumber';
                $headers[]= get_string('idnumber');
            }

            $columns[]= 'timestart';
            $headers[]= get_string('startedon', 'quiz');

            $columns[]= 'timefinish';
            $headers[]= get_string('timecompleted','quiz');

            $columns[]= 'duration';
            $headers[]= get_string('attemptduration', 'quiz');

            if ($detailedmarks) {
                foreach ($questions as $id => $question) {
                    // Ignore questions of zero length
                    $columns[] = 'qsgrade'.$id;
                    $header = '#'.$question->number;
                    if (!$table->is_downloading()) {
                        $header .='<br />';
                    } else {
                        $header .=' ';
                    }
                    $header .='--/'.quiz_rescale_grade($question->maxgrade, $quiz, 'question');
                    $headers[] = $header;
                    $question->formattedname = strip_tags(format_string($question->name));
                }
            }
            if (!$table->is_downloading() && has_capability('mod/quiz:regrade', $this->context) && $regradedattempts) {
                $columns[] = 'regraded';
                $headers[] = get_string('regrade', 'quiz_overview');
            }
            if ($showgrades) {
                $columns[] = 'sumgrades';
                $headers[] = get_string('grade', 'quiz').'/'.quiz_format_grade($quiz, $quiz->grade);
             }

            if ($hasfeedback) {
                $columns[] = 'feedbacktext';
                $headers[] = get_string('feedback', 'quiz');
             }

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

            // Set up the table
            $table->define_baseurl($reporturl->out(true, $displayoptions));

            $table->collapsible(true);

            $table->no_sorting('feedbacktext');

            $table->column_class('picture', 'picture');
            $table->column_class('lastname', 'bold');
            $table->column_class('firstname', 'bold');
            $table->column_class('fullname', 'bold');
            $table->column_class('sumgrades', 'bold');

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

            $table->out($pagesize, true);
        }
        if (!$table->is_downloading() && $showgrades) {
            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 = "{$CFG->wwwroot}/mod/quiz/report/overview/overviewgraph.php?id={$quiz->id}&amp;groupid=$currentgroup";
                     $graphname = get_string('overviewreportgraphgroup', 'quiz_overview', groups_get_group_name($currentgroup));
                     echo $OUTPUT->heading($graphname);
                     echo '<div class="graph"><img src="'.$imageurl.'" alt="'.$graphname.'" /></div>';
                }
            }
            if ($DB->record_exists('quiz_grades', array('quiz'=> $quiz->id))) {
                 $graphname = get_string('overviewreportgraph', 'quiz_overview');
                 $imageurl = $CFG->wwwroot.'/mod/quiz/report/overview/overviewgraph.php?id='.$quiz->id;
                 echo $OUTPUT->heading($graphname);
                 echo '<div class="graph"><img src="'.$imageurl.'" alt="'.$graphname.'" /></div>';
            }
        }
        return true;
    }
 /**
  * Render the total marks available for the quiz.
  *
  * @param \stdClass $quiz the quiz settings from the database.
  * @return string HTML to output.
  */
 public function total_marks($quiz)
 {
     $totalmark = html_writer::span(quiz_format_grade($quiz, $quiz->sumgrades), 'mod_quiz_summarks');
     return html_writer::tag('span', get_string('totalmarksx', 'quiz', $totalmark), array('class' => 'totalpoints'));
 }
Example #13
0
function quiz_report_scale_sumgrades_as_percentage($rawgrade, $quiz, $round = true)
{
    if ($quiz->sumgrades != 0) {
        $grade = $rawgrade * 100 / $quiz->sumgrades;
        if ($round) {
            $grade = quiz_format_grade($quiz, $grade);
        }
    } else {
        return '';
    }
    return $grade . '%';
}
 /**
  * Generates the table of data
  *
  * @param array $quiz Array contining quiz data
  * @param int $context The page context ID
  * @param mod_quiz_view_object $viewobj
  */
 public function view_table($quiz, $context, $viewobj)
 {
     // Most of the following code is unfortunately a duplicate of the existing renderer. There was no way to reuse the existing
     // code and add the extra columns we wanted so I had to duplicate it.
     // New parts of the code are marked with a comment // Grade by category code start. and // Grade by category code end.
     global $DB;
     // Grade by category code start.
     // If gradebycategory setting is not on then just use the existing renderer.
     if (!$quiz->gradebycategory) {
         return parent::view_table($quiz, $context, $viewobj);
     }
     // Grade by category code end.
     if (!$viewobj->attempts) {
         return '';
     }
     // Prepare table header.
     $table = new html_table();
     $table->attributes['class'] = 'generaltable quizattemptsummary';
     $table->head = array();
     $table->align = array();
     $table->size = array();
     if ($viewobj->attemptcolumn) {
         $table->head[] = get_string('attemptnumber', 'quiz');
         $table->align[] = 'center';
         $table->size[] = '';
     }
     $table->head[] = get_string('attemptstate', 'quiz');
     $table->align[] = 'left';
     $table->size[] = '';
     if ($viewobj->markcolumn) {
         $table->head[] = get_string('marks', 'quiz') . ' / ' . quiz_format_grade($quiz, $quiz->sumgrades);
         $table->align[] = 'center';
         $table->size[] = '';
     }
     if ($viewobj->gradecolumn) {
         $table->head[] = get_string('grade') . ' / ' . quiz_format_grade($quiz, $quiz->grade);
         $table->align[] = 'center';
         $table->size[] = '';
     }
     // Grade by category code start.
     $catgrades = new quizaccess_gradebycategory_calculator($quiz);
     // $this->lateststeps may or may not already have been loaded depending if the reoprt
     // is set to show question grades.
     $catgrades->load_latest_steps($viewobj->attempts);
     $categorynames = $catgrades->load_cat_data();
     // Output column headings for category averages
     foreach ($categorynames as $catname) {
         $table->head[] = $catname . ' / ' . quiz_format_grade($quiz, 100);
         $table->align[] = 'center';
         $table->size[] = '';
     }
     // Grade by category code end.
     if ($viewobj->canreviewmine) {
         $table->head[] = get_string('review', 'quiz');
         $table->align[] = 'center';
         $table->size[] = '';
     }
     if ($viewobj->feedbackcolumn) {
         $table->head[] = get_string('feedback', 'quiz');
         $table->align[] = 'left';
         $table->size[] = '';
     }
     // One row for each attempt.
     foreach ($viewobj->attemptobjs as $attemptobj) {
         $attemptoptions = $attemptobj->get_display_options(true);
         $row = array();
         // Add the attempt number.
         if ($viewobj->attemptcolumn) {
             if ($attemptobj->is_preview()) {
                 $row[] = get_string('preview', 'quiz');
             } else {
                 $row[] = $attemptobj->get_attempt_number();
             }
         }
         $row[] = $this->attempt_state($attemptobj);
         if ($viewobj->markcolumn) {
             if ($attemptoptions->marks >= question_display_options::MARK_AND_MAX && $attemptobj->is_finished()) {
                 $row[] = quiz_format_grade($quiz, $attemptobj->get_sum_marks());
             } else {
                 $row[] = '';
             }
         }
         // Outside the if because we may be showing feedback but not grades.
         $attemptgrade = quiz_rescale_grade($attemptobj->get_sum_marks(), $quiz, false);
         if ($viewobj->gradecolumn) {
             if ($attemptoptions->marks >= question_display_options::MARK_AND_MAX && $attemptobj->is_finished()) {
                 // Highlight the highest grade if appropriate.
                 if ($viewobj->overallstats && !$attemptobj->is_preview() && $viewobj->numattempts > 1 && !is_null($viewobj->mygrade) && $attemptgrade == $viewobj->mygrade && $quiz->grademethod == QUIZ_GRADEHIGHEST) {
                     $table->rowclasses[$attemptobj->get_attempt_number()] = 'bestrow';
                 }
                 $row[] = quiz_format_grade($quiz, $attemptgrade);
             } else {
                 $row[] = '';
             }
         }
         // Grade by category code start.
         // Output cell contents for category average.
         foreach (array_keys($categorynames) as $catid) {
             $row[] = $catgrades->grade_by_category($attemptobj->get_uniqueid(), $catid);
         }
         // Grade by category code end.
         if ($viewobj->canreviewmine) {
             $row[] = $viewobj->accessmanager->make_review_link($attemptobj->get_attempt(), $attemptoptions, $this);
         }
         if ($viewobj->feedbackcolumn && $attemptobj->is_finished()) {
             if ($attemptoptions->overallfeedback) {
                 $row[] = quiz_feedback_for_grade($attemptgrade, $quiz, $context);
             } else {
                 $row[] = '';
             }
         }
         if ($attemptobj->is_preview()) {
             $table->data['preview'] = $row;
         } else {
             $table->data[$attemptobj->get_attempt_number()] = $row;
         }
     }
     // End of loop over attempts.
     $output = '';
     $output .= $this->view_table_heading();
     $output .= html_writer::table($table);
     return $output;
 }
 /**
  * Format an entry in an average row.
  * @param object $record with fields grade and numaveraged
  */
 protected function format_average($record, $question = false)
 {
     if (is_null($record->grade)) {
         $average = '-';
     } else {
         if ($question) {
             $average = quiz_format_question_grade($this->quiz, $record->grade);
         } else {
             $average = quiz_format_grade($this->quiz, $record->grade);
         }
     }
     if ($this->download) {
         return $average;
     } else {
         if (is_null($record->numaveraged) || $record->numaveraged == 0) {
             return html_writer::tag('span', html_writer::tag('span', $average, array('class' => 'average')), array('class' => 'avgcell'));
         } else {
             return html_writer::tag('span', html_writer::tag('span', $average, array('class' => 'average')) . ' ' . html_writer::tag('span', '(' . $record->numaveraged . ')', array('class' => 'count')), array('class' => 'avgcell'));
         }
     }
 }
 /**
  * Add the titles of the columns.
  * @param array $headers
  */
 function add_extra_headers($catnames)
 {
     foreach ($catnames as $catname) {
         $header = $catname;
         if (!$this->is_downloading()) {
             $header .= '<br />';
         } else {
             $header .= ' ';
         }
         $header .= '/ ' . quiz_format_grade($this->quiz, 100);
         $this->add_header($header);
     }
 }
Example #17
0
/**
 * Print the status bar
 *
 * @param object $quiz The quiz object of the quiz in question
 */
function quiz_print_status_bar($quiz)
{
    global $CFG;
    $numberofquestions = quiz_number_of_questions_in_quiz($quiz->questions);
    ?>
<div class="statusbar"><span class="totalpoints">
    <?php 
    echo get_string('totalpointsx', 'quiz', quiz_format_grade($quiz, $quiz->sumgrades));
    ?>
</span>
    | <span class="numberofquestions">
    <?php 
    echo get_string('numquestionsx', 'quiz', $numberofquestions);
    ?>
</span>
    <?php 
    // Current status of the quiz, with open an close dates as a tool tip.
    $currentstatus = get_string('quizisopen', 'quiz');
    $dates = array();
    $timenow = time();
    if ($quiz->timeopen > 0) {
        if ($timenow > $quiz->timeopen) {
            $dates[] = get_string('quizopenedon', 'quiz', userdate($quiz->timeopen));
        } else {
            $dates[] = get_string('quizwillopen', 'quiz', userdate($quiz->timeopen));
            print_string('quizisclosed', 'quiz');
        }
    }
    if ($quiz->timeclose > 0) {
        if ($timenow > $quiz->timeclose) {
            $dates[] = get_string('quizclosed', 'quiz', userdate($quiz->timeclose));
            print_string('quizisclosed', 'quiz');
        } else {
            $dates[] = get_string('quizcloseson', 'quiz', userdate($quiz->timeclose));
            $currentstatus = get_string('quizisopenwillclose', 'quiz', userdate($quiz->timeclose, get_string('strftimedatetimeshort', 'langconfig')));
        }
    }
    if (empty($dates)) {
        $dates[] = get_string('alwaysavailable', 'quiz');
    }
    $dates = implode(', ', $dates);
    echo ' | <span class="quizopeningstatus" title="' . $dates . '">' . $currentstatus . '</span>';
    ?>
    </div>
    <?php 
}
Example #18
0
/**
 * Convert the raw grade stored in $attempt into a grade out of the maximum
 * grade for this quiz.
 *
 * @param float $rawgrade the unadjusted grade, fof example $attempt->sumgrades
 * @param object $quiz the quiz object. Only the fields grade, sumgrades, decimalpoints and questiondecimalpoints are used.
 * @param mixed $round false = don't round, true = round using quiz_format_grade, 'question' = round using quiz_format_question_grade.
 * @return float the rescaled grade.
 */
function quiz_rescale_grade($rawgrade, $quiz, $round = true)
{
    if ($quiz->sumgrades != 0) {
        $grade = $rawgrade * $quiz->grade / $quiz->sumgrades;
        if ($round === 'question') {
            // === really necessary here true == 'question' is true in PHP!
            $grade = quiz_format_question_grade($quiz, $grade);
        } else {
            if ($round) {
                $grade = quiz_format_grade($quiz, $grade);
            }
        }
    } else {
        $grade = 0;
    }
    return $grade;
}
Example #19
0
/// Print information about the student's best score for this quiz if possible.
$moreattempts = $unfinished || !$accessmanager->is_finished($numattempts, $lastfinishedattempt);
if (!$moreattempts) {
    echo $OUTPUT->heading(get_string("nomoreattempts", "quiz"));
}
if ($numattempts && $gradecolumn && !is_null($mygrade)) {
    $resultinfo = '';
    if ($overallstats) {
        if ($moreattempts) {
            $a = new stdClass();
            $a->method = quiz_get_grading_option_name($quiz->grademethod);
            $a->mygrade = quiz_format_grade($quiz, $mygrade);
            $a->quizgrade = quiz_format_grade($quiz, $quiz->grade);
            $resultinfo .= $OUTPUT->heading(get_string('gradesofar', 'quiz', $a), 2, 'main');
        } else {
            $a = quiz_format_grade($quiz, $mygrade) . '/' . quiz_format_grade($quiz, $quiz->grade);
            $resultinfo .= $OUTPUT->heading(get_string('yourfinalgradeis', 'quiz', $a), 2, 'main');
        }
    }
    if ($mygradeoverridden) {
        $resultinfo .= '<p class="overriddennotice">' . get_string('overriddennotice', 'grades') . "</p>\n";
    }
    if ($gradebookfeedback) {
        $resultinfo .= $OUTPUT->heading(get_string('comment', 'quiz'), 3, 'main');
        $resultinfo .= '<p class="quizteacherfeedback">' . $gradebookfeedback . "</p>\n";
    }
    if ($feedbackcolumn) {
        $resultinfo .= $OUTPUT->heading(get_string('overallfeedback', 'quiz'), 3, 'main');
        $resultinfo .= '<p class="quizgradefeedback">' . quiz_feedback_for_grade($mygrade, $quiz->id) . "</p>\n";
    }
    if ($resultinfo) {
Example #20
0
 /**
  * Add all the grade and feedback columns, if applicable, to the $columns
  * and $headers arrays.
  * @param object $quiz the quiz settings.
  * @param bool $usercanseegrades whether the user is allowed to see grades for this quiz.
  * @param array $columns the list of columns. Added to.
  * @param array $headers the columns headings. Added to.
  * @param bool $includefeedback whether to include the feedbacktext columns
  */
 protected function add_grade_columns($quiz, $usercanseegrades, &$columns, &$headers, $includefeedback = true)
 {
     if ($usercanseegrades) {
         $columns[] = 'sumgrades';
         $headers[] = get_string('grade', 'quiz') . '/' . quiz_format_grade($quiz, $quiz->grade);
     }
     if ($includefeedback && quiz_has_feedback($quiz)) {
         $columns[] = 'feedbacktext';
         $headers[] = get_string('feedback', 'quiz');
     }
 }
Example #21
0
    protected function get_formatted_quiz_info_data($course, $cm, $quiz, $quizstats) {

        // You can edit this array to control which statistics are displayed.
        $todisplay = array('firstattemptscount' => 'number',
                    'allattemptscount' => 'number',
                    'firstattemptsavg' => 'summarks_as_percentage',
                    'allattemptsavg' => 'summarks_as_percentage',
                    'median' => 'summarks_as_percentage',
                    'standarddeviation' => 'summarks_as_percentage',
                    'skewness' => 'number_format',
                    'kurtosis' => 'number_format',
                    'cic' => 'number_format_percent',
                    'errorratio' => 'number_format_percent',
                    'standarderror' => 'summarks_as_percentage');

        // General information about the quiz.
        $quizinfo = array();
        $quizinfo[get_string('quizname', 'quiz_statistics')] = format_string($quiz->name);
        $quizinfo[get_string('coursename', 'quiz_statistics')] = format_string($course->fullname);
        if ($cm->idnumber) {
            $quizinfo[get_string('idnumbermod')] = $cm->idnumber;
        }
        if ($quiz->timeopen) {
            $quizinfo[get_string('quizopen', 'quiz')] = userdate($quiz->timeopen);
        }
        if ($quiz->timeclose) {
            $quizinfo[get_string('quizclose', 'quiz')] = userdate($quiz->timeclose);
        }
        if ($quiz->timeopen && $quiz->timeclose) {
            $quizinfo[get_string('duration', 'quiz_statistics')] =
                    format_time($quiz->timeclose - $quiz->timeopen);
        }

        // The statistics.
        foreach ($todisplay as $property => $format) {
            if (!isset($quizstats->$property) || empty($format[$property])) {
                continue;
            }
            $value = $quizstats->$property;

            switch ($format) {
                case 'summarks_as_percentage':
                    $formattedvalue = quiz_report_scale_summarks_as_percentage($value, $quiz);
                    break;
                case 'number_format_percent':
                    $formattedvalue = quiz_format_grade($quiz, $value) . '%';
                    break;
                case 'number_format':
                    // 2 extra decimal places, since not a percentage,
                    // and we want the same number of sig figs.
                    $formattedvalue = format_float($value, $quiz->decimalpoints + 2);
                    break;
                case 'number':
                    $formattedvalue = $value + 0;
                    break;
                default:
                    $formattedvalue = $value;
            }

            $quizinfo[get_string($property, 'quiz_statistics',
                    $this->using_attempts_string(!empty($quizstats->allattempts)))] =
                    $formattedvalue;
        }

        return $quizinfo;
    }
Example #22
0
/**
 * Returns all quiz graded users since a given time for specified quiz
 */
function quiz_get_recent_mod_activity(&$activities, &$index, $timestart,
        $courseid, $cmid, $userid = 0, $groupid = 0) {
    global $CFG, $COURSE, $USER, $DB;
    require_once($CFG->dirroot . '/mod/quiz/locallib.php');

    if ($COURSE->id == $courseid) {
        $course = $COURSE;
    } else {
        $course = $DB->get_record('course', array('id' => $courseid));
    }

    $modinfo = get_fast_modinfo($course);

    $cm = $modinfo->cms[$cmid];
    $quiz = $DB->get_record('quiz', array('id' => $cm->instance));

    if ($userid) {
        $userselect = "AND u.id = :userid";
        $params['userid'] = $userid;
    } else {
        $userselect = '';
    }

    if ($groupid) {
        $groupselect = 'AND gm.groupid = :groupid';
        $groupjoin   = 'JOIN {groups_members} gm ON  gm.userid=u.id';
        $params['groupid'] = $groupid;
    } else {
        $groupselect = '';
        $groupjoin   = '';
    }

    $params['timestart'] = $timestart;
    $params['quizid'] = $quiz->id;

    if (!$attempts = $DB->get_records_sql("
              SELECT qa.*,
                     u.firstname, u.lastname, u.email, u.picture, u.imagealt
                FROM {quiz_attempts} qa
                     JOIN {user} u ON u.id = qa.userid
                     $groupjoin
               WHERE qa.timefinish > :timestart
                 AND qa.quiz = :quizid
                 AND qa.preview = 0
                     $userselect
                     $groupselect
            ORDER BY qa.timefinish ASC", $params)) {
        return;
    }

    $context         = context_module::instance($cm->id);
    $accessallgroups = has_capability('moodle/site:accessallgroups', $context);
    $viewfullnames   = has_capability('moodle/site:viewfullnames', $context);
    $grader          = has_capability('mod/quiz:viewreports', $context);
    $groupmode       = groups_get_activity_groupmode($cm, $course);

    if (is_null($modinfo->groups)) {
        // Load all my groups and cache it in modinfo.
        $modinfo->groups = groups_get_user_groups($course->id);
    }

    $usersgroups = null;
    $aname = format_string($cm->name, true);
    foreach ($attempts as $attempt) {
        if ($attempt->userid != $USER->id) {
            if (!$grader) {
                // Grade permission required.
                continue;
            }

            if ($groupmode == SEPARATEGROUPS and !$accessallgroups) {
                if (is_null($usersgroups)) {
                    $usersgroups = groups_get_all_groups($course->id,
                            $attempt->userid, $cm->groupingid);
                    if (is_array($usersgroups)) {
                        $usersgroups = array_keys($usersgroups);
                    } else {
                        $usersgroups = array();
                    }
                }
                if (!array_intersect($usersgroups, $modinfo->groups[$cm->id])) {
                    continue;
                }
            }
        }

        $options = quiz_get_review_options($quiz, $attempt, $context);

        $tmpactivity = new stdClass();

        $tmpactivity->type       = 'quiz';
        $tmpactivity->cmid       = $cm->id;
        $tmpactivity->name       = $aname;
        $tmpactivity->sectionnum = $cm->sectionnum;
        $tmpactivity->timestamp  = $attempt->timefinish;

        $tmpactivity->content = new stdClass();
        $tmpactivity->content->attemptid = $attempt->id;
        $tmpactivity->content->attempt   = $attempt->attempt;
        if (quiz_has_grades($quiz) && $options->marks >= question_display_options::MARK_AND_MAX) {
            $tmpactivity->content->sumgrades = quiz_format_grade($quiz, $attempt->sumgrades);
            $tmpactivity->content->maxgrade  = quiz_format_grade($quiz, $quiz->sumgrades);
        } else {
            $tmpactivity->content->sumgrades = null;
            $tmpactivity->content->maxgrade  = null;
        }

        $tmpactivity->user = new stdClass();
        $tmpactivity->user->id        = $attempt->userid;
        $tmpactivity->user->firstname = $attempt->firstname;
        $tmpactivity->user->lastname  = $attempt->lastname;
        $tmpactivity->user->fullname  = fullname($attempt, $viewfullnames);
        $tmpactivity->user->picture   = $attempt->picture;
        $tmpactivity->user->imagealt  = $attempt->imagealt;
        $tmpactivity->user->email     = $attempt->email;

        $activities[$index++] = $tmpactivity;
    }
}
 function get_content()
 {
     global $USER, $CFG, $DB;
     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 ($this->page->activityname == 'quiz' && $this->page->context->id == $this->instance->parentcontextid) {
         $quiz = $this->page->activityrecord;
         $quizid = $quiz->id;
         $courseid = $this->page->course->id;
         $inquiz = true;
     } else {
         if (!empty($this->config->quizid)) {
             $quizid = $this->config->quizid;
             $quiz = $DB->get_record('quiz', array('id' => $quizid));
             if (empty($quiz)) {
                 $this->content->text = get_string('error_emptyquizrecord', 'block_quiz_results');
                 return $this->content;
             }
             $courseid = $quiz->course;
             $inquiz = false;
         } else {
             $quizid = 0;
         }
     }
     if (empty($quizid)) {
         $this->content->text = get_string('error_emptyquizid', 'block_quiz_results');
         return $this->content;
     }
     if (empty($this->config->showbest) && empty($this->config->showworst)) {
         $this->content->text = get_string('configuredtoshownothing', 'block_quiz_results');
         return $this->content;
     }
     // Get the grades for this quiz
     $grades = $DB->get_records('quiz_grades', array('quiz' => $quizid), 'grade, timemodified DESC');
     if (empty($grades)) {
         // No grades, sorry
         // The block will hide itself in this case
         return $this->content;
     }
     $groupmode = NOGROUPS;
     $best = array();
     $worst = array();
     if (!empty($this->config->nameformat)) {
         $nameformat = $this->config->nameformat;
     } else {
         $nameformat = B_QUIZRESULTS_NAME_FORMAT_FULL;
     }
     if (!empty($this->config->usegroups)) {
         if ($inquiz) {
             $cm = $this->page->cm;
             $context = $this->page->context;
         } else {
             $cm = get_coursemodule_from_instance('quiz', $quizid, $courseid);
             $context = get_context_instance(CONTEXT_MODULE, $cm->id);
         }
         $groupmode = groups_get_activity_groupmode($cm);
         if ($groupmode == SEPARATEGROUPS && has_capability('moodle/site:accessallgroups', $context)) {
             // We 'll make an exception in this case
             $groupmode = VISIBLEGROUPS;
         }
     }
     switch ($groupmode) {
         case VISIBLEGROUPS:
             // Display group-mode results
             $groups = groups_get_all_groups($courseid);
             if (empty($groups)) {
                 // No groups exist, sorry
                 $this->content->text = get_string('error_nogroupsexist', 'block_quiz_results');
                 return $this->content;
             }
             // Find out all the userids which have a submitted grade
             $userids = array();
             $gradeforuser = array();
             foreach ($grades as $grade) {
                 $userids[] = $grade->userid;
                 $gradeforuser[$grade->userid] = (double) $grade->grade;
             }
             // Now find which groups these users belong in
             list($usertest, $params) = $DB->get_in_or_equal($userids);
             $params[] = $courseid;
             $usergroups = $DB->get_records_sql('
                 SELECT gm.id, gm.userid, gm.groupid, g.name
                 FROM {groups} g
                 LEFT JOIN {groups_members} gm ON g.id = gm.groupid
                 WHERE gm.userid ' . $usertest . ' AND g.courseid = ?', $params);
             // Now, iterate the grades again and sum them up for each group
             $groupgrades = array();
             foreach ($usergroups as $usergroup) {
                 if (!isset($groupgrades[$usergroup->groupid])) {
                     $groupgrades[$usergroup->groupid] = array('sum' => (double) $gradeforuser[$usergroup->userid], 'number' => 1, 'group' => $usergroup->name);
                 } else {
                     $groupgrades[$usergroup->groupid]['sum'] += $gradeforuser[$usergroup->userid];
                     $groupgrades[$usergroup->groupid]['number'] += 1;
                 }
             }
             foreach ($groupgrades as $groupid => $groupgrade) {
                 $groupgrades[$groupid]['average'] = $groupgrades[$groupid]['sum'] / $groupgrades[$groupid]['number'];
             }
             // Sort groupgrades according to average grade, ascending
             uasort($groupgrades, create_function('$a, $b', 'if($a["average"] == $b["average"]) return 0; return ($a["average"] > $b["average"] ? 1 : -1);'));
             // How many groups do we have with graded member submissions to show?
             $numbest = empty($this->config->showbest) ? 0 : min($this->config->showbest, count($groupgrades));
             $numworst = empty($this->config->showworst) ? 0 : min($this->config->showworst, count($groupgrades) - $numbest);
             // Collect all the group results we are going to use in $best and $worst
             $remaining = $numbest;
             $groupgrade = end($groupgrades);
             while ($remaining--) {
                 $best[key($groupgrades)] = $groupgrade['average'];
                 $groupgrade = prev($groupgrades);
             }
             $remaining = $numworst;
             $groupgrade = reset($groupgrades);
             while ($remaining--) {
                 $worst[key($groupgrades)] = $groupgrade['average'];
                 $groupgrade = next($groupgrades);
             }
             // Ready for output!
             $gradeformat = intval(empty($this->config->gradeformat) ? B_QUIZRESULTS_GRADE_FORMAT_PCT : $this->config->gradeformat);
             if (!$inquiz) {
                 // Don't show header and link to the quiz if we ARE at the quiz...
                 $this->content->text .= '<h1><a href="' . $CFG->wwwroot . '/mod/quiz/view.php?q=' . $quizid . '">' . $quiz->name . '</a></h1>';
             }
             if ($nameformat = B_QUIZRESULTS_NAME_FORMAT_FULL) {
                 if (has_capability('moodle/course:managegroups', $context)) {
                     $grouplink = $CFG->wwwroot . '/group/overview.php?id=' . $courseid . '&amp;group=';
                 } else {
                     if (has_capability('moodle/course:viewparticipants', $context)) {
                         $grouplink = $CFG->wwwroot . '/user/index.php?id=' . $courseid . '&amp;group=';
                     } else {
                         $grouplink = '';
                     }
                 }
             }
             $rank = 0;
             if (!empty($best)) {
                 $this->content->text .= '<table class="grades"><caption>';
                 $this->content->text .= $numbest == 1 ? get_string('bestgroupgrade', 'block_quiz_results') : get_string('bestgroupgrades', 'block_quiz_results', $numbest);
                 $this->content->text .= '</caption><colgroup class="number" /><colgroup class="name" /><colgroup class="grade" /><tbody>';
                 foreach ($best as $groupid => $averagegrade) {
                     switch ($nameformat) {
                         case B_QUIZRESULTS_NAME_FORMAT_ANON:
                         case B_QUIZRESULTS_NAME_FORMAT_ID:
                             $thisname = get_string('group');
                             break;
                         default:
                         case B_QUIZRESULTS_NAME_FORMAT_FULL:
                             if ($grouplink) {
                                 $thisname = '<a href="' . $grouplink . $groupid . '">' . $groupgrades[$groupid]['group'] . '</a>';
                             } else {
                                 $thisname = $groupgrades[$groupid]['group'];
                             }
                             break;
                     }
                     $this->content->text .= '<tr><td>' . ++$rank . '.</td><td>' . $thisname . '</td><td>';
                     switch ($gradeformat) {
                         case B_QUIZRESULTS_GRADE_FORMAT_FRA:
                             $this->content->text .= quiz_format_grade($quiz, $averagegrade) . '/' . $quiz->grade;
                             break;
                         case B_QUIZRESULTS_GRADE_FORMAT_ABS:
                             $this->content->text .= quiz_format_grade($quiz, $averagegrade);
                             break;
                         default:
                         case B_QUIZRESULTS_GRADE_FORMAT_PCT:
                             $this->content->text .= round((double) $averagegrade / (double) $quiz->grade * 100) . '%';
                             break;
                     }
                     $this->content->text .= '</td></tr>';
                 }
                 $this->content->text .= '</tbody></table>';
             }
             $rank = 0;
             if (!empty($worst)) {
                 $worst = array_reverse($worst, true);
                 $this->content->text .= '<table class="grades"><caption>';
                 $this->content->text .= $numworst == 1 ? get_string('worstgroupgrade', 'block_quiz_results') : get_string('worstgroupgrades', 'block_quiz_results', $numworst);
                 $this->content->text .= '</caption><colgroup class="number" /><colgroup class="name" /><colgroup class="grade" /><tbody>';
                 foreach ($worst as $groupid => $averagegrade) {
                     switch ($nameformat) {
                         case B_QUIZRESULTS_NAME_FORMAT_ANON:
                         case B_QUIZRESULTS_NAME_FORMAT_ID:
                             $thisname = get_string('group');
                             break;
                         default:
                         case B_QUIZRESULTS_NAME_FORMAT_FULL:
                             $thisname = '<a href="' . $CFG->wwwroot . '/course/group.php?group=' . $groupid . '&amp;id=' . $courseid . '">' . $groupgrades[$groupid]['group'] . '</a>';
                             break;
                     }
                     $this->content->text .= '<tr><td>' . ++$rank . '.</td><td>' . $thisname . '</td><td>';
                     switch ($gradeformat) {
                         case B_QUIZRESULTS_GRADE_FORMAT_FRA:
                             $this->content->text .= quiz_format_grade($quiz, $averagegrade) . '/' . $quiz->grade;
                             break;
                         case B_QUIZRESULTS_GRADE_FORMAT_ABS:
                             $this->content->text .= quiz_format_grade($quiz, $averagegrade);
                             break;
                         default:
                         case B_QUIZRESULTS_GRADE_FORMAT_PCT:
                             $this->content->text .= round((double) $averagegrade / (double) $quiz->grade * 100) . '%';
                             break;
                     }
                     $this->content->text .= '</td></tr>';
                 }
                 $this->content->text .= '</tbody></table>';
             }
             break;
         case SEPARATEGROUPS:
             // This is going to be just like no-groups mode, only we 'll filter
             // out the grades from people not in our group.
             if (!isloggedin()) {
                 // Not logged in, so show nothing
                 return $this->content;
             }
             $mygroups = groups_get_all_groups($courseid, $USER->id);
             if (empty($mygroups)) {
                 // Not member of a group, show nothing
                 return $this->content;
             }
             // Get users from the same groups as me.
             list($grouptest, $params) = $DB->get_in_or_equal(array_keys($mygroups));
             $mygroupsusers = $DB->get_records_sql_menu('SELECT DISTINCT userid, 1 FROM {groups_members} WHERE groupid ' . $grouptest, $params);
             // Filter out the grades belonging to other users, and proceed as if there were no groups
             foreach ($grades as $key => $grade) {
                 if (!isset($mygroupsusers[$grade->userid])) {
                     unset($grades[$key]);
                 }
             }
             // No break, fall through to the default case now we have filtered the $grades array.
         // No break, fall through to the default case now we have filtered the $grades array.
         default:
         case NOGROUPS:
             // Single user mode
             $numbest = empty($this->config->showbest) ? 0 : min($this->config->showbest, count($grades));
             $numworst = empty($this->config->showworst) ? 0 : min($this->config->showworst, count($grades) - $numbest);
             // Collect all the usernames we are going to need
             $remaining = $numbest;
             $grade = end($grades);
             while ($remaining--) {
                 $best[$grade->userid] = $grade->id;
                 $grade = prev($grades);
             }
             $remaining = $numworst;
             $grade = reset($grades);
             while ($remaining--) {
                 $worst[$grade->userid] = $grade->id;
                 $grade = next($grades);
             }
             if (empty($best) && empty($worst)) {
                 // Nothing to show, for some reason...
                 return $this->content;
             }
             // Now grab all the users from the database
             $userids = array_merge(array_keys($best), array_keys($worst));
             $users = $DB->get_records_list('user', 'id', $userids, '', 'id, firstname, lastname, idnumber');
             // Ready for output!
             $gradeformat = intval(empty($this->config->gradeformat) ? B_QUIZRESULTS_GRADE_FORMAT_PCT : $this->config->gradeformat);
             if (!$inquiz) {
                 // Don't show header and link to the quiz if we ARE at the quiz...
                 $this->content->text .= '<h1><a href="' . $CFG->wwwroot . '/mod/quiz/view.php?q=' . $quizid . '">' . $quiz->name . '</a></h1>';
             }
             $rank = 0;
             if (!empty($best)) {
                 $this->content->text .= '<table class="grades"><caption>';
                 $this->content->text .= $numbest == 1 ? get_string('bestgrade', 'block_quiz_results') : get_string('bestgrades', 'block_quiz_results', $numbest);
                 $this->content->text .= '</caption><colgroup class="number" /><colgroup class="name" /><colgroup class="grade" /><tbody>';
                 foreach ($best as $userid => $gradeid) {
                     switch ($nameformat) {
                         case B_QUIZRESULTS_NAME_FORMAT_ID:
                             $thisname = get_string('user') . ' ' . $users[$userid]->idnumber;
                             break;
                         case B_QUIZRESULTS_NAME_FORMAT_ANON:
                             $thisname = get_string('user');
                             break;
                         default:
                         case B_QUIZRESULTS_NAME_FORMAT_FULL:
                             $thisname = '<a href="' . $CFG->wwwroot . '/user/view.php?id=' . $userid . '&amp;course=' . $courseid . '">' . fullname($users[$userid]) . '</a>';
                             break;
                     }
                     $this->content->text .= '<tr><td>' . ++$rank . '.</td><td>' . $thisname . '</td><td>';
                     switch ($gradeformat) {
                         case B_QUIZRESULTS_GRADE_FORMAT_FRA:
                             $this->content->text .= quiz_format_grade($quiz, $grades[$gradeid]->grade) . '/' . $quiz->grade;
                             break;
                         case B_QUIZRESULTS_GRADE_FORMAT_ABS:
                             $this->content->text .= quiz_format_grade($quiz, $grades[$gradeid]->grade);
                             break;
                         default:
                         case B_QUIZRESULTS_GRADE_FORMAT_PCT:
                             if ($quiz->grade) {
                                 $this->content->text .= round((double) $grades[$gradeid]->grade / (double) $quiz->grade * 100) . '%';
                             } else {
                                 $this->content->text .= '--%';
                             }
                             break;
                     }
                     $this->content->text .= '</td></tr>';
                 }
                 $this->content->text .= '</tbody></table>';
             }
             $rank = 0;
             if (!empty($worst)) {
                 $worst = array_reverse($worst, true);
                 $this->content->text .= '<table class="grades"><caption>';
                 $this->content->text .= $numworst == 1 ? get_string('worstgrade', 'block_quiz_results') : get_string('worstgrades', 'block_quiz_results', $numworst);
                 $this->content->text .= '</caption><colgroup class="number" /><colgroup class="name" /><colgroup class="grade" /><tbody>';
                 foreach ($worst as $userid => $gradeid) {
                     switch ($nameformat) {
                         case B_QUIZRESULTS_NAME_FORMAT_ID:
                             $thisname = get_string('user') . ' ' . $users[$userid]->idnumber;
                             break;
                         case B_QUIZRESULTS_NAME_FORMAT_ANON:
                             $thisname = get_string('user');
                             break;
                         default:
                         case B_QUIZRESULTS_NAME_FORMAT_FULL:
                             $thisname = '<a href="' . $CFG->wwwroot . '/user/view.php?id=' . $userid . '&amp;course=' . $courseid . '">' . fullname($users[$userid]) . '</a>';
                             break;
                     }
                     $this->content->text .= '<tr><td>' . ++$rank . '.</td><td>' . $thisname . '</td><td>';
                     switch ($gradeformat) {
                         case B_QUIZRESULTS_GRADE_FORMAT_FRA:
                             $this->content->text .= quiz_format_grade($quiz, $grades[$gradeid]->grade) . '/' . $quiz->grade;
                             break;
                         case B_QUIZRESULTS_GRADE_FORMAT_ABS:
                             $this->content->text .= quiz_format_grade($quiz, $grades[$gradeid]->grade);
                             break;
                         default:
                         case B_QUIZRESULTS_GRADE_FORMAT_PCT:
                             $this->content->text .= round((double) $grades[$gradeid]->grade / (double) $quiz->grade * 100) . '%';
                             break;
                     }
                     $this->content->text .= '</td></tr>';
                 }
                 $this->content->text .= '</tbody></table>';
             }
             break;
     }
     return $this->content;
 }
Example #24
0
/**
 * Print the status bar
 *
 * @param object $quiz The quiz object of the quiz in question
 */
function quiz_print_status_bar($quiz) {
    global $CFG;

    $bits = array();

    $bits[] = html_writer::tag('span',
            get_string('totalmarksx', 'quiz', quiz_format_grade($quiz, $quiz->sumgrades)),
            array('class' => 'totalpoints'));

    $bits[] = html_writer::tag('span',
            get_string('numquestionsx', 'quiz', quiz_number_of_questions_in_quiz($quiz->questions)),
            array('class' => 'numberofquestions'));

    $timenow = time();

    // Exact open and close dates for the tool-tip.
    $dates = array();
    if ($quiz->timeopen > 0) {
        if ($timenow > $quiz->timeopen) {
            $dates[] = get_string('quizopenedon', 'quiz', userdate($quiz->timeopen));
        } else {
            $dates[] = get_string('quizwillopen', 'quiz', userdate($quiz->timeopen));
        }
    }
    if ($quiz->timeclose > 0) {
        if ($timenow > $quiz->timeclose) {
            $dates[] = get_string('quizclosed', 'quiz', userdate($quiz->timeclose));
        } else {
            $dates[] = get_string('quizcloseson', 'quiz', userdate($quiz->timeclose));
        }
    }
    if (empty($dates)) {
        $dates[] = get_string('alwaysavailable', 'quiz');
    }
    $tooltip = implode(', ', $dates);;

    // Brief summary on the page.
    if ($timenow < $quiz->timeopen) {
        $currentstatus = get_string('quizisclosedwillopen', 'quiz',
                userdate($quiz->timeopen, get_string('strftimedatetimeshort', 'langconfig')));
    } else if ($quiz->timeclose && $timenow <= $quiz->timeclose) {
        $currentstatus = get_string('quizisopenwillclose', 'quiz',
                userdate($quiz->timeclose, get_string('strftimedatetimeshort', 'langconfig')));
    } else if ($quiz->timeclose && $timenow > $quiz->timeclose) {
        $currentstatus = get_string('quizisclosed', 'quiz');
    } else {
        $currentstatus = get_string('quizisopen', 'quiz');
    }

    $bits[] = html_writer::tag('span', $currentstatus,
            array('class' => 'quizopeningstatus', 'title' => implode(', ', $dates)));

    echo html_writer::tag('div', implode(' | ', $bits), array('class' => 'statusbar'));
}
Example #25
0
    if (quiz_has_grades($quiz)) {
        if ($overtime) {
            $result->sumgrades = "0";
            $result->grade = "0.0";
        }
        /// Show raw marks only if they are different from the grade (like on the view page.
        if ($quiz->grade != $quiz->sumgrades) {
            $a = new stdClass();
            $a->grade = quiz_format_grade($quiz, $attempt->sumgrades);
            $a->maxgrade = quiz_format_grade($quiz, $quiz->sumgrades);
            $rows[] = '<tr><th scope="row" class="cell">' . get_string('marks', 'quiz') . '</th><td class="cell">' . get_string('outofshort', 'quiz', $a) . '</td></tr>';
        }
        /// Now the scaled grade.
        $a = new stdClass();
        $a->grade = '<b>' . quiz_format_grade($quiz, $grade) . '</b>';
        $a->maxgrade = quiz_format_grade($quiz, $quiz->grade);
        $a->percent = '<b>' . round($attempt->sumgrades / $quiz->sumgrades * 100, 0) . '</b>';
        $rows[] = '<tr><th scope="row" class="cell">' . get_string('grade') . '</th><td class="cell">' . get_string('outofpercent', 'quiz', $a) . '</td></tr>';
    }
}
/// Feedback if there is any, and the user is allowed to see it now.
$feedback = $attemptobj->get_overall_feedback($grade);
if ($options->overallfeedback && $feedback) {
    $rows[] = '<tr><th scope="row" class="cell">' . get_string('feedback', 'quiz') . '</th><td class="cell">' . $feedback . '</td></tr>';
}
/// Now output the summary table, if there are any rows to be shown.
if (!empty($rows)) {
    echo '<table class="generaltable generalbox quizreviewsummary"><tbody>', "\n";
    echo implode("\n", $rows);
    echo "\n</tbody></table>\n";
}
Example #26
0
 /**
  * Get the bands labels.
  *
  * @param int $bands The number of bands.
  * @param int $bandwidth The band width.
  * @param object $quiz The quiz object.
  * @return string[] The labels.
  */
 public static function get_bands_labels($bands, $bandwidth, $quiz) {
     $bandlabels = [];
     for ($i = 1; $i <= $bands; $i++) {
         $bandlabels[] = quiz_format_grade($quiz, ($i - 1) * $bandwidth) . ' - ' . quiz_format_grade($quiz, $i * $bandwidth);
     }
     return $bandlabels;
 }
/**
 * Format a number as a percentage out of $quiz->sumgrades
 * @param number $rawgrade the mark to format.
 * @param object $quiz the quiz settings
 * @param bool $round whether to round the results ot $quiz->decimalpoints.
 */
function quiz_report_scale_summarks_as_percentage($rawmark, $quiz, $round = true)
{
    if ($quiz->sumgrades == 0) {
        return '';
    }
    if (!is_numeric($rawmark)) {
        return $rawmark;
    }
    $mark = $rawmark * 100 / $quiz->sumgrades;
    if ($round) {
        $mark = quiz_format_grade($quiz, $mark);
    }
    return $mark . '%';
}
Example #28
0
                        $json = array();
                        foreach ($slots as $slot) {
                            $json[$slot->slot] = array('id' => $slot->id, 'slot' => $slot->slot,
                                                            'page' => $slot->page);
                        }
                        echo json_encode(array('slots' => $json));
                        break;
                }
                break;

            case 'course':
                break;
        }
        break;

    case 'DELETE':
        switch ($class) {
            case 'resource':
                require_capability('mod/quiz:manage', $modcontext);
                if (!$slot = $DB->get_record('quiz_slots', array('quizid' => $quiz->id, 'id' => $id))) {
                    throw new moodle_exception('AJAX commands.php: Bad slot ID '.$id);
                }
                $structure->remove_slot($quiz, $slot->slot);
                quiz_delete_previews($quiz);
                quiz_update_sumgrades($quiz);
                echo json_encode(array('newsummarks' => quiz_format_grade($quiz, $quiz->sumgrades)));
                break;
        }
        break;
}
Example #29
0
    /**
     * Generates data pertaining to quiz results
     *
     * @param array $quiz Array containing quiz data
     * @param int $context The page context ID
     * @param int $cm The Course Module Id
     * @param mod_quiz_view_object $viewobj
     */
    public function view_result_info($quiz, $context, $cm, $viewobj) {
        $output = '';
        if (!$viewobj->numattempts && !$viewobj->gradecolumn && is_null($viewobj->mygrade)) {
            return $output;
        }
        $resultinfo = '';

        if ($viewobj->overallstats) {
            if ($viewobj->moreattempts) {
                $a = new stdClass();
                $a->method = quiz_get_grading_option_name($quiz->grademethod);
                $a->mygrade = quiz_format_grade($quiz, $viewobj->mygrade);
                $a->quizgrade = quiz_format_grade($quiz, $quiz->grade);
                $resultinfo .= $this->heading(get_string('gradesofar', 'quiz', $a), 2, 'main');
            } else {
                $a = new stdClass();
                $a->grade = quiz_format_grade($quiz, $viewobj->mygrade);
                $a->maxgrade = quiz_format_grade($quiz, $quiz->grade);
                $a = get_string('outofshort', 'quiz', $a);
                $resultinfo .= $this->heading(get_string('yourfinalgradeis', 'quiz', $a), 2,
                        'main');
            }
        }

        if ($viewobj->mygradeoverridden) {

            $resultinfo .= html_writer::tag('p', get_string('overriddennotice', 'grades'),
                    array('class' => 'overriddennotice'))."\n";
        }
        if ($viewobj->gradebookfeedback) {
            $resultinfo .= $this->heading(get_string('comment', 'quiz'), 3, 'main');
            $resultinfo .= '<p class="quizteacherfeedback">'.$viewobj->gradebookfeedback.
                    "</p>\n";
        }
        if ($viewobj->feedbackcolumn) {
            $resultinfo .= $this->heading(get_string('overallfeedback', 'quiz'), 3, 'main');
            $resultinfo .= html_writer::tag('p',
                    quiz_feedback_for_grade($viewobj->mygrade, $quiz, $context),
                    array('class' => 'quizgradefeedback'))."\n";
        }

        if ($resultinfo) {
            $output .= $this->box($resultinfo, 'generalbox', 'feedback');
        }
        return $output;
    }
Example #30
0
 function output_quiz_info_table($course, $cm, $quiz, $quizstats, $usingattemptsstring, $currentgroup, $groupstudents, $useallattempts, $download, $reporturl, $everything)
 {
     global $DB, $OUTPUT;
     // Print information on the number of existing attempts
     $quizinformationtablehtml = $OUTPUT->heading(get_string('quizinformation', 'quiz_statistics'), 2, 'main');
     $quizinformationtable = new html_table();
     $quizinformationtable->align = array('center', 'center');
     $quizinformationtable->width = '60%';
     $quizinformationtable->class = 'generaltable titlesleft';
     $quizinformationtable->data = array();
     $quizinformationtable->data[] = array(get_string('quizname', 'quiz_statistics'), $quiz->name);
     $quizinformationtable->data[] = array(get_string('coursename', 'quiz_statistics'), $course->fullname);
     if ($cm->idnumber) {
         $quizinformationtable->data[] = array(get_string('idnumbermod'), $cm->idnumber);
     }
     if ($quiz->timeopen) {
         $quizinformationtable->data[] = array(get_string('quizopen', 'quiz'), userdate($quiz->timeopen));
     }
     if ($quiz->timeclose) {
         $quizinformationtable->data[] = array(get_string('quizclose', 'quiz'), userdate($quiz->timeclose));
     }
     if ($quiz->timeopen && $quiz->timeclose) {
         $quizinformationtable->data[] = array(get_string('duration', 'quiz_statistics'), format_time($quiz->timeclose - $quiz->timeopen));
     }
     $format = array('firstattemptscount' => '', 'allattemptscount' => '', 'firstattemptsavg' => 'sumgrades_as_percentage', 'allattemptsavg' => 'sumgrades_as_percentage', 'median' => 'sumgrades_as_percentage', 'standarddeviation' => 'sumgrades_as_percentage', 'skewness' => '', 'kurtosis' => '', 'cic' => 'number_format', 'errorratio' => 'number_format', 'standarderror' => 'sumgrades_as_percentage');
     foreach ($quizstats as $property => $value) {
         if (!isset($format[$property])) {
             continue;
         }
         if (!is_null($value)) {
             switch ($format[$property]) {
                 case 'sumgrades_as_percentage':
                     $formattedvalue = quiz_report_scale_sumgrades_as_percentage($value, $quiz);
                     break;
                 case 'number_format':
                     $formattedvalue = quiz_format_grade($quiz, $value) . '%';
                     break;
                 default:
                     $formattedvalue = $value;
             }
             $quizinformationtable->data[] = array(get_string($property, 'quiz_statistics', $usingattemptsstring), $formattedvalue);
         }
     }
     if (!$this->table->is_downloading()) {
         if (isset($quizstats->timemodified)) {
             list($fromqa, $whereqa, $qaparams) = quiz_report_attempts_sql($quiz->id, $currentgroup, $groupstudents, $useallattempts);
             $sql = 'SELECT COUNT(1) ' . 'FROM ' . $fromqa . ' ' . 'WHERE ' . $whereqa . ' AND qa.timefinish > :time';
             $a = new object();
             $a->lastcalculated = format_time(time() - $quizstats->timemodified);
             if (!($a->count = $DB->count_records_sql($sql, array('time' => $quizstats->timemodified) + $qaparams))) {
                 $a->count = 0;
             }
             $quizinformationtablehtml .= $OUTPUT->box_start('boxaligncenter generalbox boxwidthnormal mdl-align');
             $quizinformationtablehtml .= get_string('lastcalculated', 'quiz_statistics', $a);
             $quizinformationtablehtml .= $OUTPUT->button(html_form::make_button($reporturl->out(true), $reporturl->params() + array('recalculate' => 1), get_string('recalculatenow', 'quiz_statistics')));
             $quizinformationtablehtml .= $OUTPUT->box_end();
         }
         $downloadoptions = $this->table->get_download_menu();
         $quizinformationtablehtml .= '<form action="' . $this->table->baseurl . '" method="post">';
         $quizinformationtablehtml .= '<div class="mdl-align">';
         $quizinformationtablehtml .= '<input type="hidden" name="everything" value="1"/>';
         $quizinformationtablehtml .= '<input type="submit" value="' . get_string('downloadeverything', 'quiz_statistics') . '"/>';
         $select = html_select::make($downloadoptions, 'download', $this->table->defaultdownloadformat, false);
         $select->nothingvalue = '';
         $quizinformationtablehtml .= $OUTPUT->select($select);
         $quizinformationtablehtml .= $OUTPUT->help_icon(moodle_help_icon::make('tableexportformats', get_string('tableexportformats', 'table')));
         $quizinformationtablehtml .= '</div></form>';
     }
     $quizinformationtablehtml .= $OUTPUT->table($quizinformationtable);
     if (!$this->table->is_downloading()) {
         echo $quizinformationtablehtml;
     } elseif ($everything) {
         $exportclass =& $this->table->export_class_instance();
         if ($download == 'xhtml') {
             echo $quizinformationtablehtml;
         } else {
             $exportclass->start_table(get_string('quizinformation', 'quiz_statistics'));
             $headers = array();
             $row = array();
             foreach ($quizinformationtable->data as $data) {
                 $headers[] = $data[0];
                 $row[] = $data[1];
             }
             $exportclass->output_headers($headers);
             $exportclass->add_data($row);
             $exportclass->finish_table();
         }
     }
 }