Merge branch 'install_master' of git://github.com/amosbot/moodle
[moodle.git] / question / type / shortanswer / question.php
CommitLineData
068b4594 1<?php
068b4594
TH
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
068b4594
TH
17/**
18 * Short answer question definition class.
19 *
7764183a
TH
20 * @package qtype
21 * @subpackage shortanswer
22 * @copyright 2009 The Open University
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
068b4594
TH
24 */
25
26
a17b297d
TH
27defined('MOODLE_INTERNAL') || die();
28
29
068b4594
TH
30/**
31 * Represents a short answer question.
32 *
7764183a
TH
33 * @copyright 2009 The Open University
34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
068b4594
TH
35 */
36class qtype_shortanswer_question extends question_graded_by_strategy
37 implements question_response_answer_comparer {
38 /** @var boolean whether answers should be graded case-sensitively. */
39 public $usecase;
40 /** @var array of question_answer. */
41 public $answers = array();
42
43 public function __construct() {
44 parent::__construct(new question_first_matching_answer_grading_strategy($this));
45 }
46
47 public function get_expected_data() {
74c479f2 48 return array('answer' => PARAM_RAW_TRIMMED);
068b4594
TH
49 }
50
51 public function summarise_response(array $response) {
52 if (isset($response['answer'])) {
53 return $response['answer'];
54 } else {
55 return null;
56 }
57 }
58
59 public function is_complete_response(array $response) {
60 return array_key_exists('answer', $response) &&
61 ($response['answer'] || $response['answer'] === '0');
62 }
63
64 public function get_validation_error(array $response) {
65 if ($this->is_gradable_response($response)) {
66 return '';
67 }
68 return get_string('pleaseenterananswer', 'qtype_shortanswer');
69 }
70
71 public function is_same_response(array $prevresponse, array $newresponse) {
72 return question_utils::arrays_same_at_key_missing_is_blank(
73 $prevresponse, $newresponse, 'answer');
74 }
75
76 public function get_answers() {
77 return $this->answers;
78 }
79
80 public function compare_response_with_answer(array $response, question_answer $answer) {
8cfc4fbd
TH
81 return self::compare_string_with_wildcard(
82 $response['answer'], $answer->answer, !$this->usecase);
068b4594
TH
83 }
84
85 public static function compare_string_with_wildcard($string, $pattern, $ignorecase) {
86 // Break the string on non-escaped asterisks.
87 $bits = preg_split('/(?<!\\\\)\*/', $pattern);
88 // Escape regexp special characters in the bits.
89 $excapedbits = array();
90 foreach ($bits as $bit) {
91 $excapedbits[] = preg_quote(str_replace('\*', '*', $bit));
92 }
93 // Put it back together to make the regexp.
94 $regexp = '|^' . implode('.*', $excapedbits) . '$|u';
95
96 // Make the match insensitive if requested to.
97 if ($ignorecase) {
98 $regexp .= 'i';
99 }
100
101 return preg_match($regexp, trim($string));
102 }
7a719748 103
52ad7e0c
TH
104 public function check_file_access($qa, $options, $component, $filearea,
105 $args, $forcedownload) {
7a719748
TH
106 if ($component == 'question' && $filearea == 'answerfeedback') {
107 $currentanswer = $qa->get_last_qt_var('answer');
108 $answer = $qa->get_question()->get_matching_answer(array('answer' => $currentanswer));
109 $answerid = reset($args); // itemid is answer id.
110 return $options->feedback && $answerid == $answer->id;
111
112 } else if ($component == 'question' && $filearea == 'hint') {
93cadb1e 113 return $this->check_hint_file_access($qa, $options, $args);
7a719748
TH
114
115 } else {
8cfc4fbd
TH
116 return parent::check_file_access($qa, $options, $component, $filearea,
117 $args, $forcedownload);
7a719748
TH
118 }
119 }
068b4594 120}