Esempio n. 1
0
 public function update_user_preferences()
 {
     parent::update_user_preferences();
     if (quiz_has_grades($this->quiz)) {
         set_user_preference('quiz_overview_slotmarks', $this->slotmarks);
     }
 }
Esempio n. 2
0
 protected function other_preference_fields(MoodleQuickForm $mform) {
     if (quiz_has_grades($this->_customdata['quiz'])) {
         $mform->addElement('selectyesno', 'slotmarks',
                 get_string('showdetailedmarks', 'quiz_overview'));
     } else {
         $mform->addElement('hidden', 'slotmarks', 0);
     }
 }
 public function test_quiz_has_grades()
 {
     $quiz = new stdClass();
     $quiz->grade = '100.0000';
     $quiz->sumgrades = '100.0000';
     $this->assertTrue(quiz_has_grades($quiz));
     $quiz->sumgrades = '0.0000';
     $this->assertFalse(quiz_has_grades($quiz));
     $quiz->grade = '0.0000';
     $this->assertFalse(quiz_has_grades($quiz));
     $quiz->sumgrades = '100.0000';
     $this->assertFalse(quiz_has_grades($quiz));
 }
 /**
  * Should the grades be displayed in this report. That depends on the quiz
  * display options, and whether the quiz is graded.
  * @param object $quiz the quiz settings.
  * @return bool
  */
 protected function should_show_grades($quiz)
 {
     if (!is_null($this->showgrades)) {
         return $this->showgrades;
     }
     if ($quiz->timeclose && time() > $quiz->timeclose) {
         $when = mod_quiz_display_options::AFTER_CLOSE;
     } else {
         $when = mod_quiz_display_options::LATER_WHILE_OPEN;
     }
     $reviewoptions = mod_quiz_display_options::make_from_quiz($quiz, $when);
     $this->showgrades = quiz_has_grades($quiz) && ($reviewoptions->marks >= question_display_options::MARK_AND_MAX || has_capability('moodle/grade:viewhidden', $this->context));
     return $this->showgrades;
 }
Esempio n. 5
0
 * Create view object for use within renderers file
 */
$viewobj = new mod_quiz_view_object();
$viewobj->attempts = $attempts;
$viewobj->accessmanager = $accessmanager;
$viewobj->canreviewmine = $canreviewmine;

// Print table with existing attempts
if ($attempts) {
    // Work out which columns we need, taking account what data is available in each attempt.
    list($someoptions, $alloptions) = quiz_get_combined_reviewoptions($quiz, $attempts, $context);

    $viewobj->attemptcolumn = $quiz->attempts != 1;

    $viewobj->gradecolumn = $someoptions->marks >= question_display_options::MARK_AND_MAX &&
            quiz_has_grades($quiz);
    $viewobj->markcolumn = $viewobj->gradecolumn && ($quiz->grade != $quiz->sumgrades);
    $viewobj->overallstats = $lastfinishedattempt && $alloptions->marks >= question_display_options::MARK_AND_MAX;

    $viewobj->feedbackcolumn = quiz_has_feedback($quiz) && $alloptions->overallfeedback;
} else {
    $viewobj->attemptcolumn = 1;
}

$viewobj->timenow = $timenow;
$viewobj->numattempts = $numattempts;
$viewobj->mygrade = $mygrade;
$viewobj->moreattempts = $unfinished ||
        !$accessmanager->is_finished($numattempts, $lastfinishedattempt);
$viewobj->mygradeoverridden = $mygradeoverridden;
$viewobj->gradebookfeedback = $gradebookfeedback;
Esempio n. 6
0
        }
        if (!empty($grade->str_feedback)) {
            $gradebookfeedback = $grade->str_feedback;
        }
    }
}
$title = $course->shortname . ': ' . format_string($quiz->name);
$PAGE->set_title($title);
$PAGE->set_heading($course->fullname);
$output = $PAGE->get_renderer('mod_quiz');
// Print table with existing attempts.
if ($attempts) {
    // Work out which columns we need, taking account what data is available in each attempt.
    list($someoptions, $alloptions) = quiz_get_combined_reviewoptions($quiz, $attempts, $context);
    $viewobj->attemptcolumn = $quiz->attempts != 1;
    $viewobj->gradecolumn = $someoptions->marks >= question_display_options::MARK_AND_MAX && quiz_has_grades($quiz);
    $viewobj->markcolumn = $viewobj->gradecolumn && $quiz->grade != $quiz->sumgrades;
    $viewobj->overallstats = $lastfinishedattempt && $alloptions->marks >= question_display_options::MARK_AND_MAX;
    $viewobj->feedbackcolumn = quiz_has_feedback($quiz) && $alloptions->overallfeedback;
}
$viewobj->timenow = $timenow;
$viewobj->numattempts = $numattempts;
$viewobj->mygrade = $mygrade;
$viewobj->moreattempts = $unfinished || !$accessmanager->is_finished($numattempts, $lastfinishedattempt);
$viewobj->mygradeoverridden = $mygradeoverridden;
$viewobj->gradebookfeedback = $gradebookfeedback;
$viewobj->lastfinishedattempt = $lastfinishedattempt;
$viewobj->canedit = has_capability('mod/quiz:manage', $context);
$viewobj->editurl = new moodle_url('/mod/quiz/edit.php', array('cmid' => $cm->id));
$viewobj->backtocourseurl = new moodle_url('/course/view.php', array('id' => $course->id));
$viewobj->startattempturl = $quizobj->start_attempt_url();
Esempio n. 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;
 }
Esempio n. 8
0
        $rows[] = '<tr><th scope="row" class="cell">' . get_string('attempts', 'quiz') . '</th><td class="cell">' . $attemptlist . '</td></tr>';
    }
}
/// Timing information.
$rows[] = '<tr><th scope="row" class="cell">' . get_string('startedon', 'quiz') . '</th><td class="cell">' . userdate($attempt->timestart) . '</td></tr>';
if ($attempt->timefinish) {
    $rows[] = '<tr><th scope="row" class="cell">' . get_string('completedon', 'quiz') . '</th><td class="cell">' . userdate($attempt->timefinish) . '</td></tr>';
    $rows[] = '<tr><th scope="row" class="cell">' . get_string('timetaken', 'quiz') . '</th><td class="cell">' . $timetaken . '</td></tr>';
}
if (!empty($overtime)) {
    $rows[] = '<tr><th scope="row" class="cell">' . get_string('overdue', 'quiz') . '</th><td class="cell">' . $overtime . '</td></tr>';
}
/// Show scores (if the user is allowed to see scores at the moment).
$grade = quiz_rescale_grade($attempt->sumgrades, $quiz, false);
if ($options->scores) {
    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);
Esempio n. 9
0
            $mygrade = $grade->grade + 0;
            // Convert to number.
            $mygradeoverridden = true;
        }
        if (!empty($grade->str_feedback)) {
            $gradebookfeedback = $grade->str_feedback;
        }
    }
}
/// Print table with existing attempts
if ($attempts) {
    echo $OUTPUT->heading(get_string('summaryofattempts', 'quiz'));
    // Work out which columns we need, taking account what data is available in each attempt.
    list($someoptions, $alloptions) = quiz_get_combined_reviewoptions($quiz, $attempts, $context);
    $attemptcolumn = $quiz->attempts != 1;
    $gradecolumn = $someoptions->scores && quiz_has_grades($quiz);
    $markcolumn = $gradecolumn && $quiz->grade != $quiz->sumgrades;
    $overallstats = $alloptions->scores;
    $feedbackcolumn = quiz_has_feedback($quiz) && $alloptions->overallfeedback;
    // Prepare table header
    $table = new html_table();
    $table->class = 'generaltable quizattemptsummary';
    $table->head = array();
    $table->align = array();
    $table->size = array();
    if ($attemptcolumn) {
        $table->head[] = get_string('attempt', 'quiz');
        $table->align[] = 'center';
        $table->size[] = '';
    }
    $table->head[] = get_string('timecompleted', 'quiz');
Esempio n. 10
0
/**
 * @param object $quiz the quiz database row.
 * @return bool Whether this quiz has any non-blank feedback text.
 */
function quiz_has_feedback($quiz) {
    global $DB;
    static $cache = array();
    if (!array_key_exists($quiz->id, $cache)) {
        $cache[$quiz->id] = quiz_has_grades($quiz) &&
                $DB->record_exists_select('quiz_feedback', "quizid = ? AND " .
                    $DB->sql_isnotempty('quiz_feedback', 'feedbacktext', false, true),
                array($quiz->id));
    }
    return $cache[$quiz->id];
}
Esempio n. 11
0
        $summarydata['attemptlist'] = array('title' => get_string('attempts', 'quiz'), 'content' => $attemptlist);
    }
}
// Timing information.
$summarydata['startedon'] = array('title' => get_string('startedon', 'quiz'), 'content' => userdate($attempt->timestart));
$summarydata['state'] = array('title' => get_string('attemptstate', 'quiz'), 'content' => quiz_attempt::state_name($attempt->state));
if ($attempt->state == quiz_attempt::FINISHED) {
    $summarydata['completedon'] = array('title' => get_string('completedon', 'quiz'), 'content' => userdate($attempt->timefinish));
    $summarydata['timetaken'] = array('title' => get_string('timetaken', 'quiz'), 'content' => $timetaken);
}
if (!empty($overtime)) {
    $summarydata['overdue'] = array('title' => get_string('overdue', 'quiz'), 'content' => $overtime);
}
// Show marks (if the user is allowed to see marks at the moment).
$grade = quiz_rescale_grade($attempt->sumgrades, $quiz, false);
if ($options->marks >= question_display_options::MARK_AND_MAX && quiz_has_grades($quiz)) {
    if ($attempt->state != quiz_attempt::FINISHED) {
        // Cannot display grade.
    } else {
        if (is_null($grade)) {
            $summarydata['grade'] = array('title' => get_string('grade', 'quiz'), 'content' => quiz_format_grade($quiz, $grade));
        } else {
            // 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);
                $summarydata['marks'] = array('title' => get_string('marks', 'quiz'), 'content' => get_string('outofshort', 'quiz', $a));
            }
            // Now the scaled grade.
            $a = new stdClass();
/**
 * Should the grades be displayed in this report. That depends on the quiz
 * display options, and whether the quiz is graded.
 * @param object $quiz the quiz settings.
 * @param context $context the quiz context.
 * @return bool
 */
function quiz_report_should_show_grades($quiz, context $context)
{
    if ($quiz->timeclose && time() > $quiz->timeclose) {
        $when = mod_quiz_display_options::AFTER_CLOSE;
    } else {
        $when = mod_quiz_display_options::LATER_WHILE_OPEN;
    }
    $reviewoptions = mod_quiz_display_options::make_from_quiz($quiz, $when);
    return quiz_has_grades($quiz) && ($reviewoptions->marks >= question_display_options::MARK_AND_MAX || has_capability('moodle/grade:viewhidden', $context));
}
Esempio n. 13
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;
    }
}
Esempio n. 14
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;
    }
Esempio n. 15
0
function quiz_user_complete($course, $user, $mod, $quiz)
{
    global $DB;
    /// Print a detailed representation of what a  user has done with
    /// a given particular instance of this module, for user activity reports.
    if ($attempts = $DB->get_records('quiz_attempts', array('userid' => $user->id, 'quiz' => $quiz->id), 'attempt')) {
        if (quiz_has_grades($quiz) && ($grade = quiz_get_best_grade($quiz, $user->id))) {
            echo get_string('grade') . ': ' . $grade . '/' . quiz_format_grade($quiz, $quiz->grade) . '<br />';
        }
        foreach ($attempts as $attempt) {
            echo get_string('attempt', 'quiz') . ' ' . $attempt->attempt . ': ';
            if ($attempt->timefinish == 0) {
                print_string('unfinished');
            } else {
                echo quiz_format_grade($quiz, $attempt->sumgrades) . '/' . quiz_format_grade($quiz, $quiz->sumgrades);
            }
            echo ' - ' . userdate($attempt->timemodified) . '<br />';
        }
    } else {
        print_string('noattempts', 'quiz');
    }
    return true;
}
Esempio n. 16
0
/**
 * Print a detailed representation of what a  user has done with
 * a given particular instance of this module, for user activity reports.
 *
 * @global object
 * @param object $course
 * @param object $user
 * @param object $mod
 * @param object $quiz
 * @return bool
 */
function quiz_user_complete($course, $user, $mod, $quiz)
{
    global $DB;
    if ($attempts = $DB->get_records('quiz_attempts', array('userid' => $user->id, 'quiz' => $quiz->id), 'attempt')) {
        if (quiz_has_grades($quiz) && ($grade = quiz_get_best_grade($quiz, $user->id))) {
            echo get_string('grade') . ': ' . $grade . '/' . quiz_format_grade($quiz, $quiz->grade) . '<br />';
        }
        foreach ($attempts as $attempt) {
            echo get_string('attempt', 'quiz') . ' ' . $attempt->attempt . ': ';
            if ($attempt->timefinish == 0) {
                print_string('unfinished');
            } else {
                echo quiz_format_grade($quiz, $attempt->sumgrades) . '/' . quiz_format_grade($quiz, $quiz->sumgrades);
            }
            echo ' - ' . userdate($attempt->timemodified) . '<br />';
        }
    } else {
        print_string('noattempts', 'quiz');
    }
    return true;
}