Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/question/type/numerical/edit_numerical_form.php
Go to the documentation of this file.
00001 <?php
00002 // This file is part of Moodle - http://moodle.org/
00003 //
00004 // Moodle is free software: you can redistribute it and/or modify
00005 // it under the terms of the GNU General Public License as published by
00006 // the Free Software Foundation, either version 3 of the License, or
00007 // (at your option) any later version.
00008 //
00009 // Moodle is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
00016 
00027 defined('MOODLE_INTERNAL') || die();
00028 
00029 require_once($CFG->dirroot . '/question/type/edit_question_form.php');
00030 require_once($CFG->dirroot . '/question/type/numerical/questiontype.php');
00031 
00032 
00039 class qtype_numerical_edit_form extends question_edit_form {
00040     protected $ap = null;
00041 
00042     protected function definition_inner($mform) {
00043         $this->add_per_answer_fields($mform, get_string('answerno', 'qtype_numerical', '{no}'),
00044                 question_bank::fraction_options());
00045 
00046         $this->add_unit_options($mform);
00047         $this->add_unit_fields($mform);
00048         $this->add_interactive_settings();
00049     }
00050 
00051     protected function get_per_answer_fields($mform, $label, $gradeoptions,
00052             &$repeatedoptions, &$answersoption) {
00053         $repeated = parent::get_per_answer_fields($mform, $label, $gradeoptions,
00054                 $repeatedoptions, $answersoption);
00055 
00056         $tolerance = $mform->createElement('text', 'tolerance',
00057                 get_string('acceptederror', 'qtype_numerical'));
00058         $repeatedoptions['tolerance']['type'] = PARAM_NUMBER;
00059         $repeatedoptions['tolerance']['default'] = 0;
00060         array_splice($repeated, 3, 0, array($tolerance));
00061         $repeated[1]->setSize(10);
00062 
00063         return $repeated;
00064     }
00065 
00070     protected function add_unit_options($mform) {
00071 
00072         $mform->addElement('header', 'unithandling',
00073                 get_string('unithandling', 'qtype_numerical'));
00074 
00075         $unitoptions = array(
00076             qtype_numerical::UNITNONE     => get_string('onlynumerical', 'qtype_numerical'),
00077             qtype_numerical::UNITOPTIONAL => get_string('manynumerical', 'qtype_numerical'),
00078             qtype_numerical::UNITGRADED   => get_string('unitgraded', 'qtype_numerical'),
00079         );
00080         $mform->addElement('select', 'unitrole',
00081                 get_string('unithandling', 'qtype_numerical'), $unitoptions);
00082 
00083         $penaltygrp = array();
00084         $penaltygrp[] = $mform->createElement('text', 'unitpenalty',
00085                 get_string('unitpenalty', 'qtype_numerical'), array('size' => 6));
00086         $mform->setType('unitpenalty', PARAM_NUMBER);
00087         $mform->setDefault('unitpenalty', 0.1000000);
00088 
00089         $unitgradingtypes = array(
00090             qtype_numerical::UNITGRADEDOUTOFMARK =>
00091                     get_string('decfractionofresponsegrade', 'qtype_numerical'),
00092             qtype_numerical::UNITGRADEDOUTOFMAX =>
00093                     get_string('decfractionofquestiongrade', 'qtype_numerical'),
00094         );
00095         $penaltygrp[] = $mform->createElement('select', 'unitgradingtypes', '', $unitgradingtypes);
00096         $mform->setDefault('unitgradingtypes', 1);
00097 
00098         $mform->addGroup($penaltygrp, 'penaltygrp',
00099                 get_string('unitpenalty', 'qtype_numerical'), ' ', false);
00100         $mform->addHelpButton('penaltygrp', 'unitpenalty', 'qtype_numerical');
00101 
00102         $unitinputoptions = array(
00103             qtype_numerical::UNITINPUT => get_string('editableunittext', 'qtype_numerical'),
00104             qtype_numerical::UNITRADIO => get_string('unitchoice', 'qtype_numerical'),
00105             qtype_numerical::UNITSELECT => get_string('unitselect', 'qtype_numerical'),
00106         );
00107         $mform->addElement('select', 'multichoicedisplay',
00108                 get_string('studentunitanswer', 'qtype_numerical'), $unitinputoptions);
00109 
00110         $unitsleftoptions = array(
00111             0 => get_string('rightexample', 'qtype_numerical'),
00112             1 => get_string('leftexample', 'qtype_numerical')
00113         );
00114         $mform->addElement('select', 'unitsleft',
00115                 get_string('unitposition', 'qtype_numerical'), $unitsleftoptions);
00116         $mform->setDefault('unitsleft', 0);
00117 
00118         $mform->disabledIf('penaltygrp', 'unitrole', 'eq', qtype_numerical::UNITNONE);
00119         $mform->disabledIf('penaltygrp', 'unitrole', 'eq', qtype_numerical::UNITOPTIONAL);
00120 
00121         $mform->disabledIf('unitsleft', 'unitrole', 'eq', qtype_numerical::UNITNONE);
00122 
00123         $mform->disabledIf('multichoicedisplay', 'unitrole', 'eq', qtype_numerical::UNITNONE);
00124         $mform->disabledIf('multichoicedisplay', 'unitrole', 'eq', qtype_numerical::UNITOPTIONAL);
00125     }
00126 
00131     protected function add_unit_fields($mform) {
00132         $repeated = array(
00133             $mform->createElement('header', 'unithdr',
00134                     get_string('unithdr', 'qtype_numerical', '{no}')),
00135             $mform->createElement('text', 'unit', get_string('unit', 'quiz')),
00136             $mform->createElement('text', 'multiplier', get_string('multiplier', 'quiz')),
00137         );
00138 
00139         $repeatedoptions['unit']['type'] = PARAM_NOTAGS;
00140         $repeatedoptions['multiplier']['type'] = PARAM_NUMBER;
00141         $repeatedoptions['unit']['disabledif'] =
00142                 array('unitrole', 'eq', qtype_numerical::UNITNONE);
00143         $repeatedoptions['multiplier']['disabledif'] =
00144                 array('unitrole', 'eq', qtype_numerical::UNITNONE);
00145 
00146         if (isset($this->question->options->units)) {
00147             $countunits = count($this->question->options->units);
00148         } else {
00149             $countunits = 0;
00150         }
00151         if ($this->question->formoptions->repeatelements) {
00152             $repeatsatstart = $countunits + 1;
00153         } else {
00154             $repeatsatstart = $countunits;
00155         }
00156         $this->repeat_elements($repeated, $repeatsatstart, $repeatedoptions, 'nounits',
00157                 'addunits', 2, get_string('addmoreunitblanks', 'qtype_calculated', '{no}'));
00158 
00159         if ($mform->elementExists('multiplier[0]')) {
00160             $firstunit = $mform->getElement('multiplier[0]');
00161             $firstunit->freeze();
00162             $firstunit->setValue('1.0');
00163             $firstunit->setPersistantFreeze(true);
00164             $mform->addHelpButton('multiplier[0]', 'numericalmultiplier', 'qtype_numerical');
00165         }
00166     }
00167 
00168     protected function data_preprocessing($question) {
00169         $question = parent::data_preprocessing($question);
00170         $question = $this->data_preprocessing_answers($question);
00171         $question = $this->data_preprocessing_hints($question);
00172         $question = $this->data_preprocessing_units($question);
00173         $question = $this->data_preprocessing_unit_options($question);
00174         return $question;
00175     }
00176 
00177     protected function data_preprocessing_answers($question) {
00178         $question = parent::data_preprocessing_answers($question);
00179         if (empty($question->options->answers)) {
00180             return $question;
00181         }
00182 
00183         $key = 0;
00184         foreach ($question->options->answers as $answer) {
00185             // See comment in the parent method about this hack.
00186             unset($this->_form->_defaultValues["tolerance[$key]"]);
00187 
00188             $question->tolerance[$key] = $answer->tolerance;
00189             $key++;
00190         }
00191 
00192         return $question;
00193     }
00194 
00201     protected function data_preprocessing_units($question) {
00202         if (empty($question->options->units)) {
00203             return $question;
00204         }
00205 
00206         foreach ($question->options->units as $key => $unit) {
00207             $question->unit[$key] = $unit->unit;
00208             $question->multiplier[$key] = $unit->multiplier;
00209         }
00210 
00211         return $question;
00212     }
00213 
00220     protected function data_preprocessing_unit_options($question) {
00221         if (empty($question->options)) {
00222             return $question;
00223         }
00224 
00225         $question->unitpenalty = $question->options->unitpenalty;
00226         $question->unitsleft = $question->options->unitsleft;
00227 
00228         if ($question->options->unitgradingtype) {
00229             $question->unitgradingtypes = $question->options->unitgradingtype;
00230             $question->multichoicedisplay = $question->options->showunits;
00231             $question->unitrole = qtype_numerical::UNITGRADED;
00232         } else {
00233             $question->unitrole = $question->options->showunits;
00234         }
00235 
00236         return $question;
00237     }
00238 
00239     public function validation($data, $files) {
00240         $errors = parent::validation($data, $files);
00241         $errors = $this->validate_answers($data, $errors);
00242         $errors = $this->validate_numerical_options($data, $errors);
00243         return $errors;
00244     }
00245 
00252     protected function validate_answers($data, $errors) {
00253         // Check the answers.
00254         $answercount = 0;
00255         $maxgrade = false;
00256         $answers = $data['answer'];
00257         foreach ($answers as $key => $answer) {
00258             $trimmedanswer = trim($answer);
00259             if ($trimmedanswer != '') {
00260                 $answercount++;
00261                 if (!$this->is_valid_answer($trimmedanswer, $data)) {
00262                     $errors['answer[' . $key . ']'] = $this->valid_answer_message($trimmedanswer);
00263                 }
00264                 if ($data['fraction'][$key] == 1) {
00265                     $maxgrade = true;
00266                 }
00267                 if ($answer !== '*' && !is_numeric($data['tolerance'][$key])) {
00268                     $errors['tolerance['.$key.']'] =
00269                             get_string('mustbenumeric', 'qtype_calculated');
00270                 }
00271             } else if ($data['fraction'][$key] != 0 ||
00272                     !html_is_blank($data['feedback'][$key]['text'])) {
00273                 $errors['answer[' . $key . ']'] = $this->valid_answer_message($trimmedanswer);
00274                 $answercount++;
00275             }
00276         }
00277         if ($answercount == 0) {
00278             $errors['answer[0]'] = get_string('notenoughanswers', 'qtype_numerical');
00279         }
00280         if ($maxgrade == false) {
00281             $errors['fraction[0]'] = get_string('fractionsnomax', 'question');
00282         }
00283 
00284         return $errors;
00285     }
00286 
00293     protected function is_valid_answer($answer, $data) {
00294         return $answer == '*' || $this->is_valid_number($answer);
00295     }
00296 
00302     protected function is_valid_number($x) {
00303         if (is_null($this->ap)) {
00304             $this->ap = new qtype_numerical_answer_processor(array());
00305         }
00306 
00307         list($value, $unit) = $this->ap->apply_units($x);
00308 
00309         return !is_null($value) && !$unit;
00310     }
00311 
00315     protected function valid_answer_message($answer) {
00316         return get_string('answermustbenumberorstar', 'qtype_numerical');
00317     }
00318 
00325     protected function validate_numerical_options($data, $errors) {
00326         if ($data['unitrole'] != qtype_numerical::UNITNONE && trim($data['unit'][0]) == '') {
00327             $errors['unit[0]'] = get_string('unitonerequired', 'qtype_numerical');
00328         }
00329 
00330         if (empty($data['unit'])) {
00331             return $errors;
00332         }
00333 
00334         // Basic unit validation.
00335         foreach ($data['unit'] as $key => $unit) {
00336             if (is_numeric($unit)) {
00337                 $errors['unit[' . $key . ']'] =
00338                         get_string('mustnotbenumeric', 'qtype_calculated');
00339             }
00340 
00341             $trimmedunit = trim($unit);
00342             if (empty($trimmedunit)) {
00343                 continue;
00344             }
00345 
00346             $trimmedmultiplier = trim($data['multiplier'][$key]);
00347             if (empty($trimmedmultiplier)) {
00348                 $errors['multiplier[' . $key . ']'] =
00349                         get_string('youmustenteramultiplierhere', 'qtype_calculated');
00350             } else if (!is_numeric($trimmedmultiplier)) {
00351                 $errors['multiplier[' . $key . ']'] =
00352                         get_string('mustbenumeric', 'qtype_calculated');
00353             }
00354         }
00355 
00356         // Check for repeated units.
00357         $alreadyseenunits = array();
00358         foreach ($data['unit'] as $key => $unit) {
00359             $trimmedunit = trim($unit);
00360             if ($trimmedunit == '') {
00361                 continue;
00362             }
00363 
00364             if (in_array($trimmedunit, $alreadyseenunits)) {
00365                 $errors['unit[' . $key . ']'] =
00366                         get_string('errorrepeatedunit', 'qtype_numerical');
00367             } else {
00368                 $alreadyseenunits[] = $trimmedunit;
00369             }
00370         }
00371 
00372         return $errors;
00373     }
00374 
00375     public function qtype() {
00376         return 'numerical';
00377     }
00378 }
 All Data Structures Namespaces Files Functions Variables Enumerations