Differences Between: [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 * This defines the states a question can be in. 19 * 20 * @package moodlecore 21 * @subpackage questionengine 22 * @copyright 2010 The Open University 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 30 /** 31 * An enumeration representing the states a question can be in after a 32 * {@link question_attempt_step}. 33 * 34 * There are also some useful methods for testing and manipulating states. 35 * 36 * @copyright 2009 The Open University 37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 38 */ 39 abstract class question_state { 40 /**#@+ 41 * Specific question_state instances. 42 */ 43 public static $notstarted; 44 public static $unprocessed; 45 public static $todo; 46 public static $invalid; 47 public static $complete; 48 public static $needsgrading; 49 public static $finished; 50 public static $gaveup; 51 public static $gradedwrong; 52 public static $gradedpartial; 53 public static $gradedright; 54 public static $manfinished; 55 public static $mangaveup; 56 public static $mangrwrong; 57 public static $mangrpartial; 58 public static $mangrright; 59 /**#@+-*/ 60 61 protected function __construct() { 62 } 63 64 public static function init() { 65 $us = new ReflectionClass('question_state'); 66 foreach ($us->getStaticProperties() as $name => $notused) { 67 $class = 'question_state_' . $name; 68 $states[$name] = new $class(); 69 self::$$name = $states[$name]; 70 } 71 } 72 73 /** 74 * Get all the states in an array. 75 * 76 * @return question_state[] of question_state objects. 77 */ 78 public static function get_all() { 79 $states = array(); 80 $us = new ReflectionClass('question_state'); 81 foreach ($us->getStaticProperties() as $name => $notused) { 82 $states[] = self::$$name; 83 } 84 return $states; 85 } 86 87 /** 88 * Get all the states in an array. 89 * @param string $summarystate one of the four summary states 90 * inprogress, needsgrading, manuallygraded or autograded. 91 * @return array of the corresponding states. 92 */ 93 public static function get_all_for_summary_state($summarystate) { 94 $states = array(); 95 foreach (self::get_all() as $state) { 96 if ($state->get_summary_state() == $summarystate) { 97 $states[] = $state; 98 } 99 } 100 if (empty($states)) { 101 throw new coding_exception('unknown summary state ' . $summarystate); 102 } 103 return $states; 104 } 105 106 /** 107 * @return string convert this state to a string. 108 */ 109 public function __toString() { 110 return substr(get_class($this), 15); 111 } 112 113 /** 114 * @param string $name a state name. 115 * @return question_state the state with that name. 116 */ 117 public static function get($name) { 118 return self::$$name; 119 } 120 121 /** 122 * Is this state one of the ones that mean the question attempt is in progress? 123 * That is, started, but no finished. 124 * @return bool 125 */ 126 public function is_active() { 127 return false; 128 } 129 130 /** 131 * Is this state one of the ones that mean the question attempt is finished? 132 * That is, no further interaction possible, apart from manual grading. 133 * @return bool 134 */ 135 public function is_finished() { 136 return true; 137 } 138 139 /** 140 * Is this state one of the ones that mean the question attempt has been graded? 141 * @return bool 142 */ 143 public function is_graded() { 144 return false; 145 } 146 147 /** 148 * Is this state one of the ones that mean the question attempt has been graded? 149 * @return bool 150 */ 151 public function is_correct() { 152 return false; 153 } 154 155 /** 156 * Is this state one of the ones that mean the question attempt has been graded? 157 * @return bool 158 */ 159 public function is_partially_correct() { 160 return false; 161 } 162 163 /** 164 * Is this state one of the ones that mean the question attempt has been graded? 165 * @return bool 166 */ 167 public function is_incorrect() { 168 return false; 169 } 170 171 /** 172 * Is this state one of the ones that mean the question attempt has been graded? 173 * @return bool 174 */ 175 public function is_gave_up() { 176 return false; 177 } 178 179 /** 180 * Is this state one of the ones that mean the question attempt has had a manual comment added? 181 * @return bool 182 */ 183 public function is_commented() { 184 return false; 185 } 186 187 /** 188 * Each state can be categorised into one of four categories: 189 * inprogress, needsgrading, manuallygraded or autograded. 190 * @return string which category this state falls into. 191 */ 192 public function get_summary_state() { 193 if (!$this->is_finished()) { 194 return 'inprogress'; 195 } else if ($this == self::$needsgrading) { 196 return 'needsgrading'; 197 } else if ($this->is_commented()) { 198 return 'manuallygraded'; 199 } else { 200 return 'autograded'; 201 } 202 } 203 204 /** 205 * Return the appropriate graded state based on a fraction. That is 0 or less 206 * is $graded_incorrect, 1 is $graded_correct, otherwise it is $graded_partcorrect. 207 * Appropriate allowance is made for rounding float values. 208 * 209 * @param number $fraction the grade, on the fraction scale. 210 * @return question_state one of the state constants. 211 */ 212 public static function graded_state_for_fraction($fraction) { 213 if ($fraction < 0.000001) { 214 return self::$gradedwrong; 215 } else if ($fraction > 0.999999) { 216 return self::$gradedright; 217 } else { 218 return self::$gradedpartial; 219 } 220 } 221 222 /** 223 * Return the appropriate manually graded state based on a fraction. That is 0 or less 224 * is $manually_graded_incorrect, 1 is $manually_graded_correct, otherwise it is 225 * $manually_graded_partcorrect. Appropriate allowance is made for rounding float values. 226 * 227 * @param number $fraction the grade, on the fraction scale. 228 * @return int one of the state constants. 229 */ 230 public static function manually_graded_state_for_fraction($fraction) { 231 if (is_null($fraction)) { 232 return self::$needsgrading; 233 } else if ($fraction < 0.000001) { 234 return self::$mangrwrong; 235 } else if ($fraction > 0.999999) { 236 return self::$mangrright; 237 } else { 238 return self::$mangrpartial; 239 } 240 } 241 242 /** 243 * Compute an appropriate state to move to after a manual comment has been 244 * added to this state. 245 * @param number $fraction the manual grade (if any) on the fraction scale. 246 * @return int the new state. 247 */ 248 public function corresponding_commented_state($fraction) { 249 throw new coding_exception('Unexpected question state.'); 250 } 251 252 /** 253 * Return an appropriate CSS class name ''/'correct'/'partiallycorrect'/'incorrect', 254 * for a state. 255 * @return string 256 */ 257 public function get_feedback_class() { 258 return ''; 259 } 260 261 /** 262 * Return the name of an appropriate string to look up in the question 263 * language pack for a state. This is used, for example, by 264 * {@link question_behaviour::get_state_string()}. However, behaviours 265 * sometimes change this default string for soemthing more specific. 266 * 267 * @param bool $showcorrectness Whether right/partial/wrong states should 268 * be distinguised, or just treated as 'complete'. 269 * @return string the name of a string that can be looked up in the 'question' 270 * lang pack, or used as a CSS class name, etc. 271 */ 272 public abstract function get_state_class($showcorrectness); 273 274 /** 275 * The result of doing get_string on the result of {@link get_state_class()}. 276 * 277 * @param bool $showcorrectness Whether right/partial/wrong states should 278 * be distinguised. 279 * @return string a string from the lang pack that can be used in the UI. 280 */ 281 public function default_string($showcorrectness) { 282 return get_string($this->get_state_class($showcorrectness), 'question'); 283 } 284 } 285 286 287 /**#@+ 288 * Specific question_state subclasses. 289 * 290 * @copyright 2009 The Open University 291 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 292 */ 293 class question_state_notstarted extends question_state { 294 public function is_finished() { 295 return false; 296 } 297 public function get_state_class($showcorrectness) { 298 throw new coding_exception('Unexpected question state.'); 299 } 300 } 301 class question_state_unprocessed extends question_state { 302 public function is_finished() { 303 return false; 304 } 305 public function get_state_class($showcorrectness) { 306 throw new coding_exception('Unexpected question state.'); 307 } 308 } 309 class question_state_todo extends question_state { 310 public function is_active() { 311 return true; 312 } 313 public function is_finished() { 314 return false; 315 } 316 public function get_state_class($showcorrectness) { 317 return 'notyetanswered'; 318 } 319 } 320 class question_state_invalid extends question_state { 321 public function is_active() { 322 return true; 323 } 324 public function is_finished() { 325 return false; 326 } 327 public function get_state_class($showcorrectness) { 328 return 'invalidanswer'; 329 } 330 } 331 class question_state_complete extends question_state { 332 public function is_active() { 333 return true; 334 } 335 public function is_finished() { 336 return false; 337 } 338 public function get_state_class($showcorrectness) { 339 return 'answersaved'; 340 } 341 } 342 class question_state_needsgrading extends question_state { 343 public function get_state_class($showcorrectness) { 344 if ($showcorrectness) { 345 return 'requiresgrading'; 346 } else { 347 return 'complete'; 348 } 349 } 350 public function corresponding_commented_state($fraction) { 351 return self::manually_graded_state_for_fraction($fraction); 352 } 353 } 354 class question_state_finished extends question_state { 355 public function get_state_class($showcorrectness) { 356 return 'complete'; 357 } 358 public function corresponding_commented_state($fraction) { 359 return self::$manfinished; 360 } 361 } 362 class question_state_gaveup extends question_state { 363 public function is_gave_up() { 364 return true; 365 } 366 public function get_feedback_class() { 367 return 'incorrect'; 368 } 369 public function get_state_class($showcorrectness) { 370 return 'notanswered'; 371 } 372 public function corresponding_commented_state($fraction) { 373 if (is_null($fraction)) { 374 return self::$mangaveup; 375 } else { 376 return self::manually_graded_state_for_fraction($fraction); 377 } 378 } 379 } 380 abstract class question_state_graded extends question_state { 381 public function is_graded() { 382 return true; 383 } 384 public function get_state_class($showcorrectness) { 385 if ($showcorrectness) { 386 return $this->get_feedback_class(); 387 } else { 388 return 'complete'; 389 } 390 } 391 public function corresponding_commented_state($fraction) { 392 return self::manually_graded_state_for_fraction($fraction); 393 } 394 } 395 class question_state_gradedwrong extends question_state_graded { 396 public function is_incorrect() { 397 return true; 398 } 399 public function get_feedback_class() { 400 return 'incorrect'; 401 } 402 } 403 class question_state_gradedpartial extends question_state_graded { 404 public function is_graded() { 405 return true; 406 } 407 public function is_partially_correct() { 408 return true; 409 } 410 public function get_feedback_class() { 411 return 'partiallycorrect'; 412 } 413 } 414 class question_state_gradedright extends question_state_graded { 415 public function is_graded() { 416 return true; 417 } 418 public function is_correct() { 419 return true; 420 } 421 public function get_feedback_class() { 422 return 'correct'; 423 } 424 } 425 class question_state_manfinished extends question_state_finished { 426 public function is_commented() { 427 return true; 428 } 429 } 430 class question_state_mangaveup extends question_state_gaveup { 431 public function is_commented() { 432 return true; 433 } 434 } 435 abstract class question_state_manuallygraded extends question_state_graded { 436 public function is_commented() { 437 return true; 438 } 439 } 440 class question_state_mangrwrong extends question_state_manuallygraded { 441 public function is_incorrect() { 442 return false; 443 } 444 public function get_feedback_class() { 445 return 'incorrect'; 446 } 447 } 448 class question_state_mangrpartial extends question_state_manuallygraded { 449 public function is_partially_correct() { 450 return true; 451 } 452 public function get_feedback_class() { 453 return 'partiallycorrect'; 454 } 455 } 456 class question_state_mangrright extends question_state_manuallygraded { 457 public function is_correct() { 458 return true; 459 } 460 public function get_feedback_class() { 461 return 'correct'; 462 } 463 } 464 /**#@-*/ 465 question_state::init();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body