--- /dev/null
+<?php // $Id$
+/**
+ * Defines the editing form for the calculated simplequestion type.
+ *
+ * @copyright © 2007 Jamie Pratt
+ * @author Jamie Pratt me@jamiep.org
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package questionbank
+ * @subpackage questiontypes
+ */
+
+/**
+ * calculatedsimple editing form definition.
+ */
+class question_edit_calculatedsimple_form extends question_edit_form {
+ /**
+ * Handle to the question type for this question.
+ *
+ * @var question_calculatedsimple_qtype
+ */
+ var $qtypeobj;
+ var $wildcarddisplay ;
+// public $qtypeobj;
+ // $questiondisplay will contain the question from the form
+ var $questiondisplay ;
+
+ public $datasetdefs;
+
+ public $reload = false ;
+
+ public $maxnumber = -1;
+
+ public $regenerate = true;
+
+ public $noofitems;
+
+ public $outsidelimit = false ;
+
+ public $commentanswer = array();
+
+ public $answer = array();
+
+ public $nonemptyanswer = array();
+
+
+ function question_edit_calculatedsimple_form(&$submiturl, &$question, &$category, &$contexts, $formeditable = true){
+ global $QTYPES, $SESSION, $CFG, $DB;
+ // echo "<p> QTYPES <pre>";print_r($QTYPES);echo"</pre></p>";
+ // echo "<p> session <pre>";print_r($SESSION);echo"</pre></p>";
+ // echo "<p> question <pre>";print_r($question);echo"</pre></p>";
+ $this->regenerate = true;
+ $this->question = $question;
+ $this->qtypeobj =& $QTYPES[$this->question->qtype];
+ //get the dataset definitions for this question
+ //coming here everytime even when using a NoSubmitButton
+ //so this will only set the values to the actual question database content which is not what we want
+ //so this should be removed from here
+ // get priority to paramdatasets
+
+ // question->id == 0 so no stored datasets
+ // else get datasets
+ if ( "1" == optional_param('reload','', PARAM_INT )) {
+ // echo "<p> optional reload exist </p>";
+ $this->reload = true ;
+ }else {
+ $this->reload = false ;
+ }
+ if(!$this->reload ){ // use database data as this is first pass
+ if ( !empty($question->id)) {
+ if (empty($question->options)) {
+ $this->get_question_options($question);
+ }
+ $this->datasetdefs = $this->qtypeobj->get_dataset_definitions($question->id, array());
+
+ if(!empty($this->datasetdefs)){
+ foreach ($this->datasetdefs as $datasetdef) {
+ // Get maxnumber
+ if ($this->maxnumber == -1 || $datasetdef->itemcount < $this->maxnumber) {
+ $this->maxnumber = $datasetdef->itemcount;
+ }
+ }
+ foreach ($this->datasetdefs as $defid => $datasetdef) {
+ if (isset($datasetdef->id)) {
+ $this->datasetdefs[$defid]->items = $DB->get_records_sql( // Use number as key!!
+ " SELECT itemnumber, definition, id, value
+ FROM {question_dataset_items}
+ WHERE definition = ? ", array($datasetdef->id));
+ }
+ }
+ }
+ $i = 0 ;
+ foreach($this->question->options->answers as $answer){
+ $this->answer[$i] = $answer ;
+ $i++;
+ }
+ $this->nonemptyanswer = $this->answer ;
+ }
+ $datasettoremove = false;
+ $newdatasetvalues = false ;
+ $newdataset = false ;
+ }else {
+ // handle reload to get values from the form-elements
+ // answers, datasetdefs and data_items
+ // verify for the specific dataset values as the other parameters
+ // unints, feeedback etc are handled elsewhere
+ // handle request buttons :
+ // 'analyzequestion' (Identify the wild cards {x..} present in answers)
+ // 'addbutton' (create new set of datatitems)
+ // 'updatedatasets' is handled automatically on each reload
+ // The analyzequestion is done every time on reload
+ // to detect any new wild cards so that the current display reflects
+ // the mandatory (i.e. in answers) datasets
+ // to implement : don't do any changes if the question is used in a quiz.
+ // If new datadef, new properties should erase items.
+ $dummyform = new stdClass();
+ $mandatorydatasets = array();
+
+ if ( $dummyform->answer =optional_param('answer')) { // there is always at least one answer...
+ $fraction = optional_param('fraction') ;
+ $feedback = optional_param('feedback') ;
+ $tolerance = optional_param('tolerance') ;
+ $tolerancetype = optional_param('tolerancetype') ;
+ $correctanswerlength = optional_param('correctanswerlength') ;
+ $correctanswerformat = optional_param('correctanswerformat') ;
+
+ foreach( $dummyform->answer as $key => $answer ) {
+ if(trim($answer) != ''){ // just look for non-empty
+ $this->answer[$key]=new stdClass();
+ $this->answer[$key]->answer = $answer;
+ $this->answer[$key]->fraction = $fraction[$key];
+ $this->answer[$key]->feedback = $feedback[$key];
+ $this->answer[$key]->tolerance = $tolerance[$key];
+ $this->answer[$key]->tolerancetype = $tolerancetype[$key];
+ $this->answer[$key]->correctanswerlength = $correctanswerlength[$key];
+ $this->answer[$key]->correctanswerformat = $correctanswerformat[$key];
+ $this->nonemptyanswer[]= $this->answer[$key];
+ $mandatorydatasets +=$this->qtypeobj->find_dataset_names($answer);
+ }
+ }
+ }
+ // echo "<p>this->answer <pre>";print_r($this->answer);echo"</pre></p>";
+ // echo "<p>this->answer <pre>";print_r($this->nonemptyanswer);echo"</pre></p>";
+ $this->datasetdefs = array();
+ // rebuild datasetdefs from old values
+ $olddef = optional_param('datasetdef');
+ $oldoptions = optional_param('defoptions');
+ $calcmin = optional_param('calcmin') ;
+ $calclength = optional_param('calclength') ;
+ $calcmax = optional_param('calcmax') ;
+ /* echo "<p> calcmin <pre>";print_r(optional_param('calcmin'));echo"</pre></p>";
+ echo "<p> calcmax <pre>";print_r(optional_param('calcmax'));echo"</pre></p>";
+ echo "<p> calclength <pre>";print_r(optional_param('calclength'));echo"</pre></p>";*/
+ $newdatasetvalues = false ;
+ // echo "<p> olddef <pre>";print_r(optional_param('datasetdef'));echo"</pre></p>";
+
+ for($key = 1 ; $key <= sizeof($olddef) ; $key++) {
+ $def = $olddef[$key] ;
+ $this->datasetdefs[$def]= new stdClass ;
+ $this->datasetdefs[$def]->type = 1;
+ $this->datasetdefs[$def]->category = 0;
+ // $this->datasets[$key]->name = $datasetname;
+ $this->datasetdefs[$def]->options = $oldoptions[$key] ;
+ $this->datasetdefs[$def]->calcmin = $calcmin[$key] ;
+ $this->datasetdefs[$def]->calcmax = $calcmax[$key] ;
+ $this->datasetdefs[$def]->calclength = $calclength[$key] ;
+ //then compare with new values
+ if (ereg('^(uniform|loguniform):([^:]*):([^:]*):([0-9]*)$', $this->datasetdefs[$def]->options, $regs)) {
+ if( $this->datasetdefs[$def]->calcmin != $regs[2]||
+ $this->datasetdefs[$def]->calcmax != $regs[3] ||
+ $this->datasetdefs[$def]->calclength != $regs[4]){
+ $newdatasetvalues = true ;
+ // echo "<p> new datasetdefs values ".$regs[2]."xx". $regs[3]."xx".$regs[4]."</p>";
+ }
+
+ }
+ $this->datasetdefs[$def]->options="uniform:".$this->datasetdefs[$def]->calcmin.":".$this->datasetdefs[$def]->calcmax.":".$this->datasetdefs[$def]->calclength;
+ }
+
+ // echo "<p>this datasetdefs <pre>";print_r($this->datasetdefs);echo"</pre></p>";
+ // detect new datasets
+ $newdataset = false ;
+ foreach ($mandatorydatasets as $datasetname) {
+ if (!isset($this->datasetdefs["1-0-$datasetname"])) {
+ // list($options, $selected) =
+ // $this->dataset_options($form, $datasetname);
+ $key = "1-0-$datasetname";
+ $this->datasetdefs[$key]=new stdClass ;//"1-0-$datasetname";
+ $this->datasetdefs[$key]->type = 1;
+ $this->datasetdefs[$key]->category = 0;
+ $this->datasetdefs[$key]->name = $datasetname;
+ $this->datasetdefs[$key]->options = "uniform:1.0:10.0:1";
+ $newdataset = true ;
+ // echo "<p> new datasetdefs $datasetname </p>";
+ // $form->dataset[$key]=$selected ;
+ //$key++;
+ }else {
+ $this->datasetdefs["1-0-$datasetname"]->name = $datasetname ;
+ }
+ }
+ // remove obsolete datasets
+ $datasettoremove = false;
+ foreach ($this->datasetdefs as $defkey => $datasetdef){
+ if(!isset($datasetdef->name )){
+ // echo "<p> dataset $defkey to remove </p>";
+ $datasettoremove = true;
+ unset($this->datasetdefs[$defkey]);
+ }
+ }
+
+
+ } // handle reload
+ // create items if $newdataset and noofitems > 0 and !$newdatasetvalues
+ // eliminate any items if $newdatasetvalues
+ // eliminate any items if $datasettoremove, $newdataset, $newdatasetvalues
+ if ($datasettoremove ||$newdataset ||$newdatasetvalues ) {
+ foreach ($this->datasetdefs as $defkey => $datasetdef){
+ $datasetdef->itemcount = 0;
+ unset($datasetdef->items);
+ }
+ }
+ $maxnumber = -1 ;
+ if ( "" !=optional_param('addbutton')){
+ $maxnumber = optional_param('selectadd') ;
+ foreach ($this->datasetdefs as $defid => $datasetdef) {
+ $datasetdef->itemcount = $maxnumber;
+ unset($datasetdef->items);
+ for ($numberadded =1 ; $numberadded <= $maxnumber; $numberadded++){
+ $datasetitem = new stdClass;
+ // $datasetitem->definition = $datasetdef->id ;
+ $datasetitem->itemnumber = $numberadded;
+ $datasetitem->id = 0;
+ $datasetitem->value = $this->qtypeobj->generate_dataset_item($datasetdef->options);
+ $this->datasetdefs[$defid]->items[$numberadded]=$datasetitem ;
+ /* if (!$DB->insert_record('question_dataset_items', $datasetitem)) {
+ print_error('cannotinsert', 'question');
+ }*/
+ }//for number added
+ }// datasetsdefs end
+ $this->maxnumber = $maxnumber ;
+ // echo"<p> using create new items $this->maxnumber </p>";
+ }else {
+ // Handle reload dataset items
+ // echo"<p> using optional to build </p>";
+ if ( "" !=optional_param('definition')&& !($datasettoremove ||$newdataset ||$newdatasetvalues )){
+ $i = 1;
+ $fromformdefinition = optional_param('definition');
+ $fromformnumber = optional_param('number');
+ $fromformitemid = optional_param('itemid');
+ ksort($fromformdefinition);
+ // echo "<p> fromformdefinition <pre>";print_r($fromformdefinition);echo"</pre></p>";
+ // echo "<p> fromformnumber <pre>";print_r($fromformnumber);echo"</pre></p>";
+
+ foreach($fromformdefinition as $key => $defid) {
+ $addeditem = new stdClass();
+ $addeditem->id = $fromformitemid[$i] ;
+ $addeditem->value = $fromformnumber[$i];
+ $addeditem->itemnumber = ceil($i / count($this->datasetdefs));
+ $this->datasetdefs[$defid]->items[$addeditem->itemnumber]=$addeditem ;
+ $this->datasetdefs[$defid]->itemcount = $i ;
+ $i++;
+ }
+ }
+ if (isset($addeditem->itemnumber) && $this->maxnumber < $addeditem->itemnumber){
+ $this->maxnumber = $addeditem->itemnumber;
+ if(!empty($this->datasetdefs)){
+ foreach ($this->datasetdefs as $datasetdef) {
+ $datasetdef->itemcount = $this->maxnumber ;
+ }
+ }
+ }
+ }
+
+ // echo "<p>line 443 datasetdefs <pre>";print_r($this->datasetdefs);echo"</pre></p>";
+ //$key = 0 ;
+ // if ( "" !=optional_param('answer')) echo "<p> optional answer exist </p>";
+ // if ( "" !=optional_param('answer['.$key.']','', PARAM_NOTAGS)) echo "<p> optional $key exist </p>";
+ // if ( "" !=optional_param('noanswer','', PARAM_INT )) echo "<p> optional noanswer exist </p>";
+
+ parent::question_edit_form($submiturl, $question, $category, $contexts, $formeditable);
+ }
+
+ function get_per_answer_fields(&$mform, $label, $gradeoptions, &$repeatedoptions, &$answersoption) {
+ $repeated = parent::get_per_answer_fields(&$mform, $label, $gradeoptions, $repeatedoptions, $answersoption);
+ $mform->setType('answer', PARAM_NOTAGS);
+ $addrepeated = array();
+ $addrepeated[] =& $mform->createElement('text', 'tolerance', get_string('tolerance', 'qtype_calculated'));
+ $repeatedoptions['tolerance']['type'] = PARAM_NUMBER;
+ $repeatedoptions['tolerance']['default'] = 0.01;
+ $addrepeated[] =& $mform->createElement('select', 'tolerancetype', get_string('tolerancetype', 'quiz'), $this->qtypeobj->tolerance_types());
+ $addrepeated[] =& $mform->createElement('select', 'correctanswerlength', get_string('correctanswershows', 'qtype_calculated'), range(0, 9));
+ $repeatedoptions['correctanswerlength']['default'] = 2;
+
+ $answerlengthformats = array('1' => get_string('decimalformat', 'quiz'), '2' => get_string('significantfiguresformat', 'quiz'));
+ $addrepeated[] =& $mform->createElement('select', 'correctanswerformat', get_string('correctanswershowsformat', 'qtype_calculated'), $answerlengthformats);
+ array_splice($repeated, 3, 0, $addrepeated);
+ $repeated[1]->setLabel(get_string('correctanswerformula', 'quiz').'=');
+
+ return $repeated;
+ }
+
+ /**
+ * Add question-type specific form fields.
+ *
+ * @param MoodleQuickForm $mform the form being built.
+ */
+ function definition_inner(&$mform) {
+ global $QTYPES;
+ $this->qtypeobj =& $QTYPES[$this->qtype()];
+ $strquestionlabel = $this->qtypeobj->comment_header($this->nonemptyanswer);
+ $label = get_string("sharedwildcards", "qtype_datasetdependent");
+ $mform->addElement('hidden', 'initialcategory', 1);
+ $mform->addElement('hidden', 'reload', 1);
+// $html2 = $this->qtypeobj->print_dataset_definitions_category($this->question);
+// $mform->insertElementBefore($mform->createElement('static','listcategory',$label,$html2),'name');
+ $addfieldsname='updatecategory';
+ $addstring=get_string("updatecategory", "qtype_calculated");
+ $mform->registerNoSubmitButton($addfieldsname);
+
+// $mform->insertElementBefore( $mform->createElement('submit', $addfieldsname, $addstring),'listcategory');
+
+ $creategrades = get_grade_options();
+ $this->add_per_answer_fields($mform, get_string('answerhdr', 'qtype_calculated', '{no}'),
+ $creategrades->gradeoptions, 1, 1);
+
+ $repeated = array();
+ $repeated[] =& $mform->createElement('header', 'unithdr', get_string('unithdr', 'qtype_numerical', '{no}'));
+
+ $repeated[] =& $mform->createElement('text', 'unit', get_string('unit', 'quiz'));
+ $mform->setType('unit', PARAM_NOTAGS);
+
+ $repeated[] =& $mform->createElement('text', 'multiplier', get_string('multiplier', 'quiz'));
+ $mform->setType('multiplier', PARAM_NUMBER);
+
+ if (isset($this->question->options)){
+ $countunits = count($this->question->options->units);
+ } else {
+ $countunits = 0;
+ }
+ if ($this->question->formoptions->repeatelements){
+ $repeatsatstart = $countunits + 1;
+ } else {
+ $repeatsatstart = $countunits;
+ }
+ $this->repeat_elements($repeated, $repeatsatstart, array(), 'nounits', 'addunits', 2, get_string('addmoreunitblanks', 'qtype_calculated', '{no}'));
+
+ if ($mform->elementExists('multiplier[0]')){
+ $firstunit =& $mform->getElement('multiplier[0]');
+ $firstunit->freeze();
+ $firstunit->setValue('1.0');
+ $firstunit->setPersistantFreeze(true);
+ }
+ //hidden elements
+ // $mform->addElement('hidden', 'wizard', 'datasetdefinitions');
+ // $mform->setType('wizard', PARAM_ALPHA);
+ // $mform->addElement('header', '', '');
+ $label = "<div class='mdl-align'></div><div class='mdl-align'>".get_string('wildcardrole', 'qtype_calculatedsimple')."</div>";
+ $mform->addElement('html', "<div class='mdl-align'> </div>");
+ $mform->addElement('html', $label);// explaining the role of datasets so other strings can be shortened
+
+ $mform->addElement('submit', 'analyzequestion', get_string('findwildcards','qtype_calculatedsimple'));
+ $mform->registerNoSubmitButton('analyzequestion');
+ $mform->closeHeaderBefore('analyzequestion');
+ if ( "" != optional_param('analyzequestion','', PARAM_RAW)) {
+
+ $this->wizarddisplay = true;
+ // echo "<p> session answer <pre>";print_r($SESSION);echo"</pre></p>";
+ // echo "<p> session answer <pre>";print_r($SESSION->calculated->questionform->answers);echo"</pre></p>";
+
+
+ }else {
+ $this->wizwarddisplay = false;
+ }
+ if ($this->maxnumber != -1){
+ $this->noofitems = $this->maxnumber;
+ } else {
+ $this->noofitems = 0;
+ }
+ if(!empty($this->datasetdefs)){
+
+ $key = 0;
+ $mform->addElement('header', 'additemhdr', get_string('wildcardparam', 'qtype_calculatedsimple'));
+ $idx = 1;
+ if(!empty($this->datasetdefs)){
+ $j = (($this->noofitems) * count($this->datasetdefs))+1;//
+ foreach ($this->datasetdefs as $defkey => $datasetdef){
+ $mform->addElement('static', "na[$j]", get_string('param', 'qtype_datasetdependent', $datasetdef->name));
+ $this->qtypeobj->custom_generator_tools_part($mform, $idx, $j);
+ $mform->addElement('hidden', "datasetdef[$idx]");
+ $mform->setType("datasetdef[$idx]", PARAM_RAW);
+ $idx++;
+ $mform->addElement('static', "divider[$j]", '', '<hr />');
+ $j++;
+ }
+ }
+ $addoptions = Array();
+ $addoptions['1']='1';
+ for ($i=10; $i<=100 ; $i+=10){
+ $addoptions["$i"]="$i";
+ }
+ $mform->closeHeaderBefore('additemhdr');
+ $addgrp = array();
+ $addgrp[] =& $mform->createElement('submit', 'addbutton', get_string('generatenewitemsset', 'qtype_calculatedsimple'));
+ $addgrp[] =& $mform->createElement('select', "selectadd", get_string('additem', 'qtype_datasetdependent'), $addoptions);
+ $addgrp[] = & $mform->createElement('static',"stat","Items",get_string('item(s)', 'qtype_datasetdependent'));
+ $mform->addGroup($addgrp, 'addgrp', '', ' ', false);
+ $mform->registerNoSubmitButton('addbutton');
+ $mform->closeHeaderBefore('addgrp');
+ $mform->addElement('static', "divideradd", '', '');
+ if ($this->noofitems == 0) {
+ $mform->addElement('static','warningnoitems','','<span class="error">'.get_string('youmustaddatleastoneitem', 'qtype_datasetdependent').'</span>');
+ $mform->closeHeaderBefore('warningnoitems');
+ }else {
+ $mform->addElement('header', 'additemhdr1', get_string('wildcarditems', 'qtype_calculatedsimple'));
+ $mform->closeHeaderBefore('additemhdr1');
+ // $mform->addElement('header', '', get_string('itemno', 'qtype_datasetdependent', ""));
+ // $mform->addElement('submit', 'updatedatasets', get_string('updatedatasetparam', 'qtype_datasetdependent'));
+ // $mform->registerNoSubmitButton('updatedatasets');
+ // $mform->setAdvanced("updatedatasets",true);
+
+//------------------------------------------------------------------------------------------------------------------------------
+ $j = $this->noofitems * count($this->datasetdefs);
+ for ($i = $this->noofitems; $i >= 1 ; $i--){
+ foreach ($this->datasetdefs as $defkey => $datasetdef){
+ $mform->addElement('text', "number[$j]", get_string('param', 'qtype_datasetdependent', $datasetdef->name));
+ $mform->setType("number[$j]", PARAM_NUMBER);
+ $mform->setAdvanced("number[$j]",true);
+ $mform->addElement('hidden', "itemid[$j]");
+ $mform->setType("itemid[$j]", PARAM_INT);
+
+ $mform->addElement('hidden', "definition[$j]");
+ $mform->setType("definition[$j]", PARAM_NOTAGS);
+
+ $j--;
+ }
+ if (!empty( $strquestionlabel)){
+ $repeated[] =& $mform->addElement('static', "answercomment[$i]", "<b>".get_string('itemno', 'qtype_datasetdependent', $i)."</b> ".$strquestionlabel);
+ }
+ $mform->addElement('static', "divider1[$j]", '', '<hr />');
+
+ }
+ }
+ // if ($this->outsidelimit){
+ // $mform->addElement('static','outsidelimit','','');
+ // }
+ }else {
+ $mform->addElement('static','warningnowildcards','','<span class="error">'.get_string('atleastonewildcard', 'qtype_calculatedsimple').'</span>');
+ $mform->closeHeaderBefore('warningnowildcards');
+ }
+
+//------------------------------------------------------------------------------------------------------------------------------
+ //non standard name for button element needed so not using add_action_buttons
+ //hidden elements
+
+ $mform->addElement('hidden', 'id');
+ $mform->setType('id', PARAM_INT);
+
+ $mform->addElement('hidden', 'courseid');
+ $mform->setType('courseid', PARAM_INT);
+ $mform->setDefault('courseid', 0);
+
+ $mform->addElement('hidden', 'cmid');
+ $mform->setType('cmid', PARAM_INT);
+ $mform->setDefault('cmid', 0);
+ if (!empty($this->question->id)){
+ if ($this->question->formoptions->cansaveasnew){
+ $mform->addElement('header', 'additemhdr', get_string('converttocalculated', 'qtype_calculatedsimple'));
+ $mform->closeHeaderBefore('additemhdr');
+
+ $mform->addElement('checkbox', 'convert','' ,get_string('willconverttocalculated', 'qtype_calculatedsimple'));
+ $mform->setDefault('convert', 0);
+
+ }
+ }
+ // $mform->addElement('hidden', 'wizard', 'edit_calculatedsimple');
+ // $mform->setType('wizard', PARAM_ALPHA);
+/*
+ $mform->addElement('hidden', 'returnurl');
+ $mform->setType('returnurl', PARAM_LOCALURL);
+ $mform->setDefault('returnurl', 0);
+
+*/
+ }
+
+ function set_data($question) {
+ $answer = $this->answer;
+ $default_values = array();
+ if (count($answer)) {
+ $key = 0;
+ foreach ($answer as $answer){
+ $default_values['answer['.$key.']'] = $answer->answer;
+ $default_values['fraction['.$key.']'] = $answer->fraction;
+ $default_values['tolerance['.$key.']'] = $answer->tolerance;
+ $default_values['tolerancetype['.$key.']'] = $answer->tolerancetype;
+ $default_values['correctanswerlength['.$key.']'] = $answer->correctanswerlength;
+ $default_values['correctanswerformat['.$key.']'] = $answer->correctanswerformat;
+ $default_values['feedback['.$key.']'] = $answer->feedback;
+ $key++;
+ }
+ }
+ if (isset($question->options)){
+ $units = array_values($question->options->units);
+ // make sure the default unit is at index 0
+ usort($units, create_function('$a, $b',
+ 'if (1.0 === (float)$a->multiplier) { return -1; } else '.
+ 'if (1.0 === (float)$b->multiplier) { return 1; } else { return 0; }'));
+ if (count($units)) {
+ $key = 0;
+ foreach ($units as $unit){
+ $default_values['unit['.$key.']'] = $unit->unit;
+ $default_values['multiplier['.$key.']'] = $unit->multiplier;
+ $key++;
+ }
+ }
+ }
+ $key = 0 ;
+ // echo "<p> mandatorydatasets $key xx".optional_param("answer[0]",'', PARAM_NOTAGS)."YY".$this->_form->getElementValue('answer['.$key.']')."xx<p>";
+
+ $formdata = array();
+ $fromform = new stdClass();
+ //fill out all data sets and also the fields for the next item to add.
+ if(!empty($this->datasetdefs)){
+ $j = $this->noofitems * count($this->datasetdefs);
+ for ($itemnumber = $this->noofitems; $itemnumber >= 1; $itemnumber--){
+ $data = array();
+ foreach ($this->datasetdefs as $defid => $datasetdef){
+ if (isset($datasetdef->items[$itemnumber])){
+ $formdata["number[$j]"] = $datasetdef->items[$itemnumber]->value;
+ $formdata["definition[$j]"] = $defid;
+ $formdata["itemid[$j]"] = $datasetdef->items[$itemnumber]->id;
+ $data[$datasetdef->name] = $datasetdef->items[$itemnumber]->value;
+ }
+ $j--;
+ }
+ // echo "<p>answers avant comment <pre>";print_r($answer);echo"</pre></p>";
+ // echo "<p>data avant comment <pre>";print_r($data);echo"</pre></p>";
+
+ if($this->noofitems != 0 ) {
+ if(!isset($question->id)) $question->id = 0 ;
+ $comment = $this->qtypeobj->comment_on_datasetitems($question->id,$this->nonemptyanswer, $data, $itemnumber);//$this->
+ if ($comment->outsidelimit) {
+ $this->outsidelimit=$comment->outsidelimit ;
+ }
+ $totalcomment='';
+ // echo "<p> comment <pre>";print_r($comment);echo"</pre></p>";
+
+ foreach ($this->nonemptyanswer as $key => $answer) {
+ $totalcomment .= $comment->stranswers[$key].'<br/>';
+ }
+
+ $formdata['answercomment['.$itemnumber.']'] = $totalcomment ;
+ }
+ }
+ // $formdata['reload'] = '1';
+ // $formdata['nextpageparam[forceregeneration]'] = $this->regenerate;
+ $formdata['selectdelete'] = '1';
+ $formdata['selectadd'] = '1';
+ $j = $this->noofitems * count($this->datasetdefs)+1;
+ $data = array(); // data for comment_on_datasetitems later
+ $idx =1 ;
+ foreach ($this->datasetdefs as $defid => $datasetdef){
+ $formdata["datasetdef[$idx]"] = $defid;
+ $idx++;
+ }
+ $formdata = $this->qtypeobj->custom_generator_set_data($this->datasetdefs, $formdata);
+ }
+ $question = (object)((array)$question + $default_values+$formdata );
+ // echo "<p> question data <pre>";print_r($question);echo"</pre></p>";
+
+ parent::set_data($question);
+ }
+
+ function qtype() {
+ return 'calculatedsimple';
+ }
+
+ function validation($data, $files) {
+ $errors = parent::validation($data, $files);
+ //verifying for errors in {=...} in question text;
+ $qtext = "";
+ $qtextremaining = $data['questiontext'] ;
+ $possibledatasets = $this->qtypeobj->find_dataset_names($data['questiontext']);
+ foreach ($possibledatasets as $name => $value) {
+ $qtextremaining = str_replace('{'.$name.'}', '1', $qtextremaining);
+ }
+ // echo "numericalquestion qtextremaining <pre>";print_r($possibledatasets);
+ while (ereg('\{=([^[:space:]}]*)}', $qtextremaining, $regs1)) {
+ $qtextsplits = explode($regs1[0], $qtextremaining, 2);
+ $qtext =$qtext.$qtextsplits[0];
+ $qtextremaining = $qtextsplits[1];
+ if (!empty($regs1[1]) && $formulaerrors = qtype_calculated_find_formula_errors($regs1[1])) {
+ if(!isset($errors['questiontext'])){
+ $errors['questiontext'] = $formulaerrors.':'.$regs1[1] ;
+ }else {
+ $errors['questiontext'] .= '<br/>'.$formulaerrors.':'.$regs1[1];
+ }
+ }
+ }
+ $answers = $data['answer'];
+ $answercount = 0;
+ $maxgrade = false;
+ $possibledatasets = $this->qtypeobj->find_dataset_names($data['questiontext']);
+ $mandatorydatasets = array();
+ foreach ($answers as $key => $answer){
+ $mandatorydatasets += $this->qtypeobj->find_dataset_names($answer);
+ }
+ if ( count($mandatorydatasets )==0){
+ // $errors['questiontext']=get_string('atleastonewildcard', 'qtype_datasetdependent');
+ foreach ($answers as $key => $answer){
+ $errors['answer['.$key.']'] = get_string('atleastonewildcard', 'qtype_datasetdependent');
+ }
+ }
+ foreach ($answers as $key => $answer){
+ //check no of choices
+ // the * for everykind of answer not actually implemented
+ $trimmedanswer = trim($answer);
+ if (($trimmedanswer!='')||$answercount==0){
+ $eqerror = qtype_calculated_find_formula_errors($trimmedanswer);
+ if (FALSE !== $eqerror){
+ $errors['answer['.$key.']'] = $eqerror;
+ }
+ }
+ if ($trimmedanswer!=''){
+ if ('2' == $data['correctanswerformat'][$key]
+ && '0' == $data['correctanswerlength'][$key]) {
+ $errors['correctanswerlength['.$key.']'] = get_string('zerosignificantfiguresnotallowed','quiz');
+ }
+ if (!is_numeric($data['tolerance'][$key])){
+ $errors['tolerance['.$key.']'] = get_string('mustbenumeric', 'qtype_calculated');
+ }
+ if ($data['fraction'][$key] == 1) {
+ $maxgrade = true;
+ }
+
+ $answercount++;
+ }
+ //check grades
+
+ //TODO how should grade checking work here??
+ /*if ($answer != '') {
+ if ($data['fraction'][$key] > 0) {
+ $totalfraction += $data['fraction'][$key];
+ }
+ if ($data['fraction'][$key] > $maxfraction) {
+ $maxfraction = $data['fraction'][$key];
+ }
+ }*/
+ }
+ //grade checking :
+ /// Perform sanity checks on fractional grades
+ /*if ( ) {
+ if ($maxfraction != 1) {
+ $maxfraction = $maxfraction * 100;
+ $errors['fraction[0]'] = get_string('errfractionsnomax', 'qtype_multichoice', $maxfraction);
+ }
+ } else {
+ $totalfraction = round($totalfraction,2);
+ if ($totalfraction != 1) {
+ $totalfraction = $totalfraction * 100;
+ $errors['fraction[0]'] = get_string('errfractionsaddwrong', 'qtype_multichoice', $totalfraction);
+ }
+ }*/
+ $units = $data['unit'];
+ if (count($units)) {
+ foreach ($units as $key => $unit){
+ if (is_numeric($unit)){
+ $errors['unit['.$key.']'] = get_string('mustnotbenumeric', 'qtype_calculated');
+ }
+ $trimmedunit = trim($unit);
+ $trimmedmultiplier = trim($data['multiplier'][$key]);
+ if (!empty($trimmedunit)){
+ if (empty($trimmedmultiplier)){
+ $errors['multiplier['.$key.']'] = get_string('youmustenteramultiplierhere', 'qtype_calculated');
+ }
+ if (!is_numeric($trimmedmultiplier)){
+ $errors['multiplier['.$key.']'] = get_string('mustbenumeric', 'qtype_calculated');
+ }
+
+ }
+ }
+ }
+ if ($answercount==0){
+ $errors['answer[0]'] = get_string('atleastoneanswer', 'qtype_calculated');
+ }
+ if ($maxgrade == false) {
+ $errors['fraction[0]'] = get_string('fractionsnomax', 'question');
+ }
+ if (isset($data['backtoquiz']) && ($this->noofitems==0) ){
+ $errors['warning'] = get_string('warning', 'mnet');
+ }
+ if ($this->outsidelimit){
+ // if(!isset($errors['warning'])) $errors['warning']=' ';
+ $errors['outsidelimits'] = get_string('oneanswertrueansweroutsidelimits','qtype_calculated');
+ }
+ $numbers = $data['number'];
+ foreach ($numbers as $key => $number){
+ if(! is_numeric($number)){
+ if (stristr($number,',')){
+ $errors['number['.$key.']'] = get_string('The , cannot be used, use . as in 0.013 or 1.3e-2', 'qtype_datasetdependent');
+ }else {
+ $errors['number['.$key.']'] = get_string('This is not a valid number', 'qtype_datasetdependent');
+ }
+ }else if( stristr($number,'x')){
+ $errors['number['.$key.']'] = get_string('Hexadecimal format (i.e. 0X12d) is not allowed', 'qtype_datasetdependent');
+ } else if( is_nan($number)){
+ $errors['number['.$key.']'] = get_string('is a NAN number', 'qtype_datasetdependent');
+ }
+ }
+ if ( $this->noofitems==0 ){
+ $errors['warning'] = get_string('warning', 'mnet');
+ }
+
+ return $errors;
+ }
+}
+?>
\ No newline at end of file
--- /dev/null
+<?php // $Id$
+
+/////////////////
+// CALCULATED ///
+/////////////////
+
+/// QUESTION TYPE CLASS //////////////////
+
+
+
+class question_calculatedsimple_qtype extends question_calculated_qtype {
+
+ // Used by the function custom_generator_tools:
+ var $calcgenerateidhasbeenadded = false;
+ public $virtualqtype = false;
+
+ function name() {
+ return 'calculatedsimple';
+ }
+
+
+
+
+ function save_question_options($question) {
+ //$options = $question->subtypeoptions;
+ // Get old answers:
+ global $CFG, $DB;
+
+ if (isset($question->answer) && !isset($question->answers)) {
+ $question->answers = $question->answer;
+ }
+
+ // Get old versions of the objects
+ if (!$oldanswers = $DB->get_records('question_answers', array('question' => $question->id), 'id ASC')) {
+ $oldanswers = array();
+ }
+
+ if (!$oldoptions = $DB->get_records('question_calculated', array('question' => $question->id), 'answer ASC')) {
+ $oldoptions = array();
+ }
+
+ // Save the units.
+ $virtualqtype = $this->get_virtual_qtype();
+ $result = $virtualqtype->save_numerical_units($question);
+ if (isset($result->error)) {
+ return $result;
+ } else {
+ $units = &$result->units;
+ }
+ // Insert all the new answers
+ if (isset($question->answer) && !isset($question->answers)) {
+ $question->answers=$question->answer;
+ }
+ foreach ($question->answers as $key => $dataanswer) {
+ if ( trim($dataanswer) != '' ) {
+ $answer = new stdClass;
+ $answer->question = $question->id;
+ $answer->answer = trim($dataanswer);
+ $answer->fraction = $question->fraction[$key];
+ $answer->feedback = trim($question->feedback[$key]);
+
+ if ($oldanswer = array_shift($oldanswers)) { // Existing answer, so reuse it
+ $answer->id = $oldanswer->id;
+ if (! $DB->update_record("question_answers", $answer)) {
+ $result->error = get_string('errorupdatinganswer','question',$answer->id);
+ return $result;
+ }
+ } else { // This is a completely new answer
+ if (! $answer->id = $DB->insert_record("question_answers", $answer)) {
+ $result->error = get_string('errorinsertinganswer','question');
+ return $result;
+ }
+ }
+
+ // Set up the options object
+ if (!$options = array_shift($oldoptions)) {
+ $options = new stdClass;
+ }
+ $options->question = $question->id;
+ $options->answer = $answer->id;
+ $options->tolerance = trim($question->tolerance[$key]);
+ $options->tolerancetype = trim($question->tolerancetype[$key]);
+ $options->correctanswerlength = trim($question->correctanswerlength[$key]);
+ $options->correctanswerformat = trim($question->correctanswerformat[$key]);
+
+ // Save options
+ if (isset($options->id)) { // reusing existing record
+ if (! $DB->update_record('question_calculated', $options)) {
+ $mess->name = $this->name();
+ $mess->id = $options->id ;
+ $result->error = get_string('errorupdatingoptions','question',$mess);
+ // $result->error = "Could not update question calculated options! (id=$options->id)";
+ return $result;
+ }
+ } else { // new options
+ if (! $DB->insert_record('question_calculated', $options)) {
+ $result->error = "Could not insert question calculated options!";
+ return $result;
+ }
+ }
+ }
+ }
+ // delete old answer records
+ if (!empty($oldanswers)) {
+ foreach($oldanswers as $oa) {
+ $DB->delete_records('question_answers', array('id' => $oa->id));
+ }
+ }
+
+ // delete old answer records
+ if (!empty($oldoptions)) {
+ foreach($oldoptions as $oo) {
+ $DB->delete_records('question_calculated', array('id' => $oo->id));
+ }
+ }
+
+
+ if( isset($question->import_process)&&$question->import_process){
+ $this->import_datasets($question);
+ }else {
+ //save datasets and datatitems from form i.e in question
+ // $datasetdefs = $this->get_dataset_definitions($question->id, array());
+ $question->dataset = $question->datasetdef ;
+ // $this->save_dataset_definitions($question);
+ // Save datasets
+ $datasetdefinitions = $this->get_dataset_definitions($question->id, $question->dataset);
+ $tmpdatasets = array_flip($question->dataset);
+ $defids = array_keys($datasetdefinitions);
+ $datasetdefs = array();
+ foreach ($defids as $defid) {
+ $datasetdef = &$datasetdefinitions[$defid];
+ if (isset($datasetdef->id)) {
+ if (!isset($tmpdatasets[$defid])) {
+ // This dataset is not used any more, delete it
+ $DB->delete_records('question_datasets', array('question' => $question->id, 'datasetdefinition' => $datasetdef->id));
+ // if ($datasetdef->category == 0) { // Question local dataset
+ $DB->delete_records('question_dataset_definitions', array('id' => $datasetdef->id));
+ $DB->delete_records('question_dataset_items', array('definition' => $datasetdef->id));
+ // }
+ }
+ // This has already been saved or just got deleted
+ unset($datasetdefinitions[$defid]);
+ continue;
+ }
+ if (!$datasetdef->id = $DB->insert_record('question_dataset_definitions', $datasetdef)) {
+ print_error("cannotcreatedataset", 'question', '', $defid);
+ }
+ $datasetdefs[]= clone($datasetdef);
+ $questiondataset = new stdClass;
+ $questiondataset->question = $question->id;
+ $questiondataset->datasetdefinition = $datasetdef->id;
+ if (!$DB->insert_record('question_datasets', $questiondataset)) {
+ print_error('cannotcreaterelation', 'question', '', $name);
+ }
+ unset($datasetdefinitions[$defid]);
+ }
+ // Remove local obsolete datasets as well as relations
+ // to datasets in other categories:
+ if (!empty($datasetdefinitions)) {
+ foreach ($datasetdefinitions as $def) {
+ $DB->delete_records('question_datasets', array('question' => $question->id, 'datasetdefinition' => $def->id));
+ if ($def->category == 0) { // Question local dataset
+ $DB->delete_records('question_dataset_definitions', array('id' => $def->id));
+ $DB->delete_records('question_dataset_items', array('definition' => $def->id));
+ }
+ }
+ }
+ $datasetdefs = $this->get_dataset_definitions($question->id, $question->dataset);
+ // echo "<p> datasetdefs save <pre>";print_r($datasetdefs);echo"</pre></p>";
+ // Handle adding and removing of dataset items
+ $i = 1;
+ ksort($question->definition);
+ foreach ($question->definition as $key => $defid) {
+ $addeditem = new stdClass();
+ $addeditem->definition = $datasetdefs[$defid]->id;
+ $addeditem->value = $question->number[$i];
+ $addeditem->itemnumber = ceil($i / count($datasetdefs));
+ if (empty($question->makecopy) && $question->itemid[$i]) {
+ // Reuse any previously used record
+ $addeditem->id = $question->itemid[$i];
+ if (!$DB->update_record('question_dataset_items', $addeditem)) {
+ print_error('cannotupdateitem', 'question');
+ }
+ } else {
+ if (!$DB->insert_record('question_dataset_items', $addeditem)) {
+ print_error('cannotinsert', 'question');
+ }
+ }
+ $i++;
+ }
+ if (isset($addeditem->itemnumber) && $maxnumber < $addeditem->itemnumber){
+ $maxnumber = $addeditem->itemnumber;
+ foreach ($datasetdefs as $key => $newdef) {
+ if (isset($newdef->id) && $newdef->itemcount <= $maxnumber) {
+ $newdef->itemcount = $maxnumber;
+ // Save the new value for options
+ $DB->update_record('question_dataset_definitions', $newdef);
+ }
+ }
+ }
+ }
+ // Report any problems.
+ //convert to calculated
+ if(!empty($question->makecopy) && !empty($question->convert) ){
+ // echo "<p> question save <pre>";print_r($question);echo"</pre></p>";
+ if (!$DB->set_field('question', 'qtype', 'calculated', array('id'=> $question->id))) {
+ print_error('cannotupdateitem', 'question');
+ }
+ }
+ if (!empty($result->notice)) {
+ return $result;
+ }
+ return true;
+ }
+ function finished_edit_wizard(&$form) {
+ return true ; //isset($form->backtoquiz);
+ }
+
+
+
+
+ /**
+ * this version save the available data at the different steps of the question editing process
+ * without using global $SESSION as storage between steps
+ * at the first step $wizardnow = 'question'
+ * when creating a new question
+ * when modifying a question
+ * when copying as a new question
+ * the general parameters and answers are saved using parent::save_question
+ * then the datasets are prepared and saved
+ * at the second step $wizardnow = 'datasetdefinitions'
+ * the datadefs final type are defined as private, category or not a datadef
+ * at the third step $wizardnow = 'datasetitems'
+ * the datadefs parameters and the data items are created or defined
+ *
+ * @param object question
+ * @param object $form
+ * @param int $course
+ * @param PARAM_ALPHA $wizardnow should be added as we are coming from question2.php
+ */
+ function save_question($question, $form, $course) {
+
+ $question = default_questiontype::save_question($question, $form, $course);
+ return $question;
+ }
+
+
+ function response_summary($question, $state, $length=80, $formatting=true) {
+ // The actual response is the bit after the hyphen
+ return substr($state->answer, strpos($state->answer, '-')+1, $length);
+ }
+
+ function custom_generator_tools_part(&$mform, $idx, $j){
+
+ $minmaxgrp = array();
+ $minmaxgrp[] =& $mform->createElement('text', "calcmin[$idx]", get_string('calcmin', 'qtype_datasetdependent'));
+ $minmaxgrp[] =& $mform->createElement('text', "calcmax[$idx]", get_string('calcmax', 'qtype_datasetdependent'));
+ $mform->addGroup($minmaxgrp, 'minmaxgrp', get_string('minmax', 'qtype_datasetdependent'), ' - ', false);
+ $mform->setType("calcmin[$idx]", PARAM_NUMBER);
+ $mform->setType("calcmax[$idx]", PARAM_NUMBER);
+
+ $precisionoptions = range(0, 10);
+ $mform->addElement('select', "calclength[$idx]", get_string('calclength', 'qtype_datasetdependent'), $precisionoptions);
+
+ $distriboptions = array('uniform' => get_string('uniform', 'qtype_datasetdependent'), 'loguniform' => get_string('loguniform', 'qtype_datasetdependent'));
+ $mform->addElement('hidden', "calcdistribution[$idx]", 'uniform');
+
+
+ }
+
+ function comment_header($answers) {
+ //$this->get_question_options($question);
+ $strheader = "";
+ $delimiter = '';
+
+ // $answers = $question->options->answers;
+ // echo "<p>comments header answers <pre>";print_r($answers);echo"</pre></p>";
+
+ foreach ($answers as $key => $answer) {
+ /* if (is_string($answer)) {
+ $strheader .= $delimiter.$answer;
+ } else {*/
+ $strheader .= $delimiter.$answer->answer;
+ // }
+ $delimiter = '<br/><br/><br/>';
+ }
+ return $strheader;
+ }
+
+ function comment_on_datasetitems($questionid, $answers,$data, $number) {
+ global $DB;
+ $comment = new stdClass;
+ $comment->stranswers = array();
+ $comment->outsidelimit = false ;
+ $comment->answers = array();
+ /// Find a default unit:
+ if (!empty($questionid) && $unit = $DB->get_record('question_numerical_units', array('question'=> $questionid, 'multiplier' => 1.0))) {
+ $unit = $unit->unit;
+ } else {
+ $unit = '';
+ }
+
+ $answers = fullclone($answers);
+ $strmin = get_string('min', 'quiz');
+ $strmax = get_string('max', 'quiz');
+ $errors = '';
+ $delimiter = ': ';
+ $virtualqtype = $this->get_virtual_qtype();
+ foreach ($answers as $key => $answer) {
+ $formula = $this->substitute_variables($answer->answer,$data);
+ $formattedanswer = qtype_calculated_calculate_answer(
+ $answer->answer, $data, $answer->tolerance,
+ $answer->tolerancetype, $answer->correctanswerlength,
+ $answer->correctanswerformat, $unit);
+ if ( $formula === '*'){
+ $answer->min = ' ';
+ $formattedanswer->answer = $answer->answer ;
+ }else {
+ eval('$answer->answer = '.$formula.';') ;
+ $virtualqtype->get_tolerance_interval($answer);
+ }
+ if ($answer->min === '') {
+ // This should mean that something is wrong
+ $comment->stranswers[$key] = " $formattedanswer->answer".'<br/><br/>';
+ } else if ($formula === '*'){
+ $comment->stranswers[$key] = $formula.' = '.get_string('anyvalue','qtype_calculated').'<br/><br/>';
+ }else{
+ $comment->stranswers[$key]= $formula.' = '.$formattedanswer->answer.'' ;
+ $comment->stranswers[$key] .= "<br/>".$strmin. $delimiter.$answer->min.'---';
+ $comment->stranswers[$key] .= $strmax.$delimiter.$answer->max;
+ $comment->stranswers[$key] .='<br/>';
+ $correcttrue->correct = $formattedanswer->answer ;
+ $correcttrue->true = $answer->answer ;
+ if ($formattedanswer->answer < $answer->min || $formattedanswer->answer > $answer->max){
+ $comment->outsidelimit = true ;
+ $comment->answers[$key] = $key;
+ $comment->stranswers[$key] .=get_string('trueansweroutsidelimits','qtype_calculated',$correcttrue);//<span class="error">ERROR True answer '..' outside limits</span>';
+ }else {
+ $comment->stranswers[$key] .=get_string('trueanswerinsidelimits','qtype_calculated',$correcttrue);//' True answer :'.$calculated->trueanswer.' inside limits';
+ }
+ $comment->stranswers[$key] .='';
+ }
+ }
+ return fullclone($comment);
+ }
+
+ function tolerance_types() {
+ return array('1' => get_string('relative', 'quiz'),
+ '2' => get_string('nominal', 'quiz'),
+ // '3' => get_string('geometric', 'quiz')
+ );
+ }
+
+ function dataset_options($form, $name, $mandatory=true,$renameabledatasets=false) {
+ // Takes datasets from the parent implementation but
+ // filters options that are currently not accepted by calculated
+ // It also determines a default selection...
+ //$renameabledatasets not implemented anmywhere
+ list($options, $selected) = $this->dataset_options_from_database($form, $name,'','qtype_calculated');
+ // list($options, $selected) = $this->dataset_optionsa($form, $name);
+
+ foreach ($options as $key => $whatever) {
+ if (!ereg('^1-', $key) && $key != '0') {
+ unset($options[$key]);
+ }
+ }
+ if (!$selected) {
+ if ($mandatory){
+ $selected = "1-0-$name"; // Default
+ }else {
+ $selected = "0"; // Default
+ }
+ }
+ return array($options, $selected);
+ }
+
+
+/**
+ * Runs all the code required to set up and save an essay question for testing purposes.
+ * Alternate DB table prefix may be used to facilitate data deletion.
+ */
+ function generate_test($name, $courseid = null) {
+ global $DB;
+ list($form, $question) = parent::generate_test($name, $courseid);
+ $form->feedback = 1;
+ $form->multiplier = array(1, 1);
+ $form->shuffleanswers = 1;
+ $form->noanswers = 1;
+ $form->qtype ='calculatedsimple';
+ $question->qtype ='calculatedsimple';
+ $form->answers = array('{a} + {b}');
+ $form->fraction = array(1);
+ $form->tolerance = array(0.01);
+ $form->tolerancetype = array(1);
+ $form->correctanswerlength = array(2);
+ $form->correctanswerformat = array(1);
+ $form->questiontext = "What is {a} + {b}?";
+
+ if ($courseid) {
+ $course = $DB->get_record('course', array('id'=> $courseid));
+ }
+
+ $new_question = $this->save_question($question, $form, $course);
+
+ $dataset_form = new stdClass();
+ $dataset_form->nextpageparam["forceregeneration"]= 1;
+ $dataset_form->calcmin = array(1 => 1.0, 2 => 1.0);
+ $dataset_form->calcmax = array(1 => 10.0, 2 => 10.0);
+ $dataset_form->calclength = array(1 => 1, 2 => 1);
+ $dataset_form->number = array(1 => 5.4 , 2 => 4.9);
+ $dataset_form->itemid = array(1 => '' , 2 => '');
+ $dataset_form->calcdistribution = array(1 => 'uniform', 2 => 'uniform');
+ $dataset_form->definition = array(1 => "1-0-a",
+ 2 => "1-0-b");
+ $dataset_form->nextpageparam = array('forceregeneration' => false);
+ $dataset_form->addbutton = 1;
+ $dataset_form->selectadd = 1;
+ $dataset_form->courseid = $courseid;
+ $dataset_form->cmid = 0;
+ $dataset_form->id = $new_question->id;
+ $this->save_dataset_items($new_question, $dataset_form);
+
+ return $new_question;
+ }
+}
+//// END OF CLASS ////
+
+//////////////////////////////////////////////////////////////////////////
+//// INITIATION - Without this line the question type is not in use... ///
+//////////////////////////////////////////////////////////////////////////
+question_register_questiontype(new question_calculatedsimple_qtype());
+
+
+?>