public function finishAttempt($quizAttemptId) { $qsessarr = entries_sql('SELECT * FROM question_session WHERE quizAttemptId=:quizAttemptId', array('quizAttemptId' => $quizAttemptId)); $maxGrade = 0; $gotGrade = 0; foreach ($qsessarr as $qsess) { $q = entry_sql('SELECT * FROM question WHERE questionId=:questionId', array('questionId' => $qsess['questionId'])); $maxGrade += $q['maxGrade']; $gotGrade += $qsess['grade']; } $attemptCoef = empty($maxGrade) ? 1 : $gotGrade / $maxGrade; return entry_change('quiz_attempt', array('status' => STATUS_COMPLETE, 'grade' => $attemptCoef, 'timeChange' => date('Y-m-d H:i:s'), 'timeFinish' => date('Y-m-d H:i:s')), array('quizAttemptId' => $quizAttemptId)); }
<?php trigger_reg('material.graded', function ($codeOrName, $id, $studentId) { global $CFG; $code = is_numeric($codeOrName) ? $codeOrName : array_search($codeOrName, $CFG->material); if (!is_numeric($code)) { throw new Exception('Cannot detect meterial type of "' . $codeOrName . '"', 500); } $updisciplines = entries_sql('SELECT ud.*,e.groupPeriodId,e.learningMode FROM event e, updiscipline ud, group_period gp, group_history gh WHERE e.updisciplineId=ud.updisciplineId AND ud.upId=gp.upId AND gp.groupPeriodId=gh.groupPeriodId AND e.instanceType=:type AND e.instanceId=:id AND gh.studentId=:studentId', array('type' => $code, 'id' => $id, 'studentId' => $studentId)); foreach ($updisciplines as $upd) { $events = entries_sql('SELECT * FROM event WHERE updisciplineId=:updisciplineId AND groupPeriodId=:groupPeriodId AND learningMode=:learningMode', array('groupPeriodId' => $upd['groupPeriodId'], 'updisciplineId' => $upd['updisciplineId'], 'learningMode' => $upd['learningMode'])); $result = array_reduce($events, function ($r, $e) { $r['sum'] += $e['weight']; $r['got'] += $e['weight'] * val(material::i($e['instanceType'])->get_grade($e['instanceId'], $r['studentId']), 'coef', 0); return $r; }, array('studentId' => $studentId, 'sum' => 0, 'got' => 0)); if (empty($result['sum'])) { continue; } entry_change('result', array('grade' => $result['got'] / $result['sum'] * 100), array('studentId' => $studentId, 'updisciplineId' => $upd['updisciplineId'], 'learningMode' => $upd['learningMode'])); } });
public function attempt() { if (!env('student')) { redirect('m=login'); } $quizId = val($_REQUEST, 'id', -1); $attemptId = val($_REQUEST, 'attemptId', -1); $page = val($_REQUEST, 'page', 1); $complete = val($_REQUEST, 'complete'); $pro = val($_REQUEST, 'pro'); if (!empty($pro)) { env('modepro', true); } $now = date('Y-m-d H:i:s'); if (val(env('event'), 'instanceId') != $quizId) { throw new Exception('Cannot fetch event', 404); } $quiz = entry_sql('SELECT * FROM quiz WHERE quizId=:quizId', array('quizId' => $quizId)); if (empty($quiz)) { throw new Exception('Cannot find quiz "' . $id . '"', 404); } if ($attemptId == 0) { // create new attempt $attemptId = material::i('quiz')->startAttempt($quiz); redirect('c=quiz&m=attempt&id=' . $quizId . '&attemptId=' . $attemptId); } $attempt = entry_sql('SELECT * FROM quiz_attempt WHERE quizAttemptId=:quizAttemptId AND quizId=:quizId AND studentId=:studentId', array('quizAttemptId' => $attemptId, 'quizId' => $quizId, 'studentId' => studentId())); if (empty($attempt)) { throw new Exception('Attempt "' . $attemptId . '" not found', 404); } if ($attempt['status'] != STATUS_INPROC) { throw new Exception('Attempt is not available anymore', 403); } if (!empty($quiz['timeLimit']) && date('Y-m-d H:i:s', strtotime($attempt['timeStart']) + $quiz['timeLimit']) < $now) { // if time expired material::i('quiz')->finishAttempt($attemptId); redirect('c=quiz&id=' . $quiz['quizId'] . '&eventId=' . val(env('event'), 'eventId')); } $questions = entries_sql('SELECT * FROM question_session WHERE quizAttemptId=:quizAttemptId ORDER BY num', array('quizAttemptId' => $attemptId)); $perpage = 1; $numl = $page * $perpage; $numf = $numl - $perpage; $qresponses = val($_REQUEST, 'question', array()); foreach ($questions as &$qsess) { $qobj = question::i($qsess['questionId']); $qresponse = val($qresponses, $qsess['questionId']); if (!empty($qresponse)) { $qgrade = $qobj->get_grade($qresponse); $qsess['grade'] = $qobj->get_grade($qresponse); $qsess['response'] = json_encode($qresponse); $qsess['status'] = STATUS_ANSWER; entry_change('question_session', $qsess, array('questionSessionId' => $qsess['questionSessionId'])); entry_change('quiz_attempt', array('timeChange' => date('Y-m-d H:i:s')), array('quizAttemptId' => $attemptId)); } if ($qsess['num'] > $numf && $qsess['num'] <= $numl) { // render only questions of the page $qsess['qhtml'] = $qobj->render(json_decode($qsess['response'])); } $qsess['page'] = ceil($qsess['num'] / $perpage); } env('breadcrumbs', array_merge($this->_up_breadcrumbs(env('event')), array(lng('quiz:attempt')))); if (!empty($complete)) { material::i('quiz')->finishAttempt($attemptId); trigger_exe('material.graded', array('quiz', $quizId, studentId())); redirect('c=quiz&id=' . $quiz['quizId'] . '&eventId=' . val(env('event'), 'eventId')); } tpl('quiz/attempt', array('page' => $page, 'quiz' => $quiz, 'attempt' => $attempt, 'questions' => $questions)); }