PageRenderTime 44ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/question/type/rendererbase.php

https://gitlab.com/JrLucena/moodle
PHP | 271 lines | 115 code | 30 blank | 126 comment | 12 complexity | d2894f4c208ee47e35099fa4138e50e7 MD5 | raw file
  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. * Defines the renderer base classes for question types.
  18. *
  19. * @package moodlecore
  20. * @subpackage questiontypes
  21. * @copyright 2009 The Open University
  22. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23. */
  24. defined('MOODLE_INTERNAL') || die();
  25. /**
  26. * Renderer base classes for question types.
  27. *
  28. * @copyright 2009 The Open University
  29. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  30. */
  31. abstract class qtype_renderer extends plugin_renderer_base {
  32. /**
  33. * Generate the display of the formulation part of the question. This is the
  34. * area that contains the quetsion text, and the controls for students to
  35. * input their answers. Some question types also embed bits of feedback, for
  36. * example ticks and crosses, in this area.
  37. *
  38. * @param question_attempt $qa the question attempt to display.
  39. * @param question_display_options $options controls what should and should not be displayed.
  40. * @return string HTML fragment.
  41. */
  42. public function formulation_and_controls(question_attempt $qa,
  43. question_display_options $options) {
  44. return $qa->get_question()->format_questiontext($qa);
  45. }
  46. /**
  47. * In the question output there are some class="accesshide" headers to help
  48. * screen-readers. This method returns the text to use for the heading above
  49. * the formulation_and_controls section.
  50. * @return string to use as the heading.
  51. */
  52. public function formulation_heading() {
  53. return get_string('questiontext', 'question');
  54. }
  55. /**
  56. * Output hidden form fields to clear any wrong parts of the student's response.
  57. *
  58. * This method will only be called if the question is in read-only mode.
  59. * @param question_attempt $qa the question attempt to display.
  60. * @return string HTML fragment.
  61. */
  62. public function clear_wrong(question_attempt $qa) {
  63. $response = $qa->get_last_qt_data();
  64. if (!$response) {
  65. return '';
  66. }
  67. $cleanresponse = $qa->get_question()->clear_wrong_from_response($response);
  68. $output = '';
  69. foreach ($cleanresponse as $name => $value) {
  70. $attr = array(
  71. 'type' => 'hidden',
  72. 'name' => $qa->get_qt_field_name($name),
  73. 'value' => s($value),
  74. );
  75. $output .= html_writer::empty_tag('input', $attr);
  76. }
  77. return $output;
  78. }
  79. /**
  80. * Generate the display of the outcome part of the question. This is the
  81. * area that contains the various forms of feedback. This function generates
  82. * the content of this area belonging to the question type.
  83. *
  84. * Subclasses will normally want to override the more specific methods
  85. * {specific_feedback()}, {general_feedback()} and {correct_response()}
  86. * that this method calls.
  87. *
  88. * @param question_attempt $qa the question attempt to display.
  89. * @param question_display_options $options controls what should and should not be displayed.
  90. * @return string HTML fragment.
  91. */
  92. public function feedback(question_attempt $qa, question_display_options $options) {
  93. $output = '';
  94. $hint = null;
  95. if ($options->feedback) {
  96. $output .= html_writer::nonempty_tag('div', $this->specific_feedback($qa),
  97. array('class' => 'specificfeedback'));
  98. $hint = $qa->get_applicable_hint();
  99. }
  100. if ($options->numpartscorrect) {
  101. $output .= html_writer::nonempty_tag('div', $this->num_parts_correct($qa),
  102. array('class' => 'numpartscorrect'));
  103. }
  104. if ($hint) {
  105. $output .= $this->hint($qa, $hint);
  106. }
  107. if ($options->generalfeedback) {
  108. $output .= html_writer::nonempty_tag('div', $this->general_feedback($qa),
  109. array('class' => 'generalfeedback'));
  110. }
  111. if ($options->rightanswer) {
  112. $output .= html_writer::nonempty_tag('div', $this->correct_response($qa),
  113. array('class' => 'rightanswer'));
  114. }
  115. return $output;
  116. }
  117. /**
  118. * Generate the specific feedback. This is feedback that varies according to
  119. * the response the student gave.
  120. * @param question_attempt $qa the question attempt to display.
  121. * @return string HTML fragment.
  122. */
  123. protected function specific_feedback(question_attempt $qa) {
  124. return '';
  125. }
  126. /**
  127. * Gereate a brief statement of how many sub-parts of this question the
  128. * student got right.
  129. * @param question_attempt $qa the question attempt to display.
  130. * @return string HTML fragment.
  131. */
  132. protected function num_parts_correct(question_attempt $qa) {
  133. $a = new stdClass();
  134. list($a->num, $a->outof) = $qa->get_question()->get_num_parts_right(
  135. $qa->get_last_qt_data());
  136. if (is_null($a->outof)) {
  137. return '';
  138. } else {
  139. return get_string('yougotnright', 'question', $a);
  140. }
  141. }
  142. /**
  143. * Gereate the specific feedback. This is feedback that varies according to
  144. * the response the student gave.
  145. * @param question_attempt $qa the question attempt to display.
  146. * @return string HTML fragment.
  147. */
  148. protected function hint(question_attempt $qa, question_hint $hint) {
  149. return html_writer::nonempty_tag('div',
  150. $qa->get_question()->format_hint($hint, $qa), array('class' => 'hint'));
  151. }
  152. /**
  153. * Gereate the general feedback. This is feedback is shown ot all students.
  154. *
  155. * @param question_attempt $qa the question attempt to display.
  156. * @return string HTML fragment.
  157. */
  158. protected function general_feedback(question_attempt $qa) {
  159. return $qa->get_question()->format_generalfeedback($qa);
  160. }
  161. /**
  162. * Gereate an automatic description of the correct response to this question.
  163. * Not all question types can do this. If it is not possible, this method
  164. * should just return an empty string.
  165. *
  166. * @param question_attempt $qa the question attempt to display.
  167. * @return string HTML fragment.
  168. */
  169. protected function correct_response(question_attempt $qa) {
  170. return '';
  171. }
  172. /**
  173. * Display any extra question-type specific content that should be visible
  174. * when grading, if appropriate.
  175. *
  176. * @param question_attempt $qa a question attempt.
  177. * @param question_display_options $options controls what should and should not be displayed.
  178. * @return string HTML fragment.
  179. */
  180. public function manual_comment(question_attempt $qa, question_display_options $options) {
  181. return '';
  182. }
  183. /**
  184. * Return any HTML that needs to be included in the page's <head> when this
  185. * question is used.
  186. * @param $qa the question attempt that will be displayed on the page.
  187. * @return string HTML fragment.
  188. */
  189. public function head_code(question_attempt $qa) {
  190. // This method is used by the Opaque question type. The remote question
  191. // engine can send back arbitrary CSS that we have to link to in the
  192. // page header. If it was not for that, we might be able to eliminate
  193. // this method and load the required CSS and JS some other way.
  194. $qa->get_question()->qtype->find_standard_scripts();
  195. }
  196. protected function feedback_class($fraction) {
  197. return question_state::graded_state_for_fraction($fraction)->get_feedback_class();
  198. }
  199. /**
  200. * Return an appropriate icon (green tick, red cross, etc.) for a grade.
  201. * @param float $fraction grade on a scale 0..1.
  202. * @param bool $selected whether to show a big or small icon. (Deprecated)
  203. * @return string html fragment.
  204. */
  205. protected function feedback_image($fraction, $selected = true) {
  206. $feedbackclass = question_state::graded_state_for_fraction($fraction)->get_feedback_class();
  207. $attributes = array(
  208. 'src' => $this->output->pix_url('i/grade_' . $feedbackclass),
  209. 'alt' => get_string($feedbackclass, 'question'),
  210. 'class' => 'questioncorrectnessicon',
  211. );
  212. return html_writer::empty_tag('img', $attributes);
  213. }
  214. }
  215. /**
  216. * Renderer base classes for question types.
  217. *
  218. * @copyright 2010 The Open University
  219. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  220. */
  221. abstract class qtype_with_combined_feedback_renderer extends qtype_renderer {
  222. protected function combined_feedback(question_attempt $qa) {
  223. $question = $qa->get_question();
  224. $state = $qa->get_state();
  225. if (!$state->is_finished()) {
  226. $response = $qa->get_last_qt_data();
  227. if (!$qa->get_question()->is_gradable_response($response)) {
  228. return '';
  229. }
  230. list($notused, $state) = $qa->get_question()->grade_response($response);
  231. }
  232. $feedback = '';
  233. $field = $state->get_feedback_class() . 'feedback';
  234. $format = $state->get_feedback_class() . 'feedbackformat';
  235. if ($question->$field) {
  236. $feedback .= $question->format_text($question->$field, $question->$format,
  237. $qa, 'question', $field, $question->id);
  238. }
  239. return $feedback;
  240. }
  241. }