Example #1
0
 /**
  * Test the question answered event.
  *
  * There is no external API for answering an truefalse question, so the unit test will simply
  * create and trigger the event and ensure data is returned as expected.
  */
 public function test_question_answered()
 {
     // Trigger an event: truefalse question answered.
     $eventparams = array('context' => context_module::instance($this->lesson->properties()->cmid), 'objectid' => 25, 'other' => array('pagetype' => 'True/false'));
     $event = \mod_lesson\event\question_answered::create($eventparams);
     // Trigger and capture the event.
     $sink = $this->redirectEvents();
     $event->trigger();
     $events = $sink->get_events();
     $event = reset($events);
     // Check that the event data is valid.
     $this->assertInstanceOf('\\mod_lesson\\event\\question_answered', $event);
     $this->assertEquals(25, $event->objectid);
     $this->assertEquals('True/false', $event->other['pagetype']);
     $this->assertEventContextNotUsed($event);
     $this->assertDebuggingNotCalled();
 }
Example #2
0
 /**
  * Records an attempt at this page
  *
  * @final
  * @global moodle_database $DB
  * @param stdClass $context
  * @return stdClass Returns the result of the attempt
  */
 public final function record_attempt($context)
 {
     global $DB, $USER, $OUTPUT, $PAGE;
     /**
      * This should be overridden by each page type to actually check the response
      * against what ever custom criteria they have defined
      */
     $result = $this->check_answer();
     $result->attemptsremaining = 0;
     $result->maxattemptsreached = false;
     if ($result->noanswer) {
         $result->newpageid = $this->properties->id;
         // display same page again
         $result->feedback = get_string('noanswer', 'lesson');
     } else {
         if (!has_capability('mod/lesson:manage', $context)) {
             $nretakes = $DB->count_records("lesson_grades", array("lessonid" => $this->lesson->id, "userid" => $USER->id));
             // record student's attempt
             $attempt = new stdClass();
             $attempt->lessonid = $this->lesson->id;
             $attempt->pageid = $this->properties->id;
             $attempt->userid = $USER->id;
             $attempt->answerid = $result->answerid;
             $attempt->retry = $nretakes;
             $attempt->correct = $result->correctanswer;
             if ($result->userresponse !== null) {
                 $attempt->useranswer = $result->userresponse;
             }
             $attempt->timeseen = time();
             // if allow modattempts, then update the old attempt record, otherwise, insert new answer record
             $userisreviewing = false;
             if (isset($USER->modattempts[$this->lesson->id])) {
                 $attempt->retry = $nretakes - 1;
                 // they are going through on review, $nretakes will be too high
                 $userisreviewing = true;
             }
             // Only insert a record if we are not reviewing the lesson.
             if (!$userisreviewing) {
                 if ($this->lesson->retake || !$this->lesson->retake && $nretakes == 0) {
                     $attempt->id = $DB->insert_record("lesson_attempts", $attempt);
                     // Trigger an event: question answered.
                     $eventparams = array('context' => context_module::instance($PAGE->cm->id), 'objectid' => $this->properties->id, 'other' => array('pagetype' => $this->get_typestring()));
                     $event = \mod_lesson\event\question_answered::create($eventparams);
                     $event->add_record_snapshot('lesson_attempts', $attempt);
                     $event->trigger();
                 }
             }
             // "number of attempts remaining" message if $this->lesson->maxattempts > 1
             // displaying of message(s) is at the end of page for more ergonomic display
             if (!$result->correctanswer && $result->newpageid == 0) {
                 // wrong answer and student is stuck on this page - check how many attempts
                 // the student has had at this page/question
                 $nattempts = $DB->count_records("lesson_attempts", array("pageid" => $this->properties->id, "userid" => $USER->id, "retry" => $attempt->retry));
                 // retreive the number of attempts left counter for displaying at bottom of feedback page
                 if ($nattempts >= $this->lesson->maxattempts) {
                     if ($this->lesson->maxattempts > 1) {
                         // don't bother with message if only one attempt
                         $result->maxattemptsreached = true;
                     }
                     $result->newpageid = LESSON_NEXTPAGE;
                 } else {
                     if ($this->lesson->maxattempts > 1) {
                         // don't bother with message if only one attempt
                         $result->attemptsremaining = $this->lesson->maxattempts - $nattempts;
                     }
                 }
             }
         }
         // TODO: merge this code with the jump code below.  Convert jumpto page into a proper page id
         if ($result->newpageid == 0) {
             $result->newpageid = $this->properties->id;
         } elseif ($result->newpageid == LESSON_NEXTPAGE) {
             $result->newpageid = $this->lesson->get_next_page($this->properties->nextpageid);
         }
         // Determine default feedback if necessary
         if (empty($result->response)) {
             if (!$this->lesson->feedback && !$result->noanswer && !($this->lesson->review & !$result->correctanswer && !$result->isessayquestion)) {
                 // These conditions have been met:
                 //  1. The lesson manager has not supplied feedback to the student
                 //  2. Not displaying default feedback
                 //  3. The user did provide an answer
                 //  4. We are not reviewing with an incorrect answer (and not reviewing an essay question)
                 $result->nodefaultresponse = true;
                 // This will cause a redirect below
             } else {
                 if ($result->isessayquestion) {
                     $result->response = get_string('defaultessayresponse', 'lesson');
                 } else {
                     if ($result->correctanswer) {
                         $result->response = get_string('thatsthecorrectanswer', 'lesson');
                     } else {
                         $result->response = get_string('thatsthewronganswer', 'lesson');
                     }
                 }
             }
         }
         if ($result->response) {
             if ($this->lesson->review && !$result->correctanswer && !$result->isessayquestion) {
                 $nretakes = $DB->count_records("lesson_grades", array("lessonid" => $this->lesson->id, "userid" => $USER->id));
                 $qattempts = $DB->count_records("lesson_attempts", array("userid" => $USER->id, "retry" => $nretakes, "pageid" => $this->properties->id));
                 if ($qattempts == 1) {
                     $result->feedback = $OUTPUT->box(get_string("firstwrong", "lesson"), 'feedback');
                 } else {
                     $result->feedback = $OUTPUT->box(get_string("secondpluswrong", "lesson"), 'feedback');
                 }
             } else {
                 $result->feedback = '';
             }
             $class = 'response';
             if ($result->correctanswer) {
                 $class .= ' correct';
                 // CSS over-ride this if they exist (!important).
             } else {
                 if (!$result->isessayquestion) {
                     $class .= ' incorrect';
                     // CSS over-ride this if they exist (!important).
                 }
             }
             $options = new stdClass();
             $options->noclean = true;
             $options->para = true;
             $options->overflowdiv = true;
             $options->context = $context;
             $result->feedback .= $OUTPUT->box(format_text($this->get_contents(), $this->properties->contentsformat, $options), 'generalbox boxaligncenter');
             if (isset($result->studentanswerformat)) {
                 // This is the student's answer so it should be cleaned.
                 $studentanswer = format_text($result->studentanswer, $result->studentanswerformat, array('context' => $context, 'para' => true));
             } else {
                 $studentanswer = format_string($result->studentanswer);
             }
             $result->feedback .= '<div class="correctanswer generalbox"><em>' . get_string("youranswer", "lesson") . '</em> : ' . $studentanswer;
             if (isset($result->responseformat)) {
                 $result->response = file_rewrite_pluginfile_urls($result->response, 'pluginfile.php', $context->id, 'mod_lesson', 'page_responses', $result->answerid);
                 $result->feedback .= $OUTPUT->box(format_text($result->response, $result->responseformat, $options), $class);
             } else {
                 $result->feedback .= $OUTPUT->box($result->response, $class);
             }
             $result->feedback .= '</div>';
         }
     }
     return $result;
 }