Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]

   1  <?php
   2  
   3  // This file is part of Moodle - http://moodle.org/
   4  //
   5  // Moodle is free software: you can redistribute it and/or modify
   6  // it under the terms of the GNU General Public License as published by
   7  // the Free Software Foundation, either version 3 of the License, or
   8  // (at your option) any later version.
   9  //
  10  // Moodle is distributed in the hope that it will be useful,
  11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13  // GNU General Public License for more details.
  14  //
  15  // You should have received a copy of the GNU General Public License
  16  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  17  
  18  /**
  19   * Matching
  20   *
  21   * @package mod_lesson
  22   * @copyright  2009 Sam Hemelryk
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   **/
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  /** Matching question type */
  29  define("LESSON_PAGE_MATCHING",      "5");
  30  
  31  class lesson_page_type_matching extends lesson_page {
  32  
  33      protected $type = lesson_page::TYPE_QUESTION;
  34      protected $typeid = LESSON_PAGE_MATCHING;
  35      protected $typeidstring = 'matching';
  36      protected $string = null;
  37  
  38      public function get_typeid() {
  39          return $this->typeid;
  40      }
  41      public function get_typestring() {
  42          if ($this->string===null) {
  43              $this->string = get_string($this->typeidstring, 'lesson');
  44          }
  45          return $this->string;
  46      }
  47      public function get_idstring() {
  48          return $this->typeidstring;
  49      }
  50      public function display($renderer, $attempt) {
  51          global $USER, $CFG, $PAGE;
  52          $mform = $this->make_answer_form($attempt);
  53          $data = new stdClass;
  54          $data->id = $PAGE->cm->id;
  55          $data->pageid = $this->properties->id;
  56          $mform->set_data($data);
  57  
  58          // Trigger an event question viewed.
  59          $eventparams = array(
  60              'context' => context_module::instance($PAGE->cm->id),
  61              'objectid' => $this->properties->id,
  62              'other' => array(
  63                      'pagetype' => $this->get_typestring()
  64                  )
  65              );
  66  
  67          $event = \mod_lesson\event\question_viewed::create($eventparams);
  68          $event->trigger();
  69          return $mform->display();
  70      }
  71  
  72      protected function make_answer_form($attempt=null) {
  73          global $USER, $CFG;
  74          // don't shuffle answers (could be an option??)
  75          $getanswers = array_slice($this->get_answers(), 2);
  76  
  77          $answers = array();
  78          foreach ($getanswers as $getanswer) {
  79              $answers[$getanswer->id] = $getanswer;
  80          }
  81  
  82          $responses = array();
  83          foreach ($answers as $answer) {
  84              // get all the response
  85              if ($answer->response != null) {
  86                  $responses[] = format_text(trim($answer->response));
  87              }
  88          }
  89  
  90          $responseoptions = array(''=>get_string('choosedots'));
  91          if (!empty($responses)) {
  92              shuffle($responses);
  93              foreach ($responses as  $response) {
  94                  $responseoptions[htmlspecialchars($response, ENT_COMPAT)] = $response;
  95              }
  96          }
  97          if (isset($USER->modattempts[$this->lesson->id]) && !empty($attempt->useranswer)) {
  98              $useranswers = explode(',', $attempt->useranswer);
  99              $t = 0;
 100          } else {
 101              $useranswers = array();
 102          }
 103  
 104          $action = $CFG->wwwroot.'/mod/lesson/continue.php';
 105          $params = array('answers'=>$answers, 'useranswers'=>$useranswers, 'responseoptions'=>$responseoptions, 'lessonid'=>$this->lesson->id, 'contents'=>$this->get_contents());
 106          $mform = new lesson_display_answer_form_matching($action, $params);
 107          return $mform;
 108      }
 109  
 110      public function create_answers($properties) {
 111          global $DB, $PAGE;
 112          // now add the answers
 113          $newanswer = new stdClass;
 114          $newanswer->lessonid = $this->lesson->id;
 115          $newanswer->pageid = $this->properties->id;
 116          $newanswer->timecreated = $this->properties->timecreated;
 117  
 118          $cm = get_coursemodule_from_instance('lesson', $this->lesson->id, $this->lesson->course);
 119          $context = context_module::instance($cm->id);
 120  
 121          // Check for duplicate response format.
 122          $duplicateresponse = array();
 123          if (is_array($properties->response_editor) &&             // If there are response_editors to iterate.
 124                  is_array(reset($properties->response_editor))) {  // And they come split into text & format array.
 125              foreach ($properties->response_editor as $response) { // Iterate over all them.
 126                  $duplicateresponse[] = $response['text'];         // Picking the text only. This pagetype is that way.
 127              }
 128              $properties->response_editor = $duplicateresponse;
 129          }
 130  
 131          $answers = array();
 132  
 133          // need to add two to offset correct response and wrong response
 134          $this->lesson->maxanswers = $this->lesson->maxanswers + 2;
 135          for ($i = 0; $i < $this->lesson->maxanswers; $i++) {
 136              $answer = clone($newanswer);
 137              if (!empty($properties->answer_editor[$i]) && is_array($properties->answer_editor[$i])) {
 138                  $answer->answer = $properties->answer_editor[$i]['text'];
 139                  $answer->answerformat = $properties->answer_editor[$i]['format'];
 140              }
 141              if (!empty($properties->response_editor[$i])) {
 142                  $answer->response = $properties->response_editor[$i];
 143                  $answer->responseformat = 0;
 144              }
 145  
 146              if (isset($properties->jumpto[$i])) {
 147                  $answer->jumpto = $properties->jumpto[$i];
 148              }
 149              if ($this->lesson->custom && isset($properties->score[$i])) {
 150                  $answer->score = $properties->score[$i];
 151              }
 152  
 153              if (isset($answer->answer) && $answer->answer != '') {
 154                  $answer->id = $DB->insert_record("lesson_answers", $answer);
 155                  $this->save_answers_files($context, $PAGE->course->maxbytes,
 156                          $answer, $properties->answer_editor[$i]);
 157                  $answers[$answer->id] = new lesson_page_answer($answer);
 158              } else if ($i < 2) {
 159                  $answer->id = $DB->insert_record("lesson_answers", $answer);
 160                  $answers[$answer->id] = new lesson_page_answer($answer);
 161              } else {
 162                  break;
 163              }
 164          }
 165          $this->answers = $answers;
 166          return $answers;
 167      }
 168  
 169      public function check_answer() {
 170          global $CFG, $PAGE;
 171  
 172          $formattextdefoptions = new stdClass();
 173          $formattextdefoptions->noclean = true;
 174          $formattextdefoptions->para = false;
 175  
 176          $result = parent::check_answer();
 177  
 178          $mform = $this->make_answer_form();
 179  
 180          $data = $mform->get_data();
 181          require_sesskey();
 182  
 183          if (!$data) {
 184              $result->inmediatejump = true;
 185              $result->newpageid = $this->properties->id;
 186              return $result;
 187          }
 188  
 189          $response = $data->response;
 190          $getanswers = $this->get_answers();
 191          foreach ($getanswers as $key => $answer) {
 192              $getanswers[$key] = parent::rewrite_answers_urls($answer);
 193          }
 194  
 195          $correct = array_shift($getanswers);
 196          $wrong   = array_shift($getanswers);
 197  
 198          $answers = array();
 199          foreach ($getanswers as $key => $answer) {
 200              if ($answer->answer !== '' or $answer->response !== '') {
 201                  $answers[$answer->id] = $answer;
 202              }
 203          }
 204  
 205          // get the user's exact responses for record keeping
 206          $hits = 0;
 207          $userresponse = array();
 208          $result->studentanswerformat = FORMAT_HTML;
 209          foreach ($response as $id => $value) {
 210              if ($value == '') {
 211                  $result->noanswer = true;
 212                  return $result;
 213              }
 214              $value = htmlspecialchars_decode($value, ENT_COMPAT);
 215              $userresponse[] = $value;
 216              // Make sure the user's answer exists in question's answer
 217              if (array_key_exists($id, $answers)) {
 218                  $answer = $answers[$id];
 219                  $result->studentanswer .= '<br />'.format_text($answer->answer, $answer->answerformat, $formattextdefoptions).' = '.$value;
 220                  if (trim($answer->response) == trim($value)) {
 221                      $hits++;
 222                  }
 223              }
 224          }
 225  
 226          $result->userresponse = implode(",", $userresponse);
 227  
 228          if ($hits == count($answers)) {
 229              $result->correctanswer = true;
 230              $result->response      = format_text($correct->answer, $correct->answerformat, $formattextdefoptions);
 231              $result->answerid      = $correct->id;
 232              $result->newpageid     = $correct->jumpto;
 233          } else {
 234              $result->correctanswer = false;
 235              $result->response      = format_text($wrong->answer, $wrong->answerformat, $formattextdefoptions);
 236              $result->answerid      = $wrong->id;
 237              $result->newpageid     = $wrong->jumpto;
 238          }
 239  
 240          return $result;
 241      }
 242  
 243      public function option_description_string() {
 244          return get_string("firstanswershould", "lesson");
 245      }
 246  
 247      public function display_answers(html_table $table) {
 248          $answers = $this->get_answers();
 249          $options = new stdClass;
 250          $options->noclean = true;
 251          $options->para = false;
 252          $i = 1;
 253          $n = 0;
 254  
 255          foreach ($answers as $answer) {
 256              $answer = parent::rewrite_answers_urls($answer);
 257              if ($n < 2) {
 258                  if ($answer->answer != null) {
 259                      $cells = array();
 260                      if ($n == 0) {
 261                          $cells[] = '<label>' . get_string('correctresponse', 'lesson') . '</label>';
 262                      } else {
 263                          $cells[] = '<label>' . get_string('wrongresponse', 'lesson') . '</label>';
 264                      }
 265                      $cells[] = format_text($answer->answer, $answer->answerformat, $options);
 266                      $table->data[] = new html_table_row($cells);
 267                  }
 268  
 269                  if ($n == 0) {
 270                      $cells = array();
 271                      $cells[] = '<label>' . get_string('correctanswerscore', 'lesson') . '</label>: ';
 272                      $cells[] = $answer->score;
 273                      $table->data[] = new html_table_row($cells);
 274  
 275                      $cells = array();
 276                      $cells[] = '<label>' . get_string('correctanswerjump', 'lesson') . '</label>: ';
 277                      $cells[] = $this->get_jump_name($answer->jumpto);
 278                      $table->data[] = new html_table_row($cells);
 279                  } elseif ($n == 1) {
 280                      $cells = array();
 281                      $cells[] = '<label>' . get_string('wronganswerscore', 'lesson') . '</label>: ';
 282                      $cells[] = $answer->score;
 283                      $table->data[] = new html_table_row($cells);
 284  
 285                      $cells = array();
 286                      $cells[] = '<label>' . get_string('wronganswerjump', 'lesson') . '</label>: ';
 287                      $cells[] = $this->get_jump_name($answer->jumpto);
 288                      $table->data[] = new html_table_row($cells);
 289                  }
 290  
 291                  if ($n === 0){
 292                      $table->data[count($table->data)-1]->cells[0]->style = 'width:20%;';
 293                  }
 294                  $n++;
 295                  $i--;
 296              } else {
 297                  $cells = array();
 298                  if ($this->lesson->custom && $answer->score > 0) {
 299                      // if the score is > 0, then it is correct
 300                      $cells[] = '<label class="correct">' . get_string('answer', 'lesson') . " {$i}</label>: \n";
 301                  } else if ($this->lesson->custom) {
 302                      $cells[] = '<label>' . get_string('answer', 'lesson') . " {$i}</label>: \n";
 303                  } else if ($this->lesson->jumpto_is_correct($this->properties->id, $answer->jumpto)) {
 304                      $cells[] = '<label class="correct">' . get_string('answer', 'lesson') . " {$i}</label>: \n";
 305                  } else {
 306                      $cells[] = '<label>' . get_string('answer', 'lesson') . " {$i}</label>: \n";
 307                  }
 308                  $cells[] = format_text($answer->answer, $answer->answerformat, $options);
 309                  $table->data[] = new html_table_row($cells);
 310  
 311                  $cells = array();
 312                  $cells[] = '<label>' . get_string('matchesanswer', 'lesson') . " {$i}</label>: \n";
 313                  $cells[] = format_text($answer->response, $answer->responseformat, $options);
 314                  $table->data[] = new html_table_row($cells);
 315              }
 316              $i++;
 317          }
 318          return $table;
 319      }
 320      /**
 321       * Updates the page and its answers
 322       *
 323       * @global moodle_database $DB
 324       * @global moodle_page $PAGE
 325       * @param stdClass $properties
 326       * @return bool
 327       */
 328      public function update($properties, $context = null, $maxbytes = null) {
 329          global $DB, $PAGE;
 330          $answers  = $this->get_answers();
 331          $properties->id = $this->properties->id;
 332          $properties->lessonid = $this->lesson->id;
 333          $properties->timemodified = time();
 334          $properties = file_postupdate_standard_editor($properties, 'contents', array('noclean'=>true, 'maxfiles'=>EDITOR_UNLIMITED_FILES, 'maxbytes'=>$PAGE->course->maxbytes), context_module::instance($PAGE->cm->id), 'mod_lesson', 'page_contents', $properties->id);
 335          $DB->update_record("lesson_pages", $properties);
 336  
 337          // Trigger an event: page updated.
 338          \mod_lesson\event\page_updated::create_from_lesson_page($this, $context)->trigger();
 339  
 340          // need to add two to offset correct response and wrong response
 341          $this->lesson->maxanswers += 2;
 342          for ($i = 0; $i < $this->lesson->maxanswers; $i++) {
 343              if (!array_key_exists($i, $this->answers)) {
 344                  $this->answers[$i] = new stdClass;
 345                  $this->answers[$i]->lessonid = $this->lesson->id;
 346                  $this->answers[$i]->pageid = $this->id;
 347                  $this->answers[$i]->timecreated = $this->timecreated;
 348              }
 349  
 350              if (!empty($properties->answer_editor[$i]) && is_array($properties->answer_editor[$i])) {
 351                  $this->answers[$i]->answer = $properties->answer_editor[$i]['text'];
 352                  $this->answers[$i]->answerformat = $properties->answer_editor[$i]['format'];
 353              }
 354              if (!empty($properties->response_editor[$i])) {
 355                  $this->answers[$i]->response = $properties->response_editor[$i];
 356                  $this->answers[$i]->responseformat = 0;
 357              }
 358  
 359              if (isset($properties->jumpto[$i])) {
 360                  $this->answers[$i]->jumpto = $properties->jumpto[$i];
 361              }
 362              if ($this->lesson->custom && isset($properties->score[$i])) {
 363                  $this->answers[$i]->score = $properties->score[$i];
 364              }
 365  
 366              // we don't need to check for isset here because properties called it's own isset method.
 367              if ($this->answers[$i]->answer != '') {
 368                  if (!isset($this->answers[$i]->id)) {
 369                      $this->answers[$i]->id =  $DB->insert_record("lesson_answers", $this->answers[$i]);
 370                  } else {
 371                      $DB->update_record("lesson_answers", $this->answers[$i]->properties());
 372                  }
 373                  // Save files in answers (no response_editor for matching questions).
 374                  $this->save_answers_files($context, $maxbytes, $this->answers[$i], $properties->answer_editor[$i]);
 375              } else if ($i < 2) {
 376                  if (!isset($this->answers[$i]->id)) {
 377                      $this->answers[$i]->id =  $DB->insert_record("lesson_answers", $this->answers[$i]);
 378                  } else {
 379                      $DB->update_record("lesson_answers", $this->answers[$i]->properties());
 380                  }
 381  
 382                  // Save files in answers (no response_editor for matching questions).
 383                  $this->save_answers_files($context, $maxbytes, $this->answers[$i], $properties->answer_editor[$i]);
 384              } else if (isset($this->answers[$i]->id)) {
 385                  $DB->delete_records('lesson_answers', array('id'=>$this->answers[$i]->id));
 386                  unset($this->answers[$i]);
 387              }
 388          }
 389          return true;
 390      }
 391      public function stats(array &$pagestats, $tries) {
 392          $temp = $this->lesson->get_last_attempt($tries);
 393          if ($temp->correct) {
 394              if (isset($pagestats[$temp->pageid]["correct"])) {
 395                  $pagestats[$temp->pageid]["correct"]++;
 396              } else {
 397                  $pagestats[$temp->pageid]["correct"] = 1;
 398              }
 399          }
 400          if (isset($pagestats[$temp->pageid]["total"])) {
 401              $pagestats[$temp->pageid]["total"]++;
 402          } else {
 403              $pagestats[$temp->pageid]["total"] = 1;
 404          }
 405          return true;
 406      }
 407      public function report_answers($answerpage, $answerdata, $useranswer, $pagestats, &$i, &$n) {
 408          $answers = array();
 409          foreach ($this->get_answers() as $answer) {
 410              $answers[$answer->id] = $answer;
 411          }
 412          $formattextdefoptions = new stdClass;
 413          $formattextdefoptions->para = false;  //I'll use it widely in this page
 414          foreach ($answers as $answer) {
 415              if ($n == 0 && $useranswer != null && $useranswer->correct) {
 416                  if ($answer->response == null && $useranswer != null) {
 417                      $answerdata->response = get_string("thatsthecorrectanswer", "lesson");
 418                  } else {
 419                      $answerdata->response = $answer->response;
 420                  }
 421                  if ($this->lesson->custom) {
 422                      $answerdata->score = get_string("pointsearned", "lesson").": ".$answer->score;
 423                  } else {
 424                      $answerdata->score = get_string("receivedcredit", "lesson");
 425                  }
 426              } elseif ($n == 1 && $useranswer != null && !$useranswer->correct) {
 427                  if ($answer->response == null && $useranswer != null) {
 428                      $answerdata->response = get_string("thatsthewronganswer", "lesson");
 429                  } else {
 430                      $answerdata->response = $answer->response;
 431                  }
 432                  if ($this->lesson->custom) {
 433                      $answerdata->score = get_string("pointsearned", "lesson").": ".$answer->score;
 434                  } else {
 435                      $answerdata->score = get_string("didnotreceivecredit", "lesson");
 436                  }
 437              } elseif ($n > 1) {
 438                  $data = '<label class="accesshide" for="answer_' . $n . '">' . get_string('answer', 'lesson') . '</label>';
 439                  $data .= strip_tags(format_string($answer->answer)) . ' ';
 440                  if ($useranswer != null) {
 441                      $userresponse = explode(",", $useranswer->useranswer);
 442                      $data .= '<label class="accesshide" for="stu_answer_response_' . $n . '">' . get_string('matchesanswer', 'lesson') . '</label>';
 443                      $data .= "<select class=\"custom-select\" id=\"stu_answer_response_" . $n . "\" " .
 444                               "disabled=\"disabled\"><option selected=\"selected\">";
 445                      if (array_key_exists($i, $userresponse)) {
 446                          $data .= $userresponse[$i];
 447                      }
 448                      $data .= "</option></select>";
 449                  } else {
 450                      $data .= '<label class="accesshide" for="answer_response_' . $n . '">' . get_string('matchesanswer', 'lesson') . '</label>';
 451                      $data .= "<select class=\"custom-select\" id=\"answer_response_" . $n . "\" " .
 452                               "disabled=\"disabled\"><option selected=\"selected\">".strip_tags(format_string($answer->response))."</option></select>";
 453                  }
 454  
 455                  if ($n == 2) {
 456                      if (isset($pagestats[$this->properties->id])) {
 457                          if (!array_key_exists('correct', $pagestats[$this->properties->id])) {
 458                              $pagestats[$this->properties->id]["correct"] = 0;
 459                          }
 460                          $percent = $pagestats[$this->properties->id]["correct"] / $pagestats[$this->properties->id]["total"] * 100;
 461                          $percent = round($percent, 2);
 462                          $percent .= "% ".get_string("answeredcorrectly", "lesson");
 463                      } else {
 464                          $percent = get_string("nooneansweredthisquestion", "lesson");
 465                      }
 466                  } else {
 467                      $percent = '';
 468                  }
 469  
 470                  $answerdata->answers[] = array($data, $percent);
 471                  $i++;
 472              }
 473              $n++;
 474              $answerpage->answerdata = $answerdata;
 475          }
 476          return $answerpage;
 477      }
 478      public function get_jumps() {
 479          global $DB;
 480          // The jumps for matching question type are stored in the 1st and 2nd answer record.
 481          $jumps = array();
 482          if ($answers = $DB->get_records("lesson_answers", array("lessonid" => $this->lesson->id, "pageid" => $this->properties->id), 'id', '*', 0, 2)) {
 483              foreach ($answers as $answer) {
 484                  $jumps[] = $this->get_jump_name($answer->jumpto);
 485              }
 486          } else {
 487              $jumps[] = $this->get_jump_name($this->properties->nextpageid);
 488          }
 489          return $jumps;
 490      }
 491  }
 492  
 493  class lesson_add_page_form_matching extends lesson_add_page_form_base {
 494  
 495      public $qtype = 'matching';
 496      public $qtypestring = 'matching';
 497      protected $answerformat = LESSON_ANSWER_HTML;
 498      protected $responseformat = '';
 499  
 500      public function custom_definition() {
 501  
 502          $this->_form->addElement('header', 'correctresponse', get_string('correctresponse', 'lesson'));
 503          $this->_form->addElement('editor', 'answer_editor[0]', get_string('correctresponse', 'lesson'),
 504                  array('rows' => '4', 'columns' => '80'),
 505                  array('noclean' => true, 'maxfiles' => EDITOR_UNLIMITED_FILES, 'maxbytes' => $this->_customdata['maxbytes']));
 506          $this->_form->setType('answer_editor[0]', PARAM_RAW);
 507          $this->_form->setDefault('answer_editor[0]', array('text' => '', 'format' => FORMAT_HTML));
 508          $this->add_jumpto(0, get_string('correctanswerjump','lesson'), LESSON_NEXTPAGE);
 509          $this->add_score(0, get_string("correctanswerscore", "lesson"), 1);
 510  
 511          $this->_form->addElement('header', 'wrongresponse', get_string('wrongresponse', 'lesson'));
 512          $this->_form->addElement('editor', 'answer_editor[1]', get_string('wrongresponse', 'lesson'),
 513                  array('rows' => '4', 'columns' => '80'),
 514                  array('noclean' => true, 'maxfiles' => EDITOR_UNLIMITED_FILES, 'maxbytes' => $this->_customdata['maxbytes']));
 515          $this->_form->setType('answer_editor[1]', PARAM_RAW);
 516          $this->_form->setDefault('answer_editor[1]', array('text' => '', 'format' => FORMAT_HTML));
 517  
 518          $this->add_jumpto(1, get_string('wronganswerjump','lesson'), LESSON_THISPAGE);
 519          $this->add_score(1, get_string("wronganswerscore", "lesson"), 0);
 520  
 521          for ($i = 2; $i < $this->_customdata['lesson']->maxanswers+2; $i++) {
 522              $this->_form->addElement('header', 'matchingpair'.($i-1), get_string('matchingpair', 'lesson', $i-1));
 523              $this->add_answer($i, null, ($i < 4), LESSON_ANSWER_HTML);
 524              $required = ($i < 4);
 525              $label = get_string('matchesanswer','lesson');
 526              $count = $i;
 527              $this->_form->addElement('text', 'response_editor['.$count.']', $label, array('size'=>'50'));
 528              $this->_form->setType('response_editor['.$count.']', PARAM_NOTAGS);
 529              $this->_form->setDefault('response_editor['.$count.']', '');
 530              if ($required) {
 531                  $this->_form->addRule('response_editor['.$count.']', get_string('required'), 'required', null, 'client');
 532              }
 533          }
 534      }
 535  }
 536  
 537  class lesson_display_answer_form_matching extends moodleform {
 538  
 539      public function definition() {
 540          global $USER, $OUTPUT, $PAGE;
 541          $mform = $this->_form;
 542          $answers = $this->_customdata['answers'];
 543          $useranswers = $this->_customdata['useranswers'];
 544          $responseoptions = $this->_customdata['responseoptions'];
 545          $lessonid = $this->_customdata['lessonid'];
 546          $contents = $this->_customdata['contents'];
 547  
 548          // Disable shortforms.
 549          $mform->setDisableShortforms();
 550  
 551          $mform->addElement('header', 'pageheader');
 552  
 553          $mform->addElement('html', $OUTPUT->container($contents, 'contents'));
 554  
 555          $hasattempt = false;
 556          $disabled = '';
 557          if (isset($useranswers) && !empty($useranswers)) {
 558              $hasattempt = true;
 559              $disabled = array('disabled' => 'disabled');
 560          }
 561  
 562          $options = new stdClass;
 563          $options->para = false;
 564          $options->noclean = true;
 565  
 566          $mform->addElement('hidden', 'id');
 567          $mform->setType('id', PARAM_INT);
 568  
 569          $mform->addElement('hidden', 'pageid');
 570          $mform->setType('pageid', PARAM_INT);
 571  
 572          $i = 0;
 573  
 574          foreach ($answers as $answer) {
 575              $mform->addElement('html', '<div class="answeroption">');
 576              if ($answer->response != null) {
 577                  $responseid = 'response['.$answer->id.']';
 578                  if ($hasattempt) {
 579                      $responseid = 'response_'.$answer->id;
 580                      $mform->addElement('hidden', 'response['.$answer->id.']', htmlspecialchars($useranswers[$i], ENT_COMPAT));
 581                      // Temporary fixed until MDL-38885 gets integrated
 582                      $mform->setType('response', PARAM_TEXT);
 583                  }
 584                  $answer = lesson_page_type_matching::rewrite_answers_urls($answer);
 585                  $mform->addElement('select', $responseid, format_text($answer->answer,$answer->answerformat,$options), $responseoptions, $disabled);
 586                  $mform->setType($responseid, PARAM_TEXT);
 587                  if ($hasattempt) {
 588                      $mform->setDefault($responseid, htmlspecialchars(trim($useranswers[$i]), ENT_COMPAT));
 589                  } else {
 590                      $mform->setDefault($responseid, 'answeroption');
 591                  }
 592              }
 593              $mform->addElement('html', '</div>');
 594              $i++;
 595          }
 596          if ($hasattempt) {
 597              $this->add_action_buttons(null, get_string("nextpage", "lesson"));
 598          } else {
 599              $this->add_action_buttons(null, get_string("submit", "lesson"));
 600          }
 601      }
 602  
 603  }