Merge branch 'MDL-70148-310' of git://github.com/andrewnicols/moodle into MOODLE_310_...
[moodle.git] / question / type / truefalse / question.php
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/>.
17 /**
18  * True-false question definition class.
19  *
20  * @package    qtype
21  * @subpackage truefalse
22  * @copyright  2009 The Open University
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
27 defined('MOODLE_INTERNAL') || die();
29 require_once($CFG->dirroot . '/question/type/questionbase.php');
31 /**
32  * Represents a true-false question.
33  *
34  * @copyright  2009 The Open University
35  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36  */
37 class qtype_truefalse_question extends question_graded_automatically {
38     public $rightanswer;
39     public $truefeedback;
40     public $falsefeedback;
41     public $trueanswerid;
42     public $falseanswerid;
44     public function get_expected_data() {
45         return array('answer' => PARAM_INT);
46     }
48     public function get_correct_response() {
49         return array('answer' => (int) $this->rightanswer);
50     }
52     public function summarise_response(array $response) {
53         if (!array_key_exists('answer', $response)) {
54             return null;
55         } else if ($response['answer']) {
56             return get_string('true', 'qtype_truefalse');
57         } else {
58             return get_string('false', 'qtype_truefalse');
59         }
60     }
62     public function un_summarise_response(string $summary) {
63         if ($summary === get_string('true', 'qtype_truefalse')) {
64             return ['answer' => '1'];
65         } else if ($summary === get_string('false', 'qtype_truefalse')) {
66             return ['answer' => '0'];
67         } else {
68             return [];
69         }
70     }
72     public function classify_response(array $response) {
73         if (!array_key_exists('answer', $response)) {
74             return array($this->id => question_classified_response::no_response());
75         }
76         list($fraction) = $this->grade_response($response);
77         if ($response['answer']) {
78             return array($this->id => new question_classified_response(1,
79                     get_string('true', 'qtype_truefalse'), $fraction));
80         } else {
81             return array($this->id => new question_classified_response(0,
82                     get_string('false', 'qtype_truefalse'), $fraction));
83         }
84     }
86     public function is_complete_response(array $response) {
87         return array_key_exists('answer', $response);
88     }
90     public function get_validation_error(array $response) {
91         if ($this->is_gradable_response($response)) {
92             return '';
93         }
94         return get_string('pleaseselectananswer', 'qtype_truefalse');
95     }
97     public function is_same_response(array $prevresponse, array $newresponse) {
98         return question_utils::arrays_same_at_key_missing_is_blank(
99                 $prevresponse, $newresponse, 'answer');
100     }
102     public function grade_response(array $response) {
103         if ($this->rightanswer == true && $response['answer'] == true) {
104             $fraction = 1;
105         } else if ($this->rightanswer == false && $response['answer'] == false) {
106             $fraction = 1;
107         } else {
108             $fraction = 0;
109         }
110         return array($fraction, question_state::graded_state_for_fraction($fraction));
111     }
113     public function check_file_access($qa, $options, $component, $filearea, $args, $forcedownload) {
114         if ($component == 'question' && $filearea == 'answerfeedback') {
115             $answerid = reset($args); // Itemid is answer id.
116             $response = $qa->get_last_qt_var('answer', '');
117             return $options->feedback && (
118                     ($answerid == $this->trueanswerid && $response) ||
119                     ($answerid == $this->falseanswerid && $response !== ''));
121         } else {
122             return parent::check_file_access($qa, $options, $component, $filearea,
123                     $args, $forcedownload);
124         }
125     }
127     /**
128      * Return the question settings that define this question as structured data.
129      *
130      * @param question_attempt $qa the current attempt for which we are exporting the settings.
131      * @param question_display_options $options the question display options which say which aspects of the question
132      * should be visible.
133      * @return mixed structure representing the question settings. In web services, this will be JSON-encoded.
134      */
135     public function get_question_definition_for_external_rendering(question_attempt $qa, question_display_options $options) {
136         // No need to return anything, external clients do not need additional information for rendering this question type.
137         return null;
138     }