public function test_quiz_report_overview_report_forcesubmit_specific_attempt() { global $DB; $this->resetAfterTest(); $generator = $this->getDataGenerator(); $quizgenerator = $generator->get_plugin_generator('mod_quiz'); $questiongenerator = $generator->get_plugin_generator('core_question'); // Make a user to do the quiz. $user1 = $generator->create_user(); $user2 = $generator->create_user(); $user3 = $generator->create_user(); // Create our course. $course = $generator->create_course(array('visible' => true)); // Create the quiz. $quiz = $quizgenerator->create_instance(array('course' => $course->id, 'visible' => true, 'questionsperpage' => 0, 'grade' => 100.0, 'sumgrades' => 2)); // Create two questions. $cat = $questiongenerator->create_question_category(); $saq = $questiongenerator->create_question('shortanswer', null, array('category' => $cat->id)); $numq = $questiongenerator->create_question('numerical', null, array('category' => $cat->id)); // Add the questions to the quiz. quiz_add_quiz_question($saq->id, $quiz); quiz_add_quiz_question($numq->id, $quiz); // Get a quiz object with user access overrides. $quizobj = quiz::create($quiz->id, $user1->id); $quizobj2 = quiz::create($quiz->id, $user2->id); $quizobj3 = quiz::create($quiz->id, $user3->id); // Start the attempt. $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context()); $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour); $quba2 = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj2->get_context()); $quba2->set_preferred_behaviour($quizobj2->get_quiz()->preferredbehaviour); $quba3 = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj3->get_context()); $quba3->set_preferred_behaviour($quizobj3->get_quiz()->preferredbehaviour); // Create a quiz attempt. $timenow = time(); $attempt = quiz_create_attempt($quizobj, 1, false, $timenow, false, $user1->id); $attempt2 = quiz_create_attempt($quizobj2, 1, false, $timenow, false, $user2->id); $attempt3 = quiz_create_attempt($quizobj3, 1, false, $timenow, false, $user3->id); // Start the attempt. quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow); quiz_attempt_save_started($quizobj, $quba, $attempt); quiz_start_new_attempt($quizobj2, $quba2, $attempt2, 1, $timenow); quiz_attempt_save_started($quizobj2, $quba2, $attempt2); quiz_start_new_attempt($quizobj3, $quba3, $attempt3, 1, $timenow); quiz_attempt_save_started($quizobj3, $quba3, $attempt3); // Answer first question and set it overdue. $tosubmit = array(1 => array('answer' => 'frog')); $tosubmit2 = array(1 => array('answer' => 'tiger')); $tosubmit3 = array(1 => array('answer' => 'tiger')); $attemptobj = quiz_attempt::create($attempt->id); $attemptobj->process_submitted_actions($timenow, true, $tosubmit); $attemptobj2 = quiz_attempt::create($attempt2->id); $attemptobj2->process_submitted_actions($timenow, true, $tosubmit2); $attemptobj3 = quiz_attempt::create($attempt3->id); $attemptobj3->process_submitted_actions($timenow, true, $tosubmit3); // Finish the attempt. $attemptobj = quiz_attempt::create($attempt->id); $this->assertTrue($attemptobj->has_response_to_at_least_one_graded_question()); $attemptobj->process_abandon($timenow, false); // Re-load quiz attempt2 data. $attemptobj = quiz_attempt::create($attempt->id); $attemptobj2 = quiz_attempt::create($attempt2->id); $attemptobj3 = quiz_attempt::create($attempt3->id); // Check that the state of the attempt is as expected. $this->assertEquals(1, $attemptobj->get_attempt_number()); $this->assertEquals(quiz_attempt::ABANDONED, $attemptobj->get_state()); $this->assertEquals($user1->id, $attemptobj->get_userid()); $this->assertTrue($attemptobj->has_response_to_at_least_one_graded_question()); // Check that the state of the attempt2 is as expected. $this->assertEquals(1, $attemptobj2->get_attempt_number()); $this->assertEquals(quiz_attempt::OVERDUE, $attemptobj2->get_state()); $this->assertEquals($user2->id, $attemptobj2->get_userid()); $this->assertTrue($attemptobj2->has_response_to_at_least_one_graded_question()); // Check that the state of the attempt3 is as expected. $this->assertEquals(1, $attemptobj3->get_attempt_number()); $this->assertEquals(quiz_attempt::OVERDUE, $attemptobj3->get_state()); $this->assertEquals($user3->id, $attemptobj3->get_userid()); $this->assertTrue($attemptobj3->has_response_to_at_least_one_graded_question()); // Force submit the attempts. $overviewreport = new quiz_overview_report_testable(); $overviewreport->forcesubmit_attempts($quiz, false, array(), array($attempt->id, $attempt3->id)); // Check that it is now finished. $attemptobj = quiz_attempt::create($attempt->id); $this->assertEquals(quiz_attempt::FINISHED, $attemptobj->get_state()); $attemptobj2 = quiz_attempt::create($attempt2->id); $this->assertEquals(quiz_attempt::OVERDUE, $attemptobj2->get_state()); $attemptobj3 = quiz_attempt::create($attempt3->id); $this->assertEquals(quiz_attempt::FINISHED, $attemptobj3->get_state()); }
public static function make(quiz $quizobj, $timenow, $canignoretimelimits) { if (empty($quizobj->get_quiz()->honestycheckrequired)) { return null; } return new self($quizobj, $timenow); }
/** * Create an instance of this class representing the structure of a given quiz. * @param \quiz $quizobj the quiz. * @return structure */ public static function create_for_quiz($quizobj) { $structure = self::create(); $structure->quizobj = $quizobj; $structure->populate_structure($quizobj->get_quiz()); return $structure; }
public static function make(quiz $quizobj, $timenow, $canignoretimelimits) { if (empty($quizobj->get_quiz()->timelimit) || $canignoretimelimits) { return null; } return new self($quizobj, $timenow); }
public static function make(quiz $quizobj, $timenow, $canignoretimelimits) { if (empty($quizobj->get_quiz()->offlinemode_enabled) || !self::is_compatible_behaviour($quizobj->get_quiz()->preferredbehaviour)) { return null; } return new self($quizobj, $timenow); }
public static function make(quiz $quizobj, $timenow, $canignoretimelimits) { if ($quizobj->get_num_attempts_allowed() == 0) { return null; } return new self($quizobj, $timenow); }
/** * Render the edit page * * @param \quiz $quizobj object containing all the quiz settings information. * @param structure $structure object containing the structure of the quiz. * @param \question_edit_contexts $contexts the relevant question bank contexts. * @param \moodle_url $pageurl the canonical URL of this page. * @param array $pagevars the variables from {@link question_edit_setup()}. * @return string HTML to output. */ public function edit_page(\quiz $quizobj, structure $structure, \question_edit_contexts $contexts, \moodle_url $pageurl, array $pagevars) { $output = ''; // Page title. $output .= $this->heading_with_help(get_string('editingquizx', 'quiz', format_string($quizobj->get_quiz_name())), 'editingquiz', 'quiz', '', get_string('basicideasofquiz', 'quiz'), 2); // Information at the top. $output .= $this->quiz_state_warnings($structure); $output .= $this->quiz_information($structure); $output .= $this->maximum_grade_input($structure, $pageurl); $output .= $this->repaginate_button($structure, $pageurl); $output .= $this->total_marks($quizobj->get_quiz()); // Show the questions organised into sections and pages. $output .= $this->start_section_list($structure); foreach ($structure->get_sections() as $section) { $output .= $this->start_section($structure, $section); $output .= $this->questions_in_section($structure, $section, $contexts, $pagevars, $pageurl); if ($structure->is_last_section($section)) { $output .= \html_writer::start_div('last-add-menu'); $output .= html_writer::tag('span', $this->add_menu_actions($structure, 0, $pageurl, $contexts, $pagevars), array('class' => 'add-menu-outer')); $output .= \html_writer::end_div(); } $output .= $this->end_section(); } $output .= $this->end_section_list(); // Initialise the JavaScript. $this->initialise_editing_javascript($structure, $contexts, $pagevars, $pageurl); // Include the contents of any other popups required. if ($structure->can_be_edited()) { $popups = ''; $popups .= $this->question_bank_loading(); $this->page->requires->yui_module('moodle-mod_quiz-quizquestionbank', 'M.mod_quiz.quizquestionbank.init', array('class' => 'questionbank', 'cmid' => $structure->get_cmid())); $popups .= $this->random_question_form($pageurl, $contexts, $pagevars); $this->page->requires->yui_module('moodle-mod_quiz-randomquestion', 'M.mod_quiz.randomquestion.init'); $output .= html_writer::div($popups, 'mod_quiz_edit_forms'); // Include the question chooser. $output .= $this->question_chooser(); $this->page->requires->yui_module('moodle-mod_quiz-questionchooser', 'M.mod_quiz.init_questionchooser'); } return $output; }
public static function make(quiz $quizobj, $timenow, $canignoretimelimits) { if ($quizobj->get_quiz()->browsersecurity !== 'safebrowser') { return null; } return new self($quizobj, $timenow); }
public function test_cannot_review_message() { $quiz = new stdClass(); $quiz->reviewattempt = 0x10010; $quiz->timeclose = 0; $quiz->attempts = 0; $quiz->questions = '1,2,0,3,4,0'; $cm = new stdClass(); $cm->id = 123; $quizobj = new quiz($quiz, $cm, new stdClass(), false); $this->assertEqual('', $quizobj->cannot_review_message(mod_quiz_display_options::DURING)); $this->assertEqual('', $quizobj->cannot_review_message(mod_quiz_display_options::IMMEDIATELY_AFTER)); $this->assertEqual(get_string('noreview', 'quiz'), $quizobj->cannot_review_message(mod_quiz_display_options::LATER_WHILE_OPEN)); $this->assertEqual(get_string('noreview', 'quiz'), $quizobj->cannot_review_message(mod_quiz_display_options::AFTER_CLOSE)); $closetime = time() + 10000; $quiz->timeclose = $closetime; $quizobj = new quiz($quiz, $cm, new stdClass(), false); $this->assertEqual(get_string('noreviewuntil', 'quiz', userdate($closetime)), $quizobj->cannot_review_message(mod_quiz_display_options::LATER_WHILE_OPEN)); }
public static function make(quiz $quizobj, $timenow, $canignoretimelimits) { global $THEME; if (empty($quizobj->get_quiz()->gradebycategory)) { return null; } return new self($quizobj, $timenow); }
public static function make(quiz $quizobj, $timenow, $canignoretimelimits) { global $CFG; // If mobile services are off, the user won't be able to use any external app. if (empty($CFG->enablemobilewebservice) or empty($quizobj->get_quiz()->allowofflineattempts)) { return null; } return new self($quizobj, $timenow); }
public function test_empty_quiz() { $quiz = new stdClass(); $quiz->reviewattempt = 0x10010; $quiz->timeclose = 0; $quiz->attempts = 0; $quiz->questions = '0'; $cm = new stdClass(); $cm->id = 123; $quizobj = new quiz($quiz, $cm, new stdClass(), false); $this->assertFalse($quizobj->has_questions()); }
/** * Creates an object to represent a new attempt at a quiz * * Creates an attempt object to represent an attempt at the quiz by the current * user starting at the current time. The ->id field is not set. The object is * NOT written to the database. * * @param object $quizobj the quiz object to create an attempt for. * @param int $attemptnumber the sequence number for the attempt. * @param object $lastattempt the previous attempt by this user, if any. Only needed * if $attemptnumber > 1 and $quiz->attemptonlast is true. * @param int $timenow the time the attempt was started at. * @param bool $ispreview whether this new attempt is a preview. * * @return object the newly created attempt object. */ function quiz_create_attempt(quiz $quizobj, $attemptnumber, $lastattempt, $timenow, $ispreview = false) { global $USER; $quiz = $quizobj->get_quiz(); if ($quiz->sumgrades < 0.000005 && $quiz->grade > 0.000005) { throw new moodle_exception('cannotstartgradesmismatch', 'quiz', new moodle_url('/mod/quiz/view.php', array('q' => $quiz->id)), array('grade' => quiz_format_grade($quiz, $quiz->grade))); } if ($attemptnumber == 1 || !$quiz->attemptonlast) { // We are not building on last attempt so create a new attempt. $attempt = new stdClass(); $attempt->quiz = $quiz->id; $attempt->userid = $USER->id; $attempt->preview = 0; $attempt->layout = quiz_clean_layout($quiz->questions, true); if ($quiz->shufflequestions) { $attempt->layout = quiz_repaginate($attempt->layout, $quiz->questionsperpage, true); } } else { // Build on last attempt. if (empty($lastattempt)) { print_error('cannotfindprevattempt', 'quiz'); } $attempt = $lastattempt; } $attempt->attempt = $attemptnumber; $attempt->timestart = $timenow; $attempt->timefinish = 0; $attempt->timemodified = $timenow; $attempt->state = quiz_attempt::IN_PROGRESS; // If this is a preview, mark it as such. if ($ispreview) { $attempt->preview = 1; } $timeclose = $quizobj->get_access_manager($timenow)->get_end_time($attempt); if ($timeclose === false || $ispreview) { $attempt->timecheckstate = null; } else { $attempt->timecheckstate = $timeclose; } return $attempt; }
protected function prepare_quiz_data() { $this->resetAfterTest(true); // Create a course $course = $this->getDataGenerator()->create_course(); // Make a quiz. $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz'); $quiz = $quizgenerator->create_instance(array('course' => $course->id, 'questionsperpage' => 0, 'grade' => 100.0, 'sumgrades' => 2)); $cm = get_coursemodule_from_instance('quiz', $quiz->id, $course->id); // Create a couple of questions. $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question'); $cat = $questiongenerator->create_question_category(); $saq = $questiongenerator->create_question('shortanswer', null, array('category' => $cat->id)); $numq = $questiongenerator->create_question('numerical', null, array('category' => $cat->id)); // Add them to the quiz. quiz_add_quiz_question($saq->id, $quiz); quiz_add_quiz_question($numq->id, $quiz); // Make a user to do the quiz. $user1 = $this->getDataGenerator()->create_user(); $this->setUser($user1); $quizobj = quiz::create($quiz->id, $user1->id); // Start the attempt. $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context()); $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour); $timenow = time(); $attempt = quiz_create_attempt($quizobj, 1, false, $timenow); quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow); quiz_attempt_save_started($quizobj, $quba, $attempt); return array($quizobj, $quba, $attempt); }
public function round($id) { $utoken = session('user_id'); $maxround = leaderboard::where('user_id', $utoken)->select('round_id')->first(); $maxround = $maxround['round_id']; $cc = leaderboard::where('round_id', '>', $id)->count(); $quesquery = solved::where(['user_token' => $utoken, 'round_id' => $id])->select('question_no')->get(); $totalques = quiz::where('round', $id)->select('question_id', 'position')->get(); $rquery = roundans::where('round_id', $id)->select('question', 'round_name')->first(); $rq = $rquery['question']; $rname = $rquery['round_name']; $qdone = array(); $i = 0; foreach ($quesquery as $ques) { $qdone[$i] = $ques['question_no']; $i++; } $i = 0; $i2 = 0; $parray = array(); $tques = array(); $totpos = array(); $location = array(); foreach ($totalques as $t) { $tques[$i2] = $t['question_id']; $totpos[$i2] = $t['position']; if (in_array($tques[$i2], $qdone)) { $parray[$i] = explode(",", $t['position']); $location[$i] = $t['position']; $i++; } $i2++; } if ($id > $maxround || $id < 1) { return redirect(url('/round/' . $maxround)); } else { if ($id > $this->mxround) { return view('quiz/winner')->with('id', $id); } else { return view('quiz/round')->with(['id' => $id, 'qdone' => $qdone, 'pos' => $location, 'totalques' => $tques, 'totalpos' => $totpos, 'rq' => $rq, 'rname' => $rname, 'c' => $cc, 'locations' => $parray]); } } }
<?php /*$handle=new mysqli('localhost','sygmaapp','sygelvshi15','sygma2015'); $handle->query("CREATE TABLE IF NOT EXISTS `contestants` (p_id INT(5) PRIMARY KEY AUTO_INCREMENT, q_id INT(5), team_code VARCHAR(50), score INT(10))"); $s = $_POST['s']; $user = $_POST['user']; $id = $_POST['id']; $q="SELECT * FROM contestants WHERE team_code ='".$user."' AND q_id =".$id." "; $result= $handle->query($q); if($result->num_rows) { echo "recieved"; while($row = $result->fetch_assoc()) { $s = $row['score'] + $_POST['s']; $q="UPDATE contestants SET score = ". $s ." WHERE team_code = '".$user."'AND q_id =".$id." " ; $handle->query($q); } } else { echo "idle"; }*/ require "class.quiz.php"; $q = new quiz(); $q->updateScore($_POST);
/** * Return the potential question types that would be required for a given quiz. * Please note that for random question types we return the potential question types in the category choosen. * * @param int $quizid quiz instance id * @return array of warnings and the access information * @since Moodle 3.1 * @throws moodle_quiz_exception */ public static function get_quiz_required_qtypes($quizid) { global $DB, $USER; $warnings = array(); $params = array('quizid' => $quizid); $params = self::validate_parameters(self::get_quiz_required_qtypes_parameters(), $params); list($quiz, $course, $cm, $context) = self::validate_quiz($params['quizid']); $quizobj = quiz::create($cm->instance, $USER->id); $quizobj->preload_questions(); $quizobj->load_questions(); // Question types used. $result = array(); $result['questiontypes'] = $quizobj->get_all_question_types_used(true); $result['warnings'] = $warnings; return $result; }
/** * Check if the module has any update that affects the current user since a given time. * * @param cm_info $cm course module data * @param int $from the time to check updates from * @param array $filter if we need to check only specific updates * @return stdClass an object with the different type of areas indicating if they were updated or not * @since Moodle 3.2 */ function quiz_check_updates_since(cm_info $cm, $from, $filter = array()) { global $DB, $USER, $CFG; require_once $CFG->dirroot . '/mod/quiz/locallib.php'; $updates = course_check_module_updates_since($cm, $from, array(), $filter); // Check if questions were updated. $updates->questions = (object) array('updated' => false); $quizobj = quiz::create($cm->instance, $USER->id); $quizobj->preload_questions(); $quizobj->load_questions(); $questionids = array_keys($quizobj->get_questions()); if (!empty($questionids)) { list($questionsql, $params) = $DB->get_in_or_equal($questionids, SQL_PARAMS_NAMED); $select = 'id ' . $questionsql . ' AND (timemodified > :time1 OR timecreated > :time2)'; $params['time1'] = $from; $params['time2'] = $from; $questions = $DB->count_records_select('question', $select, $params) > 0; if (!empty($questions)) { $updates->questions->updated = true; $updates->questions->itemids = array_keys($questions); } } // Check for new attempts or grades. $updates->attempts = (object) array('updated' => false); $updates->grades = (object) array('updated' => false); $select = 'quiz = ? AND userid = ? AND timemodified > ?'; $params = array($cm->instance, $USER->id, $from); $attempts = $DB->get_records_select('quiz_attempts', $select, $params, '', 'id'); if (!empty($attempts)) { $updates->attempts->updated = true; $updates->attempts->itemids = array_keys($attempts); } $grades = $DB->get_records_select('quiz_grades', $select, $params, '', 'id'); if (!empty($grades)) { $updates->grades->updated = true; $updates->grades->itemids = array_keys($grades); } return $updates; }
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); }
/** * Returns a list of quizzes in a provided list of courses, * if no list is provided all quizzes that the user can view will be returned. * * @param array $courseids Array of course ids * @return array of quizzes details * @since Moodle 3.1 */ public static function get_quizzes_by_courses($courseids = array()) { global $USER; $warnings = array(); $returnedquizzes = array(); $params = array('courseids' => $courseids); $params = self::validate_parameters(self::get_quizzes_by_courses_parameters(), $params); $mycourses = array(); if (empty($params['courseids'])) { $mycourses = enrol_get_my_courses(); $params['courseids'] = array_keys($mycourses); } // Ensure there are courseids to loop through. if (!empty($params['courseids'])) { list($courses, $warnings) = external_util::validate_courses($params['courseids'], $mycourses); // Get the quizzes in this course, this function checks users visibility permissions. // We can avoid then additional validate_context calls. $quizzes = get_all_instances_in_courses("quiz", $courses); foreach ($quizzes as $quiz) { $context = context_module::instance($quiz->coursemodule); // Update quiz with override information. $quiz = quiz_update_effective_access($quiz, $USER->id); // Entry to return. $quizdetails = array(); // First, we return information that any user can see in the web interface. $quizdetails['id'] = $quiz->id; $quizdetails['coursemodule'] = $quiz->coursemodule; $quizdetails['course'] = $quiz->course; $quizdetails['name'] = external_format_string($quiz->name, $context->id); if (has_capability('mod/quiz:view', $context)) { // Format intro. list($quizdetails['intro'], $quizdetails['introformat']) = external_format_text($quiz->intro, $quiz->introformat, $context->id, 'mod_quiz', 'intro', null); $viewablefields = array('timeopen', 'timeclose', 'grademethod', 'section', 'visible', 'groupmode', 'groupingid'); $timenow = time(); $quizobj = quiz::create($quiz->id, $USER->id); $accessmanager = new quiz_access_manager($quizobj, $timenow, has_capability('mod/quiz:ignoretimelimits', $context, null, false)); // Fields the user could see if have access to the quiz. if (!$accessmanager->prevent_access()) { // Some times this function returns just empty. $hasfeedback = quiz_has_feedback($quiz); $quizdetails['hasfeedback'] = !empty($hasfeedback) ? 1 : 0; $quizdetails['hasquestions'] = (int) $quizobj->has_questions(); $quizdetails['autosaveperiod'] = get_config('quiz', 'autosaveperiod'); $additionalfields = array('timelimit', 'attempts', 'attemptonlast', 'grademethod', 'decimalpoints', 'questiondecimalpoints', 'reviewattempt', 'reviewcorrectness', 'reviewmarks', 'reviewspecificfeedback', 'reviewgeneralfeedback', 'reviewrightanswer', 'reviewoverallfeedback', 'questionsperpage', 'navmethod', 'sumgrades', 'grade', 'browsersecurity', 'delay1', 'delay2', 'showuserpicture', 'showblocks', 'completionattemptsexhausted', 'completionpass', 'overduehandling', 'graceperiod', 'preferredbehaviour', 'canredoquestions'); $viewablefields = array_merge($viewablefields, $additionalfields); } // Fields only for managers. if (has_capability('moodle/course:manageactivities', $context)) { $additionalfields = array('shuffleanswers', 'timecreated', 'timemodified', 'password', 'subnet'); $viewablefields = array_merge($viewablefields, $additionalfields); } foreach ($viewablefields as $field) { $quizdetails[$field] = $quiz->{$field}; } } $returnedquizzes[] = $quizdetails; } } $result = array(); $result['quizzes'] = $returnedquizzes; $result['warnings'] = $warnings; return $result; }
/** * Test get_attempt_access_information */ public function test_get_attempt_access_information() { global $DB; // Create a new quiz with attempts. $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz'); $data = array('course' => $this->course->id, 'sumgrades' => 2); $quiz = $quizgenerator->create_instance($data); // Create some questions. $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question'); $cat = $questiongenerator->create_question_category(); $question = $questiongenerator->create_question('numerical', null, array('category' => $cat->id)); quiz_add_quiz_question($question->id, $quiz); $question = $questiongenerator->create_question('shortanswer', null, array('category' => $cat->id)); quiz_add_quiz_question($question->id, $quiz); // Add new question types in the category (for the random one). $question = $questiongenerator->create_question('truefalse', null, array('category' => $cat->id)); $question = $questiongenerator->create_question('essay', null, array('category' => $cat->id)); $question = $questiongenerator->create_question('random', null, array('category' => $cat->id)); quiz_add_quiz_question($question->id, $quiz); $quizobj = quiz::create($quiz->id, $this->student->id); // Set grade to pass. $item = grade_item::fetch(array('courseid' => $this->course->id, 'itemtype' => 'mod', 'itemmodule' => 'quiz', 'iteminstance' => $quiz->id, 'outcomeid' => null)); $item->gradepass = 80; $item->update(); $this->setUser($this->student); // Default restrictions (none). $result = mod_quiz_external::get_attempt_access_information($quiz->id); $result = external_api::clean_returnvalue(mod_quiz_external::get_attempt_access_information_returns(), $result); $expected = array('isfinished' => false, 'preventnewattemptreasons' => [], 'warnings' => []); $this->assertEquals($expected, $result); // Limited attempts. $quiz->attempts = 1; $DB->update_record('quiz', $quiz); // Now, do one attempt. $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context()); $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour); $timenow = time(); $attempt = quiz_create_attempt($quizobj, 1, false, $timenow, false, $this->student->id); quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow); quiz_attempt_save_started($quizobj, $quba, $attempt); // Process some responses from the student. $attemptobj = quiz_attempt::create($attempt->id); $tosubmit = array(1 => array('answer' => '3.14')); $attemptobj->process_submitted_actions($timenow, false, $tosubmit); // Finish the attempt. $attemptobj = quiz_attempt::create($attempt->id); $this->assertTrue($attemptobj->has_response_to_at_least_one_graded_question()); $attemptobj->process_finish($timenow, false); // Can we start a new attempt? We shall not! $result = mod_quiz_external::get_attempt_access_information($quiz->id, $attempt->id); $result = external_api::clean_returnvalue(mod_quiz_external::get_attempt_access_information_returns(), $result); // Now new attemps allowed. $this->assertCount(1, $result['preventnewattemptreasons']); $this->assertFalse($result['ispreflightcheckrequired']); $this->assertEquals(get_string('nomoreattempts', 'quiz'), $result['preventnewattemptreasons'][0]); }
/** * Fire an event to tell the rest of Moodle a quiz attempt has started. * * @param object $attempt * @param quiz $quizobj */ function quiz_fire_attempt_started_event($attempt, $quizobj) { // Trigger event. $eventdata = array(); $eventdata['context'] = $quizobj->get_context(); $eventdata['courseid'] = $quizobj->get_courseid(); $eventdata['relateduserid'] = $attempt->userid; $eventdata['objectid'] = $attempt->id; $event = \mod_quiz\event\attempt_started::create($eventdata); $event->add_record_snapshot('quiz', $quizobj->get_quiz()); $event->add_record_snapshot('quiz_attempts', $attempt); $event->trigger(); }
require_once $CFG->dirroot . '/mod/quiz/locallib.php'; /// Get submitted parameters. $id = required_param('cmid', PARAM_INT); // Course Module ID $forcenew = optional_param('forcenew', false, PARAM_BOOL); // Used to force a new preview if (!($cm = get_coursemodule_from_id('quiz', $id))) { print_error('invalidcoursemodule'); } if (!($course = $DB->get_record('course', array('id' => $cm->course)))) { print_error("coursemisconf"); } if (!($quiz = $DB->get_record('quiz', array('id' => $cm->instance)))) { print_error('invalidcoursemodule'); } $quizobj = quiz::create($quiz->id, $USER->id); // This script should only ever be posted to, so set page URL to the view page. $PAGE->set_url($quizobj->view_url()); /// Check login and sesskey. require_login($quizobj->get_courseid(), false, $quizobj->get_cm()); if (!confirm_sesskey()) { throw new moodle_exception('confirmsesskeybad', 'error', $quizobj->view_url()); } $PAGE->set_pagelayout('base'); /// if no questions have been set up yet redirect to edit.php if (!$quizobj->get_question_ids() && $quizobj->has_capability('mod/quiz:manage')) { redirect($quizobj->edit_url()); } /// Create an object to manage all the other (non-roles) access rules. $accessmanager = $quizobj->get_access_manager(time()); if ($quizobj->is_preview_user() && $forcenew) {
public function start_attempt_page(quiz $quizobj, mod_quiz_preflight_check_form $mform) { $output = ''; $output .= $this->header(); $output .= $this->heading(format_string($quizobj->get_quiz_name(), true, array("context" => $quizobj->get_context()))); $output .= $this->quiz_intro($quizobj->get_quiz(), $quizobj->get_cm()); ob_start(); $mform->display(); $output .= ob_get_clean(); $output .= $this->footer(); return $output; }
/** * This function is a copy of code taken from attempt_walkthrough_test.php * that creates a sample quiz and has a student complete the quiz. * * If the test suddenly stops working, grab the new code from that file, then * adjust to required inputs/outputs. * * @param object $course The course object to create the quiz in * @param object $student The student object that takes the quiz * @return array {attempt ID (int), quiz ID (int)} * */ private function create_quiz_attempt($course, $student) { // Make a quiz. $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz'); $quiz = $quizgenerator->create_instance(array('course' => $course->id, 'questionsperpage' => 0, 'grade' => 100.0, 'sumgrades' => 2)); // Create a couple of questions. $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question'); $cat = $questiongenerator->create_question_category(); $saq = $questiongenerator->create_question('shortanswer', null, array('category' => $cat->id)); $numq = $questiongenerator->create_question('numerical', null, array('category' => $cat->id)); // Add them to the quiz. quiz_add_quiz_question($saq->id, $quiz); quiz_add_quiz_question($numq->id, $quiz); $quizobj = quiz::create($quiz->id, $student->id); // Start the attempt. $quba = question_engine::make_questions_usage_by_activity('mod_quiz', $quizobj->get_context()); $quba->set_preferred_behaviour($quizobj->get_quiz()->preferredbehaviour); $timenow = time(); $attempt = quiz_create_attempt($quizobj, 1, false, $timenow, false, $student->id); quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow); quiz_attempt_save_started($quizobj, $quba, $attempt); // Process some responses from the student. $attemptobj = quiz_attempt::create($attempt->id); $prefix1 = $quba->get_field_prefix(1); $prefix2 = $quba->get_field_prefix(2); $tosubmit = array(1 => array('answer' => 'frog'), 2 => array('answer' => '3.14')); $attemptobj->process_submitted_actions($timenow, false, $tosubmit); // Finish the attempt. $attemptobj = quiz_attempt::create($attempt->id); $attemptobj->process_finish($timenow, false); // Re-load quiz attempt data. $attemptobj = quiz_attempt::create($attempt->id); return array($attempt->id, $quiz->id); }
require_once $CFG->dirroot . '/mod/quiz/locallib.php'; /// Get submitted parameters. $id = required_param('cmid', PARAM_INT); // Course Module ID $forcenew = optional_param('forcenew', false, PARAM_BOOL); // Used to force a new preview if (!($cm = get_coursemodule_from_id('quiz', $id))) { print_error('invalidcoursemodule'); } if (!($course = $DB->get_record('course', array('id' => $cm->course)))) { print_error("coursemisconf"); } if (!($quiz = $DB->get_record('quiz', array('id' => $cm->instance)))) { print_error('invalidcoursemodule'); } $quizobj = new quiz($quiz, $cm, $course); /// Check login and sesskey. require_login($quizobj->get_courseid(), false, $quizobj->get_cm()); if (!confirm_sesskey()) { throw new moodle_exception('confirmsesskeybad', 'error', $quizobj->view_url()); } /// if no questions have been set up yet redirect to edit.php if (!$quizobj->get_question_ids() && $quizobj->has_capability('mod/quiz:manage')) { redirect($quizobj->edit_url()); } /// Create an object to manage all the other (non-roles) access rules. $accessmanager = $quizobj->get_access_manager(time()); if ($quizobj->is_preview_user() && $forcenew) { $accessmanager->clear_password_access(); } /// Check capabilites.
} } // Check login and get context. require_login($course, false, $cm); $context = get_context_instance(CONTEXT_MODULE, $cm->id); require_capability('mod/quiz:view', $context); // Cache some other capabilities we use several times. $canattempt = has_capability('mod/quiz:attempt', $context); $canreviewmine = has_capability('mod/quiz:reviewmyattempts', $context); $canpreview = has_capability('mod/quiz:preview', $context); // Create an object to manage all the other (non-roles) access rules. $timenow = time(); $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);
} if (!($cm = get_coursemodule_from_instance("quiz", $quiz->id, $course->id))) { print_error('invalidcoursemodule'); } } /// Check login and get context. require_login($course->id, false, $cm); $context = get_context_instance(CONTEXT_MODULE, $cm->id); require_capability('mod/quiz:view', $context); /// Cache some other capabilities we use several times. $canattempt = has_capability('mod/quiz:attempt', $context); $canreviewmine = has_capability('mod/quiz:reviewmyattempts', $context); $canpreview = has_capability('mod/quiz:preview', $context); /// Create an object to manage all the other (non-roles) access rules. $timenow = time(); $accessmanager = new quiz_access_manager(quiz::create($quiz->id, $USER->id), $timenow, has_capability('mod/quiz:ignoretimelimits', $context, NULL, false)); /// If no questions have been set up yet redirect to edit.php if (!$quiz->questions && has_capability('mod/quiz:manage', $context)) { redirect($CFG->wwwroot . '/mod/quiz/edit.php?cmid=' . $cm->id); } /// Log this request. add_to_log($course->id, "quiz", "view", "view.php?id={$cm->id}", $quiz->id, $cm->id); // Mark module as viewed $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)); $edit = optional_param('edit', -1, PARAM_BOOL); if ($edit != -1 && $PAGE->user_allowed_editing()) { $USER->editing = $edit; }
public function start_attempt_page(quiz $quizobj, mod_quiz_preflight_check_form $mform) { $output = ''; $output .= $this->header(); $output .= $this->quiz_intro($quizobj->get_quiz(), $quizobj->get_cm()); ob_start(); $mform->display(); $output .= ob_get_clean(); $output .= $this->footer(); return $output; }
$column = optional_param('column', 0, PARAM_ALPHA); $id = optional_param('id', 0, PARAM_INT); $summary = optional_param('summary', '', PARAM_RAW); $sequence = optional_param('sequence', '', PARAM_SEQUENCE); $visible = optional_param('visible', 0, PARAM_INT); $pageaction = optional_param('action', '', PARAM_ALPHA); // Used to simulate a DELETE command. $maxmark = optional_param('maxmark', '', PARAM_FLOAT); $page = optional_param('page', '', PARAM_INT); $PAGE->set_url('/mod/quiz/edit-rest.php', array('quizid' => $quizid, 'class' => $class)); require_sesskey(); $quiz = $DB->get_record('quiz', array('id' => $quizid), '*', MUST_EXIST); $cm = get_coursemodule_from_instance('quiz', $quiz->id, $quiz->course); $course = $DB->get_record('course', array('id' => $quiz->course), '*', MUST_EXIST); require_login($course, false, $cm); $quizobj = new quiz($quiz, $cm, $course); $structure = $quizobj->get_structure(); $modcontext = context_module::instance($cm->id); echo $OUTPUT->header(); // Send headers. // OK, now let's process the parameters and do stuff // MDL-10221 the DELETE method is not allowed on some web servers, // so we simulate it with the action URL param. $requestmethod = $_SERVER['REQUEST_METHOD']; if ($pageaction == 'DELETE') { $requestmethod = 'DELETE'; } switch ($requestmethod) { case 'POST': case 'GET': // For debugging.