[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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 * Defines the quiz module ettings form. 19 * 20 * @package mod_quiz 21 * @copyright 2006 Jamie Pratt 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 require_once($CFG->dirroot . '/course/moodleform_mod.php'); 29 require_once($CFG->dirroot . '/mod/quiz/locallib.php'); 30 31 32 /** 33 * Settings form for the quiz module. 34 * 35 * @copyright 2006 Jamie Pratt 36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 37 */ 38 class mod_quiz_mod_form extends moodleform_mod { 39 /** @var array options to be used with date_time_selector fields in the quiz. */ 40 public static $datefieldoptions = array('optional' => true, 'step' => 1); 41 42 protected $_feedbacks; 43 protected static $reviewfields = array(); // Initialised in the constructor. 44 45 /** @var int the max number of attempts allowed in any user or group override on this quiz. */ 46 protected $maxattemptsanyoverride = null; 47 48 public function __construct($current, $section, $cm, $course) { 49 self::$reviewfields = array( 50 'attempt' => array('theattempt', 'quiz'), 51 'correctness' => array('whethercorrect', 'question'), 52 'marks' => array('marks', 'quiz'), 53 'specificfeedback' => array('specificfeedback', 'question'), 54 'generalfeedback' => array('generalfeedback', 'question'), 55 'rightanswer' => array('rightanswer', 'question'), 56 'overallfeedback' => array('reviewoverallfeedback', 'quiz'), 57 ); 58 parent::__construct($current, $section, $cm, $course); 59 } 60 61 protected function definition() { 62 global $COURSE, $CFG, $DB, $PAGE; 63 $quizconfig = get_config('quiz'); 64 $mform = $this->_form; 65 66 // ------------------------------------------------------------------------------- 67 $mform->addElement('header', 'general', get_string('general', 'form')); 68 69 // Name. 70 $mform->addElement('text', 'name', get_string('name'), array('size'=>'64')); 71 if (!empty($CFG->formatstringstriptags)) { 72 $mform->setType('name', PARAM_TEXT); 73 } else { 74 $mform->setType('name', PARAM_CLEANHTML); 75 } 76 $mform->addRule('name', null, 'required', null, 'client'); 77 $mform->addRule('name', get_string('maximumchars', '', 255), 'maxlength', 255, 'client'); 78 79 // Introduction. 80 $this->standard_intro_elements(get_string('introduction', 'quiz')); 81 82 // ------------------------------------------------------------------------------- 83 $mform->addElement('header', 'timing', get_string('timing', 'quiz')); 84 85 // Open and close dates. 86 $mform->addElement('date_time_selector', 'timeopen', get_string('quizopen', 'quiz'), 87 self::$datefieldoptions); 88 $mform->addHelpButton('timeopen', 'quizopenclose', 'quiz'); 89 90 $mform->addElement('date_time_selector', 'timeclose', get_string('quizclose', 'quiz'), 91 self::$datefieldoptions); 92 93 // Time limit. 94 $mform->addElement('duration', 'timelimit', get_string('timelimit', 'quiz'), 95 array('optional' => true)); 96 $mform->addHelpButton('timelimit', 'timelimit', 'quiz'); 97 $mform->setAdvanced('timelimit', $quizconfig->timelimit_adv); 98 $mform->setDefault('timelimit', $quizconfig->timelimit); 99 100 // What to do with overdue attempts. 101 $mform->addElement('select', 'overduehandling', get_string('overduehandling', 'quiz'), 102 quiz_get_overdue_handling_options()); 103 $mform->addHelpButton('overduehandling', 'overduehandling', 'quiz'); 104 $mform->setAdvanced('overduehandling', $quizconfig->overduehandling_adv); 105 $mform->setDefault('overduehandling', $quizconfig->overduehandling); 106 // TODO Formslib does OR logic on disableif, and we need AND logic here. 107 // $mform->disabledIf('overduehandling', 'timelimit', 'eq', 0); 108 // $mform->disabledIf('overduehandling', 'timeclose', 'eq', 0); 109 110 // Grace period time. 111 $mform->addElement('duration', 'graceperiod', get_string('graceperiod', 'quiz'), 112 array('optional' => true)); 113 $mform->addHelpButton('graceperiod', 'graceperiod', 'quiz'); 114 $mform->setAdvanced('graceperiod', $quizconfig->graceperiod_adv); 115 $mform->setDefault('graceperiod', $quizconfig->graceperiod); 116 $mform->disabledIf('graceperiod', 'overduehandling', 'neq', 'graceperiod'); 117 118 // ------------------------------------------------------------------------------- 119 // Grade settings. 120 $this->standard_grading_coursemodule_elements(); 121 122 $mform->removeElement('grade'); 123 if (property_exists($this->current, 'grade')) { 124 $currentgrade = $this->current->grade; 125 } else { 126 $currentgrade = $quizconfig->maximumgrade; 127 } 128 $mform->addElement('hidden', 'grade', $currentgrade); 129 $mform->setType('grade', PARAM_FLOAT); 130 131 // Number of attempts. 132 $attemptoptions = array('0' => get_string('unlimited')); 133 for ($i = 1; $i <= QUIZ_MAX_ATTEMPT_OPTION; $i++) { 134 $attemptoptions[$i] = $i; 135 } 136 $mform->addElement('select', 'attempts', get_string('attemptsallowed', 'quiz'), 137 $attemptoptions); 138 $mform->setAdvanced('attempts', $quizconfig->attempts_adv); 139 $mform->setDefault('attempts', $quizconfig->attempts); 140 141 // Grading method. 142 $mform->addElement('select', 'grademethod', get_string('grademethod', 'quiz'), 143 quiz_get_grading_options()); 144 $mform->addHelpButton('grademethod', 'grademethod', 'quiz'); 145 $mform->setAdvanced('grademethod', $quizconfig->grademethod_adv); 146 $mform->setDefault('grademethod', $quizconfig->grademethod); 147 if ($this->get_max_attempts_for_any_override() < 2) { 148 $mform->disabledIf('grademethod', 'attempts', 'eq', 1); 149 } 150 151 // ------------------------------------------------------------------------------- 152 $mform->addElement('header', 'layouthdr', get_string('layout', 'quiz')); 153 154 $pagegroup = array(); 155 $pagegroup[] = $mform->createElement('select', 'questionsperpage', 156 get_string('newpage', 'quiz'), quiz_questions_per_page_options(), array('id' => 'id_questionsperpage')); 157 $mform->setDefault('questionsperpage', $quizconfig->questionsperpage); 158 159 if (!empty($this->_cm)) { 160 $pagegroup[] = $mform->createElement('checkbox', 'repaginatenow', '', 161 get_string('repaginatenow', 'quiz'), array('id' => 'id_repaginatenow')); 162 } 163 164 $mform->addGroup($pagegroup, 'questionsperpagegrp', 165 get_string('newpage', 'quiz'), null, false); 166 $mform->addHelpButton('questionsperpagegrp', 'newpage', 'quiz'); 167 $mform->setAdvanced('questionsperpagegrp', $quizconfig->questionsperpage_adv); 168 169 // Navigation method. 170 $mform->addElement('select', 'navmethod', get_string('navmethod', 'quiz'), 171 quiz_get_navigation_options()); 172 $mform->addHelpButton('navmethod', 'navmethod', 'quiz'); 173 $mform->setAdvanced('navmethod', $quizconfig->navmethod_adv); 174 $mform->setDefault('navmethod', $quizconfig->navmethod); 175 176 // ------------------------------------------------------------------------------- 177 $mform->addElement('header', 'interactionhdr', get_string('questionbehaviour', 'quiz')); 178 179 // Shuffle within questions. 180 $mform->addElement('selectyesno', 'shuffleanswers', get_string('shufflewithin', 'quiz')); 181 $mform->addHelpButton('shuffleanswers', 'shufflewithin', 'quiz'); 182 $mform->setAdvanced('shuffleanswers', $quizconfig->shuffleanswers_adv); 183 $mform->setDefault('shuffleanswers', $quizconfig->shuffleanswers); 184 185 // How questions behave (question behaviour). 186 if (!empty($this->current->preferredbehaviour)) { 187 $currentbehaviour = $this->current->preferredbehaviour; 188 } else { 189 $currentbehaviour = ''; 190 } 191 $behaviours = question_engine::get_behaviour_options($currentbehaviour); 192 $mform->addElement('select', 'preferredbehaviour', 193 get_string('howquestionsbehave', 'question'), $behaviours); 194 $mform->addHelpButton('preferredbehaviour', 'howquestionsbehave', 'question'); 195 $mform->setDefault('preferredbehaviour', $quizconfig->preferredbehaviour); 196 197 // Can redo completed questions. 198 $redochoices = array(0 => get_string('no'), 1 => get_string('canredoquestionsyes', 'quiz')); 199 $mform->addElement('select', 'canredoquestions', get_string('canredoquestions', 'quiz'), $redochoices); 200 $mform->addHelpButton('canredoquestions', 'canredoquestions', 'quiz'); 201 $mform->setAdvanced('canredoquestions', $quizconfig->canredoquestions_adv); 202 $mform->setDefault('canredoquestions', $quizconfig->canredoquestions); 203 foreach ($behaviours as $behaviour => $notused) { 204 if (!question_engine::can_questions_finish_during_the_attempt($behaviour)) { 205 $mform->disabledIf('canredoquestions', 'preferredbehaviour', 'eq', $behaviour); 206 } 207 } 208 209 // Each attempt builds on last. 210 $mform->addElement('selectyesno', 'attemptonlast', 211 get_string('eachattemptbuildsonthelast', 'quiz')); 212 $mform->addHelpButton('attemptonlast', 'eachattemptbuildsonthelast', 'quiz'); 213 $mform->setAdvanced('attemptonlast', $quizconfig->attemptonlast_adv); 214 $mform->setDefault('attemptonlast', $quizconfig->attemptonlast); 215 if ($this->get_max_attempts_for_any_override() < 2) { 216 $mform->disabledIf('attemptonlast', 'attempts', 'eq', 1); 217 } 218 219 // ------------------------------------------------------------------------------- 220 $mform->addElement('header', 'reviewoptionshdr', 221 get_string('reviewoptionsheading', 'quiz')); 222 $mform->addHelpButton('reviewoptionshdr', 'reviewoptionsheading', 'quiz'); 223 224 // Review options. 225 $this->add_review_options_group($mform, $quizconfig, 'during', 226 mod_quiz_display_options::DURING, true); 227 $this->add_review_options_group($mform, $quizconfig, 'immediately', 228 mod_quiz_display_options::IMMEDIATELY_AFTER); 229 $this->add_review_options_group($mform, $quizconfig, 'open', 230 mod_quiz_display_options::LATER_WHILE_OPEN); 231 $this->add_review_options_group($mform, $quizconfig, 'closed', 232 mod_quiz_display_options::AFTER_CLOSE); 233 234 foreach ($behaviours as $behaviour => $notused) { 235 $unusedoptions = question_engine::get_behaviour_unused_display_options($behaviour); 236 foreach ($unusedoptions as $unusedoption) { 237 $mform->disabledIf($unusedoption . 'during', 'preferredbehaviour', 238 'eq', $behaviour); 239 } 240 } 241 $mform->disabledIf('attemptduring', 'preferredbehaviour', 242 'neq', 'wontmatch'); 243 $mform->disabledIf('overallfeedbackduring', 'preferredbehaviour', 244 'neq', 'wontmatch'); 245 246 // ------------------------------------------------------------------------------- 247 $mform->addElement('header', 'display', get_string('appearance')); 248 249 // Show user picture. 250 $mform->addElement('select', 'showuserpicture', get_string('showuserpicture', 'quiz'), 251 quiz_get_user_image_options()); 252 $mform->addHelpButton('showuserpicture', 'showuserpicture', 'quiz'); 253 $mform->setAdvanced('showuserpicture', $quizconfig->showuserpicture_adv); 254 $mform->setDefault('showuserpicture', $quizconfig->showuserpicture); 255 256 // Overall decimal points. 257 $options = array(); 258 for ($i = 0; $i <= QUIZ_MAX_DECIMAL_OPTION; $i++) { 259 $options[$i] = $i; 260 } 261 $mform->addElement('select', 'decimalpoints', get_string('decimalplaces', 'quiz'), 262 $options); 263 $mform->addHelpButton('decimalpoints', 'decimalplaces', 'quiz'); 264 $mform->setAdvanced('decimalpoints', $quizconfig->decimalpoints_adv); 265 $mform->setDefault('decimalpoints', $quizconfig->decimalpoints); 266 267 // Question decimal points. 268 $options = array(-1 => get_string('sameasoverall', 'quiz')); 269 for ($i = 0; $i <= QUIZ_MAX_Q_DECIMAL_OPTION; $i++) { 270 $options[$i] = $i; 271 } 272 $mform->addElement('select', 'questiondecimalpoints', 273 get_string('decimalplacesquestion', 'quiz'), $options); 274 $mform->addHelpButton('questiondecimalpoints', 'decimalplacesquestion', 'quiz'); 275 $mform->setAdvanced('questiondecimalpoints', $quizconfig->questiondecimalpoints_adv); 276 $mform->setDefault('questiondecimalpoints', $quizconfig->questiondecimalpoints); 277 278 // Show blocks during quiz attempt. 279 $mform->addElement('selectyesno', 'showblocks', get_string('showblocks', 'quiz')); 280 $mform->addHelpButton('showblocks', 'showblocks', 'quiz'); 281 $mform->setAdvanced('showblocks', $quizconfig->showblocks_adv); 282 $mform->setDefault('showblocks', $quizconfig->showblocks); 283 284 // ------------------------------------------------------------------------------- 285 $mform->addElement('header', 'security', get_string('extraattemptrestrictions', 'quiz')); 286 287 // Require password to begin quiz attempt. 288 $mform->addElement('passwordunmask', 'quizpassword', get_string('requirepassword', 'quiz')); 289 $mform->setType('quizpassword', PARAM_TEXT); 290 $mform->addHelpButton('quizpassword', 'requirepassword', 'quiz'); 291 $mform->setAdvanced('quizpassword', $quizconfig->password_adv); 292 $mform->setDefault('quizpassword', $quizconfig->password); 293 294 // IP address. 295 $mform->addElement('text', 'subnet', get_string('requiresubnet', 'quiz')); 296 $mform->setType('subnet', PARAM_TEXT); 297 $mform->addHelpButton('subnet', 'requiresubnet', 'quiz'); 298 $mform->setAdvanced('subnet', $quizconfig->subnet_adv); 299 $mform->setDefault('subnet', $quizconfig->subnet); 300 301 // Enforced time delay between quiz attempts. 302 $mform->addElement('duration', 'delay1', get_string('delay1st2nd', 'quiz'), 303 array('optional' => true)); 304 $mform->addHelpButton('delay1', 'delay1st2nd', 'quiz'); 305 $mform->setAdvanced('delay1', $quizconfig->delay1_adv); 306 $mform->setDefault('delay1', $quizconfig->delay1); 307 if ($this->get_max_attempts_for_any_override() < 2) { 308 $mform->disabledIf('delay1', 'attempts', 'eq', 1); 309 } 310 311 $mform->addElement('duration', 'delay2', get_string('delaylater', 'quiz'), 312 array('optional' => true)); 313 $mform->addHelpButton('delay2', 'delaylater', 'quiz'); 314 $mform->setAdvanced('delay2', $quizconfig->delay2_adv); 315 $mform->setDefault('delay2', $quizconfig->delay2); 316 if ($this->get_max_attempts_for_any_override() < 3) { 317 $mform->disabledIf('delay2', 'attempts', 'eq', 1); 318 $mform->disabledIf('delay2', 'attempts', 'eq', 2); 319 } 320 321 // Browser security choices. 322 $mform->addElement('select', 'browsersecurity', get_string('browsersecurity', 'quiz'), 323 quiz_access_manager::get_browser_security_choices()); 324 $mform->addHelpButton('browsersecurity', 'browsersecurity', 'quiz'); 325 $mform->setAdvanced('browsersecurity', $quizconfig->browsersecurity_adv); 326 $mform->setDefault('browsersecurity', $quizconfig->browsersecurity); 327 328 // Any other rule plugins. 329 quiz_access_manager::add_settings_form_fields($this, $mform); 330 331 // ------------------------------------------------------------------------------- 332 $mform->addElement('header', 'overallfeedbackhdr', get_string('overallfeedback', 'quiz')); 333 $mform->addHelpButton('overallfeedbackhdr', 'overallfeedback', 'quiz'); 334 335 if (isset($this->current->grade)) { 336 $needwarning = $this->current->grade === 0; 337 } else { 338 $needwarning = $quizconfig->maximumgrade == 0; 339 } 340 if ($needwarning) { 341 $mform->addElement('static', 'nogradewarning', '', 342 get_string('nogradewarning', 'quiz')); 343 } 344 345 $mform->addElement('static', 'gradeboundarystatic1', 346 get_string('gradeboundary', 'quiz'), '100%'); 347 348 $repeatarray = array(); 349 $repeatedoptions = array(); 350 $repeatarray[] = $mform->createElement('editor', 'feedbacktext', 351 get_string('feedback', 'quiz'), array('rows' => 3), array('maxfiles' => EDITOR_UNLIMITED_FILES, 352 'noclean' => true, 'context' => $this->context)); 353 $repeatarray[] = $mform->createElement('text', 'feedbackboundaries', 354 get_string('gradeboundary', 'quiz'), array('size' => 10)); 355 $repeatedoptions['feedbacktext']['type'] = PARAM_RAW; 356 $repeatedoptions['feedbackboundaries']['type'] = PARAM_RAW; 357 358 if (!empty($this->_instance)) { 359 $this->_feedbacks = $DB->get_records('quiz_feedback', 360 array('quizid' => $this->_instance), 'mingrade DESC'); 361 $numfeedbacks = count($this->_feedbacks); 362 } else { 363 $this->_feedbacks = array(); 364 $numfeedbacks = $quizconfig->initialnumfeedbacks; 365 } 366 $numfeedbacks = max($numfeedbacks, 1); 367 368 $nextel = $this->repeat_elements($repeatarray, $numfeedbacks - 1, 369 $repeatedoptions, 'boundary_repeats', 'boundary_add_fields', 3, 370 get_string('addmoreoverallfeedbacks', 'quiz'), true); 371 372 // Put some extra elements in before the button. 373 $mform->insertElementBefore($mform->createElement('editor', 374 "feedbacktext[$nextel]", get_string('feedback', 'quiz'), array('rows' => 3), 375 array('maxfiles' => EDITOR_UNLIMITED_FILES, 'noclean' => true, 376 'context' => $this->context)), 377 'boundary_add_fields'); 378 $mform->insertElementBefore($mform->createElement('static', 379 'gradeboundarystatic2', get_string('gradeboundary', 'quiz'), '0%'), 380 'boundary_add_fields'); 381 382 // Add the disabledif rules. We cannot do this using the $repeatoptions parameter to 383 // repeat_elements because we don't want to dissable the first feedbacktext. 384 for ($i = 0; $i < $nextel; $i++) { 385 $mform->disabledIf('feedbackboundaries[' . $i . ']', 'grade', 'eq', 0); 386 $mform->disabledIf('feedbacktext[' . ($i + 1) . ']', 'grade', 'eq', 0); 387 } 388 389 // ------------------------------------------------------------------------------- 390 $this->standard_coursemodule_elements(); 391 392 // Check and act on whether setting outcomes is considered an advanced setting. 393 $mform->setAdvanced('modoutcomes', !empty($quizconfig->outcomes_adv)); 394 395 // The standard_coursemodule_elements method sets this to 100, but the 396 // quiz has its own setting, so use that. 397 $mform->setDefault('grade', $quizconfig->maximumgrade); 398 399 // ------------------------------------------------------------------------------- 400 $this->add_action_buttons(); 401 402 $PAGE->requires->yui_module('moodle-mod_quiz-modform', 'M.mod_quiz.modform.init'); 403 } 404 405 protected function add_review_options_group($mform, $quizconfig, $whenname, 406 $when, $withhelp = false) { 407 global $OUTPUT; 408 409 $group = array(); 410 foreach (self::$reviewfields as $field => $string) { 411 list($identifier, $component) = $string; 412 413 $label = get_string($identifier, $component); 414 if ($withhelp) { 415 $label .= ' ' . $OUTPUT->help_icon($identifier, $component); 416 } 417 418 $group[] = $mform->createElement('checkbox', $field . $whenname, '', $label); 419 } 420 $mform->addGroup($group, $whenname . 'optionsgrp', 421 get_string('review' . $whenname, 'quiz'), null, false); 422 423 foreach (self::$reviewfields as $field => $notused) { 424 $cfgfield = 'review' . $field; 425 if ($quizconfig->$cfgfield & $when) { 426 $mform->setDefault($field . $whenname, 1); 427 } else { 428 $mform->setDefault($field . $whenname, 0); 429 } 430 } 431 432 if ($whenname != 'during') { 433 $mform->disabledIf('correctness' . $whenname, 'attempt' . $whenname); 434 $mform->disabledIf('specificfeedback' . $whenname, 'attempt' . $whenname); 435 $mform->disabledIf('generalfeedback' . $whenname, 'attempt' . $whenname); 436 $mform->disabledIf('rightanswer' . $whenname, 'attempt' . $whenname); 437 } 438 } 439 440 protected function preprocessing_review_settings(&$toform, $whenname, $when) { 441 foreach (self::$reviewfields as $field => $notused) { 442 $fieldname = 'review' . $field; 443 if (array_key_exists($fieldname, $toform)) { 444 $toform[$field . $whenname] = $toform[$fieldname] & $when; 445 } 446 } 447 } 448 449 public function data_preprocessing(&$toform) { 450 if (isset($toform['grade'])) { 451 // Convert to a real number, so we don't get 0.0000. 452 $toform['grade'] = $toform['grade'] + 0; 453 } 454 455 if (count($this->_feedbacks)) { 456 $key = 0; 457 foreach ($this->_feedbacks as $feedback) { 458 $draftid = file_get_submitted_draft_itemid('feedbacktext['.$key.']'); 459 $toform['feedbacktext['.$key.']']['text'] = file_prepare_draft_area( 460 $draftid, // Draftid. 461 $this->context->id, // Context. 462 'mod_quiz', // Component. 463 'feedback', // Filarea. 464 !empty($feedback->id) ? (int) $feedback->id : null, // Itemid. 465 null, 466 $feedback->feedbacktext // Text. 467 ); 468 $toform['feedbacktext['.$key.']']['format'] = $feedback->feedbacktextformat; 469 $toform['feedbacktext['.$key.']']['itemid'] = $draftid; 470 471 if ($toform['grade'] == 0) { 472 // When a quiz is un-graded, there can only be one lot of 473 // feedback. If the quiz previously had a maximum grade and 474 // several lots of feedback, we must now avoid putting text 475 // into input boxes that are disabled, but which the 476 // validation will insist are blank. 477 break; 478 } 479 480 if ($feedback->mingrade > 0) { 481 $toform['feedbackboundaries['.$key.']'] = 482 round(100.0 * $feedback->mingrade / $toform['grade'], 6) . '%'; 483 } 484 $key++; 485 } 486 } 487 488 if (isset($toform['timelimit'])) { 489 $toform['timelimitenable'] = $toform['timelimit'] > 0; 490 } 491 492 $this->preprocessing_review_settings($toform, 'during', 493 mod_quiz_display_options::DURING); 494 $this->preprocessing_review_settings($toform, 'immediately', 495 mod_quiz_display_options::IMMEDIATELY_AFTER); 496 $this->preprocessing_review_settings($toform, 'open', 497 mod_quiz_display_options::LATER_WHILE_OPEN); 498 $this->preprocessing_review_settings($toform, 'closed', 499 mod_quiz_display_options::AFTER_CLOSE); 500 $toform['attemptduring'] = true; 501 $toform['overallfeedbackduring'] = false; 502 503 // Password field - different in form to stop browsers that remember 504 // passwords from getting confused. 505 if (isset($toform['password'])) { 506 $toform['quizpassword'] = $toform['password']; 507 unset($toform['password']); 508 } 509 510 // Load any settings belonging to the access rules. 511 if (!empty($toform['instance'])) { 512 $accesssettings = quiz_access_manager::load_settings($toform['instance']); 513 foreach ($accesssettings as $name => $value) { 514 $toform[$name] = $value; 515 } 516 } 517 } 518 519 public function validation($data, $files) { 520 $errors = parent::validation($data, $files); 521 522 // Check open and close times are consistent. 523 if ($data['timeopen'] != 0 && $data['timeclose'] != 0 && 524 $data['timeclose'] < $data['timeopen']) { 525 $errors['timeclose'] = get_string('closebeforeopen', 'quiz'); 526 } 527 528 // Check that the grace period is not too short. 529 if ($data['overduehandling'] == 'graceperiod') { 530 $graceperiodmin = get_config('quiz', 'graceperiodmin'); 531 if ($data['graceperiod'] <= $graceperiodmin) { 532 $errors['graceperiod'] = get_string('graceperiodtoosmall', 'quiz', format_time($graceperiodmin)); 533 } 534 } 535 536 // Check the boundary value is a number or a percentage, and in range. 537 $i = 0; 538 while (!empty($data['feedbackboundaries'][$i] )) { 539 $boundary = trim($data['feedbackboundaries'][$i]); 540 if (strlen($boundary) > 0) { 541 if ($boundary[strlen($boundary) - 1] == '%') { 542 $boundary = trim(substr($boundary, 0, -1)); 543 if (is_numeric($boundary)) { 544 $boundary = $boundary * $data['grade'] / 100.0; 545 } else { 546 $errors["feedbackboundaries[$i]"] = 547 get_string('feedbackerrorboundaryformat', 'quiz', $i + 1); 548 } 549 } else if (!is_numeric($boundary)) { 550 $errors["feedbackboundaries[$i]"] = 551 get_string('feedbackerrorboundaryformat', 'quiz', $i + 1); 552 } 553 } 554 if (is_numeric($boundary) && $boundary <= 0 || $boundary >= $data['grade'] ) { 555 $errors["feedbackboundaries[$i]"] = 556 get_string('feedbackerrorboundaryoutofrange', 'quiz', $i + 1); 557 } 558 if (is_numeric($boundary) && $i > 0 && 559 $boundary >= $data['feedbackboundaries'][$i - 1]) { 560 $errors["feedbackboundaries[$i]"] = 561 get_string('feedbackerrororder', 'quiz', $i + 1); 562 } 563 $data['feedbackboundaries'][$i] = $boundary; 564 $i += 1; 565 } 566 $numboundaries = $i; 567 568 // Check there is nothing in the remaining unused fields. 569 if (!empty($data['feedbackboundaries'])) { 570 for ($i = $numboundaries; $i < count($data['feedbackboundaries']); $i += 1) { 571 if (!empty($data['feedbackboundaries'][$i] ) && 572 trim($data['feedbackboundaries'][$i] ) != '') { 573 $errors["feedbackboundaries[$i]"] = 574 get_string('feedbackerrorjunkinboundary', 'quiz', $i + 1); 575 } 576 } 577 } 578 for ($i = $numboundaries + 1; $i < count($data['feedbacktext']); $i += 1) { 579 if (!empty($data['feedbacktext'][$i]['text']) && 580 trim($data['feedbacktext'][$i]['text'] ) != '') { 581 $errors["feedbacktext[$i]"] = 582 get_string('feedbackerrorjunkinfeedback', 'quiz', $i + 1); 583 } 584 } 585 586 // Any other rule plugins. 587 $errors = quiz_access_manager::validate_settings_form_fields($errors, $data, $files, $this); 588 589 return $errors; 590 } 591 592 /** 593 * Display module-specific activity completion rules. 594 * Part of the API defined by moodleform_mod 595 * @return array Array of string IDs of added items, empty array if none 596 */ 597 public function add_completion_rules() { 598 $mform = $this->_form; 599 $items = array(); 600 601 $group = array(); 602 $group[] = $mform->createElement('advcheckbox', 'completionpass', null, get_string('completionpass', 'quiz'), 603 array('group' => 'cpass')); 604 605 $group[] = $mform->createElement('advcheckbox', 'completionattemptsexhausted', null, 606 get_string('completionattemptsexhausted', 'quiz'), 607 array('group' => 'cattempts')); 608 $mform->disabledIf('completionattemptsexhausted', 'completionpass', 'notchecked'); 609 $mform->addGroup($group, 'completionpassgroup', get_string('completionpass', 'quiz'), ' ', false); 610 $mform->addHelpButton('completionpassgroup', 'completionpass', 'quiz'); 611 $items[] = 'completionpassgroup'; 612 return $items; 613 } 614 615 /** 616 * Called during validation. Indicates whether a module-specific completion rule is selected. 617 * 618 * @param array $data Input data (not yet validated) 619 * @return bool True if one or more rules is enabled, false if none are. 620 */ 621 public function completion_rule_enabled($data) { 622 return !empty($data['completionattemptsexhausted']) || !empty($data['completionpass']); 623 } 624 625 /** 626 * Get the maximum number of attempts that anyone might have due to a user 627 * or group override. Used to decide whether disabledIf rules should be applied. 628 * @return int the number of attempts allowed. For the purpose of this method, 629 * unlimited is returned as 1000, not 0. 630 */ 631 public function get_max_attempts_for_any_override() { 632 global $DB; 633 634 if (empty($this->_instance)) { 635 // Quiz not created yet, so no overrides. 636 return 1; 637 } 638 639 if ($this->maxattemptsanyoverride === null) { 640 $this->maxattemptsanyoverride = $DB->get_field_sql(" 641 SELECT MAX(CASE WHEN attempts = 0 THEN 1000 ELSE attempts END) 642 FROM {quiz_overrides} 643 WHERE quiz = ?", 644 array($this->_instance)); 645 if ($this->maxattemptsanyoverride < 1) { 646 // This happens when no override alters the number of attempts. 647 $this->maxattemptsanyoverride = 1; 648 } 649 } 650 651 return $this->maxattemptsanyoverride; 652 } 653 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |