Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Matching question renderer class.
  19   *
  20   * @package   qtype_match
  21   * @copyright 2009 The Open University
  22   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  
  29  /**
  30   * Generates the output for matching questions.
  31   *
  32   * @copyright 2009 The Open University
  33   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  34   */
  35  class qtype_match_renderer extends qtype_with_combined_feedback_renderer {
  36  
  37      public function formulation_and_controls(question_attempt $qa,
  38              question_display_options $options) {
  39  
  40          $question = $qa->get_question();
  41          $stemorder = $question->get_stem_order();
  42          $response = $qa->get_last_qt_data();
  43  
  44          $choices = $this->format_choices($question);
  45  
  46          $result = '';
  47          $result .= html_writer::tag('div', $question->format_questiontext($qa),
  48                  array('class' => 'qtext'));
  49  
  50          $result .= html_writer::start_tag('div', array('class' => 'ablock'));
  51          $result .= html_writer::start_tag('table', array('class' => 'answer'));
  52          $result .= html_writer::start_tag('tbody');
  53  
  54          $parity = 0;
  55          $i = 1;
  56          foreach ($stemorder as $key => $stemid) {
  57  
  58              $result .= html_writer::start_tag('tr', array('class' => 'r' . $parity));
  59              $fieldname = 'sub' . $key;
  60  
  61              $result .= html_writer::tag('td', $this->format_stem_text($qa, $stemid),
  62                      array('class' => 'text'));
  63  
  64              $classes = 'control';
  65              $feedbackimage = '';
  66  
  67              if (array_key_exists($fieldname, $response)) {
  68                  $selected = $response[$fieldname];
  69              } else {
  70                  $selected = 0;
  71              }
  72  
  73              $fraction = (int) ($selected && $selected == $question->get_right_choice_for($stemid));
  74  
  75              if ($options->correctness && $selected) {
  76                  $classes .= ' ' . $this->feedback_class($fraction);
  77                  $feedbackimage = $this->feedback_image($fraction);
  78              }
  79  
  80              $result .= html_writer::tag('td',
  81                      html_writer::label(get_string('answer', 'qtype_match', $i),
  82                              'menu' . $qa->get_qt_field_name('sub' . $key), false,
  83                              array('class' => 'accesshide')) .
  84                      html_writer::select($choices, $qa->get_qt_field_name('sub' . $key), $selected,
  85                              array('0' => 'choose'), array('disabled' => $options->readonly, 'class' => 'custom-select ml-1')) .
  86                      ' ' . $feedbackimage, array('class' => $classes));
  87  
  88              $result .= html_writer::end_tag('tr');
  89              $parity = 1 - $parity;
  90              $i++;
  91          }
  92          $result .= html_writer::end_tag('tbody');
  93          $result .= html_writer::end_tag('table');
  94  
  95          $result .= html_writer::end_tag('div'); // Closes <div class="ablock">.
  96  
  97          if ($qa->get_state() == question_state::$invalid) {
  98              $result .= html_writer::nonempty_tag('div',
  99                      $question->get_validation_error($response),
 100                      array('class' => 'validationerror'));
 101          }
 102  
 103          return $result;
 104      }
 105  
 106      public function specific_feedback(question_attempt $qa) {
 107          return $this->combined_feedback($qa);
 108      }
 109  
 110      /**
 111       * Format each question stem. Overwritten by randomsamatch renderer.
 112       *
 113       * @param question_attempt $qa
 114       * @param integer $stemid stem index
 115       * @return string
 116       */
 117      public function format_stem_text($qa, $stemid) {
 118          $question = $qa->get_question();
 119          return $question->format_text(
 120                      $question->stems[$stemid], $question->stemformat[$stemid],
 121                      $qa, 'qtype_match', 'subquestion', $stemid);
 122      }
 123  
 124      protected function format_choices($question) {
 125          $choices = array();
 126          foreach ($question->get_choice_order() as $key => $choiceid) {
 127              $choices[$key] = format_string($question->choices[$choiceid]);
 128          }
 129          return $choices;
 130      }
 131  
 132      public function correct_response(question_attempt $qa) {
 133          $question = $qa->get_question();
 134          $stemorder = $question->get_stem_order();
 135  
 136          $choices = $this->format_choices($question);
 137          $right = array();
 138          foreach ($stemorder as $key => $stemid) {
 139              if (!isset($choices[$question->get_right_choice_for($stemid)])) {
 140                  continue;
 141              }
 142              $right[] = $question->make_html_inline($this->format_stem_text($qa, $stemid)) . ' &#x2192; ' .
 143                      $choices[$question->get_right_choice_for($stemid)];
 144          }
 145  
 146          if (!empty($right)) {
 147              return get_string('correctansweris', 'qtype_match', implode(', ', $right));
 148          }
 149      }
 150  }