[ Index ] |
PHP Cross Reference of moodle-2.8 |
[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->add_intro_editor(false, 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 // Shuffle questions. 155 $shuffleoptions = array( 156 0 => get_string('asshownoneditscreen', 'quiz'), 157 1 => get_string('shuffledrandomly', 'quiz') 158 ); 159 $mform->addElement('select', 'shufflequestions', get_string('questionorder', 'quiz'), 160 $shuffleoptions, array('id' => 'id_shufflequestions')); 161 $mform->setAdvanced('shufflequestions', $quizconfig->shufflequestions_adv); 162 $mform->setDefault('shufflequestions', $quizconfig->shufflequestions); 163 164 $pagegroup = array(); 165 $pagegroup[] = $mform->createElement('select', 'questionsperpage', 166 get_string('newpage', 'quiz'), quiz_questions_per_page_options(), array('id' => 'id_questionsperpage')); 167 $mform->setDefault('questionsperpage', $quizconfig->questionsperpage); 168 169 if (!empty($this->_cm)) { 170 $pagegroup[] = $mform->createElement('checkbox', 'repaginatenow', '', 171 get_string('repaginatenow', 'quiz'), array('id' => 'id_repaginatenow')); 172 $mform->disabledIf('repaginatenow', 'shufflequestions', 'eq', 1); 173 } 174 175 $mform->addGroup($pagegroup, 'questionsperpagegrp', 176 get_string('newpage', 'quiz'), null, false); 177 $mform->addHelpButton('questionsperpagegrp', 'newpage', 'quiz'); 178 $mform->setAdvanced('questionsperpagegrp', $quizconfig->questionsperpage_adv); 179 180 // Navigation method. 181 $mform->addElement('select', 'navmethod', get_string('navmethod', 'quiz'), 182 quiz_get_navigation_options()); 183 $mform->addHelpButton('navmethod', 'navmethod', 'quiz'); 184 $mform->setAdvanced('navmethod', $quizconfig->navmethod_adv); 185 $mform->setDefault('navmethod', $quizconfig->navmethod); 186 187 // ------------------------------------------------------------------------------- 188 $mform->addElement('header', 'interactionhdr', get_string('questionbehaviour', 'quiz')); 189 190 // Shuffle within questions. 191 $mform->addElement('selectyesno', 'shuffleanswers', get_string('shufflewithin', 'quiz')); 192 $mform->addHelpButton('shuffleanswers', 'shufflewithin', 'quiz'); 193 $mform->setAdvanced('shuffleanswers', $quizconfig->shuffleanswers_adv); 194 $mform->setDefault('shuffleanswers', $quizconfig->shuffleanswers); 195 196 // How questions behave (question behaviour). 197 if (!empty($this->current->preferredbehaviour)) { 198 $currentbehaviour = $this->current->preferredbehaviour; 199 } else { 200 $currentbehaviour = ''; 201 } 202 $behaviours = question_engine::get_behaviour_options($currentbehaviour); 203 $mform->addElement('select', 'preferredbehaviour', 204 get_string('howquestionsbehave', 'question'), $behaviours); 205 $mform->addHelpButton('preferredbehaviour', 'howquestionsbehave', 'question'); 206 $mform->setDefault('preferredbehaviour', $quizconfig->preferredbehaviour); 207 208 // Each attempt builds on last. 209 $mform->addElement('selectyesno', 'attemptonlast', 210 get_string('eachattemptbuildsonthelast', 'quiz')); 211 $mform->addHelpButton('attemptonlast', 'eachattemptbuildsonthelast', 'quiz'); 212 $mform->setAdvanced('attemptonlast', $quizconfig->attemptonlast_adv); 213 $mform->setDefault('attemptonlast', $quizconfig->attemptonlast); 214 if ($this->get_max_attempts_for_any_override() < 2) { 215 $mform->disabledIf('attemptonlast', 'attempts', 'eq', 1); 216 } 217 218 // ------------------------------------------------------------------------------- 219 $mform->addElement('header', 'reviewoptionshdr', 220 get_string('reviewoptionsheading', 'quiz')); 221 $mform->addHelpButton('reviewoptionshdr', 'reviewoptionsheading', 'quiz'); 222 223 // Review options. 224 $this->add_review_options_group($mform, $quizconfig, 'during', 225 mod_quiz_display_options::DURING, true); 226 $this->add_review_options_group($mform, $quizconfig, 'immediately', 227 mod_quiz_display_options::IMMEDIATELY_AFTER); 228 $this->add_review_options_group($mform, $quizconfig, 'open', 229 mod_quiz_display_options::LATER_WHILE_OPEN); 230 $this->add_review_options_group($mform, $quizconfig, 'closed', 231 mod_quiz_display_options::AFTER_CLOSE); 232 233 foreach ($behaviours as $behaviour => $notused) { 234 $unusedoptions = question_engine::get_behaviour_unused_display_options($behaviour); 235 foreach ($unusedoptions as $unusedoption) { 236 $mform->disabledIf($unusedoption . 'during', 'preferredbehaviour', 237 'eq', $behaviour); 238 } 239 } 240 $mform->disabledIf('attemptduring', 'preferredbehaviour', 241 'neq', 'wontmatch'); 242 $mform->disabledIf('overallfeedbackduring', 'preferredbehaviour', 243 'neq', 'wontmatch'); 244 245 // ------------------------------------------------------------------------------- 246 $mform->addElement('header', 'display', get_string('appearance')); 247 248 // Show user picture. 249 $mform->addElement('select', 'showuserpicture', get_string('showuserpicture', 'quiz'), 250 quiz_get_user_image_options()); 251 $mform->addHelpButton('showuserpicture', 'showuserpicture', 'quiz'); 252 $mform->setAdvanced('showuserpicture', $quizconfig->showuserpicture_adv); 253 $mform->setDefault('showuserpicture', $quizconfig->showuserpicture); 254 255 // Overall decimal points. 256 $options = array(); 257 for ($i = 0; $i <= QUIZ_MAX_DECIMAL_OPTION; $i++) { 258 $options[$i] = $i; 259 } 260 $mform->addElement('select', 'decimalpoints', get_string('decimalplaces', 'quiz'), 261 $options); 262 $mform->addHelpButton('decimalpoints', 'decimalplaces', 'quiz'); 263 $mform->setAdvanced('decimalpoints', $quizconfig->decimalpoints_adv); 264 $mform->setDefault('decimalpoints', $quizconfig->decimalpoints); 265 266 // Question decimal points. 267 $options = array(-1 => get_string('sameasoverall', 'quiz')); 268 for ($i = 0; $i <= QUIZ_MAX_Q_DECIMAL_OPTION; $i++) { 269 $options[$i] = $i; 270 } 271 $mform->addElement('select', 'questiondecimalpoints', 272 get_string('decimalplacesquestion', 'quiz'), $options); 273 $mform->addHelpButton('questiondecimalpoints', 'decimalplacesquestion', 'quiz'); 274 $mform->setAdvanced('questiondecimalpoints', $quizconfig->questiondecimalpoints_adv); 275 $mform->setDefault('questiondecimalpoints', $quizconfig->questiondecimalpoints); 276 277 // Show blocks during quiz attempt. 278 $mform->addElement('selectyesno', 'showblocks', get_string('showblocks', 'quiz')); 279 $mform->addHelpButton('showblocks', 'showblocks', 'quiz'); 280 $mform->setAdvanced('showblocks', $quizconfig->showblocks_adv); 281 $mform->setDefault('showblocks', $quizconfig->showblocks); 282 283 // ------------------------------------------------------------------------------- 284 $mform->addElement('header', 'security', get_string('extraattemptrestrictions', 'quiz')); 285 286 // Require password to begin quiz attempt. 287 $mform->addElement('passwordunmask', 'quizpassword', get_string('requirepassword', 'quiz')); 288 $mform->setType('quizpassword', PARAM_TEXT); 289 $mform->addHelpButton('quizpassword', 'requirepassword', 'quiz'); 290 $mform->setAdvanced('quizpassword', $quizconfig->password_adv); 291 $mform->setDefault('quizpassword', $quizconfig->password); 292 293 // IP address. 294 $mform->addElement('text', 'subnet', get_string('requiresubnet', 'quiz')); 295 $mform->setType('subnet', PARAM_TEXT); 296 $mform->addHelpButton('subnet', 'requiresubnet', 'quiz'); 297 $mform->setAdvanced('subnet', $quizconfig->subnet_adv); 298 $mform->setDefault('subnet', $quizconfig->subnet); 299 300 // Enforced time delay between quiz attempts. 301 $mform->addElement('duration', 'delay1', get_string('delay1st2nd', 'quiz'), 302 array('optional' => true)); 303 $mform->addHelpButton('delay1', 'delay1st2nd', 'quiz'); 304 $mform->setAdvanced('delay1', $quizconfig->delay1_adv); 305 $mform->setDefault('delay1', $quizconfig->delay1); 306 if ($this->get_max_attempts_for_any_override() < 2) { 307 $mform->disabledIf('delay1', 'attempts', 'eq', 1); 308 } 309 310 $mform->addElement('duration', 'delay2', get_string('delaylater', 'quiz'), 311 array('optional' => true)); 312 $mform->addHelpButton('delay2', 'delaylater', 'quiz'); 313 $mform->setAdvanced('delay2', $quizconfig->delay2_adv); 314 $mform->setDefault('delay2', $quizconfig->delay2); 315 if ($this->get_max_attempts_for_any_override() < 3) { 316 $mform->disabledIf('delay2', 'attempts', 'eq', 1); 317 $mform->disabledIf('delay2', 'attempts', 'eq', 2); 318 } 319 320 // Browser security choices. 321 $mform->addElement('select', 'browsersecurity', get_string('browsersecurity', 'quiz'), 322 quiz_access_manager::get_browser_security_choices()); 323 $mform->addHelpButton('browsersecurity', 'browsersecurity', 'quiz'); 324 $mform->setAdvanced('browsersecurity', $quizconfig->browsersecurity_adv); 325 $mform->setDefault('browsersecurity', $quizconfig->browsersecurity); 326 327 // Any other rule plugins. 328 quiz_access_manager::add_settings_form_fields($this, $mform); 329 330 // ------------------------------------------------------------------------------- 331 $mform->addElement('header', 'overallfeedbackhdr', get_string('overallfeedback', 'quiz')); 332 $mform->addHelpButton('overallfeedbackhdr', 'overallfeedback', 'quiz'); 333 334 if (isset($this->current->grade)) { 335 $needwarning = $this->current->grade === 0; 336 } else { 337 $needwarning = $quizconfig->maximumgrade == 0; 338 } 339 if ($needwarning) { 340 $mform->addElement('static', 'nogradewarning', '', 341 get_string('nogradewarning', 'quiz')); 342 } 343 344 $mform->addElement('static', 'gradeboundarystatic1', 345 get_string('gradeboundary', 'quiz'), '100%'); 346 347 $repeatarray = array(); 348 $repeatedoptions = array(); 349 $repeatarray[] = $mform->createElement('editor', 'feedbacktext', 350 get_string('feedback', 'quiz'), array('rows' => 3), array('maxfiles' => EDITOR_UNLIMITED_FILES, 351 'noclean' => true, 'context' => $this->context)); 352 $repeatarray[] = $mform->createElement('text', 'feedbackboundaries', 353 get_string('gradeboundary', 'quiz'), array('size' => 10)); 354 $repeatedoptions['feedbacktext']['type'] = PARAM_RAW; 355 $repeatedoptions['feedbackboundaries']['type'] = PARAM_RAW; 356 357 if (!empty($this->_instance)) { 358 $this->_feedbacks = $DB->get_records('quiz_feedback', 359 array('quizid' => $this->_instance), 'mingrade DESC'); 360 } else { 361 $this->_feedbacks = array(); 362 } 363 $numfeedbacks = max(count($this->_feedbacks) * 1.5, 5); 364 365 $nextel = $this->repeat_elements($repeatarray, $numfeedbacks - 1, 366 $repeatedoptions, 'boundary_repeats', 'boundary_add_fields', 3, 367 get_string('addmoreoverallfeedbacks', 'quiz'), true); 368 369 // Put some extra elements in before the button. 370 $mform->insertElementBefore($mform->createElement('editor', 371 "feedbacktext[$nextel]", get_string('feedback', 'quiz'), array('rows' => 3), 372 array('maxfiles' => EDITOR_UNLIMITED_FILES, 'noclean' => true, 373 'context' => $this->context)), 374 'boundary_add_fields'); 375 $mform->insertElementBefore($mform->createElement('static', 376 'gradeboundarystatic2', get_string('gradeboundary', 'quiz'), '0%'), 377 'boundary_add_fields'); 378 379 // Add the disabledif rules. We cannot do this using the $repeatoptions parameter to 380 // repeat_elements because we don't want to dissable the first feedbacktext. 381 for ($i = 0; $i < $nextel; $i++) { 382 $mform->disabledIf('feedbackboundaries[' . $i . ']', 'grade', 'eq', 0); 383 $mform->disabledIf('feedbacktext[' . ($i + 1) . ']', 'grade', 'eq', 0); 384 } 385 386 // ------------------------------------------------------------------------------- 387 $this->standard_coursemodule_elements(); 388 389 // Check and act on whether setting outcomes is considered an advanced setting. 390 $mform->setAdvanced('modoutcomes', !empty($quizconfig->outcomes_adv)); 391 392 // The standard_coursemodule_elements method sets this to 100, but the 393 // quiz has its own setting, so use that. 394 $mform->setDefault('grade', $quizconfig->maximumgrade); 395 396 // ------------------------------------------------------------------------------- 397 $this->add_action_buttons(); 398 399 $PAGE->requires->yui_module('moodle-mod_quiz-modform', 'M.mod_quiz.modform.init'); 400 } 401 402 protected function add_review_options_group($mform, $quizconfig, $whenname, 403 $when, $withhelp = false) { 404 global $OUTPUT; 405 406 $group = array(); 407 foreach (self::$reviewfields as $field => $string) { 408 list($identifier, $component) = $string; 409 410 $label = get_string($identifier, $component); 411 if ($withhelp) { 412 $label .= ' ' . $OUTPUT->help_icon($identifier, $component); 413 } 414 415 $group[] = $mform->createElement('checkbox', $field . $whenname, '', $label); 416 } 417 $mform->addGroup($group, $whenname . 'optionsgrp', 418 get_string('review' . $whenname, 'quiz'), null, false); 419 420 foreach (self::$reviewfields as $field => $notused) { 421 $cfgfield = 'review' . $field; 422 if ($quizconfig->$cfgfield & $when) { 423 $mform->setDefault($field . $whenname, 1); 424 } else { 425 $mform->setDefault($field . $whenname, 0); 426 } 427 } 428 429 if ($whenname != 'during') { 430 $mform->disabledIf('correctness' . $whenname, 'attempt' . $whenname); 431 $mform->disabledIf('specificfeedback' . $whenname, 'attempt' . $whenname); 432 $mform->disabledIf('generalfeedback' . $whenname, 'attempt' . $whenname); 433 $mform->disabledIf('rightanswer' . $whenname, 'attempt' . $whenname); 434 } 435 } 436 437 protected function preprocessing_review_settings(&$toform, $whenname, $when) { 438 foreach (self::$reviewfields as $field => $notused) { 439 $fieldname = 'review' . $field; 440 if (array_key_exists($fieldname, $toform)) { 441 $toform[$field . $whenname] = $toform[$fieldname] & $when; 442 } 443 } 444 } 445 446 public function data_preprocessing(&$toform) { 447 if (isset($toform['grade'])) { 448 // Convert to a real number, so we don't get 0.0000. 449 $toform['grade'] = $toform['grade'] + 0; 450 } 451 452 if (count($this->_feedbacks)) { 453 $key = 0; 454 foreach ($this->_feedbacks as $feedback) { 455 $draftid = file_get_submitted_draft_itemid('feedbacktext['.$key.']'); 456 $toform['feedbacktext['.$key.']']['text'] = file_prepare_draft_area( 457 $draftid, // Draftid. 458 $this->context->id, // Context. 459 'mod_quiz', // Component. 460 'feedback', // Filarea. 461 !empty($feedback->id) ? (int) $feedback->id : null, // Itemid. 462 null, 463 $feedback->feedbacktext // Text. 464 ); 465 $toform['feedbacktext['.$key.']']['format'] = $feedback->feedbacktextformat; 466 $toform['feedbacktext['.$key.']']['itemid'] = $draftid; 467 468 if ($toform['grade'] == 0) { 469 // When a quiz is un-graded, there can only be one lot of 470 // feedback. If the quiz previously had a maximum grade and 471 // several lots of feedback, we must now avoid putting text 472 // into input boxes that are disabled, but which the 473 // validation will insist are blank. 474 break; 475 } 476 477 if ($feedback->mingrade > 0) { 478 $toform['feedbackboundaries['.$key.']'] = 479 round(100.0 * $feedback->mingrade / $toform['grade'], 6) . '%'; 480 } 481 $key++; 482 } 483 } 484 485 if (isset($toform['timelimit'])) { 486 $toform['timelimitenable'] = $toform['timelimit'] > 0; 487 } 488 489 $this->preprocessing_review_settings($toform, 'during', 490 mod_quiz_display_options::DURING); 491 $this->preprocessing_review_settings($toform, 'immediately', 492 mod_quiz_display_options::IMMEDIATELY_AFTER); 493 $this->preprocessing_review_settings($toform, 'open', 494 mod_quiz_display_options::LATER_WHILE_OPEN); 495 $this->preprocessing_review_settings($toform, 'closed', 496 mod_quiz_display_options::AFTER_CLOSE); 497 $toform['attemptduring'] = true; 498 $toform['overallfeedbackduring'] = false; 499 500 // Password field - different in form to stop browsers that remember 501 // passwords from getting confused. 502 if (isset($toform['password'])) { 503 $toform['quizpassword'] = $toform['password']; 504 unset($toform['password']); 505 } 506 507 // Load any settings belonging to the access rules. 508 if (!empty($toform['instance'])) { 509 $accesssettings = quiz_access_manager::load_settings($toform['instance']); 510 foreach ($accesssettings as $name => $value) { 511 $toform[$name] = $value; 512 } 513 } 514 } 515 516 public function validation($data, $files) { 517 $errors = parent::validation($data, $files); 518 519 // Check open and close times are consistent. 520 if ($data['timeopen'] != 0 && $data['timeclose'] != 0 && 521 $data['timeclose'] < $data['timeopen']) { 522 $errors['timeclose'] = get_string('closebeforeopen', 'quiz'); 523 } 524 525 // Check that the grace period is not too short. 526 if ($data['overduehandling'] == 'graceperiod') { 527 $graceperiodmin = get_config('quiz', 'graceperiodmin'); 528 if ($data['graceperiod'] <= $graceperiodmin) { 529 $errors['graceperiod'] = get_string('graceperiodtoosmall', 'quiz', format_time($graceperiodmin)); 530 } 531 } 532 533 // Check the boundary value is a number or a percentage, and in range. 534 $i = 0; 535 while (!empty($data['feedbackboundaries'][$i] )) { 536 $boundary = trim($data['feedbackboundaries'][$i]); 537 if (strlen($boundary) > 0) { 538 if ($boundary[strlen($boundary) - 1] == '%') { 539 $boundary = trim(substr($boundary, 0, -1)); 540 if (is_numeric($boundary)) { 541 $boundary = $boundary * $data['grade'] / 100.0; 542 } else { 543 $errors["feedbackboundaries[$i]"] = 544 get_string('feedbackerrorboundaryformat', 'quiz', $i + 1); 545 } 546 } else if (!is_numeric($boundary)) { 547 $errors["feedbackboundaries[$i]"] = 548 get_string('feedbackerrorboundaryformat', 'quiz', $i + 1); 549 } 550 } 551 if (is_numeric($boundary) && $boundary <= 0 || $boundary >= $data['grade'] ) { 552 $errors["feedbackboundaries[$i]"] = 553 get_string('feedbackerrorboundaryoutofrange', 'quiz', $i + 1); 554 } 555 if (is_numeric($boundary) && $i > 0 && 556 $boundary >= $data['feedbackboundaries'][$i - 1]) { 557 $errors["feedbackboundaries[$i]"] = 558 get_string('feedbackerrororder', 'quiz', $i + 1); 559 } 560 $data['feedbackboundaries'][$i] = $boundary; 561 $i += 1; 562 } 563 $numboundaries = $i; 564 565 // Check there is nothing in the remaining unused fields. 566 if (!empty($data['feedbackboundaries'])) { 567 for ($i = $numboundaries; $i < count($data['feedbackboundaries']); $i += 1) { 568 if (!empty($data['feedbackboundaries'][$i] ) && 569 trim($data['feedbackboundaries'][$i] ) != '') { 570 $errors["feedbackboundaries[$i]"] = 571 get_string('feedbackerrorjunkinboundary', 'quiz', $i + 1); 572 } 573 } 574 } 575 for ($i = $numboundaries + 1; $i < count($data['feedbacktext']); $i += 1) { 576 if (!empty($data['feedbacktext'][$i]['text']) && 577 trim($data['feedbacktext'][$i]['text'] ) != '') { 578 $errors["feedbacktext[$i]"] = 579 get_string('feedbackerrorjunkinfeedback', 'quiz', $i + 1); 580 } 581 } 582 583 // Any other rule plugins. 584 $errors = quiz_access_manager::validate_settings_form_fields($errors, $data, $files, $this); 585 586 return $errors; 587 } 588 589 /** 590 * Display module-specific activity completion rules. 591 * Part of the API defined by moodleform_mod 592 * @return array Array of string IDs of added items, empty array if none 593 */ 594 public function add_completion_rules() { 595 $mform = $this->_form; 596 $items = array(); 597 598 $group = array(); 599 $group[] = $mform->createElement('advcheckbox', 'completionpass', null, get_string('completionpass', 'quiz'), 600 array('group' => 'cpass')); 601 602 $group[] = $mform->createElement('advcheckbox', 'completionattemptsexhausted', null, 603 get_string('completionattemptsexhausted', 'quiz'), 604 array('group' => 'cattempts')); 605 $mform->disabledIf('completionattemptsexhausted', 'completionpass', 'notchecked'); 606 $mform->addGroup($group, 'completionpassgroup', get_string('completionpass', 'quiz'), ' ', false); 607 $mform->addHelpButton('completionpassgroup', 'completionpass', 'quiz'); 608 $items[] = 'completionpassgroup'; 609 return $items; 610 } 611 612 /** 613 * Called during validation. Indicates whether a module-specific completion rule is selected. 614 * 615 * @param array $data Input data (not yet validated) 616 * @return bool True if one or more rules is enabled, false if none are. 617 */ 618 public function completion_rule_enabled($data) { 619 return !empty($data['completionattemptsexhausted']) || !empty($data['completionpass']); 620 } 621 622 /** 623 * Get the maximum number of attempts that anyone might have due to a user 624 * or group override. Used to decide whether disabledIf rules should be applied. 625 * @return int the number of attempts allowed. For the purpose of this method, 626 * unlimited is returned as 1000, not 0. 627 */ 628 public function get_max_attempts_for_any_override() { 629 global $DB; 630 631 if (empty($this->_instance)) { 632 // Quiz not created yet, so no overrides. 633 return 1; 634 } 635 636 if ($this->maxattemptsanyoverride === null) { 637 $this->maxattemptsanyoverride = $DB->get_field_sql(" 638 SELECT MAX(CASE WHEN attempts = 0 THEN 1000 ELSE attempts END) 639 FROM {quiz_overrides} 640 WHERE quiz = ?", 641 array($this->_instance)); 642 if ($this->maxattemptsanyoverride < 1) { 643 // This happens when no override alters the number of attempts. 644 $this->maxattemptsanyoverride = 1; 645 } 646 } 647 648 return $this->maxattemptsanyoverride; 649 } 650 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |