[ 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 editing form for the calculated question data set items. 19 * 20 * @package qtype 21 * @subpackage calculated 22 * @copyright 2007 Jamie Pratt me@jamiep.org 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 require_once($CFG->dirroot . '/question/type/edit_question_form.php'); 30 31 32 /** 33 * Calculated question data set items editing form definition. 34 * 35 * @copyright 2007 Jamie Pratt me@jamiep.org 36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 37 */ 38 class question_dataset_dependent_items_form extends question_wizard_form { 39 /** 40 * Question object with options and answers already loaded by get_question_options 41 * Be careful how you use this it is needed sometimes to set up the structure of the 42 * form in definition_inner but data is always loaded into the form with set_defaults. 43 * 44 * @var object 45 */ 46 public $question; 47 /** 48 * Reference to question type object 49 * 50 * @var question_dataset_dependent_questiontype 51 */ 52 public $qtypeobj; 53 54 /** @var stdClass the question category. */ 55 protected $category; 56 57 /** @var context the context of the question category. */ 58 protected $categorycontext; 59 60 public $datasetdefs; 61 62 public $maxnumber = -1; 63 64 public $regenerate; 65 66 public $noofitems; 67 68 public $outsidelimit = false; 69 70 public $commentanswers = array(); 71 72 /** 73 * Add question-type specific form fields. 74 * 75 * @param MoodleQuickForm $mform the form being built. 76 */ 77 public function __construct($submiturl, $question, $regenerate) { 78 global $SESSION, $CFG, $DB; 79 $this->regenerate = $regenerate; 80 $this->question = $question; 81 $this->qtypeobj = question_bank::get_qtype($this->question->qtype); 82 // Validate the question category. 83 if (!$category = $DB->get_record('question_categories', 84 array('id' => $question->category))) { 85 print_error('categorydoesnotexist', 'question', $returnurl); 86 } 87 $this->category = $category; 88 $this->categorycontext = context::instance_by_id($category->contextid); 89 // Get the dataset defintions for this question. 90 if (empty($question->id)) { 91 $this->datasetdefs = $this->qtypeobj->get_dataset_definitions( 92 $question->id, $SESSION->calculated->definitionform->dataset); 93 } else { 94 if (empty($question->options)) { 95 $this->get_question_options($question); 96 } 97 $this->datasetdefs = $this->qtypeobj->get_dataset_definitions( 98 $question->id, array()); 99 } 100 101 foreach ($this->datasetdefs as $datasetdef) { 102 // Get maxnumber. 103 if ($this->maxnumber == -1 || $datasetdef->itemcount < $this->maxnumber) { 104 $this->maxnumber = $datasetdef->itemcount; 105 } 106 } 107 foreach ($this->datasetdefs as $defid => $datasetdef) { 108 if (isset($datasetdef->id)) { 109 $this->datasetdefs[$defid]->items = 110 $this->qtypeobj->get_database_dataset_items($datasetdef->id); 111 } 112 } 113 parent::__construct($submiturl); 114 } 115 116 protected function definition() { 117 global $PAGE; 118 119 $labelsharedwildcard = get_string("sharedwildcard", "qtype_calculated"); 120 $mform = $this->_form; 121 $mform->setDisableShortforms(); 122 123 $strquestionlabel = $this->qtypeobj->comment_header($this->question); 124 if ($this->maxnumber != -1 ) { 125 $this->noofitems = $this->maxnumber; 126 } else { 127 $this->noofitems = 0; 128 } 129 $label = get_string("sharedwildcards", "qtype_calculated"); 130 131 $html2 = $this->qtypeobj->print_dataset_definitions_category_shared( 132 $this->question, $this->datasetdefs); 133 $mform->addElement('static', 'listcategory', $label, $html2); 134 // ...----------------------------------------------------------------------. 135 $mform->addElement('submit', 'updatedatasets', 136 get_string('updatedatasetparam', 'qtype_calculated')); 137 $mform->registerNoSubmitButton('updatedatasets'); 138 $mform->addElement('header', 'additemhdr', 139 get_string('itemtoadd', 'qtype_calculated')); 140 $idx = 1; 141 $data = array(); 142 $j = (($this->noofitems) * count($this->datasetdefs))+1; 143 foreach ($this->datasetdefs as $defkey => $datasetdef) { 144 if ($datasetdef->category |= 0 ) { 145 $name = get_string('sharedwildcard', 'qtype_calculated', $datasetdef->name); 146 } else { 147 $name = get_string('wildcard', 'qtype_calculated', $datasetdef->name); 148 } 149 $mform->addElement('text', "number[{$j}]", $name); 150 $mform->setType("number[{$j}]", PARAM_RAW); // This parameter will be validated in validation(). 151 $this->qtypeobj->custom_generator_tools_part($mform, $idx, $j); 152 $idx++; 153 $mform->addElement('hidden', "definition[{$j}]"); 154 $mform->setType("definition[{$j}]", PARAM_RAW); 155 $mform->addElement('hidden', "itemid[{$j}]"); 156 $mform->setType("itemid[{$j}]", PARAM_RAW); 157 $mform->addElement('static', "divider[{$j}]", '', '<hr />'); 158 $mform->setType("divider[{$j}]", PARAM_RAW); 159 $j++; 160 } 161 162 $mform->addElement('header', 'updateanswershdr', 163 get_string('answerstoleranceparam', 'qtype_calculated')); 164 $mform->addElement('submit', 'updateanswers', 165 get_string('updatetolerancesparam', 'qtype_calculated')); 166 $mform->setAdvanced('updateanswers', true); 167 $mform->registerNoSubmitButton('updateanswers'); 168 169 $answers = fullclone($this->question->options->answers); 170 $key1 =1; 171 foreach ($answers as $key => $answer) { 172 $ans = shorten_text($answer->answer, 17, true); 173 if ($ans === '*') { 174 $mform->addElement('static', 175 'answercomment[' . ($this->noofitems+$key1) . ']', $ans); 176 $mform->addElement('hidden', 'tolerance['.$key.']', ''); 177 $mform->setType('tolerance['.$key.']', PARAM_RAW); 178 $mform->setAdvanced('tolerance['.$key.']', true); 179 $mform->addElement('hidden', 'tolerancetype['.$key.']', ''); 180 $mform->setType('tolerancetype['.$key.']', PARAM_RAW); 181 $mform->setAdvanced('tolerancetype['.$key.']', true); 182 $mform->addElement('hidden', 'correctanswerlength['.$key.']', ''); 183 $mform->setType('correctanswerlength['.$key.']', PARAM_RAW); 184 $mform->setAdvanced('correctanswerlength['.$key.']', true); 185 $mform->addElement('hidden', 'correctanswerformat['.$key.']', ''); 186 $mform->setType('correctanswerformat['.$key.']', PARAM_RAW); 187 $mform->setAdvanced('correctanswerformat['.$key.']', true); 188 } else if ( $ans !== '' ) { 189 $mform->addElement('static', 'answercomment[' . ($this->noofitems+$key1) . ']', 190 $ans); 191 $mform->addElement('text', 'tolerance['.$key.']', 192 get_string('tolerance', 'qtype_calculated')); 193 $mform->setType('tolerance['.$key.']', PARAM_RAW); 194 $mform->setAdvanced('tolerance['.$key.']', true); 195 $mform->addElement('select', 'tolerancetype['.$key.']', 196 get_string('tolerancetype', 'qtype_numerical'), 197 $this->qtypeobj->tolerance_types()); 198 $mform->setAdvanced('tolerancetype['.$key.']', true); 199 200 $mform->addElement('select', 'correctanswerlength['.$key.']', 201 get_string('correctanswershows', 'qtype_calculated'), range(0, 9)); 202 $mform->setAdvanced('correctanswerlength['.$key.']', true); 203 204 $answerlengthformats = array( 205 '1' => get_string('decimalformat', 'qtype_numerical'), 206 '2' => get_string('significantfiguresformat', 'qtype_calculated') 207 ); 208 $mform->addElement('select', 'correctanswerformat['.$key.']', 209 get_string('correctanswershowsformat', 'qtype_calculated'), 210 $answerlengthformats); 211 $mform->setAdvanced('correctanswerformat['.$key.']', true); 212 $mform->addElement('static', 'dividertolerance', '', '<hr />'); 213 $mform->setAdvanced('dividertolerance', true); 214 } 215 $key1++; 216 } 217 218 $addremoveoptions = array(); 219 $addremoveoptions['1']='1'; 220 for ($i=10; $i<=100; $i+=10) { 221 $addremoveoptions["{$i}"] = "{$i}"; 222 } 223 $showoptions = Array(); 224 $showoptions['1']='1'; 225 $showoptions['2']='2'; 226 $showoptions['5']='5'; 227 for ($i=10; $i<=100; $i+=10) { 228 $showoptions["{$i}"] = "{$i}"; 229 } 230 $mform->addElement('header', 'addhdr', get_string('add', 'moodle')); 231 $mform->closeHeaderBefore('addhdr'); 232 233 if ($this->qtypeobj->supports_dataset_item_generation()) { 234 $radiogrp = array(); 235 $radiogrp[] =& $mform->createElement('radio', 'nextpageparam[forceregeneration]', 236 null, get_string('reuseifpossible', 'qtype_calculated'), 0); 237 $radiogrp[] =& $mform->createElement('radio', 'nextpageparam[forceregeneration]', 238 null, get_string('forceregenerationshared', 'qtype_calculated'), 1); 239 $radiogrp[] =& $mform->createElement('radio', 'nextpageparam[forceregeneration]', 240 null, get_string('forceregenerationall', 'qtype_calculated'), 2); 241 $mform->addGroup($radiogrp, 'forceregenerationgrp', 242 get_string('nextitemtoadd', 'qtype_calculated'), "<br/>", false); 243 } 244 245 $mform->addElement('submit', 'getnextbutton', get_string('getnextnow', 'qtype_calculated')); 246 $mform->addElement('static', "dividera", '', '<hr />'); 247 $addgrp = array(); 248 $addgrp[] =& $mform->createElement('submit', 'addbutton', get_string('add', 'moodle')); 249 $addgrp[] =& $mform->createElement('select', "selectadd", 250 get_string('additem', 'qtype_calculated'), $addremoveoptions); 251 $addgrp[] = & $mform->createElement('static', "stat", "Items", 252 get_string('newsetwildcardvalues', 'qtype_calculatedsimple')); 253 $mform->addGroup($addgrp, 'addgrp', get_string('additem', 'qtype_calculated'), ' ', false); 254 $mform->addElement('static', "divideradd", '', ''); 255 if ($this->noofitems > 0) { 256 $mform->addElement('header', 'deleteitemhdr', get_string('delete', 'moodle')); 257 $deletegrp = array(); 258 $deletegrp[] = $mform->createElement('submit', 'deletebutton', 259 get_string('delete', 'moodle')); 260 $deletegrp[] = $mform->createElement('select', 'selectdelete', 261 get_string('deleteitem', 'qtype_calculated')."1", $addremoveoptions); 262 $deletegrp[] = $mform->createElement('static', "stat", "Items", 263 get_string('setwildcardvalues', 'qtype_calculatedsimple')); 264 $mform->addGroup($deletegrp, 'deletegrp', '', ' ', false); 265 } else { 266 $mform->addElement('static', 'warning', '', '<span class="error">' . 267 get_string('youmustaddatleastoneitem', 'qtype_calculated').'</span>'); 268 } 269 270 $addgrp1 = array(); 271 $addgrp1[] = $mform->createElement('submit', 'showbutton', 272 get_string('showitems', 'qtype_calculated')); 273 $addgrp1[] = $mform->createElement('select', "selectshow", '' , $showoptions); 274 $addgrp1[] = $mform->createElement('static', "stat", '', 275 get_string('setwildcardvalues', 'qtype_calculated')); 276 $mform->addGroup($addgrp1, 'addgrp1', '', ' ', false); 277 $mform->registerNoSubmitButton('showbutton'); 278 $mform->closeHeaderBefore('addgrp1'); 279 // ...----------------------------------------------------------------------. 280 $j = $this->noofitems * count($this->datasetdefs); 281 $k = optional_param('selectshow', 1, PARAM_INT); 282 for ($i = $this->noofitems; $i >= 1; $i--) { 283 if ($k > 0) { 284 $mform->addElement('header', 'setnoheader' . $i, "<b>" . 285 get_string('setno', 'qtype_calculated', $i)."</b> "); 286 } 287 foreach ($this->datasetdefs as $defkey => $datasetdef) { 288 if ($k > 0) { 289 if ($datasetdef->category == 0 ) { 290 $mform->addElement('text', "number[{$j}]", 291 get_string('wildcard', 'qtype_calculated', $datasetdef->name)); 292 } else { 293 $mform->addElement('text', "number[{$j}]", get_string( 294 'sharedwildcard', 'qtype_calculated', $datasetdef->name)); 295 } 296 297 } else { 298 $mform->addElement('hidden', "number[{$j}]" , ''); 299 } 300 $mform->setType("number[{$j}]", PARAM_RAW); // This parameter will be validated in validation(). 301 $mform->addElement('hidden', "itemid[{$j}]"); 302 $mform->setType("itemid[{$j}]", PARAM_INT); 303 304 $mform->addElement('hidden', "definition[{$j}]"); 305 $mform->setType("definition[{$j}]", PARAM_NOTAGS); 306 $data[$datasetdef->name] =$datasetdef->items[$i]->value; 307 308 $j--; 309 } 310 if ('' != $strquestionlabel && ($k > 0 )) { 311 // ... $this->outsidelimit || !empty($this->numbererrors ). 312 $repeated[] = $mform->addElement('static', "answercomment[{$i}]", $strquestionlabel); 313 // Decode equations in question text. 314 $qtext = $this->qtypeobj->substitute_variables( 315 $this->question->questiontext, $data); 316 $textequations = $this->qtypeobj->find_math_equations($qtext); 317 if ($textequations != '' && count($textequations) > 0 ) { 318 $mform->addElement('static', "divider1[{$j}]", '', 319 'Formulas {=..} in question text'); 320 foreach ($textequations as $key => $equation) { 321 if ($formulaerrors = qtype_calculated_find_formula_errors($equation)) { 322 $str = $formulaerrors; 323 } else { 324 eval('$str = '.$equation.';'); 325 } 326 $equation = shorten_text($equation, 17, true); 327 $mform->addElement('static', "textequation", "{={$equation}}", "=".$str); 328 } 329 } 330 331 } 332 $k--; 333 334 } 335 $mform->addElement('static', 'outsidelimit', '', ''); 336 337 // Submit buttons. 338 if ($this->noofitems > 0) { 339 $buttonarray = array(); 340 $buttonarray[] = $mform->createElement( 341 'submit', 'savechanges', get_string('savechanges')); 342 343 $previewlink = $PAGE->get_renderer('core_question')->question_preview_link( 344 $this->question->id, $this->categorycontext, true); 345 $buttonarray[] = $mform->createElement('static', 'previewlink', '', $previewlink); 346 347 $mform->addGroup($buttonarray, 'buttonar', '', array(' '), false); 348 $mform->closeHeaderBefore('buttonar'); 349 } 350 351 $this->add_hidden_fields(); 352 353 $mform->addElement('hidden', 'category'); 354 $mform->setType('category', PARAM_SEQUENCE); 355 356 $mform->addElement('hidden', 'wizard', 'datasetitems'); 357 $mform->setType('wizard', PARAM_ALPHA); 358 } 359 360 public function set_data($question) { 361 $formdata = array(); 362 $fromform = new stdClass(); 363 if (isset($question->options)) { 364 $answers = $question->options->answers; 365 if (count($answers)) { 366 if (optional_param('updateanswers', false, PARAM_BOOL) || 367 optional_param('updatedatasets', false, PARAM_BOOL)) { 368 foreach ($answers as $key => $answer) { 369 $fromform->tolerance[$key]= $this->_form->getElementValue( 370 'tolerance['.$key.']'); 371 $answer->tolerance = $fromform->tolerance[$key]; 372 $fromform->tolerancetype[$key]= $this->_form->getElementValue( 373 'tolerancetype['.$key.']'); 374 if (is_array($fromform->tolerancetype[$key])) { 375 $fromform->tolerancetype[$key]= $fromform->tolerancetype[$key][0]; 376 } 377 $answer->tolerancetype = $fromform->tolerancetype[$key]; 378 $fromform->correctanswerlength[$key]= $this->_form->getElementValue( 379 'correctanswerlength['.$key.']'); 380 if (is_array($fromform->correctanswerlength[$key])) { 381 $fromform->correctanswerlength[$key] = 382 $fromform->correctanswerlength[$key][0]; 383 } 384 $answer->correctanswerlength = $fromform->correctanswerlength[$key]; 385 $fromform->correctanswerformat[$key] = $this->_form->getElementValue( 386 'correctanswerformat['.$key.']'); 387 if (is_array($fromform->correctanswerformat[$key])) { 388 $fromform->correctanswerformat[$key] = 389 $fromform->correctanswerformat[$key][0]; 390 } 391 $answer->correctanswerformat = $fromform->correctanswerformat[$key]; 392 } 393 $this->qtypeobj->save_question_calculated($question, $fromform); 394 395 } else { 396 foreach ($answers as $key => $answer) { 397 $formdata['tolerance['.$key.']'] = $answer->tolerance; 398 $formdata['tolerancetype['.$key.']'] = $answer->tolerancetype; 399 $formdata['correctanswerlength['.$key.']'] = $answer->correctanswerlength; 400 $formdata['correctanswerformat['.$key.']'] = $answer->correctanswerformat; 401 } 402 } 403 } 404 } 405 // Fill out all data sets and also the fields for the next item to add. 406 $j = $this->noofitems * count($this->datasetdefs); 407 for ($itemnumber = $this->noofitems; $itemnumber >= 1; $itemnumber--) { 408 $data = array(); 409 foreach ($this->datasetdefs as $defid => $datasetdef) { 410 if (isset($datasetdef->items[$itemnumber])) { 411 $formdata["number[{$j}]"] = $datasetdef->items[$itemnumber]->value; 412 $formdata["definition[{$j}]"] = $defid; 413 $formdata["itemid[{$j}]"] = $datasetdef->items[$itemnumber]->id; 414 $data[$datasetdef->name] = $datasetdef->items[$itemnumber]->value; 415 } 416 $j--; 417 } 418 $comment = $this->qtypeobj->comment_on_datasetitems($this->qtypeobj, $question->id, 419 $question->questiontext, $answers, $data, $itemnumber); 420 if ($comment->outsidelimit) { 421 $this->outsidelimit=$comment->outsidelimit; 422 } 423 $totalcomment=''; 424 foreach ($question->options->answers as $key => $answer) { 425 $totalcomment .= $comment->stranswers[$key].'<br/>'; 426 } 427 $formdata['answercomment['.$itemnumber.']'] = $totalcomment; 428 } 429 430 $formdata['nextpageparam[forceregeneration]'] = $this->regenerate; 431 $formdata['selectdelete'] = '1'; 432 $formdata['selectadd'] = '1'; 433 $j = $this->noofitems * count($this->datasetdefs)+1; 434 $data = array(); // Data for comment_on_datasetitems later. 435 // Dataset generation defaults. 436 if ($this->qtypeobj->supports_dataset_item_generation()) { 437 $itemnumber = $this->noofitems+1; 438 foreach ($this->datasetdefs as $defid => $datasetdef) { 439 if (!optional_param('updatedatasets', false, PARAM_BOOL) && 440 !optional_param('updateanswers', false, PARAM_BOOL)) { 441 $formdata["number[{$j}]"] = $this->qtypeobj->generate_dataset_item( 442 $datasetdef->options); 443 } else { 444 $formdata["number[{$j}]"] = $this->_form->getElementValue("number[{$j}]"); 445 } 446 $formdata["definition[{$j}]"] = $defid; 447 $formdata["itemid[{$j}]"] = isset($datasetdef->items[$itemnumber]) ? 448 $datasetdef->items[$itemnumber]->id : 0; 449 $data[$datasetdef->name] = $formdata["number[{$j}]"]; 450 $j++; 451 } 452 } 453 454 // Existing records override generated data depending on radio element. 455 $j = $this->noofitems * count($this->datasetdefs) + 1; 456 if (!$this->regenerate && !optional_param('updatedatasets', false, PARAM_BOOL) && 457 !optional_param('updateanswers', false, PARAM_BOOL)) { 458 $idx = 1; 459 $itemnumber = $this->noofitems + 1; 460 foreach ($this->datasetdefs as $defid => $datasetdef) { 461 if (isset($datasetdef->items[$itemnumber])) { 462 $formdata["number[{$j}]"] = $datasetdef->items[$itemnumber]->value; 463 $formdata["definition[{$j}]"] = $defid; 464 $formdata["itemid[{$j}]"] = $datasetdef->items[$itemnumber]->id; 465 $data[$datasetdef->name] = $datasetdef->items[$itemnumber]->value; 466 } 467 $j++; 468 } 469 } 470 471 $comment = $this->qtypeobj->comment_on_datasetitems($this->qtypeobj, $question->id, 472 $question->questiontext, $answers, $data, ($this->noofitems + 1)); 473 if (isset($comment->outsidelimit) && $comment->outsidelimit) { 474 $this->outsidelimit=$comment->outsidelimit; 475 } 476 $key1 = 1; 477 foreach ($question->options->answers as $key => $answer) { 478 $formdata['answercomment['.($this->noofitems+$key1).']'] = $comment->stranswers[$key]; 479 $key1++; 480 } 481 482 if ($this->outsidelimit) { 483 $formdata['outsidelimit']= '<span class="error">' . 484 get_string('oneanswertrueansweroutsidelimits', 'qtype_calculated') . '</span>'; 485 } 486 $formdata = $this->qtypeobj->custom_generator_set_data($this->datasetdefs, $formdata); 487 488 parent::set_data((object)($formdata + (array)$question)); 489 } 490 491 public function validation($data, $files) { 492 $errors = array(); 493 if (isset($data['savechanges']) && ($this->noofitems==0) ) { 494 $errors['warning'] = get_string('warning', 'mnet'); 495 } 496 if ($this->outsidelimit) { 497 $errors['outsidelimits'] = 498 get_string('oneanswertrueansweroutsidelimits', 'qtype_calculated'); 499 } 500 $numbers = $data['number']; 501 foreach ($numbers as $key => $number) { 502 if (! is_numeric($number)) { 503 if (stristr($number, ',')) { 504 $errors['number['.$key.']'] = get_string('nocommaallowed', 'qtype_calculated'); 505 } else { 506 $errors['number['.$key.']'] = get_string('notvalidnumber', 'qtype_calculated'); 507 } 508 } else if (stristr($number, 'x')) { 509 $a = new stdClass(); 510 $a->name = ''; 511 $a->value = $number; 512 $errors['number['.$key.']'] = get_string('hexanotallowed', 'qtype_calculated', $a); 513 } else if (is_nan($number)) { 514 $errors['number['.$key.']'] = get_string('notvalidnumber', 'qtype_calculated'); 515 } 516 } 517 return $errors; 518 } 519 }
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 |