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());
 }
Esempio n. 2
0
 /**
  * Put the specified questions on the specified pages of a given quiz.
  *
  * Give the question name in the first column, and that page number in the
  * second column. You may optionally give the desired maximum mark for each
  * question in a third column.
  *
  * @param string $quizname the name of the quiz to add questions to.
  * @param TableNode $data information about the questions to add.
  *
  * @Given /^quiz "([^"]*)" contains the following questions:$/
  */
 public function quiz_contains_the_following_questions($quizname, TableNode $data)
 {
     global $DB;
     $quiz = $DB->get_record('quiz', array('name' => $quizname), '*', MUST_EXIST);
     // The action depends on the field type.
     foreach ($data->getRows() as $questiondata) {
         if (count($questiondata) < 2 || count($questiondata) > 3) {
             throw new ExpectationException('When adding questions to a quiz, you should give 2 or three 3 things: ' . ' the question name, the page number, and optionally a the maxiumum mark. ' . count($questiondata) . ' values passed.', $this->getSession());
         }
         list($questionname, $rawpage) = $questiondata;
         if (!isset($questiondata[2]) || $questiondata[2] === '') {
             $maxmark = null;
         } else {
             $maxmark = clean_param($questiondata[2], PARAM_FLOAT);
             if (!is_numeric($questiondata[2]) || $maxmark < 0) {
                 throw new ExpectationException('When adding questions to a quiz, the max mark must be a positive number.', $this->getSession());
             }
         }
         $page = clean_param($rawpage, PARAM_INT);
         if ($page <= 0 || (string) $page !== $rawpage) {
             throw new ExpectationException('When adding questions to a quiz, the page number must be a positive integer.', $this->getSession());
         }
         $questionid = $DB->get_field('question', 'id', array('name' => $questionname), MUST_EXIST);
         quiz_add_quiz_question($questionid, $quiz, $page, $maxmark);
     }
     quiz_update_sumgrades($quiz);
 }
Esempio n. 3
0
 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);
 }
 /**
  * Utility method to add a quiz to a course.
  * @param $course
  * @return testable_assign
  */
 private function add_quiz_to_course($course)
 {
     // Add a quiz to the course.
     $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 using test data in mod_quiz.
     $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);
     return $quiz;
 }
Esempio n. 5
0
 /**
  * Setup a course, a quiz, a question category and a question for testing.
  *
  * @param string $type The type of question category to create.
  * @return array The created data objects
  */
 public function setup_quiz_and_questions($type = 'module')
 {
     // Create course category.
     $category = $this->getDataGenerator()->create_category();
     // Create course.
     $course = $this->getDataGenerator()->create_course(array('numsections' => 5));
     $options = array('course' => $course->id, 'duedate' => time());
     // Generate an assignment with due date (will generate a course event).
     $quiz = $this->getDataGenerator()->create_module('quiz', $options);
     $qgen = $this->getDataGenerator()->get_plugin_generator('core_question');
     if ('course' == $type) {
         $context = context_course::instance($course->id);
     } else {
         if ('category' == $type) {
             $context = context_coursecat::instance($category->id);
         } else {
             $context = context_module::instance($quiz->cmid);
         }
     }
     $qcat = $qgen->create_question_category(array('contextid' => $context->id));
     $questions = array($qgen->create_question('shortanswer', null, array('category' => $qcat->id)), $qgen->create_question('shortanswer', null, array('category' => $qcat->id)));
     quiz_add_quiz_question($questions[0]->id, $quiz);
     return array($category, $course, $quiz, $qcat, $questions);
 }
Esempio n. 6
0
        // on whether to include questions in subcategories
        $form->questiontextformat = 0;
        $form->image = '';
        $form->defaultgrade = 1;
        $form->hidden = 1;
        for ($i = 0; $i < $randomcount; $i++) {
            $form->category = "{$category->id},{$category->contextid}";
            $form->stamp = make_unique_id_code();
            // Set the unique code (not to be changed)
            $question = new stdClass();
            $question->qtype = RANDOM;
            $question = $QTYPES[RANDOM]->save_question($question, $form, $course);
            if (!isset($question->id)) {
                error('Could not insert new random question!');
            }
            quiz_add_quiz_question($question->id, $quiz);
        }
    }
    $significantchangemade = true;
}
if (optional_param('repaginate', false, PARAM_BOOL) and confirm_sesskey()) {
    /// Re-paginate the quiz
    $questionsperpage = optional_param('questionsperpage', $quiz->questionsperpage, PARAM_INT);
    if ($questionsperpage != $quiz->questionsperpage) {
        $quiz->questionsperpage = $questionsperpage;
        if (!set_field('quiz', 'questionsperpage', $quiz->questionsperpage, 'id', $quiz->id)) {
            error('Could not save number of questions per page');
        }
    }
    $quiz->questions = quiz_repaginate($quiz->questions, $quiz->questionsperpage);
    if (!set_field('quiz', 'questions', $quiz->questions, 'id', $quiz->id)) {
             $questions[$courseid][] = $question->generate_test("question{$qtype}-{$i}", $courseid);
             verbose("Generated a question of type {$qtype} for course id {$courseid}.");
         }
     }
     // Assign questions to quizzes, if such exist
     if (!empty($quizzes) && !empty($questions) && !empty($settings['questions-per-quiz'])) {
         // Cannot assign more questions per quiz than are available, so determine which is the largest
         $questions_per_quiz = max(count($questions), $settings['questions-per-quiz']);
         foreach ($quizzes as $quiz) {
             $questions_added = array();
             for ($i = 0; $i < $questions_per_quiz; $i++) {
                 // Add a random question to the quiz
                 do {
                     $random = rand(0, count($questions[$quiz->course]));
                 } while (in_array($random, $questions_added) || !array_key_exists($random, $questions[$quiz->course]));
                 if (!quiz_add_quiz_question($questions[$quiz->course][$random]->id, $quiz)) {
                     // Could not add question to quiz!! report error
                     echo "WARNING: Could not add question id {$random} to quiz id {$quiz->id}{$settings['eolchar']}";
                 } else {
                     verbose("Adding question id {$random} to quiz id {$quiz->id}.");
                     $questions_added[] = $random;
                 }
             }
         }
     }
 }
 /**
  * ROLE ASSIGNMENTS
  */
 if (count($courses) > 0) {
     verbose("Inserting student->course role assignments...");
Esempio n. 8
0
        $form->questiontextformat = 0;
        $form->image = '';
        $form->defaultgrade = 1;
        $form->hidden = 1;
        for ($i = 0; $i < $randomcount; $i++) {
            $form->category = $category->id . ',' . $category->contextid;
            $form->stamp = make_unique_id_code();
            // Set the unique
            //code (not to be changed)
            $question = new stdClass();
            $question->qtype = RANDOM;
            $question = $QTYPES[RANDOM]->save_question($question, $form, $course);
            if (!isset($question->id)) {
                print_error('cannotinsertrandomquestion', 'quiz');
            }
            quiz_add_quiz_question($question->id, $quiz, $addonpage);
        }
    }
    quiz_update_sumgrades($quiz);
    quiz_delete_previews($quiz);
    redirect($thispageurl->out());
}
if (optional_param('addnewpagesafterselected', null) && !empty($selectedquestionids) && confirm_sesskey()) {
    foreach ($selectedquestionids as $questionid) {
        $quiz->questions = quiz_add_page_break_after($quiz->questions, $questionid);
    }
    quiz_save_new_layout($quiz);
    redirect($thispageurl->out());
}
$addpage = optional_param('addpage', false, PARAM_INT);
if ($addpage !== false && confirm_sesskey()) {
 /**
  * This adds a particular question to the supplied quiz. Based on /mod/quiz/edit.php
  *
  * @param int $questionid
  * @param stdClass $quiz
  * @return void
  */
 public function add_question_to_quiz($questionid, $quiz)
 {
     quiz_require_question_use($questionid);
     quiz_add_quiz_question($questionid, $quiz, 0);
     quiz_delete_previews($quiz);
     quiz_update_sumgrades($quiz);
 }
Esempio n. 10
0
 public function test_question_remove_stale_questions_from_category()
 {
     global $DB;
     $this->resetAfterTest(true);
     $dg = $this->getDataGenerator();
     $course = $dg->create_course();
     $quiz = $dg->create_module('quiz', ['course' => $course->id]);
     $qgen = $dg->get_plugin_generator('core_question');
     $context = context_system::instance();
     $qcat1 = $qgen->create_question_category(['contextid' => $context->id]);
     $q1a = $qgen->create_question('shortanswer', null, ['category' => $qcat1->id]);
     // Will be hidden.
     $q1b = $qgen->create_question('random', null, ['category' => $qcat1->id]);
     // Will not be used.
     $DB->set_field('question', 'hidden', 1, ['id' => $q1a->id]);
     $qcat2 = $qgen->create_question_category(['contextid' => $context->id]);
     $q2a = $qgen->create_question('shortanswer', null, ['category' => $qcat2->id]);
     // Will be hidden.
     $q2b = $qgen->create_question('shortanswer', null, ['category' => $qcat2->id]);
     // Will be hidden but used.
     $q2c = $qgen->create_question('random', null, ['category' => $qcat2->id]);
     // Will not be used.
     $q2d = $qgen->create_question('random', null, ['category' => $qcat2->id]);
     // Will be used.
     $DB->set_field('question', 'hidden', 1, ['id' => $q2a->id]);
     $DB->set_field('question', 'hidden', 1, ['id' => $q2b->id]);
     quiz_add_quiz_question($q2b->id, $quiz);
     quiz_add_quiz_question($q2d->id, $quiz);
     $this->assertEquals(2, $DB->count_records('question', ['category' => $qcat1->id]));
     $this->assertEquals(4, $DB->count_records('question', ['category' => $qcat2->id]));
     // Non-existing category, nothing will happen.
     question_remove_stale_questions_from_category(0);
     $this->assertEquals(2, $DB->count_records('question', ['category' => $qcat1->id]));
     $this->assertEquals(4, $DB->count_records('question', ['category' => $qcat2->id]));
     // First category, should be empty afterwards.
     question_remove_stale_questions_from_category($qcat1->id);
     $this->assertEquals(0, $DB->count_records('question', ['category' => $qcat1->id]));
     $this->assertEquals(4, $DB->count_records('question', ['category' => $qcat2->id]));
     $this->assertFalse($DB->record_exists('question', ['id' => $q1a->id]));
     $this->assertFalse($DB->record_exists('question', ['id' => $q1b->id]));
     // Second category, used questions should be left untouched.
     question_remove_stale_questions_from_category($qcat2->id);
     $this->assertEquals(0, $DB->count_records('question', ['category' => $qcat1->id]));
     $this->assertEquals(2, $DB->count_records('question', ['category' => $qcat2->id]));
     $this->assertFalse($DB->record_exists('question', ['id' => $q2a->id]));
     $this->assertTrue($DB->record_exists('question', ['id' => $q2b->id]));
     $this->assertFalse($DB->record_exists('question', ['id' => $q2c->id]));
     $this->assertTrue($DB->record_exists('question', ['id' => $q2d->id]));
 }
Esempio n. 11
0
 /**
  * Test deleting a quiz instance.
  */
 public function test_quiz_delete_instance()
 {
     global $SITE, $DB;
     $this->resetAfterTest(true);
     $this->setAdminUser();
     // Setup a quiz with 1 standard and 1 random question.
     $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
     $quiz = $quizgenerator->create_instance(array('course' => $SITE->id, 'questionsperpage' => 3, 'grade' => 100.0));
     $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
     $cat = $questiongenerator->create_question_category();
     $standardq = $questiongenerator->create_question('shortanswer', null, array('category' => $cat->id));
     quiz_add_quiz_question($standardq->id, $quiz);
     quiz_add_random_questions($quiz, 0, $cat->id, 1, false);
     // Get the random question.
     $randomq = $DB->get_record('question', array('qtype' => 'random'));
     quiz_delete_instance($quiz->id);
     // Check that the random question was deleted.
     $count = $DB->count_records('question', array('id' => $randomq->id));
     $this->assertEquals(0, $count);
     // Check that the standard question was not deleted.
     $count = $DB->count_records('question', array('id' => $standardq->id));
     $this->assertEquals(1, $count);
     // Check that all the slots were removed.
     $count = $DB->count_records('quiz_slots', array('quizid' => $quiz->id));
     $this->assertEquals(0, $count);
     // Check that the quiz was removed.
     $count = $DB->count_records('quiz', array('id' => $quiz->id));
     $this->assertEquals(0, $count);
 }
Esempio n. 12
0
    /**
     * Create a quiz, add five questions to the quiz
     * which are all on one page and return the quiz object.
     */
    private function get_quiz_object() {
        global $SITE;
        $this->resetAfterTest(true);

        // Make a quiz.
        $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');

        $quiz = $quizgenerator->create_instance(array(
                'course' => $SITE->id, 'questionsperpage' => 0, 'grade' => 100.0, 'sumgrades' => 2));

        // Create five questions.
        $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
        $cat = $questiongenerator->create_question_category();

        $shortanswer = $questiongenerator->create_question('shortanswer', null, array('category' => $cat->id));
        $numerical = $questiongenerator->create_question('numerical', null, array('category' => $cat->id));
        $essay = $questiongenerator->create_question('essay', null, array('category' => $cat->id));
        $truefalse = $questiongenerator->create_question('truefalse', null, array('category' => $cat->id));
        $match = $questiongenerator->create_question('match', null, array('category' => $cat->id));

        // Add them to the quiz.
        quiz_add_quiz_question($shortanswer->id, $quiz);
        quiz_add_quiz_question($numerical->id, $quiz);
        quiz_add_quiz_question($essay->id, $quiz);
        quiz_add_quiz_question($truefalse->id, $quiz);
        quiz_add_quiz_question($match->id, $quiz);

        // Return the quiz object.
        return \mod_quiz\structure::create_for($quiz);
    }
Esempio n. 13
0
 public function generate_questions($courses, $modules)
 {
     global $DB, $CFG;
     if (!is_null($this->get('questions_per_course')) && count($courses) > 0 && is_array($courses)) {
         require_once $CFG->libdir . '/questionlib.php';
         require_once $CFG->dirroot . '/mod/quiz/editlib.php';
         $questions = array();
         $questionsmenu = question_type_menu();
         $questiontypes = array();
         foreach ($questionsmenu as $qtype => $qname) {
             $questiontypes[] = $qtype;
         }
         // Add the questions
         foreach ($courses as $courseid) {
             $questions[$courseid] = array();
             for ($i = 0; $i < $this->get('questions_per_course'); $i++) {
                 $qtype = $questiontypes[array_rand($questiontypes)];
                 // Only the following types are supported right now. Hang around for more!
                 $supported_types = array('match', 'essay', 'multianswer', 'multichoice', 'shortanswer', 'numerical', 'truefalse', 'calculated');
                 $qtype = $supported_types[array_rand($supported_types)];
                 if ($qtype == 'calculated') {
                     continue;
                 }
                 $classname = "question_{$qtype}_qtype";
                 if ($qtype == 'multianswer') {
                     $classname = "embedded_cloze_qtype";
                 }
                 $question = new $classname();
                 $question->qtype = $qtype;
                 $questions[$courseid][] = $question->generate_test("question{$qtype}-{$i}", $courseid);
                 $this->verbose("Generated a question of type {$qtype} for course id {$courseid}.");
             }
         }
         // Assign questions to quizzes, if such exist
         if (!empty($modules['quiz']) && !empty($questions) && !is_null($this->get('questions_per_quiz'))) {
             $quizzes = $modules['quiz'];
             // Cannot assign more questions per quiz than are available, so determine which is the largest
             $questions_per_quiz = max(count($questions), $this->get('questions_per_quiz'));
             foreach ($quizzes as $quiz) {
                 $questions_added = array();
                 for ($i = 0; $i < $questions_per_quiz; $i++) {
                     // Add a random question to the quiz
                     do {
                         if (empty($quiz->course)) {
                             print_object($quizzes);
                             die;
                         }
                         $random = rand(0, count($questions[$quiz->course]));
                     } while (in_array($random, $questions_added) || !array_key_exists($random, $questions[$quiz->course]));
                     if (!quiz_add_quiz_question($questions[$quiz->course][$random]->id, $quiz)) {
                         // Could not add question to quiz!! report error
                         if (!$this->get('quiet')) {
                             echo "WARNING: Could not add question id {$random} to quiz id {$quiz->id}{$this->eolchar}";
                         }
                     } else {
                         $this->verbose("Adding question id {$random} to quiz id {$quiz->id}.");
                         $questions_added[] = $random;
                     }
                 }
             }
         }
         return $questions;
     }
     return null;
 }
Esempio n. 14
0
    quiz_delete_previews($quiz);
    quiz_update_sumgrades($quiz);
    $thispageurl->param('lastchanged', $addquestion);
    redirect($afteractionurl);
}
if (optional_param('add', false, PARAM_BOOL) && confirm_sesskey()) {
    $structure->check_can_be_edited();
    $addonpage = optional_param('addonpage', 0, PARAM_INT);
    // Add selected questions to the current quiz.
    $rawdata = (array) data_submitted();
    foreach ($rawdata as $key => $value) {
        // Parse input for question ids.
        if (preg_match('!^q([0-9]+)$!', $key, $matches)) {
            $key = $matches[1];
            quiz_require_question_use($key);
            quiz_add_quiz_question($key, $quiz, $addonpage);
        }
    }
    quiz_delete_previews($quiz);
    quiz_update_sumgrades($quiz);
    redirect($afteractionurl);
}
if (optional_param('addrandom', false, PARAM_BOOL) && confirm_sesskey()) {
    // Add random questions to the quiz.
    $structure->check_can_be_edited();
    $recurse = optional_param('recurse', 0, PARAM_BOOL);
    $addonpage = optional_param('addonpage', 0, PARAM_INT);
    $categoryid = required_param('categoryid', PARAM_INT);
    $randomcount = required_param('randomcount', PARAM_INT);
    quiz_add_random_questions($quiz, $addonpage, $categoryid, $randomcount, $recurse);
    quiz_delete_previews($quiz);
Esempio n. 15
0
function addRandomQuizQuestions($cmid, $cat_id)
{
    global $QTYPES;
    $result = true;
    $recurse = 1;
    list($quiz, $cm) = get_module_from_cmid($cmid);
    if ($rs = get_records('question_categories', 'parent', $cat_id, 'sortorder')) {
        $course = get_record('course', 'id', $quiz->course);
        foreach ($rs as $cat) {
            $categoryid = $cat->id;
            $randomcount = 1;
            // load category
            if (!($category = get_record('question_categories', 'id', $categoryid))) {
                error('Category ID is incorrect');
            }
            $catcontext = get_context_instance_by_id($category->contextid);
            require_capability('moodle/question:useall', $catcontext);
            $category->name = addslashes($category->name);
            // Find existing random questions in this category that are not used by any quiz.
            if ($existingquestions = get_records_sql("SELECT * FROM " . $CFG->prefix . "question q\n                        WHERE qtype = '" . RANDOM . "'\n                            AND category = {$category->id}\n                            AND " . sql_compare_text('questiontext') . " = '{$recurse}'\n                            AND NOT EXISTS (SELECT * FROM " . $CFG->prefix . "quiz_question_instances WHERE question = q.id)\n                        ORDER BY id")) {
                // Take as many of these as needed.
                while ($existingquestion = array_shift($existingquestions) and $randomcount > 0) {
                    if (!quiz_add_quiz_question($existingquestion->id, $quiz)) {
                        $result = false;
                    }
                    $randomcount--;
                }
            }
            // If more are needed, create them.
            if ($randomcount > 0) {
                //echo "NOT EXISTING:".$cat->id."<br/>";
                $form->questiontext = $recurse;
                // we use the questiontext field to store the info
                // on whether to include questions in subcategories
                $form->questiontextformat = 0;
                $form->image = '';
                $form->defaultgrade = 1;
                $form->hidden = 1;
                for ($i = 0; $i < $randomcount; $i++) {
                    $form->category = "{$category->id},{$category->contextid}";
                    $form->stamp = make_unique_id_code();
                    // Set the unique code (not to be changed)
                    $question = new stdClass();
                    $question->qtype = RANDOM;
                    $question = $QTYPES[RANDOM]->save_question($question, $form, $course);
                    if (!isset($question->id)) {
                        error('Could not insert new random question!');
                        $result = false;
                    }
                    //quiz_add_quiz_question($question->id, $quiz);
                    if (!quiz_add_quiz_question($question->id, $quiz)) {
                        $result = false;
                    }
                }
            }
            $significantchangemade = true;
        }
    }
    return $result;
    /*
        $result = true;
        $recurse = 1;
       list($quiz, $cm) = get_module_from_cmid($cmid);
       if ($rs = get_recordset('question_categories','parent',$cat_id)) {
               $course = get_record('course','id',$quiz->course);
                foreach ($rs as $category) {
                        echo $category->name."<br/>";
                        /// Add random questions to the quiz
                        // - Source from: /mod/quiz/edit.php
                        $randomcount = 1;
                        // load category
                       //$catcontext = get_context_instance_by_id($category->contextid);
                        //require_capability('moodle/question:useall', $catcontext);
                        $category->name = $category->name;
                        // Find existing random questions in this category that are
                        // not used by any quiz.
                        if ($existingquestions = get_records_sql(
                                "SELECT q.id,q.qtype FROM {question} q
                                WHERE qtype = '" . RANDOM . "'
                                    AND category = ?
                                    AND " . $DB->sql_compare_text('questiontext') . " = ?
                                    AND NOT EXISTS (SELECT * FROM {quiz_question_instances} WHERE question = q.id)
                                ORDER BY id", array($category->id, $recurse))) {
                            // Take as many of these as needed.
                            while (($existingquestion = array_shift($existingquestions)) && $randomcount > 0) {
                                //quiz_add_quiz_question($existingquestion->id, $quiz);
                                if(!quiz_add_quiz_question($existingquestion->id, $quiz)){
                                    $result = false;
                                }
                                $randomcount--;
                            }
                        }
                       // If more are needed, create them.
                        if ($randomcount > 0) {
                           $form->questiontext = $recurse; // we use the questiontext field
                                    // to store the info on whether to include
                                    // questions in subcategories
                            $form->questiontextformat = 0;
                            $form->image = '';
                            $form->defaultgrade = 1;
                            $form->hidden = 1;
                            for ($i = 0; $i < $randomcount; $i++) {
                                $form->category = $category->id . ',' . $category->contextid;
                                $form->stamp = make_unique_id_code(); // Set the unique
                                        //code (not to be changed)
                                $question = new stdClass;
                                $question->qtype = RANDOM;
                                $question = $QTYPES[RANDOM]->save_question($question, $form, $course);
                               if(!isset($question->id)) {
                                    //print_error('cannotinsertrandomquestion', 'quiz');
                                    $result = false;
                                }
                                //quiz_add_quiz_question($question->id, $quiz);
                                if(!quiz_add_quiz_question($question->id, $quiz)){
                                    $result = false;
                                }
                            }
                        }
                       quiz_update_sumgrades($quiz);
                        quiz_delete_previews($quiz);
               }
                //$rs->close(); /// Don't forget to close the recordset!
        }
        return $result;
    */
}
    /**
     * Create a quiz with a single question with variants and walk through quiz attempts.
     *
     * @dataProvider get_correct_response_for_variants
     */
    public function test_quiz_with_question_with_variants_attempt_walkthrough($variantno, $correctresponse, $done = false) {
        global $SITE;

        $this->resetAfterTest($done);

        $this->setAdminUser();

        if ($this->quizwithvariants === null) {
            // Make a quiz.
            $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');

            $this->quizwithvariants = $quizgenerator->create_instance(array('course'=>$SITE->id,
                                                                            'questionsperpage' => 0,
                                                                            'grade' => 100.0,
                                                                            'sumgrades' => 1));

            $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');

            $cat = $questiongenerator->create_question_category();
            $calc = $questiongenerator->create_question('calculatedsimple', 'sumwithvariants', array('category' => $cat->id));
            quiz_add_quiz_question($calc->id, $this->quizwithvariants, 0);
        }


        // Make a new user to do the quiz.
        $user1 = $this->getDataGenerator()->create_user();
        $this->setUser($user1);
        $quizobj = quiz::create($this->quizwithvariants->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);

        // Select variant.
        quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow, array(), array(1 => $variantno));
        $this->assertEquals('1,0', $attempt->layout);
        quiz_attempt_save_started($quizobj, $quba, $attempt);

        // Process some responses from the student.
        $attemptobj = quiz_attempt::create($attempt->id);
        $tosubmit = array(1 => array('answer' => $correctresponse));
        $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);

        // Check that results are stored as expected.
        $this->assertEquals(1, $attemptobj->get_attempt_number());
        $this->assertEquals(1, $attemptobj->get_sum_marks());
        $this->assertEquals(true, $attemptobj->is_finished());
        $this->assertEquals($timenow, $attemptobj->get_submitted_date());
        $this->assertEquals($user1->id, $attemptobj->get_userid());

        // Check quiz grades.
        $grades = quiz_get_user_grades($this->quizwithvariants, $user1->id);
        $grade = array_shift($grades);
        $this->assertEquals(100.0, $grade->rawgrade);

        // Check grade book.
        $gradebookgrades = grade_get_grades($SITE->id, 'mod', 'quiz', $this->quizwithvariants->id, $user1->id);
        $gradebookitem = array_shift($gradebookgrades->items);
        $gradebookgrade = array_shift($gradebookitem->grades);
        $this->assertEquals(100, $gradebookgrade->grade);
    }
 /**
  * Populate quiz with eight questions.
  * @param stdClass $quiz the quiz to add to.
  */
 public function add_eight_questions_to_the_quiz($quiz)
 {
     // We add 8 numerical questions with this layout:
     // Slot 1 2 3 4 5 6 7 8
     // Page 1 2 2 2 2 2 3 4.
     // Create slots.
     $pagenumber = 1;
     $pagenumberdefaults = array(2, 7, 8);
     // Create a couple of questions.
     $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
     $cat = $questiongenerator->create_question_category();
     for ($i = 0; $i < 8; $i++) {
         $numq = $questiongenerator->create_question('numerical', null, array('category' => $cat->id));
         if (in_array($i + 1, $pagenumberdefaults)) {
             $pagenumber++;
         }
         // Add them to the quiz.
         quiz_add_quiz_question($numq->id, $quiz, $pagenumber);
     }
 }
Esempio n. 18
0
        // we use the questiontext field to store the info
        // on whether to include questions in subcategories
        $form->questiontextformat = 0;
        $form->image = '';
        $form->defaultgrade = 1;
        $form->hidden = 1;
        for ($i = 0; $i < $randomcreate; $i++) {
            $form->stamp = make_unique_id_code();
            // Set the unique code (not to be changed)
            $question = new stdClass();
            $question->qtype = RANDOM;
            $question = $QTYPES[RANDOM]->save_question($question, $form, $course);
            if (!isset($question->id)) {
                error('Could not insert new random question!');
            }
            quiz_add_quiz_question($question->id, $modform);
        }
    }
}
if (isset($_REQUEST['repaginate']) and confirm_sesskey()) {
    /// Re-paginate the quiz
    if (isset($_REQUEST['questionsperpage'])) {
        $modform->questionsperpage = required_param('questionsperpage', PARAM_INT);
        if (!set_field('quiz', 'questionsperpage', $modform->questionsperpage, 'id', $modform->id)) {
            error('Could not save number of questions per page');
        }
    }
    $modform->questions = quiz_repaginate($modform->questions, $modform->questionsperpage);
    if (!set_field('quiz', 'questions', $modform->questions, 'id', $modform->id)) {
        error('Could not save layout');
    }
Esempio n. 19
0
 /**
  * Put the specified questions on the specified pages of a given quiz.
  *
  * The first row should be column names:
  * | question | page | maxmark |
  * The first two of those are required. The others are optional.
  *
  * question        needs to uniquely match a question name.
  * page            is a page number. Must start at 1, and on each following
  *                 row should be the same as the previous, or one more.
  * maxmark         What the question is marked out of. Defaults to question.defaultmark.
  *
  * Then there should be a number of rows of data, one for each question you want to add.
  *
  * For backwards-compatibility reasons, specifying the column names is optional
  * (but strongly encouraged). If not specified, the columns are asseumed to be
  * | question | page | maxmark |.
  *
  * @param string $quizname the name of the quiz to add questions to.
  * @param TableNode $data information about the questions to add.
  *
  * @Given /^quiz "([^"]*)" contains the following questions:$/
  */
 public function quiz_contains_the_following_questions($quizname, TableNode $data)
 {
     global $CFG, $DB;
     require_once __DIR__ . '/../../editlib.php';
     $quiz = $DB->get_record('quiz', array('name' => $quizname), '*', MUST_EXIST);
     // Deal with backwards-compatibility, optional first row.
     $firstrow = $data->getRow(0);
     if (!in_array('question', $firstrow) && !in_array('page', $firstrow)) {
         if (count($firstrow) == 2) {
             $headings = array('question', 'page');
         } else {
             if (count($firstrow) == 3) {
                 $headings = array('question', 'page', 'maxmark');
             } else {
                 throw new ExpectationException('When adding questions to a quiz, you should give 2 or three 3 things: ' . ' the question name, the page number, and optionally the maxiumum mark. ' . count($firstrow) . ' values passed.', $this->getSession());
             }
         }
         $rows = $data->getRows();
         array_unshift($rows, $headings);
         $data->setRows($rows);
     }
     // Add the questions.
     $lastpage = 0;
     foreach ($data->getHash() as $questiondata) {
         if (!array_key_exists('question', $questiondata)) {
             throw new ExpectationException('When adding questions to a quiz, ' . 'the question name column is required.', $this->getSession());
         }
         if (!array_key_exists('page', $questiondata)) {
             throw new ExpectationException('When adding questions to a quiz, ' . 'the page number column is required.', $this->getSession());
         }
         // Question id.
         $questionid = $DB->get_field('question', 'id', array('name' => $questiondata['question']), MUST_EXIST);
         // Page number.
         $page = clean_param($questiondata['page'], PARAM_INT);
         if ($page <= 0 || (string) $page !== $questiondata['page']) {
             throw new ExpectationException('The page number for question "' . $questiondata['question'] . '" must be a positive integer.', $this->getSession());
         }
         if ($page < $lastpage || $page > $lastpage + 1) {
             throw new ExpectationException('When adding questions to a quiz, ' . 'the page number for each question must either be the same, ' . 'or one more, then the page number for the previous question.', $this->getSession());
         }
         $lastpage = $page;
         // Max mark.
         if (!array_key_exists('maxmark', $questiondata) || $questiondata['maxmark'] === '') {
             $maxmark = null;
         } else {
             $maxmark = clean_param($questiondata['maxmark'], PARAM_FLOAT);
             if (!is_numeric($questiondata['maxmark']) || $maxmark < 0) {
                 throw new ExpectationException('The max mark for question "' . $questiondata['question'] . '" must be a positive number.', $this->getSession());
             }
         }
         // Add the question.
         quiz_add_quiz_question($questionid, $quiz, $page, $maxmark);
     }
     quiz_update_sumgrades($quiz);
 }
Esempio n. 20
0
 public function test_add_question_at_end_does_not_update_headings()
 {
     $quizobj = $this->create_test_quiz(array(array('TF1', 1, 'truefalse'), 'Heading 2', array('TF2', 2, 'truefalse')));
     $structure = \mod_quiz\structure::create_for_quiz($quizobj);
     $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
     $cat = $questiongenerator->create_question_category();
     $q = $questiongenerator->create_question('truefalse', null, array('name' => 'TF3', 'category' => $cat->id));
     quiz_add_quiz_question($q->id, $quizobj->get_quiz(), 0);
     $structure = \mod_quiz\structure::create_for_quiz($quizobj);
     $this->assert_quiz_layout(array(array('TF1', 1, 'truefalse'), 'Heading 2', array('TF2', 2, 'truefalse'), array('TF3', 2, 'truefalse')), $structure);
 }
 /**
  * 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);
 }
Esempio n. 22
0
function quiz_add_random_questions($quiz, $addonpage, $categoryid, $number,
        $includesubcategories) {
    global $DB;

    $category = $DB->get_record('question_categories', array('id' => $categoryid));
    if (!$category) {
        print_error('invalidcategoryid', 'error');
    }

    $catcontext = get_context_instance_by_id($category->contextid);
    require_capability('moodle/question:useall', $catcontext);

    // Find existing random questions in this category that are
    // not used by any quiz.
    if ($existingquestions = $DB->get_records_sql(
            "SELECT q.id, q.qtype FROM {question} q
            WHERE qtype = 'random'
                AND category = ?
                AND " . $DB->sql_compare_text('questiontext') . " = ?
                AND NOT EXISTS (
                        SELECT *
                          FROM {quiz_question_instances}
                         WHERE question = q.id)
            ORDER BY id", array($category->id, $includesubcategories))) {
        // Take as many of these as needed.
        while (($existingquestion = array_shift($existingquestions)) && $number > 0) {
            quiz_add_quiz_question($existingquestion->id, $quiz, $addonpage);
            $number -= 1;
        }
    }

    if ($number <= 0) {
        return;
    }

    // More random questions are needed, create them.
    for ($i = 0; $i < $number; $i += 1) {
        $form = new stdClass();
        $form->questiontext = array('text' => $includesubcategories, 'format' => 0);
        $form->category = $category->id . ',' . $category->contextid;
        $form->defaultmark = 1;
        $form->hidden = 1;
        $form->stamp = make_unique_id_code(); // Set the unique code (not to be changed).
        $question = new stdClass();
        $question->qtype = 'random';
        $question = question_bank::get_qtype('random')->save_question($question, $form);
        if (!isset($question->id)) {
            print_error('cannotinsertrandomquestion', 'quiz');
        }
        quiz_add_quiz_question($question->id, $quiz, $addonpage);
    }
}
Esempio n. 23
0
 /**
  * Test get_quiz_required_qtypes
  */
 public function test_get_quiz_required_qtypes()
 {
     global $DB;
     // Create a new quiz.
     $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
     $data = array('course' => $this->course->id);
     $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);
     $this->setUser($this->student);
     $result = mod_quiz_external::get_quiz_required_qtypes($quiz->id);
     $result = external_api::clean_returnvalue(mod_quiz_external::get_quiz_required_qtypes_returns(), $result);
     $expected = array('questiontypes' => ['essay', 'numerical', 'random', 'shortanswer', 'truefalse'], 'warnings' => []);
     $this->assertEquals($expected, $result);
 }
Esempio n. 24
0
 /**
  * @desc Takes in an array of questins and adds them to a quiz
  * @param array $questions An array of the question data to add.
  * @param integer $quizid The ID of the quiz.
  * @return bool.
  */
 function insert_set_definition_questions($questions, $quizid)
 {
     global $COURSE;
     //partial quiz object
     $quizinfo = new stdClass();
     $quizinfo->grades = array();
     $quizinfo->questionsperpage = 1;
     $quizinfo->questions = "";
     $quizinfo->instance = $quizid;
     $quizinfo->id = $quizid;
     //loop to find questions
     $count = 0;
     foreach ($questions as $question) {
         //get question name
         $filepath = $question['file'];
         $name = $this->filepath_to_name($filepath);
         $parts = explode('/', $filepath);
         $partcount = count($parts);
         if ($partcount >= 2) {
             $categoryname = $parts[$partcount - 2];
             //try first with course constraint
             $result = get_field('question_categories', 'id', 'name', $categoryname, 'course', $COURSE->id);
             if ($result == false) {
                 $result = get_field('question_categories', 'id', 'name', $categoryname);
                 if ($result == false) {
                     echo "The category '{$categoryname}' was not found for question '{$name}'. - You will have to manually add this question.<br>";
                     continue;
                 } else {
                     $categoryid = $result;
                 }
             } else {
                 $categoryid = $result;
             }
             $result = get_field('question', 'id', 'category', $categoryid, 'name', $name);
         }
         $result = get_field('question', 'id', 'name', $name);
         if ($result != false) {
             echo "Added Question '{$name}' to quiz.<br>";
             quiz_add_quiz_question($result, $quizinfo);
             $count++;
         } else {
             echo "A question was not found: '{$name}' - You will have to manually add it.<br>";
         }
     }
     return $count;
 }
Esempio n. 25
0
 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);
 }
Esempio n. 26
0
 /**
  * Test checking the completion state of a quiz.
  */
 public function test_quiz_get_completion_state()
 {
     global $CFG, $DB;
     $this->resetAfterTest(true);
     // Enable completion before creating modules, otherwise the completion data is not written in DB.
     $CFG->enablecompletion = true;
     // Create a course and student.
     $course = $this->getDataGenerator()->create_course(array('enablecompletion' => true));
     $passstudent = $this->getDataGenerator()->create_user();
     $failstudent = $this->getDataGenerator()->create_user();
     $studentrole = $DB->get_record('role', array('shortname' => 'student'));
     $this->assertNotEmpty($studentrole);
     // Enrol students.
     $this->assertTrue($this->getDataGenerator()->enrol_user($passstudent->id, $course->id, $studentrole->id));
     $this->assertTrue($this->getDataGenerator()->enrol_user($failstudent->id, $course->id, $studentrole->id));
     // Make a scale and an outcome.
     $scale = $this->getDataGenerator()->create_scale();
     $data = array('courseid' => $course->id, 'fullname' => 'Team work', 'shortname' => 'Team work', 'scaleid' => $scale->id);
     $outcome = $this->getDataGenerator()->create_grade_outcome($data);
     // Make a quiz with the outcome on.
     $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
     $data = array('course' => $course->id, 'outcome_' . $outcome->id => 1, 'grade' => 100.0, 'questionsperpage' => 0, 'sumgrades' => 1, 'completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionpass' => 1);
     $quiz = $quizgenerator->create_instance($data);
     $cm = get_coursemodule_from_id('quiz', $quiz->cmid);
     // Create a couple of 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);
     $quizobj = quiz::create($quiz->id, $passstudent->id);
     // Set grade to pass.
     $item = grade_item::fetch(array('courseid' => $course->id, 'itemtype' => 'mod', 'itemmodule' => 'quiz', 'iteminstance' => $quiz->id, 'outcomeid' => null));
     $item->gradepass = 80;
     $item->update();
     // Start the passing 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, $passstudent->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);
     // Start the failing 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, $failstudent->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' => '0'));
     $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);
     // Check the results.
     $this->assertTrue(quiz_get_completion_state($course, $cm, $passstudent->id, 'return'));
     $this->assertFalse(quiz_get_completion_state($course, $cm, $failstudent->id, 'return'));
 }
Esempio n. 27
0
function RWSAAQRand()
{
    global $CFG;
    global $DB;
    global $RWSUID;
    RWSCMAuth();
    RWSCRAuth();
    RWSCMUSvc();
    RWSCMMaint();
    $r_pm = RWSGSOpt("quizid", PARAM_ALPHANUM);
    if ($r_pm === false || strlen($r_pm) == 0) {
        RWSSErr("2067");
    }
    $r_qzmi = intval($r_pm);
    $r_cmod = RWSCMUQuiz($r_qzmi);
    $r_cid = $r_cmod->course;
    RWSCMUCourse($r_cid, true);
    $r_mr = $DB->get_record("modules", array("id" => $r_cmod->module));
    if ($r_mr === false) {
        RWSSErr("2043");
    }
    $r_qiz = $DB->get_record($r_mr->name, array("id" => $r_cmod->instance));
    if ($r_qiz === false) {
        RWSSErr("2044");
    }
    $r_pm = RWSGSOpt("qcatid", PARAM_ALPHANUM);
    if ($r_pm === false || strlen($r_pm) == 0) {
        RWSSErr("2064");
    }
    $r_qci = intval($r_pm);
    $r_qca = $DB->get_record("question_categories", array("id" => $r_qci));
    if ($r_qca === false) {
        RWSSErr("2065");
    }
    if (respondusws_floatcompare($CFG->version, 2013111800, 2) >= 0) {
        $r_ctx = context::instance_by_id($r_qca->contextid);
    } else {
        $r_ctx = get_context_instance_by_id($r_qca->contextid);
    }
    $r_qcci = RWSGCFCat($r_ctx);
    if ($r_qcci != $r_cid) {
        if (is_siteadmin($RWSUID)) {
            if ($r_qcci != SITEID) {
                RWSSErr("2109");
            }
        } else {
            RWSSErr("2084");
        }
    }
    $r_pm = RWSGSOpt("qcount", PARAM_ALPHANUM);
    if ($r_pm === false || strlen($r_pm) == 0) {
        RWSSErr("2085");
    }
    $r_qct = intval($r_pm);
    if ($r_qct <= 0) {
        RWSSErr("2085");
    }
    $r_pm = RWSGSOpt("qgrade", PARAM_NOTAGS);
    if ($r_pm === false || strlen($r_pm) == 0) {
        RWSSErr("2086");
    }
    $r_qg = round(floatval($r_pm));
    if ($r_qg <= 0) {
        RWSSErr("2086");
    }
    $r_mr = $DB->get_record("modules", array("id" => $r_cmod->module));
    if ($r_mr === false) {
        RWSSErr("2043");
    }
    $r_qiz = $DB->get_record($r_mr->name, array("id" => $r_cmod->instance));
    if ($r_qiz === false) {
        RWSSErr("2044");
    }
    if (!isset($r_qiz->instance)) {
        $r_qiz->instance = $r_qiz->id;
    }
    $r_aerr = 0;
    for ($r_i = 0; $r_i < $r_qct; $r_i++) {
        $r_qst = new stdClass();
        $r_qst->qtype = RWSRND;
        $r_qst->parent = 0;
        $r_qst->hidden = 0;
        $r_qst->length = 1;
        $r_qst->questiontext = 1;
        if (respondusws_floatcompare($CFG->version, 2011070100, 2) >= 0) {
            $r_rqt = question_bank::get_qtype("random");
            $r_qst->name = $r_rqt->question_name($r_qca, !empty($r_qst->questiontext));
        } else {
            $r_qst->name = random_qtype::question_name($r_qca, !empty($r_qst->questiontext));
        }
        $r_qst->questiontextformat = FORMAT_HTML;
        $r_qst->penalty = 0;
        if (respondusws_floatcompare($CFG->version, 2011070100, 2) >= 0) {
            $r_qst->defaultmark = $r_qg;
        } else {
            $r_qst->defaultgrade = $r_qg;
        }
        $r_qst->generalfeedback = "";
        $r_qst->generalfeedbackformat = FORMAT_HTML;
        $r_qst->category = $r_qca->id;
        $r_qst->stamp = make_unique_id_code();
        $r_qst->createdby = $RWSUID;
        $r_qst->modifiedby = $RWSUID;
        $r_qst->timecreated = time();
        $r_qst->timemodified = time();
        $r_qst->id = $DB->insert_record("question", $r_qst);
        $DB->set_field("question", "parent", $r_qst->id, array("id" => $r_qst->id));
        $r_h = question_hash($r_qst);
        $DB->set_field("question", "version", $r_h, array("id" => $r_qst->id));
        if (respondusws_floatcompare($CFG->version, 2011070100, 2) >= 0) {
            quiz_add_quiz_question($r_qst->id, $r_qiz);
        } else {
            $r_ok = quiz_add_quiz_question($r_qst->id, $r_qiz);
            if (!$r_ok) {
                $DB->delete_records("question", array("id" => $r_qst->id));
                $r_aerr++;
            }
        }
    }
    if ($r_aerr > 0) {
        RWSSErr("2087,{$r_aerr}");
    }
    if ($r_aerr < $r_qct) {
        quiz_delete_previews($r_qiz);
    }
    if (respondusws_floatcompare($CFG->version, 2014051200, 2) >= 0) {
        quiz_update_sumgrades($r_qiz);
    } else {
        $r_qiz->grades = quiz_get_all_question_grades($r_qiz);
        $r_sumg = array_sum($r_qiz->grades);
        $DB->set_field("quiz", "sumgrades", $r_sumg, array("id" => $r_qiz->id));
    }
    RWSSStat("1006");
}
 public function create_quiz($quizsettings, $qs)
 {
     global $SITE, $DB;
     $this->setAdminUser();
     $questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
     $slots = array();
     $qidsbycat = array();
     $sumofgrades = 0;
     for ($rowno = 0; $rowno < $qs->getRowCount(); $rowno++) {
         $q = $this->explode_dot_separated_keys_to_make_subindexs($qs->getRow($rowno));
         $catname = array('name' => $q['cat']);
         if (!($cat = $DB->get_record('question_categories', array('name' => $q['cat'])))) {
             $cat = $questiongenerator->create_question_category($catname);
         }
         $q['catid'] = $cat->id;
         foreach (array('which' => null, 'overrides' => array()) as $key => $default) {
             if (empty($q[$key])) {
                 $q[$key] = $default;
             }
         }
         if ($q['type'] !== 'random') {
             // Don't actually create random questions here.
             $overrides = array('category' => $cat->id, 'defaultmark' => $q['mark']) + $q['overrides'];
             $question = $questiongenerator->create_question($q['type'], $q['which'], $overrides);
             $q['id'] = $question->id;
             if (!isset($qidsbycat[$q['cat']])) {
                 $qidsbycat[$q['cat']] = array();
             }
             if (!empty($q['which'])) {
                 $name = $q['type'] . '_' . $q['which'];
             } else {
                 $name = $q['type'];
             }
             $qidsbycat[$q['catid']][$name] = $q['id'];
         }
         if (!empty($q['slot'])) {
             $slots[$q['slot']] = $q;
             $sumofgrades += $q['mark'];
         }
     }
     ksort($slots);
     // Make a quiz.
     $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
     // Settings from param override defaults.
     $aggregratedsettings = $quizsettings + array('course' => $SITE->id, 'questionsperpage' => 0, 'grade' => 100.0, 'sumgrades' => $sumofgrades);
     $this->quiz = $quizgenerator->create_instance($aggregratedsettings);
     $this->randqids = array();
     foreach ($slots as $slotno => $slotquestion) {
         if ($slotquestion['type'] !== 'random') {
             quiz_add_quiz_question($slotquestion['id'], $this->quiz, 0, $slotquestion['mark']);
         } else {
             quiz_add_random_questions($this->quiz, 0, $slotquestion['catid'], 1, 0);
             $this->randqids[$slotno] = $qidsbycat[$slotquestion['catid']];
         }
     }
 }
Esempio n. 29
0
    $addonpage = optional_param('addonpage', 0, PARAM_INT);
    quiz_add_quiz_question($addquestion, $quiz, $addonpage);
    quiz_delete_previews($quiz);
    quiz_update_sumgrades($quiz);
    $thispageurl->param('lastchanged', $addquestion);
    redirect($afteractionurl);
}
if (optional_param('add', false, PARAM_BOOL) && confirm_sesskey()) {
    // Add selected questions to the current quiz.
    $rawdata = (array) data_submitted();
    foreach ($rawdata as $key => $value) {
        // Parse input for question ids.
        if (preg_match('!^q([0-9]+)$!', $key, $matches)) {
            $key = $matches[1];
            quiz_require_question_use($key);
            quiz_add_quiz_question($key, $quiz);
        }
    }
    quiz_delete_previews($quiz);
    quiz_update_sumgrades($quiz);
    redirect($afteractionurl);
}
if (optional_param('addrandom', false, PARAM_BOOL) && confirm_sesskey()) {
    // Add random questions to the quiz.
    $recurse = optional_param('recurse', 0, PARAM_BOOL);
    $addonpage = optional_param('addonpage', 0, PARAM_INT);
    $categoryid = required_param('categoryid', PARAM_INT);
    $randomcount = required_param('randomcount', PARAM_INT);
    quiz_add_random_questions($quiz, $addonpage, $categoryid, $randomcount, $recurse);
    quiz_delete_previews($quiz);
    quiz_update_sumgrades($quiz);
Esempio n. 30
0
 /**
  * Test start_attempt
  */
 public function test_start_attempt()
 {
     global $DB;
     // Create a new quiz with attempts.
     $quizgenerator = $this->getDataGenerator()->get_plugin_generator('mod_quiz');
     $data = array('course' => $this->course->id, 'sumgrades' => 1);
     $quiz = $quizgenerator->create_instance($data);
     $context = context_module::instance($quiz->cmid);
     try {
         mod_quiz_external::start_attempt($quiz->id);
         $this->fail('Exception expected due to missing questions.');
     } catch (moodle_quiz_exception $e) {
         $this->assertEquals('noquestionsfound', $e->errorcode);
     }
     // Create a question.
     $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);
     $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);
     // Try to open attempt in closed quiz.
     $quiz->timeopen = time() - WEEKSECS;
     $quiz->timeclose = time() - DAYSECS;
     $DB->update_record('quiz', $quiz);
     $result = mod_quiz_external::start_attempt($quiz->id);
     $result = external_api::clean_returnvalue(mod_quiz_external::start_attempt_returns(), $result);
     $this->assertEquals([], $result['attempt']);
     $this->assertCount(1, $result['warnings']);
     // Now with a password.
     $quiz->timeopen = 0;
     $quiz->timeclose = 0;
     $quiz->password = '******';
     $DB->update_record('quiz', $quiz);
     try {
         mod_quiz_external::start_attempt($quiz->id, array(array("name" => "quizpassword", "value" => 'bad')));
         $this->fail('Exception expected due to invalid passwod.');
     } catch (moodle_exception $e) {
         $this->assertEquals(get_string('passworderror', 'quizaccess_password'), $e->errorcode);
     }
     // Now, try everything correct.
     $result = mod_quiz_external::start_attempt($quiz->id, array(array("name" => "quizpassword", "value" => 'abc')));
     $result = external_api::clean_returnvalue(mod_quiz_external::start_attempt_returns(), $result);
     $this->assertEquals(1, $result['attempt']['attempt']);
     $this->assertEquals($this->student->id, $result['attempt']['userid']);
     $this->assertEquals($quiz->id, $result['attempt']['quiz']);
     $this->assertCount(0, $result['warnings']);
     $attemptid = $result['attempt']['id'];
     // We are good, try to start a new attempt now.
     try {
         mod_quiz_external::start_attempt($quiz->id, array(array("name" => "quizpassword", "value" => 'abc')));
         $this->fail('Exception expected due to attempt not finished.');
     } catch (moodle_quiz_exception $e) {
         $this->assertEquals('attemptstillinprogress', $e->errorcode);
     }
     // Finish the started attempt.
     // Process some responses from the student.
     $timenow = time();
     $attemptobj = quiz_attempt::create($attemptid);
     $tosubmit = array(1 => array('answer' => '3.14'));
     $attemptobj->process_submitted_actions($timenow, false, $tosubmit);
     // Finish the attempt.
     $attemptobj = quiz_attempt::create($attemptid);
     $this->assertTrue($attemptobj->has_response_to_at_least_one_graded_question());
     $attemptobj->process_finish($timenow, false);
     // We should be able to start a new attempt.
     $result = mod_quiz_external::start_attempt($quiz->id, array(array("name" => "quizpassword", "value" => 'abc')));
     $result = external_api::clean_returnvalue(mod_quiz_external::start_attempt_returns(), $result);
     $this->assertEquals(2, $result['attempt']['attempt']);
     $this->assertEquals($this->student->id, $result['attempt']['userid']);
     $this->assertEquals($quiz->id, $result['attempt']['quiz']);
     $this->assertCount(0, $result['warnings']);
     // Test user with no capabilities.
     // We need a explicit prohibit since this capability is only defined in authenticated user and guest roles.
     assign_capability('mod/quiz:attempt', CAP_PROHIBIT, $this->studentrole->id, $context->id);
     // Empty all the caches that may be affected  by this change.
     accesslib_clear_all_caches_for_unit_testing();
     course_modinfo::clear_instance_cache();
     try {
         mod_quiz_external::start_attempt($quiz->id);
         $this->fail('Exception expected due to missing capability.');
     } catch (required_capability_exception $e) {
         $this->assertEquals('nopermissions', $e->errorcode);
     }
 }