private static function accessmanager_process($quizobj, $accessmanager, $forcenew, $uid) { self::new_preview_request($quizobj, $accessmanager, $forcenew, $uid); // Look for an existing attempt. $attempts = quiz_get_user_attempts($quizobj->get_quizid(), $uid, 'all', true); $lastattempt = end($attempts); // Get number for the next or unfinished attempt. if ($lastattempt && !$lastattempt->preview && !$quizobj->is_preview_user()) { $attemptnumber = $lastattempt->attempt + 1; } else { $lastattempt = false; $attemptnumber = 1; } $currentattemptid = null; $accessmanager->notify_preflight_check_passed($currentattemptid); // Delete any previous preview attempts belonging to this user. quiz_delete_previews($quizobj->get_quiz(), $uid); $res = new stdClass(); $res->lastattempt = $lastattempt; $res->attemptnumber = $attemptnumber; return $res; }
/** * Validate permissions for creating a new attempt and start a new preview attempt if required. * * @param quiz $quizobj quiz object * @param quiz_access_manager $accessmanager quiz access manager * @param bool $forcenew whether was required to start a new preview attempt * @param int $page page to jump to in the attempt * @param bool $redirect whether to redirect or throw exceptions (for web or ws usage) * @return array an array containing the attempt information, access error messages and the page to jump to in the attempt * @throws moodle_quiz_exception * @since Moodle 3.1 */ function quiz_validate_new_attempt(quiz $quizobj, quiz_access_manager $accessmanager, $forcenew, $page, $redirect) { global $DB, $USER; $timenow = time(); if ($quizobj->is_preview_user() && $forcenew) { $accessmanager->current_attempt_finished(); } // Check capabilities. if (!$quizobj->is_preview_user()) { $quizobj->require_capability('mod/quiz:attempt'); } // Check to see if a new preview was requested. if ($quizobj->is_preview_user() && $forcenew) { // To force the creation of a new preview, we mark the current attempt (if any) // as finished. It will then automatically be deleted below. $DB->set_field('quiz_attempts', 'state', quiz_attempt::FINISHED, array('quiz' => $quizobj->get_quizid(), 'userid' => $USER->id)); } // Look for an existing attempt. $attempts = quiz_get_user_attempts($quizobj->get_quizid(), $USER->id, 'all', true); $lastattempt = end($attempts); $attemptnumber = null; // If an in-progress attempt exists, check password then redirect to it. if ($lastattempt && ($lastattempt->state == quiz_attempt::IN_PROGRESS || $lastattempt->state == quiz_attempt::OVERDUE)) { $currentattemptid = $lastattempt->id; $messages = $accessmanager->prevent_access(); // If the attempt is now overdue, deal with that. $quizobj->create_attempt_object($lastattempt)->handle_if_time_expired($timenow, true); // And, if the attempt is now no longer in progress, redirect to the appropriate place. if ($lastattempt->state == quiz_attempt::ABANDONED || $lastattempt->state == quiz_attempt::FINISHED) { if ($redirect) { redirect($quizobj->review_url($lastattempt->id)); } else { throw new moodle_quiz_exception($quizobj, 'attemptalreadyclosed'); } } // If the page number was not explicitly in the URL, go to the current page. if ($page == -1) { $page = $lastattempt->currentpage; } } else { while ($lastattempt && $lastattempt->preview) { $lastattempt = array_pop($attempts); } // Get number for the next or unfinished attempt. if ($lastattempt) { $attemptnumber = $lastattempt->attempt + 1; } else { $lastattempt = false; $attemptnumber = 1; } $currentattemptid = null; $messages = $accessmanager->prevent_access() + $accessmanager->prevent_new_attempt(count($attempts), $lastattempt); if ($page == -1) { $page = 0; } } return array($currentattemptid, $attemptnumber, $lastattempt, $messages, $page); }
/** * Return access information for a given attempt in a quiz. * * @param int $quizid quiz instance id * @param int $attemptid attempt id, 0 for the user last attempt if exists * @return array of warnings and the access information * @since Moodle 3.1 * @throws moodle_quiz_exception */ public static function get_attempt_access_information($quizid, $attemptid = 0) { global $DB, $USER; $warnings = array(); $params = array('quizid' => $quizid, 'attemptid' => $attemptid); $params = self::validate_parameters(self::get_attempt_access_information_parameters(), $params); list($quiz, $course, $cm, $context) = self::validate_quiz($params['quizid']); $attempttocheck = 0; if (!empty($params['attemptid'])) { $attemptobj = quiz_attempt::create($params['attemptid']); if ($attemptobj->get_userid() != $USER->id) { throw new moodle_quiz_exception($attemptobj->get_quizobj(), 'notyourattempt'); } $attempttocheck = $attemptobj->get_attempt(); } // Access manager now. $quizobj = quiz::create($cm->instance, $USER->id); $ignoretimelimits = has_capability('mod/quiz:ignoretimelimits', $context, null, false); $timenow = time(); $accessmanager = new quiz_access_manager($quizobj, $timenow, $ignoretimelimits); $attempts = quiz_get_user_attempts($quiz->id, $USER->id, 'finished', true); $lastfinishedattempt = end($attempts); if ($unfinishedattempt = quiz_get_user_attempt_unfinished($quiz->id, $USER->id)) { $attempts[] = $unfinishedattempt; // Check if the attempt is now overdue. In that case the state will change. $quizobj->create_attempt_object($unfinishedattempt)->handle_if_time_expired(time(), false); if ($unfinishedattempt->state != quiz_attempt::IN_PROGRESS and $unfinishedattempt->state != quiz_attempt::OVERDUE) { $lastfinishedattempt = $unfinishedattempt; } } $numattempts = count($attempts); if (!$attempttocheck) { $attempttocheck = $unfinishedattempt ? $unfinishedattempt : $lastfinishedattempt; } $result = array(); $result['isfinished'] = $accessmanager->is_finished($numattempts, $lastfinishedattempt); $result['preventnewattemptreasons'] = $accessmanager->prevent_new_attempt($numattempts, $lastfinishedattempt); if ($attempttocheck) { $endtime = $accessmanager->get_end_time($attempttocheck); $result['endtime'] = $endtime === false ? 0 : $endtime; $attemptid = $unfinishedattempt ? $unfinishedattempt->id : null; $result['ispreflightcheckrequired'] = $accessmanager->is_preflight_check_required($attemptid); } $result['warnings'] = $warnings; return $result; }
/** * Save the overall grade for a user at a quiz in the quiz_grades table * * @param object $quiz The quiz for which the best grade is to be calculated and then saved. * @param integer $userid The userid to calculate the grade for. Defaults to the current user. * @return boolean Indicates success or failure. */ function quiz_save_best_grade($quiz, $userid = null) { global $USER; if (empty($userid)) { $userid = $USER->id; } // Get all the attempts made by the user if (!($attempts = quiz_get_user_attempts($quiz->id, $userid))) { notify('Could not find any user attempts'); return false; } // Calculate the best grade $bestgrade = quiz_calculate_best_grade($quiz, $attempts); $bestgrade = quiz_rescale_grade($bestgrade, $quiz); // Save the best grade in the database if ($grade = get_record('quiz_grades', 'quiz', $quiz->id, 'userid', $userid)) { $grade->grade = $bestgrade; $grade->timemodified = time(); if (!update_record('quiz_grades', $grade)) { notify('Could not update best grade'); return false; } } else { $grade->quiz = $quiz->id; $grade->userid = $userid; $grade->grade = $bestgrade; $grade->timemodified = time(); if (!insert_record('quiz_grades', $grade)) { notify('Could not insert new best grade'); return false; } } quiz_update_grades($quiz, $userid); return true; }
<input type="submit" name="cancelpassword" value="<?php print_string('cancel'); ?> " /> </div> </form> <?php print_box_end(); print_footer('empty'); exit; } } } if (!empty($quiz->delay1) or !empty($quiz->delay2)) { //quiz enforced time delay if ($attempts = quiz_get_user_attempts($quiz->id, $USER->id)) { $numattempts = count($attempts); } else { $numattempts = 0; } $timenow = time(); $lastattempt_obj = get_record_select('quiz_attempts', "quiz = {$quiz->id} AND attempt = {$numattempts} AND userid = {$USER->id}", 'timefinish, timestart'); if ($lastattempt_obj) { $lastattempt = $lastattempt_obj->timefinish; if ($quiz->timelimit > 0) { $lastattempt = min($lastattempt, $lastattempt_obj->timestart + $quiz->timelimit * 60); } } if ($numattempts == 1 && !empty($quiz->delay1)) { if ($timenow - $quiz->delay1 < $lastattempt) { print_error('timedelay', 'quiz', 'view.php?q=' . $quiz->id);
$accessmanager = $quizobj->get_access_manager($timenow); if ($quizobj->is_preview_user() && $forcenew) { $accessmanager->current_attempt_finished(); } // Check capabilities. if (!$quizobj->is_preview_user()) { $quizobj->require_capability('mod/quiz:attempt'); } // Check to see if a new preview was requested. if ($quizobj->is_preview_user() && $forcenew) { // To force the creation of a new preview, we mark the current attempt (if any) // as finished. It will then automatically be deleted below. $DB->set_field('quiz_attempts', 'state', quiz_attempt::FINISHED, array('quiz' => $quizobj->get_quizid(), 'userid' => $USER->id)); } // Look for an existing attempt. $attempts = quiz_get_user_attempts($quizobj->get_quizid(), $USER->id, 'all', true); $lastattempt = end($attempts); // If an in-progress attempt exists, check password then redirect to it. if ($lastattempt && ($lastattempt->state == quiz_attempt::IN_PROGRESS || $lastattempt->state == quiz_attempt::OVERDUE)) { $currentattemptid = $lastattempt->id; $messages = $accessmanager->prevent_access(); // If the attempt is now overdue, deal with that. $quizobj->create_attempt_object($lastattempt)->handle_if_time_expired($timenow, true); // And, if the attempt is now no longer in progress, redirect to the appropriate place. if ($lastattempt->state == quiz_attempt::OVERDUE) { redirect($quizobj->summary_url($lastattempt->id)); } else { if ($lastattempt->state != quiz_attempt::IN_PROGRESS) { redirect($quizobj->review_url($lastattempt->id)); } }
$PAGE->set_heading(format_string($course->fullname)); $PAGE->set_context($context); $PAGE->set_cacheable(false); $PAGE->requires->css("/mod/studyplan/view.css"); $PAGE->add_body_class('studyplan-view'); echo $OUTPUT->header(); // Output starts here echo $OUTPUT->heading($studyplan->name); if ($studyplan->intro) { // Conditions to show the intro can change to look for own settings or whatever echo $OUTPUT->box(format_module_intro('studyplan', $studyplan, $cm->id), 'studyplan-intro', 'studyplanintro'); } if ($studyplan->standardblock) { echo '<div class="studyplan-standard">'; include dirname(__FILE__) . '/intro.php'; echo '</div>'; } $attempts = quiz_get_user_attempts($studyplan->quiz, $USER->id, 'finished', true); if (empty($attempts)) { $url = new moodle_url('/mod/quiz/view.php', array('q' => $studyplan->quiz)); $quiz_name = htmlentities(sp_get_quiz_name($studyplan->quiz)); print "<h2 class=\"studyplan-header studyplan-no-quiz\">" . get_string('youhavenotfinished', 'studyplan') . " <a href=\"{$url}\">{$quiz_name}</a>." . "</h2>"; } else { $lastfinishedattempt = end($attempts); $attemptobj = quiz_attempt::create($lastfinishedattempt->id); $questionids = sp_get_questionids_from_attempt($attemptobj); $presummary = sp_presummarize($attemptobj, $questionids, $showtabulation); echo sp_render_block($studyplan->id, $presummary, false, false, $showtabulation, "student"); } // Finish the page echo $OUTPUT->footer();
/** * Save the overall grade for a user at a quiz in the quiz_grades table * * @param object $quiz The quiz for which the best grade is to be calculated and then saved. * @param int $userid The userid to calculate the grade for. Defaults to the current user. * @param array $attempts The attempts of this user. Useful if you are * looping through many users. Attempts can be fetched in one master query to * avoid repeated querying. * @return bool Indicates success or failure. */ function quiz_save_best_grade($quiz, $userid = null, $attempts = array()) { global $DB, $OUTPUT, $USER; if (empty($userid)) { $userid = $USER->id; } if (!$attempts) { // Get all the attempts made by the user. $attempts = quiz_get_user_attempts($quiz->id, $userid); } // Calculate the best grade. $bestgrade = quiz_calculate_best_grade($quiz, $attempts); $bestgrade = quiz_rescale_grade($bestgrade, $quiz, false); // Save the best grade in the database. if (is_null($bestgrade)) { $DB->delete_records('quiz_grades', array('quiz' => $quiz->id, 'userid' => $userid)); } else if ($grade = $DB->get_record('quiz_grades', array('quiz' => $quiz->id, 'userid' => $userid))) { $grade->grade = $bestgrade; $grade->timemodified = time(); $DB->update_record('quiz_grades', $grade); } else { $grade = new stdClass(); $grade->quiz = $quiz->id; $grade->userid = $userid; $grade->grade = $bestgrade; $grade->timemodified = time(); $DB->insert_record('quiz_grades', $grade); } quiz_update_grades($quiz, $userid); }
function sp_get_activity_completed($activityid = 0) { global $DB, $COURSE, $USER, $STUDENT; $user_id = $USER->id; if (isset($STUDENT)) { $user_id = $STUDENT->id; } if ($activityid <= 0) { return false; } $cms = get_fast_modinfo($COURSE)->get_cms(); $mod = $cms[$activityid]; $completion = new completion_info($COURSE); // echo "<br />COMPLETION: " . print_r($mod->modname, true); if ($mod->modname == "quiz") { $attempts = quiz_get_user_attempts($studyplan->quiz, $user_id, 'finished', true); if (empty($attempts)) { return false; } return true; } else { #http://docs.moodle.org/dev/Course_completion & http://docs.moodle.org/dev/Activity_completion_API #lib/completionlib.php - line # 907 - get_data $comp_data = $completion->get_data($mod, false, $user_id); if (empty($comp_data)) { return false; } if ($comp_data->completionstate >= COMPLETION_COMPLETE) { return true; } } return false; }
/** * @param $steps PHPUnit_Extensions_Database_DataSet_ITable the step data from the csv file. * @return array attempt no as in csv file => the id of the quiz_attempt as stored in the db. */ protected function walkthrough_attempts($steps) { global $DB; $attemptids = array(); for ($rowno = 0; $rowno < $steps->getRowCount(); $rowno++) { $step = $this->explode_dot_separated_keys_to_make_subindexs($steps->getRow($rowno)); // Find existing user or make a new user to do the quiz. $username = array('firstname' => $step['firstname'], 'lastname' => $step['lastname']); if (!($user = $DB->get_record('user', $username))) { $user = $this->getDataGenerator()->create_user($username); } if (!isset($attemptids[$step['quizattempt']])) { // Start the attempt. $quizobj = quiz::create($this->quiz->id, $user->id); $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context()); $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour); $prevattempts = quiz_get_user_attempts($this->quiz->id, $user->id, 'all', true); $attemptnumber = count($prevattempts) + 1; $timenow = time(); $attempt = quiz_create_attempt($quizobj, $attemptnumber, false, $timenow, false, $user->id); // Select variant and / or random sub question. if (!isset($step['variants'])) { $step['variants'] = array(); } if (isset($step['randqs'])) { // Replace 'names' with ids. foreach ($step['randqs'] as $slotno => $randqname) { $step['randqs'][$slotno] = $this->randqids[$slotno][$randqname]; } } else { $step['randqs'] = array(); } quiz_start_new_attempt($quizobj, $quba, $attempt, $attemptnumber, $timenow, $step['randqs'], $step['variants']); quiz_attempt_save_started($quizobj, $quba, $attempt); $attemptid = $attemptids[$step['quizattempt']] = $attempt->id; } else { $attemptid = $attemptids[$step['quizattempt']]; } // Process some responses from the student. $attemptobj = quiz_attempt::create($attemptid); $attemptobj->process_submitted_actions($timenow, false, $step['responses']); // Finish the attempt. if (!isset($step['finished']) || $step['finished'] == 1) { $attemptobj = quiz_attempt::create($attemptid); $attemptobj->process_finish($timenow, false); } } return $attemptids; }
function evaluate_quiz($acode, $jobid, $newattempt, $blended) { global $USER; global $CFG; mtrace("Evaluation QUIZ Processing..." . "<BR><BR>"); try { print "New Attempt is: " . $newattempt . "<BR/>"; $detected_userid = find_userid($acode, $jobid); if ($detected_userid == null or $detected_userid == '') { throw new EvaluationError(get_string('ErrorUserIDEmpty', 'blended'), EvaluationError::USERID_IS_EMPTY); } $user_reg = blended_get_user($detected_userid, $blended); if ($user_reg == null) { throw new EvaluationError(get_string('ErrorUserNotInCourse', 'blended'), EvaluationError::USER_NOT_IN_THIS_COURSE); } $userid = $user_reg->id; mtrace('Obtained USERID value: ' . $userid . " OK. <BR/>"); $quiz = get_quiz($acode); $attempts = quiz_get_user_attempts($quiz->id, $userid, 'all', true); mtrace("Searching quiz... Success." . "<BR/>"); $uniqueid = get_uniqueid($acode); mtrace('Obtained uniqueid: OK. <BR/>'); $timestamp = get_timestamp($acode); mtrace('Obtained timestamp: OK. <BR/>'); if (!get_record('quiz_attempts', 'uniqueid', $uniqueid)) { $newattempt = true; } else { $newattempt = false; mtrace("User {$userid} had opened this attempt already."); } $attemptnumber = 1; if ($newattempt == false) { mtrace('Obtaining user attempt...<BR/>'); set_attempt_unfinished($uniqueid); $attempt = quiz_get_user_attempt_unfinished($quiz->id, $userid); } elseif ($newattempt == true) { mtrace('Creating new attempt...<BR/>'); $attempt = create_new_attempt($quiz, $attemptnumber, $userid, $acode, $uniqueid, $timestamp); // Save the attempt if (!insert_record('quiz_attempts', $attempt)) { throw new EvaluationError(get_string('ErrorCouldNotCreateAttempt', 'blended'), EvaluationError::CREATE_QUIZ_ATTEMPT_ERROR); } // Actualizamos el estado de las imágenes para indicar que ya está creado un nuevo attempt update_images_status($acode, $jobid); } update_question_attempts($uniqueid); // /* mtrace('<BR>Getting questions and question options... '); $questions = get_questions($attempt, $quiz); if (!get_question_options($questions)) { error('Could not load question options'); } mtrace('Success! <BR>'); // print ("<BR>He obtenido questions: "); //print_object($questions); $lastattemptid = false; // if ($attempt->attempt > 1 and $quiz->attemptonlast and !$attempt->preview) { // Find the previous attempt // if (!$lastattemptid = get_field('quiz_attempts', 'uniqueid', 'quiz', $attempt->quiz, 'userid', $attempt->userid, 'attempt', $attempt->attempt-1)) { // error('Could not find previous attempt to build on'); // } //} //print ('He obtenido lastattemptid'); mtrace('Getting question states... '); if (!($states = get_question_states($questions, $quiz, $attempt, $lastattemptid))) { error('Could not restore question sessions'); } mtrace('Success! <BR>'); mtrace('Getting responses... <BR>'); $responses = get_responses($acode, $jobid, $attempt); //print('Estas son las responses:'); //print_object($responses); //$timestamp=time(); $event = 8; $actions = question_extract_responses($questions, $responses, $event); $questionids = get_questionids($acode); // print $questionids; $questionidarray = explode(',', $questionids); $success = true; mtrace('<BR> Processing responses and saving session... '); foreach ($questionidarray as $i) { if (!isset($actions[$i])) { $actions[$i]->responses = array('' => ''); $actions[$i]->event = QUESTION_EVENTOPEN; } $actions[$i]->timestamp = $timestamp; if (question_process_responses($questions[$i], $states[$i], $actions[$i], $quiz, $attempt)) { save_question_session($questions[$i], $states[$i]); } else { $success = false; } } mtrace('Success! <BR>'); // Set the attempt to be finished $timestamp = time(); //$attempt->timefinish = $timestamp; // Update the quiz attempt and the overall grade for the quiz mtrace('<BR> Finishing the attempt... '); // print_object ($attempt); if (set_field('quiz_attempts', 'timefinish', $timestamp, 'uniqueid', $uniqueid) == false) { throw new EvaluationError('Unable to finish the quiz attempt!', EvaluationError::FINISH_QUIZ_ATTEMPT_ERROR); } mtrace('Success! <BR>'); if ($attempt->attempt > 1 || $attempt->timefinish > 0 and !$attempt->preview) { mtrace('<BR> Saving quiz grade... '); quiz_save_best_grade($quiz, $userid); } mtrace('Success! <BR>'); // */ mtrace("Process Done. <BR><BR>"); mtrace("<center> Your quiz has been succesfully evaluated!! </center>"); } catch (EvaluationError $e) { throw $e; } return; }
function get_employeescore($id,$course,$userid) { $cm = get_coursemodule_from_instance("quiz", $id, $course); $quizobj = quiz::create($cm->instance, $userid); $quiz = $quizobj->get_quiz(); $viewobj = new mod_quiz_view_object(); $attempts = quiz_get_user_attempts($id, $userid, 'finished', true); $lastfinishedattempt = end($attempts); $numattempts = count($attempts); $viewobj->attempts = $attempts; $viewobj->attemptobjs = array(); foreach ($attempts as $attempt) { $viewobj->attemptobjs[] = new quiz_attempt($attempt, $quiz, $cm, $quiz->course, false); } /*Function to display attemps and grades */ $attemptgrade=''; foreach ($viewobj->attemptobjs as $attemptobj) { $attemptgrade = quiz_rescale_grade($attemptobj->get_sum_marks(), $quiz, false); } return $attemptgrade; }
function is_quiz_finished($cmid) { global $USER, $CFG; require_once $CFG->dirroot . '/mod/quiz/locallib.php'; require_once $CFG->dirroot . '/mod/quiz/lib.php'; $cm = get_coursemodule_from_id('quiz', $cmid); $quizobj = quiz::create($cm->instance, $USER->id); $attempts = quiz_get_user_attempts($quizobj->get_quizid(), $USER->id, 'all', true); foreach ($attempts as $attempt) { if ($attempt && $attempt->state == quiz_attempt::FINISHED && $attempt->sumgrades == 1) { return true; } } return false; }
/** * Save the overall grade for a user at a quiz in the quiz_grades table * * @param object $quiz The quiz for which the best grade is to be calculated and then saved. * @param integer $userid The userid to calculate the grade for. Defaults to the current user. * @param array $attempts The attempts of this user. Useful if you are * looping through many users. Attempts can be fetched in one master query to * avoid repeated querying. * @return boolean Indicates success or failure. */ function quiz_save_best_grade($quiz, $userid = null, $attempts = array()) { global $DB; global $USER, $OUTPUT; if (empty($userid)) { $userid = $USER->id; } if (!$attempts) { // Get all the attempts made by the user if (!($attempts = quiz_get_user_attempts($quiz->id, $userid))) { echo $OUTPUT->notification('Could not find any user attempts'); return false; } } // Calculate the best grade $bestgrade = quiz_calculate_best_grade($quiz, $attempts); $bestgrade = quiz_rescale_grade($bestgrade, $quiz, false); // Save the best grade in the database if ($grade = $DB->get_record('quiz_grades', array('quiz' => $quiz->id, 'userid' => $userid))) { $grade->grade = $bestgrade; $grade->timemodified = time(); $DB->update_record('quiz_grades', $grade); } else { $grade->quiz = $quiz->id; $grade->userid = $userid; $grade->grade = $bestgrade; $grade->timemodified = time(); $DB->insert_record('quiz_grades', $grade); } quiz_update_grades($quiz, $userid); return true; }
/** * @param $cm * @return bool */ function navbuttons_mod_quiz_showbuttons($cm) { global $USER, $CFG; require_once $CFG->dirroot . '/mod/quiz/locallib.php'; if (quiz_get_user_attempt_unfinished($cm->instance, $USER->id)) { return false; // Unfinished attempt in progress } if (!quiz_get_user_attempts($cm->instance, $USER->id, 'finished', true)) { return false; // No finished attempts } return true; }
/** * Obtains the automatic completion state for this quiz on any conditions * in quiz settings, such as if all attempts are used or a certain grade is achieved. * * @param object $course Course * @param object $cm Course-module * @param int $userid User ID * @param bool $type Type of comparison (or/and; can be used as return value if no conditions) * @return bool True if completed, false if not. (If no conditions, then return * value depends on comparison type) */ function quiz_get_completion_state($course, $cm, $userid, $type) { global $DB; global $CFG; $quiz = $DB->get_record('quiz', array('id' => $cm->instance), '*', MUST_EXIST); if (!$quiz->completionattemptsexhausted && !$quiz->completionpass) { return $type; } // Check if the user has used up all attempts. if ($quiz->completionattemptsexhausted) { $attempts = quiz_get_user_attempts($quiz->id, $userid, 'finished', true); if ($attempts) { $lastfinishedattempt = end($attempts); $context = context_module::instance($cm->id); $quizobj = quiz::create($quiz->id, $userid); $accessmanager = new quiz_access_manager($quizobj, time(), has_capability('mod/quiz:ignoretimelimits', $context, $userid, false)); if ($accessmanager->is_finished(count($attempts), $lastfinishedattempt)) { return true; } } } // Check for passing grade. if ($quiz->completionpass) { require_once $CFG->libdir . '/gradelib.php'; $item = grade_item::fetch(array('courseid' => $course->id, 'itemtype' => 'mod', 'itemmodule' => 'quiz', 'iteminstance' => $cm->instance, 'outcomeid' => null)); if ($item) { $grades = grade_grade::fetch_users_grades($item, array($userid), false); if (!empty($grades[$userid])) { return $grades[$userid]->is_passed($item); } } } return false; }
$users = emarking_get_enroled_students($course->id); $pbar = new progress_bar(); $pbar->create(); if ($create) { quiz_delete_all_attempts($quiz); } $cur = 1; $total = count($users); // Insert answers or finish the attempt for each student foreach ($users as $user) { $pbar->update($cur, $total, get_string('processing', 'mod_emarking') . $user->lastname . $user->firstname); flush(); // Get the quiz instance for the specific student $quizobj = quiz::create($cm->instance, $user->id); // Get all the attempts $attempts = quiz_get_user_attempts($quizobj->get_quizid(), $user->id, 'all'); if ($create) { emarking_add_user_attempt($cm, $user); } else { // For each attempt insert the answers or finish foreach ($attempts as $attempt) { if ($finish) { emarking_finish_user_attempt($attempt->id); } } } $cur++; } $pbar->update_full(100, get_string('finished', 'mod_emarking')); echo $OUTPUT->single_button(new moodle_url('/mod/emarking/orm/quizzes.php', array('course' => $cm->course)), get_string('continue')); echo $OUTPUT->footer();
/** * Prints quiz summaries on MyMoodle Page */ function quiz_print_overview($courses, &$htmlarray) { global $USER, $CFG; /// These next 6 Lines are constant in all modules (just change module name) if (empty($courses) || !is_array($courses) || count($courses) == 0) { return array(); } if (!($quizzes = get_all_instances_in_courses('quiz', $courses))) { return; } /// Fetch some language strings outside the main loop. $strquiz = get_string('modulename', 'quiz'); $strnoattempts = get_string('noattempts', 'quiz'); /// We want to list quizzes that are currently available, and which have a close date. /// This is the same as what the lesson does, and the dabate is in MDL-10568. $now = time(); foreach ($quizzes as $quiz) { if ($quiz->timeclose >= $now && $quiz->timeopen < $now) { /// Give a link to the quiz, and the deadline. $str = '<div class="quiz overview">' . '<div class="name">' . $strquiz . ': <a ' . ($quiz->visible ? '' : ' class="dimmed"') . ' href="' . $CFG->wwwroot . '/mod/quiz/view.php?id=' . $quiz->coursemodule . '">' . $quiz->name . '</a></div>'; $str .= '<div class="info">' . get_string('quizcloseson', 'quiz', userdate($quiz->timeclose)) . '</div>'; /// Now provide more information depending on the uers's role. $context = get_context_instance(CONTEXT_MODULE, $quiz->coursemodule); if (has_capability('mod/quiz:viewreports', $context)) { /// For teacher-like people, show a summary of the number of student attempts. // The $quiz objects returned by get_all_instances_in_course have the necessary $cm // fields set to make the following call work. $str .= '<div class="info">' . quiz_num_attempt_summary($quiz, $quiz, true) . '</div>'; } else { if (has_capability('mod/quiz:attempt', $context)) { // Student /// For student-like people, tell them how many attempts they have made. if (isset($USER->id) && ($attempts = quiz_get_user_attempts($quiz->id, $USER->id))) { $numattempts = count($attempts); $str .= '<div class="info">' . get_string('numattemptsmade', 'quiz', $numattempts) . '</div>'; } else { $str .= '<div class="info">' . $strnoattempts . '</div>'; } } else { /// For ayone else, there is no point listing this quiz, so stop processing. continue; } } /// Add the output for this quiz to the rest. $str .= '</div>'; if (empty($htmlarray[$quiz->course]['quiz'])) { $htmlarray[$quiz->course]['quiz'] = $str; } else { $htmlarray[$quiz->course]['quiz'] .= $str; } } } }
$quiz = $DB->get_record('quiz', array('id' => $cm->instance), '*', MUST_EXIST); require_login($course, false, $cm); $reportlist = quiz_report_list(context_module::instance($cm->id)); if (empty($reportlist) || $userid == $USER->id) { // If the user cannot see reports, or can see reports but is looking // at their own grades, redirect them to the view.php page. // (The looking at their own grades case is unlikely, since users who // appear in the gradebook are unlikely to be able to see quiz reports, // but it is possible.) redirect(new moodle_url('/mod/quiz/view.php', array('id' => $cm->id))); } // Now we know the user is interested in reports. If they are interested in a // specific other user, try to send them to the most appropriate attempt review page. if ($userid) { // Work out which attempt is most significant from a grading point of view. $attempts = quiz_get_user_attempts($quiz->id, $userid, 'finished'); $attempt = null; switch ($quiz->grademethod) { case QUIZ_ATTEMPTFIRST: $attempt = reset($attempts); break; case QUIZ_ATTEMPTLAST: case QUIZ_GRADEAVERAGE: $attempt = end($attempts); break; case QUIZ_GRADEHIGHEST: $maxmark = 0; foreach ($attempts as $at) { // Operator >=, since we want to most recent relevant attempt. if ((double) $at->sumgrades >= $maxmark) { $maxmark = $at->sumgrades;
$data[] = ''; } if ($showing == 'stats') { // The $quiz objects returned by get_all_instances_in_course have the necessary $cm // fields set to make the following call work. $attemptcount = quiz_num_attempt_summary($quiz, $quiz); if ($attemptcount) { $data[] = "<a{$class} href=\"report.php?id={$quiz->coursemodule}\">{$attemptcount}</a>"; } else { $data[] = ''; } } else { if ($showing == 'scores') { // Grade and feedback. $bestgrade = quiz_get_best_grade($quiz, $USER->id); $attempts = quiz_get_user_attempts($quiz->id, $USER->id, 'all'); list($someoptions, $alloptions) = quiz_get_combined_reviewoptions($quiz, $attempts, $context); $grade = ''; $feedback = ''; if ($quiz->grade && !is_null($bestgrade)) { if ($alloptions->scores) { $grade = "{$bestgrade} / {$quiz->grade}"; } if ($alloptions->overallfeedback) { $feedback = quiz_feedback_for_grade($bestgrade, $quiz->id); } } $data[] = $grade; $data[] = $feedback; } }
/** * Crea un archivo PDF a partir de un quiz, agregando una hoja de respuestas de opción múltiple * * @param unknown $cm * @param string $debug * @param string $context * @param string $course * @param string $logofilepath * @param boolean $answersheetsonly * @return void|NULL */ function emarking_create_quiz_pdf($cm, $debug = false, $context = null, $course = null, $answersheetsonly = false, $pbar = false) { global $DB, $CFG, $OUTPUT; // Inclusión de librerías require_once $CFG->dirroot . '/mod/assign/feedback/editpdf/fpdi/fpdi2tcpdf_bridge.php'; require_once $CFG->dirroot . '/mod/assign/feedback/editpdf/fpdi/fpdi.php'; require_once $CFG->libdir . '/pdflib.php'; require_once $CFG->dirroot . '/mod/quiz/locallib.php'; require_once $CFG->dirroot . '/mod/emarking/print/locallib.php'; $filedir = $CFG->dataroot . "/temp/emarking/{$context->id}"; emarking_initialize_directory($filedir, true); $fileimg = $CFG->dataroot . "/temp/emarking/{$context->id}/qr"; emarking_initialize_directory($fileimg, true); $userimgdir = $CFG->dataroot . "/temp/emarking/{$context->id}/u"; emarking_initialize_directory($userimgdir, true); $logofile = emarking_get_logo_file(); $logofilepath = $logofile ? emarking_get_path_from_hash($filedir, $logofile->get_pathnamehash()) : null; $fullhtml = array(); $numanswers = array(); $attemptids = array(); $images = array(); $imageshtml = array(); $users = emarking_get_enroled_students($course->id); if ($pbar) { echo $OUTPUT->heading(get_string('loadingquestions', 'mod_emarking'), 3); $progressbar = new progress_bar(); $progressbar->create(); $progressbar->update(0, count($users), get_string('processing', 'mod_emarking')); } $current = 0; foreach ($users as $user) { $current++; if ($pbar) { $progressbar->update($current, count($users), "{$user->firstname}, {$user->lastname}"); } // Get the quiz object $quizobj = quiz::create($cm->instance, $user->id); // Create the new attempt and initialize the question sessions $attemptnumber = 1; $lastattempt = null; $timenow = time(); // Update time now, in case the server is running really slowly. $attempts = quiz_get_user_attempts($quizobj->get_quizid(), $user->id, 'all'); $numattempts = count($attempts); foreach ($attempts as $attempt) { $attemptobj = quiz_attempt::create($attempt->id); $slots = $attemptobj->get_slots(); foreach ($slots as $slot) { $qattempt = $attemptobj->get_question_attempt($slot); $question = $qattempt->get_question(); if ($question->get_type_name() === 'multianswer') { $q = $question->subquestions[1]; $numanswers[$user->id][] = count($q->answers); } else { if ($question->get_type_name() === 'multichoice') { $numanswers[$user->id][] = count($question->answers); } } $attemptids[$user->id] = $attempt->id; $qhtml = $attemptobj->render_question($slot, false); $qhtml = emarking_clean_question_html($qhtml); $currentimages = emarking_extract_images_url($qhtml); $idx = 0; foreach ($currentimages[1] as $imageurl) { if (!array_search($imageurl, $images)) { $images[] = $imageurl; $imageshtml[] = $currentimages[0][$idx]; } $idx++; } $fullhtml[$user->id][] = $qhtml; } // One attempt per user break; } } $save_to = $CFG->tempdir . '/emarking/printquiz/' . $cm->id . '/'; emarking_initialize_directory($save_to, true); // Bajar las imágenes del HTML a dibujar $search = array(); $replace = array(); $replaceweb = array(); $imagesize = array(); $idx = 0; if ($pbar) { $progressbar->update_full(100, get_string('finished', 'mod_emarking')); echo $OUTPUT->heading(get_string('downloadingimages', 'mod_emarking'), 3); $progressbar = new progress_bar(); $progressbar->create(); $progressbar->update(0, count($images), get_string('processing', 'mod_emarking')); } foreach ($images as $image) { if ($pbar) { $imagefilename = explode("/", $image); $progressbar->update($idx + 1, count($images), $imagefilename[count($imagefilename) - 1]); } // Si solamente incluiremos hojas de respuesta terminamos el ciclo if ($answersheetsonly) { break; } if (!(list($filename, $imageinfo) = emarking_get_file_from_url($image, $save_to))) { echo "Problem downloading file {$image} <hr>"; } else { // Buscamos el src de la imagen $search[] = 'src="' . $image . '"'; $replacehtml = ' src="' . $filename . '"'; $replacehtmlxweb = ' src="' . $image . '"'; // Si el html de la misma contiene ancho o alto, se deja tal cual $imghtml = $imageshtml[$idx]; if (substr_count($imghtml, "width") + substr_count($imghtml, "height") == 0) { $width = $imageinfo[0]; $height = $imageinfo[1]; $ratio = floatval(10) / floatval($height); $height = 10; $width = (int) ($ratio * floatval($width)); $sizehtml = 'width="' . $width . '" height="' . $height . '"'; $replacehtml = $sizehtml . ' ' . $replacehtml; $replacehtmlxweb = $sizehtml . ' ' . $replacehtmlxweb; } $replace[] = $replacehtml; $replaceweb[] = $replacehtmlxweb; $imagesize[] = $imageinfo; } $idx++; } if ($debug) { foreach ($fullhtml as $uid => $questions) { $index = 0; foreach ($questions as $question) { echo str_replace($search, $replaceweb, $fullhtml[$uid][$index]); $index++; } } return; } // Now we create the pdf file with the modified html $doc = new FPDI(); $doc->setPrintHeader(false); $doc->setPrintFooter(false); $doc->SetFont('times', '', 12); // set margins $doc->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT); $doc->SetHeaderMargin(250); $doc->SetFooterMargin(PDF_MARGIN_FOOTER); if ($pbar) { $progressbar->update_full(100, get_string('finished', 'mod_emarking')); echo $OUTPUT->heading(get_string('creatingpdffile', 'mod_emarking'), 3); $progressbar = new progress_bar(); $progressbar->create(); } $current = 0; foreach ($fullhtml as $uid => $questions) { $current++; $stinfo = $DB->get_record('user', array('id' => $uid)); $stinfo->name = $stinfo->firstname . ' ' . $stinfo->lastname; $stinfo->picture = emarking_get_student_picture($stinfo, $userimgdir); $stinfo->idnumber = $uid . '-' . $attemptids[$uid]; if ($pbar) { $progressbar->update($current, count($fullhtml), $stinfo->name); } $groups = groups_get_user_groups($course->id, $uid); if ($groups && isset($groups[0][0]) && ($group = $DB->get_record('groups', array('id' => $groups[0][0])))) { $stinfo->group = $group->name; } else { $stinfo->group = ''; } emarking_add_answer_sheet($doc, $filedir, $stinfo, $logofilepath, null, $fileimg, $course, $quizobj->get_quiz_name(), $numanswers[$uid], $attemptids[$uid]); // Una vez agregada la página de respuestas, si es todo lo que hay que hacer saltar al siguiente if ($answersheetsonly) { continue; } $doc->AddPage(); emarking_draw_header($doc, $stinfo, $quizobj->get_quiz_name(), 2, $fileimg, $logofilepath, $course, null, false, 0); $doc->SetFont('times', '', 12); $doc->SetAutoPageBreak(true); $doc->SetXY(PDF_MARGIN_LEFT, 40); $index = 0; foreach ($questions as $question) { $prevy = $doc->getY(); $fullhtml[$uid][$index] = str_replace($search, $replace, $fullhtml[$uid][$index]); $doc->writeHTML($fullhtml[$uid][$index]); $y = $doc->getY(); $fmargin = $doc->getFooterMargin(); $height = $doc->getPageHeight(); $spaceleft = $height - $fmargin - $y; $questionsize = $y - $prevy; if ($spaceleft < 70) { $doc->AddPage(); } $index++; } } if ($pbar) { $progressbar->update_full(100, get_string('finished', 'mod_emarking')); } $qid = $quizobj->get_quizid(); $pdfquizfilename = 'quiz-' . $qid . '-' . random_string() . '.pdf'; $fs = get_file_storage(); $filerecord = array('component' => 'mod_emarking', 'filearea' => 'pdfquiz', 'contextid' => $context->id, 'itemid' => $quizobj->get_quizid(), 'filepath' => '/', 'filename' => $pdfquizfilename); $doc->Output($filedir . '/' . $pdfquizfilename, 'F'); $file = $fs->create_file_from_pathname($filerecord, $filedir . '/' . $pdfquizfilename); $downloadurl = moodle_url::make_file_url("{$CFG->wwwroot}/pluginfile.php", "/{$context->id}/mod_emarking/pdfquiz/{$qid}/{$pdfquizfilename}", null, true); return $downloadurl; }
public function test_quiz_get_user_attempts() { global $DB; $this->resetAfterTest(); $dg = $this->getDataGenerator(); $quizgen = $dg->get_plugin_generator('mod_quiz'); $course = $dg->create_course(); $u1 = $dg->create_user(); $u2 = $dg->create_user(); $u3 = $dg->create_user(); $u4 = $dg->create_user(); $role = $DB->get_record('role', ['shortname' => 'student']); $dg->enrol_user($u1->id, $course->id, $role->id); $dg->enrol_user($u2->id, $course->id, $role->id); $dg->enrol_user($u3->id, $course->id, $role->id); $dg->enrol_user($u4->id, $course->id, $role->id); $quiz1 = $quizgen->create_instance(['course' => $course->id, 'sumgrades' => 2]); $quiz2 = $quizgen->create_instance(['course' => $course->id, 'sumgrades' => 2]); // Questions. $questgen = $dg->get_plugin_generator('core_question'); $quizcat = $questgen->create_question_category(); $question = $questgen->create_question('numerical', null, ['category' => $quizcat->id]); quiz_add_quiz_question($question->id, $quiz1); quiz_add_quiz_question($question->id, $quiz2); $quizobj1a = quiz::create($quiz1->id, $u1->id); $quizobj1b = quiz::create($quiz1->id, $u2->id); $quizobj1c = quiz::create($quiz1->id, $u3->id); $quizobj1d = quiz::create($quiz1->id, $u4->id); $quizobj2a = quiz::create($quiz2->id, $u1->id); // Set attempts. $quba1a = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj1a->get_context()); $quba1a->set_preferred_behaviour($quizobj1a->get_quiz()->preferredbehaviour); $quba1b = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj1b->get_context()); $quba1b->set_preferred_behaviour($quizobj1b->get_quiz()->preferredbehaviour); $quba1c = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj1c->get_context()); $quba1c->set_preferred_behaviour($quizobj1c->get_quiz()->preferredbehaviour); $quba1d = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj1d->get_context()); $quba1d->set_preferred_behaviour($quizobj1d->get_quiz()->preferredbehaviour); $quba2a = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj2a->get_context()); $quba2a->set_preferred_behaviour($quizobj2a->get_quiz()->preferredbehaviour); $timenow = time(); // User 1 passes quiz 1. $attempt = quiz_create_attempt($quizobj1a, 1, false, $timenow, false, $u1->id); quiz_start_new_attempt($quizobj1a, $quba1a, $attempt, 1, $timenow); quiz_attempt_save_started($quizobj1a, $quba1a, $attempt); $attemptobj = quiz_attempt::create($attempt->id); $attemptobj->process_submitted_actions($timenow, false, [1 => ['answer' => '3.14']]); $attemptobj->process_finish($timenow, false); // User 2 goes overdue in quiz 1. $attempt = quiz_create_attempt($quizobj1b, 1, false, $timenow, false, $u2->id); quiz_start_new_attempt($quizobj1b, $quba1b, $attempt, 1, $timenow); quiz_attempt_save_started($quizobj1b, $quba1b, $attempt); $attemptobj = quiz_attempt::create($attempt->id); $attemptobj->process_going_overdue($timenow, true); // User 3 does not finish quiz 1. $attempt = quiz_create_attempt($quizobj1c, 1, false, $timenow, false, $u3->id); quiz_start_new_attempt($quizobj1c, $quba1c, $attempt, 1, $timenow); quiz_attempt_save_started($quizobj1c, $quba1c, $attempt); // User 4 abandons the quiz 1. $attempt = quiz_create_attempt($quizobj1d, 1, false, $timenow, false, $u4->id); quiz_start_new_attempt($quizobj1d, $quba1d, $attempt, 1, $timenow); quiz_attempt_save_started($quizobj1d, $quba1d, $attempt); $attemptobj = quiz_attempt::create($attempt->id); $attemptobj->process_abandon($timenow, true); // User 1 attempts the quiz three times (abandon, finish, in progress). $quba2a = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj2a->get_context()); $quba2a->set_preferred_behaviour($quizobj2a->get_quiz()->preferredbehaviour); $attempt = quiz_create_attempt($quizobj2a, 1, false, $timenow, false, $u1->id); quiz_start_new_attempt($quizobj2a, $quba2a, $attempt, 1, $timenow); quiz_attempt_save_started($quizobj2a, $quba2a, $attempt); $attemptobj = quiz_attempt::create($attempt->id); $attemptobj->process_abandon($timenow, true); $quba2a = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj2a->get_context()); $quba2a->set_preferred_behaviour($quizobj2a->get_quiz()->preferredbehaviour); $attempt = quiz_create_attempt($quizobj2a, 2, false, $timenow, false, $u1->id); quiz_start_new_attempt($quizobj2a, $quba2a, $attempt, 2, $timenow); quiz_attempt_save_started($quizobj2a, $quba2a, $attempt); $attemptobj = quiz_attempt::create($attempt->id); $attemptobj->process_finish($timenow, false); $quba2a = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj2a->get_context()); $quba2a->set_preferred_behaviour($quizobj2a->get_quiz()->preferredbehaviour); $attempt = quiz_create_attempt($quizobj2a, 3, false, $timenow, false, $u1->id); quiz_start_new_attempt($quizobj2a, $quba2a, $attempt, 3, $timenow); quiz_attempt_save_started($quizobj2a, $quba2a, $attempt); // Check for user 1. $attempts = quiz_get_user_attempts($quiz1->id, $u1->id, 'all'); $this->assertCount(1, $attempts); $attempt = array_shift($attempts); $this->assertEquals(quiz_attempt::FINISHED, $attempt->state); $this->assertEquals($u1->id, $attempt->userid); $this->assertEquals($quiz1->id, $attempt->quiz); $attempts = quiz_get_user_attempts($quiz1->id, $u1->id, 'finished'); $this->assertCount(1, $attempts); $attempt = array_shift($attempts); $this->assertEquals(quiz_attempt::FINISHED, $attempt->state); $this->assertEquals($u1->id, $attempt->userid); $this->assertEquals($quiz1->id, $attempt->quiz); $attempts = quiz_get_user_attempts($quiz1->id, $u1->id, 'unfinished'); $this->assertCount(0, $attempts); // Check for user 2. $attempts = quiz_get_user_attempts($quiz1->id, $u2->id, 'all'); $this->assertCount(1, $attempts); $attempt = array_shift($attempts); $this->assertEquals(quiz_attempt::OVERDUE, $attempt->state); $this->assertEquals($u2->id, $attempt->userid); $this->assertEquals($quiz1->id, $attempt->quiz); $attempts = quiz_get_user_attempts($quiz1->id, $u2->id, 'finished'); $this->assertCount(0, $attempts); $attempts = quiz_get_user_attempts($quiz1->id, $u2->id, 'unfinished'); $this->assertCount(1, $attempts); $attempt = array_shift($attempts); $this->assertEquals(quiz_attempt::OVERDUE, $attempt->state); $this->assertEquals($u2->id, $attempt->userid); $this->assertEquals($quiz1->id, $attempt->quiz); // Check for user 3. $attempts = quiz_get_user_attempts($quiz1->id, $u3->id, 'all'); $this->assertCount(1, $attempts); $attempt = array_shift($attempts); $this->assertEquals(quiz_attempt::IN_PROGRESS, $attempt->state); $this->assertEquals($u3->id, $attempt->userid); $this->assertEquals($quiz1->id, $attempt->quiz); $attempts = quiz_get_user_attempts($quiz1->id, $u3->id, 'finished'); $this->assertCount(0, $attempts); $attempts = quiz_get_user_attempts($quiz1->id, $u3->id, 'unfinished'); $this->assertCount(1, $attempts); $attempt = array_shift($attempts); $this->assertEquals(quiz_attempt::IN_PROGRESS, $attempt->state); $this->assertEquals($u3->id, $attempt->userid); $this->assertEquals($quiz1->id, $attempt->quiz); // Check for user 4. $attempts = quiz_get_user_attempts($quiz1->id, $u4->id, 'all'); $this->assertCount(1, $attempts); $attempt = array_shift($attempts); $this->assertEquals(quiz_attempt::ABANDONED, $attempt->state); $this->assertEquals($u4->id, $attempt->userid); $this->assertEquals($quiz1->id, $attempt->quiz); $attempts = quiz_get_user_attempts($quiz1->id, $u4->id, 'finished'); $this->assertCount(1, $attempts); $attempt = array_shift($attempts); $this->assertEquals(quiz_attempt::ABANDONED, $attempt->state); $this->assertEquals($u4->id, $attempt->userid); $this->assertEquals($quiz1->id, $attempt->quiz); $attempts = quiz_get_user_attempts($quiz1->id, $u4->id, 'unfinished'); $this->assertCount(0, $attempts); // Multiple attempts for user 1 in quiz 2. $attempts = quiz_get_user_attempts($quiz2->id, $u1->id, 'all'); $this->assertCount(3, $attempts); $attempt = array_shift($attempts); $this->assertEquals(quiz_attempt::ABANDONED, $attempt->state); $this->assertEquals($u1->id, $attempt->userid); $this->assertEquals($quiz2->id, $attempt->quiz); $attempt = array_shift($attempts); $this->assertEquals(quiz_attempt::FINISHED, $attempt->state); $this->assertEquals($u1->id, $attempt->userid); $this->assertEquals($quiz2->id, $attempt->quiz); $attempt = array_shift($attempts); $this->assertEquals(quiz_attempt::IN_PROGRESS, $attempt->state); $this->assertEquals($u1->id, $attempt->userid); $this->assertEquals($quiz2->id, $attempt->quiz); $attempts = quiz_get_user_attempts($quiz2->id, $u1->id, 'finished'); $this->assertCount(2, $attempts); $attempt = array_shift($attempts); $this->assertEquals(quiz_attempt::ABANDONED, $attempt->state); $attempt = array_shift($attempts); $this->assertEquals(quiz_attempt::FINISHED, $attempt->state); $attempts = quiz_get_user_attempts($quiz2->id, $u1->id, 'unfinished'); $this->assertCount(1, $attempts); $attempt = array_shift($attempts); // Multiple quiz attempts fetched at once. $attempts = quiz_get_user_attempts([$quiz1->id, $quiz2->id], $u1->id, 'all'); $this->assertCount(4, $attempts); $attempt = array_shift($attempts); $this->assertEquals(quiz_attempt::FINISHED, $attempt->state); $this->assertEquals($u1->id, $attempt->userid); $this->assertEquals($quiz1->id, $attempt->quiz); $attempt = array_shift($attempts); $this->assertEquals(quiz_attempt::ABANDONED, $attempt->state); $this->assertEquals($u1->id, $attempt->userid); $this->assertEquals($quiz2->id, $attempt->quiz); $attempt = array_shift($attempts); $this->assertEquals(quiz_attempt::FINISHED, $attempt->state); $this->assertEquals($u1->id, $attempt->userid); $this->assertEquals($quiz2->id, $attempt->quiz); $attempt = array_shift($attempts); $this->assertEquals(quiz_attempt::IN_PROGRESS, $attempt->state); $this->assertEquals($u1->id, $attempt->userid); $this->assertEquals($quiz2->id, $attempt->quiz); }
/** * Given a URL containing attempt={this attempt id}, return an array of variant URLs * @param $url a URL. * @return string HTML fragment. Comma-separated list of links to the other * attempts with the attempt number as the link text. The curent attempt is * included but is not a link. */ public function links_to_other_attempts($url) { $search = '/\\battempt=' . $this->attempt->id . '\\b/'; $attempts = quiz_get_user_attempts($this->quiz->id, $this->attempt->userid, 'all'); if (count($attempts) <= 1) { return false; } $attemptlist = array(); foreach ($attempts as $at) { if ($at->id == $this->attempt->id) { $attemptlist[] = '<strong>' . $at->attempt . '</strong>'; } else { $changedurl = preg_replace($search, 'attempt=' . $at->id, $url); $attemptlist[] = '<a href="' . s($changedurl) . '">' . $at->attempt . '</a>'; } } return implode(', ', $attemptlist); }
$quizobj = quiz::create($cm->instance, $USER->id); $accessmanager = new quiz_access_manager($quizobj, $timenow, has_capability('mod/quiz:ignoretimelimits', $context, null, false)); $quiz = $quizobj->get_quiz(); // Log this request. add_to_log($course->id, 'quiz', 'view', 'view.php?id=' . $cm->id, $quiz->id, $cm->id); $completion = new completion_info($course); $completion->set_module_viewed($cm); // Initialize $PAGE, compute blocks $PAGE->set_url('/mod/quiz/view.php', array('id' => $cm->id)); // Get this user's attempts. $attempts = quiz_get_user_attempts($quiz->id, $USER->id, 'finished', true); $lastfinishedattempt = end($attempts); $unfinished = false; if ($unfinishedattempt = quiz_get_user_attempt_unfinished($quiz->id, $USER->id)) { $attempts[] = $unfinishedattempt; $unfinished = true; } $numattempts = count($attempts); // Work out the final grade, checking whether it was overridden in the gradebook. if (!$canpreview) { $mygrade = quiz_get_best_grade($quiz, $USER->id); } else if ($lastfinishedattempt) { // Users who can preview the quiz don't get a proper grade, so work out a // plausible value to display instead, so the page looks right. $mygrade = quiz_rescale_grade($lastfinishedattempt->sumgrades, $quiz, false);
/** * Combines the review options from a number of different quiz attempts. * * @param int $quizid quiz instance id * @param int $userid user id (empty for current user) * @return array of warnings and the review options * @since Moodle 3.1 */ public static function get_combined_review_options($quizid, $userid = 0) { global $DB, $USER; $warnings = array(); $params = array('quizid' => $quizid, 'userid' => $userid); $params = self::validate_parameters(self::get_combined_review_options_parameters(), $params); // Request and permission validation. $quiz = $DB->get_record('quiz', array('id' => $params['quizid']), '*', MUST_EXIST); list($course, $cm) = get_course_and_cm_from_instance($quiz, 'quiz'); $context = context_module::instance($cm->id); self::validate_context($context); // Default value for userid. if (empty($params['userid'])) { $params['userid'] = $USER->id; } $user = core_user::get_user($params['userid'], '*', MUST_EXIST); core_user::require_active_user($user); // Extra checks so only users with permissions can view other users attempts. if ($USER->id != $user->id) { require_capability('mod/quiz:viewreports', $context); } $attempts = quiz_get_user_attempts($quiz->id, $user->id, 'all', true); $result = array(); $result['someoptions'] = []; $result['alloptions'] = []; list($someoptions, $alloptions) = quiz_get_combined_reviewoptions($quiz, $attempts); foreach (array('someoptions', 'alloptions') as $typeofoption) { foreach (${$typeofoption} as $key => $value) { $result[$typeofoption][] = array("name" => $key, "value" => !empty($value) ? $value : 0); } } $result['warnings'] = $warnings; return $result; }
/** * Return an array of variant URLs to other attempts at this quiz. * * The $url passed in must contain an attempt parameter. * * The {@link mod_quiz_links_to_other_attempts} object returned contains an * array with keys that are the attempt number, 1, 2, 3. * The array values are either a {@link moodle_url} with the attmept parameter * updated to point to the attempt id of the other attempt, or null corresponding * to the current attempt number. * * @param moodle_url $url a URL. * @return mod_quiz_links_to_other_attempts containing array int => null|moodle_url. */ public function links_to_other_attempts(moodle_url $url) { $attempts = quiz_get_user_attempts($this->get_quiz()->id, $this->attempt->userid, 'all'); if (count($attempts) <= 1) { return false; } $links = new mod_quiz_links_to_other_attempts(); foreach ($attempts as $at) { if ($at->id == $this->attempt->id) { $links->links[$at->attempt] = null; } else { $links->links[$at->attempt] = new moodle_url($url, array('attempt' => $at->id)); } } return $links; }
public function assign_quizusers($id){ global $CFG, $OUTPUT, $DB, $USER,$PAGE; require_once($CFG->dirroot.'/mod/quiz/lib.php'); $sql ="SELECT ou.id,u.id as userid,u.firstname,u.lastname,u.email,ou.supervisorid,q.grade,q.id as quizid from {local_onlinetest_users} ou JOIN {quiz} q ON ou.onlinetest=q.id JOIN {user} u ON ou.userid=u.id where ou.onlinetest={$id} order by q.id DESC"; $assigned_users= $DB->get_records_sql($sql); $out=''; $data=array(); if(!empty($assigned_users)){ //$out.='<p><label id="course_label"><input type="checkbox" id="checkAll"/> Check all</label></p>'; foreach($assigned_users as $assigned_user){ $row=array(); $user=$DB->get_record_sql("SELECT * FROM {user} WHERE id=$assigned_user->userid"); if($user){ $user_data=$DB->get_record_sql("SELECT * FROM {local_userdata} WHERE id={$assigned_user->userid}"); $row[]=$user->firstname.' '.$user->lastname; $row[]=$user->email; $row[]=$user->idnumber; if($assigned_user->supervisorid!=''){ $supervisor=$DB->get_record_sql("SELECT * FROM {user} WHERE id={$assigned_user->supervisorid}"); if($supervisor) $row[]=$supervisor->firstname.' .'.$supervisor->lastname; else $row[]="N/A"; }else{ $supervisor=''; $row[]='Not assigned supervisor'; } $sql="SELECT * FROM {quiz_attempts} where id=(SELECT max(id) id from {quiz_attempts} where userid={$assigned_user->userid} and quiz={$assigned_user->quizid})"; $attemptdate=$DB->get_record_sql($sql); if(empty($attemptdate) || ($attemptdate->timestart==0 && $attemptdate->timefinish==0)) $row[]='Not Yet Started'; else if($attemptdate->timestart!=0 && $attemptdate->timefinish==0) $row[] = date('d M, Y', $attemptdate->timestart). ' / Not Completed'; else $row[] = date('d M, Y', $attemptdate->timestart). ' / ' .date('d M, Y', $attemptdate->timefinish); $attempts=quiz_get_user_attempts($assigned_user->quizid, $assigned_user->userid, 'finished', true); $row[]=count($attempts); $finalgrade=get_employeescore($assigned_user->quizid,1,$assigned_user->userid); //$row[]=round($assigned_user->grade,2); $row[]=$finalgrade; $sql="SELECT max(id) as id FROM {quiz_attempts} where userid={$assigned_user->userid} and quiz={$id} "; $review=$DB->get_field_sql($sql); $link = html_writer::link( $CFG->wwwroot.'/mod/quiz/review.php?attempt='.$review, get_string('review', 'quiz'), array('title' => get_string('review', 'quiz'))); if($review) $row[]=$link; else $row[]='Not Attempted'; } $data[]=$row; } } $table = new html_table(); $head=array('User Name','Email Id','Employee Id','Supervisor','Last Attempted Date','Attempts','Score','Review'); $table->head = $head; $table->width = '100%'; $table->id ='assigned_users_view'.$id.''; $table->align = array('left','left','left','left','center','center'); $table->data = $data; if(!empty($data)){ $out.= html_writer::table($table); $out.=html_writer::script('$(document).ready(function() { $("#assigned_users_view'.$id.'").DataTable( { scrollY:"50vh", scrollCollapse: true, paging:false }); $("#checkAll'.$id.'").change(function () { $("input:checkbox").prop("checked", $(this).prop("checked")); }); });'); }else{ $out.="<div id=emptymsg>No users are assigned to this test.</div>"; } return $out; }