]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-9496 Adding multianswer to calculated and MDL-9657 cleaning abstractype code.
authorpichetp <pichetp>
Wed, 25 Apr 2007 08:15:50 +0000 (08:15 +0000)
committerpichetp <pichetp>
Wed, 25 Apr 2007 08:15:50 +0000 (08:15 +0000)
question/type/calculated/edit_calculated_form.php
question/type/calculated/questiontype.php

index a38f13b27e09576dc52570ea1aa25f5496c87b4d..c8821cdff22b8c86dab42d4dad2702e678461668 100644 (file)
@@ -27,9 +27,16 @@ class question_edit_calculated_form extends question_edit_form {
     function definition_inner(&$mform) {
         global $QTYPES;
         $this->qtypeobj =& $QTYPES[$this->qtype()];
+        $label = get_string("sharedwildcards", "qtype_datasetdependent");
+        $mform->addElement('hidden', 'initialcategory', 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');
 
-//------------------------------------------------------------------------------------------
-/*      //not working now datasetdependent code cannot handle multiple answer formulas and not needed ??
         $repeated = array();
         $repeated[] =& $mform->createElement('header', 'answerhdr', get_string('answerhdr', 'qtype_calculated', '{no}'));
 
@@ -61,50 +68,9 @@ class question_edit_calculated_form extends question_edit_form {
             $count = 0;
         }
         $repeatsatstart = $count + 1;
-        $this->repeat_elements($repeated, $repeatsatstart, $repeatedoptions, 'noanswers', 'addanswers', 1, get_string('addmoreanswerblanks', 'qtype_calculated'));*/
-//------------------------------------------------------------------------------------------
-        $label = get_string("sharedwildcards", "qtype_datasetdependent");
-        $mform->addElement('hidden', 'initialcategory', 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');
-
-        $mform->addElement('header', 'answerhdr', get_string('answerhdr', 'qtype_calculated'));
-
-        $mform->addElement('text', 'answers[0]', get_string('correctanswerformula', 'quiz'));
-        $mform->setType('answers[0]', PARAM_NOTAGS);
-
-/*        $creategrades = get_grade_options();
-        $gradeoptions = $creategrades->gradeoptions;
-        $mform->addElement('select', 'fraction[0]', get_string('grade'), $gradeoptions);
-        $mform->setDefault('fraction[0]', 0);*/
-        $mform->addElement('hidden', 'fraction[0]', 1);
-      //  $mform->setConstants(array('fraction[0]'=>PARAM_INT));
-
-        $tolgrp = array();
-        $tolgrp[] =& $mform->createElement('text', 'tolerance[0]', get_string('tolerance', 'qtype_calculated'));
-        $mform->setType('tolerance[0]', PARAM_NUMBER);
-        $mform->setDefault('tolerance[0]', 0.01);
-        $tolgrp[] =& $mform->createElement('select', 'tolerancetype[0]', get_string('tolerancetype', 'quiz'), $this->qtypeobj->tolerance_types());
-        $mform->addGroup($tolgrp, 'tolgrp', get_string('tolerance', 'qtype_calculated'), null, false);
+        $this->repeat_elements($repeated, $repeatsatstart, $repeatedoptions, 'noanswers', 'addanswers', 1, get_string('addmoreanswerblanks', 'qtype_calculated'));
 
-        $anslengrp = array();
-        $anslengrp[] =&  $mform->createElement('select', 'correctanswerlength[0]', get_string('correctanswershows', 'qtype_calculated'), range(0, 9));
-        $mform->setDefault('correctanswerlength[0]', 2);
-
-        $answerlengthformats = array('1' => get_string('decimalformat', 'quiz'), '2' => get_string('significantfiguresformat', 'quiz'));
-        $anslengrp[] =&  $mform->createElement('select', 'correctanswerformat[0]', get_string('correctanswershowsformat', 'qtype_calculated'), $answerlengthformats);
-        $mform->addGroup($anslengrp, 'anslengrp', get_string('correctanswershows', 'qtype_calculated'), null, false);
-
-        $mform->addElement('htmleditor', 'feedback[0]', get_string('feedback', 'quiz'));
-        $mform->setType('feedback', PARAM_RAW);
-
-//------------------------------------------------------------------------------------------
-        $repeated = array();
+       $repeated = array();
         $repeated[] =& $mform->createElement('header', 'unithdr', get_string('unithdr', 'qtype_numerical', '{no}'));
 
         $repeated[] =& $mform->createElement('text', 'unit', get_string('unit', 'quiz'));
@@ -150,7 +116,7 @@ class question_edit_calculated_form extends question_edit_form {
             }
             $units  = array_values($question->options->units);
             // make sure the default unit is at index 0
-            usort($units, create_function('$a, $b', // 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)) {
@@ -194,22 +160,21 @@ class question_edit_calculated_form extends question_edit_form {
         $errors = array();
         $answers = $data['answers'];
         $answercount = 0;
-        //check grades
-        /*$totalfraction = 0;
-        $maxfraction = -1; */
+        $maxgrade = false;
         $possibledatasets = $this->qtypeobj->find_dataset_names($data['questiontext']);
         $mandatorydatasets = array();
         foreach ($answers as $key => $answer){
-            $mandatorydatasets += $this->qtypeobj->find_dataset_names($data['questiontext']);
+            $mandatorydatasets += $this->qtypeobj->find_dataset_names($answer);
         }      
-        if (count($possibledatasets) == 0 && count($mandatorydatasets )==0){
-            $errors['questiontext']=get_string('atleastonewildcard', 'qtype_datasetdependent');
+        if ( count($mandatorydatasets )==0){
+          //  $errors['questiontext']=get_string('atleastonewildcard', 'qtype_datasetdependent');
             foreach ($answers as $key => $answer){
                 $errors['answers['.$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);
@@ -225,6 +190,9 @@ class question_edit_calculated_form extends question_edit_form {
                 if (!is_numeric($data['tolerance'][$key])){
                     $errors['tolerance['.$key.']'] = get_string('mustbenumeric', 'qtype_calculated');
                 }
+                if ($data['fraction'][$key] == 1) {
+                   $maxgrade = true;
+                }
 
                 $answercount++;
             }
@@ -276,6 +244,9 @@ class question_edit_calculated_form extends question_edit_form {
         if ($answercount==0){
             $errors['answers[0]'] = get_string('atleastoneanswer', 'qtype_calculated');
         }
+        if ($maxgrade == false) {
+            $errors['fraction[0]'] = get_string('fractionsnomax', 'question');
+        }
 
         return $errors;
     }
index 11c4a31dd3856878aa4e12d00592be7c67a7ecd4..607e02d78c7ba0bd88ff50d6f67cc41b0379a643 100644 (file)
@@ -19,35 +19,49 @@ class question_calculated_qtype extends question_dataset_dependent_questiontype
 
     function get_question_options(&$question) {
         // First get the datasets and default options
-        if(false === parent::get_question_options($question)) {
+         global $CFG;
+        if (!$question->options->answers = get_records_sql(
+                                "SELECT a.*, c.tolerance, c.tolerancetype, c.correctanswerlength, c.correctanswerformat " .
+                                "FROM {$CFG->prefix}question_answers a, " .
+                                "     {$CFG->prefix}question_calculated c " .
+                                "WHERE a.question = $question->id " .
+                                "AND   a.id = c.answer ".
+                                "ORDER BY a.id ASC")) {
+            notify('Error: Missing question answer!');
             return false;
         }
 
-        if (!$options = get_record('question_calculated', 'question', $question->id)) {
+/*
+       if(false === parent::get_question_options($question)) {
+            return false;
+        }
+
+        if (!$options = get_records('question_calculated', 'question', $question->id)) {
             notify("No options were found for calculated question
              #{$question->id}! Proceeding with defaults.");
-            $options = new stdClass;
+        //     $options = new Array(); 
+            $options= new stdClass;
             $options->tolerance           = 0.01;
             $options->tolerancetype       = 1; // relative
             $options->correctanswerlength = 2;
             $options->correctanswerformat = 1; // decimals
-        }
+        } 
 
         // For historic reasons we also need these fields in the answer objects.
         // This should eventually be removed and related code changed to use
         // the values in $question->options instead.
-        foreach ($question->options->answers as $key => $answer) {
+         foreach ($question->options->answers as $key => $answer) {
             $answer = &$question->options->answers[$key]; // for PHP 4.x
-            $answer->calcid              = $options->id;
+           $answer->calcid              = $options->id;
             $answer->tolerance           = $options->tolerance;
             $answer->tolerancetype       = $options->tolerancetype;
             $answer->correctanswerlength = $options->correctanswerlength;
             $answer->correctanswerformat = $options->correctanswerformat;
-        }
+        }*/
 
         $virtualqtype = $this->get_virtual_qtype();
         $virtualqtype->get_numerical_units($question);
-        
+       
         if( isset($question->export_process)&&$question->export_process){
             $question->options->datasets = $this->get_datasets_for_export($question);
         }   
@@ -106,88 +120,93 @@ class question_calculated_qtype extends question_dataset_dependent_questiontype
         //$options = $question->subtypeoptions;
         // Get old answers:
         global $CFG;
-        if (!$oldanswers = get_records_sql(
-            "SELECT a.*, c.tolerance, c.tolerancetype,
-                    c.correctanswerlength, c.id AS calcid
-               FROM {$CFG->prefix}question_answers a,
-                    {$CFG->prefix}question_calculated c
-              WHERE c.question = $question->id AND a.id = c.answer
-           ORDER BY a.id ASC")) {
+                
+        // Get old versions of the objects
+        if (!$oldanswers = get_records('question_answers', 'question', $question->id, 'id ASC')) {
             $oldanswers = array();
         }
 
-        // Update with new answers
-        $answerrec->question = $calcrec->question = $question->id;
-        $n = count($question->answers);
-        for ($i = 0; $i < $n; $i++) {
-            $answerrec->answer   = $question->answers[$i];
-            $answerrec->fraction = isset($question->fraction[$i])
-                                 ? $question->fraction[$i] : 1.0;
-            $answerrec->feedback = isset($question->feedback[$i])
-                                 ? $question->feedback[$i] : '';
-            $calcrec->tolerance           = isset($question->tolerance[$i])
-                                          ? $question->tolerance[$i]
-                                          : $question->tolerance[0];
-            $calcrec->tolerancetype       = isset($question->tolerancetype[$i])
-                                          ? $question->tolerancetype[$i]
-                                          : $question->tolerancetype[0];
-            $calcrec->correctanswerlength = isset($question->correctanswerlength[$i])
-                                          ? $question->correctanswerlength[$i]
-                                          : $question->correctanswerlength[0];
-            $calcrec->correctanswerformat = isset($question->correctanswerformat[$i])
-                                          ? $question->correctanswerformat[$i]
-                                          : $question->correctanswerformat[0];
-            if ($oldanswer = array_shift($oldanswers)) {
-                // Reuse old records:
-                $calcrec->answer = $answerrec->id = $oldanswer->id;
-                $calcrec->id = $oldanswer->calcid;
-                if (!update_record('question_answers', $answerrec)) {
-                    error("Unable to update answer for calculated question #{$question->id}!");
-                } else {
-                    // notify("Answer updated successfully for calculated question $question->name");
-                }
-                if (!update_record('question_calculated', $calcrec)) {
-                    error("Unable to update options for calculated question #{$question->id}!");
-                } else {
-                    // notify("Options updated successfully for calculated question $question->name");
+        if (!$oldoptions = get_records('question_calculated', 'question', $question->id, 'answer ASC')) {
+            $oldoptions = array();
+        }
+                // Save the units.
+        // Save 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
+        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 (! update_record("question_answers", $answer)) {
+                        $result->error = "Could not update question answer! (id=$answer->id)";
+                        return $result;
+                    }
+                } else { // This is a completely new answer
+                    if (! $answer->id = insert_record("question_answers", $answer)) {
+                        $result->error = "Could not insert question answer!";
+                        return $result;
+                    }
                 }
-            } else {
-                unset($answerrec->id);
-                unset($calcrec->id);
-                if (!($calcrec->answer = insert_record('question_answers',
-                 $answerrec))) {
-                    error("Unable to insert answer for calculated question $question->id");
-                } else {
-                    // notify("Answer inserted successfully for calculated question $question->id");
+
+                // Set up the options object
+                if (!$options = array_shift($oldoptions)) {
+                    $options = new stdClass;
                 }
-                if (!insert_record('question_calculated', $calcrec)) {
-                    error("Unable to insert options calculared question $question->id");
-                } else {
-                    // notify("Options inserted successfully for calculated question $question->id");
+                $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 (! update_record('question_calculated', $options)) {
+                        $result->error = "Could not update question calculated options! (id=$options->id)";
+                        return $result;
+                    }
+                } else { // new options
+                    if (! insert_record('question_calculated', $options)) {
+                        $result->error = "Could not insert question  calculated options!";
+                        return $result;
+                    }
                 }
             }
         }
-
-        // Delete excessive records:
-        foreach ($oldanswers as $oldanswer) {
-            if (!delete_records('question_answers', 'id', $oldanswer->id)) {
-                error("Unable to delete old answers for calculated question $question->id");
-            } else {
-                // notify("Old answers deleted successfully for calculated question $question->id");
+        // delete old answer records
+        if (!empty($oldanswers)) {
+            foreach($oldanswers as $oa) {
+                delete_records('question_answers', 'id', $oa->id);
             }
-            if (!delete_records('question_calculated', 'id', $oldanswer->calcid)) {
-                error("Unable to delete old options for calculated question $question->id");
-            } else {
-                // notify("Old options deleted successfully for calculated question $question->id");
+        }
+
+        // delete old answer records
+        if (!empty($oldoptions)) {
+            foreach($oldoptions as $oo) {
+                delete_records('question_calculated', 'id', $oo->id);
             }
         }
 
-        // Save units
-        $virtualqtype = $this->get_virtual_qtype();
-        $virtualqtype->save_numerical_units($question);
+
         if( isset($question->import_process)&&$question->import_process){
             $this->import_datasets($question);
          }   
+        // Report any problems.
+        if (!empty($result->notice)) {
+            return $result;
+        }
         return true;
     }
 
@@ -258,7 +277,8 @@ class question_calculated_qtype extends question_dataset_dependent_questiontype
         $question->options->answers = array();
         foreach ($form->answers as $key => $answer) {
             $a->answer              = trim($form->answer[$key]);
-            $a->tolerance           = $form->tolerance[$key];
+            $a->fraction              = $form->fraction[$key];//new
+           $a->tolerance           = $form->tolerance[$key];
             $a->tolerancetype       = $form->tolerancetype[$key];
             $a->correctanswerlength = $form->correctanswerlength[$key];
             $a->correctanswerformat = $form->correctanswerformat[$key];
@@ -339,39 +359,52 @@ class question_calculated_qtype extends question_dataset_dependent_questiontype
         $unit = $virtualqtype->get_default_numerical_unit($question);
 
         // We modify the question to look like a numerical question
-        $numericalquestion = clone($question);
-        $numericalquestion->options = clone($question->options);
+        $numericalquestion = fullclone($question);
+      /*  $numericalquestion->options = clone($question->options);
         foreach ($question->options->answers as $key => $answer) {
             $numericalquestion->options->answers[$key] = clone($answer);
-        }
+        }*/
         foreach ($numericalquestion->options->answers as $key => $answer) {
-            $answer = &$numericalquestion->options->answers[$key]; // for PHP 4.x
+        //    $answer = &$numericalquestion->options->answers[$key]; // for PHP 4.x
+          $answer = fullclone($numericalquestion->options->answers[$key]);
             $correctanswer = qtype_calculated_calculate_answer(
                  $answer->answer, $state->options->dataset, $answer->tolerance,
                  $answer->tolerancetype, $answer->correctanswerlength,
                  $answer->correctanswerformat, $unit->unit);
-            $answer->answer = $correctanswer->answer;
+           $numericalquestion->options->answers[$key]->answer = $correctanswer->answer;
         }
         $numericalquestion->questiontext = parent::substitute_variables(
         $numericalquestion->questiontext, $state->options->dataset);
         $virtualqtype->print_question_formulation_and_controls($numericalquestion, $state, $cmoptions, $options);
     }
-
     function grade_responses(&$question, &$state, $cmoptions) {
-        // Forward the grading to the virtual qtype
+        // Forward the grading to the virtual qtype but not actually..
+         echo "calculated question type question grade_reponse <pre>";print_r($question);
 
         // We modify the question to look like a numerical question
-        $numericalquestion = clone($question);
+        $numericalquestion = fullclone($question);
+    /*      echo "calculated1question type question grade_reponse <pre>";print_r($numericalquestion);
         $numericalquestion->options = clone($question->options);
+          echo "calculated2 question type question grade_reponse <pre>";print_r($numericalquestion);
         foreach ($question->options->answers as $key => $answer) {
             $numericalquestion->options->answers[$key] = clone($answer);
         }
-        foreach ($numericalquestion->options->answers as $key => $answer) {
-            $answer = &$numericalquestion->options->answers[$key]; // for PHP 4.x
-            $answer->answer = $this->substitute_variables($answer->answer,
+        */
+           echo "calculated3question type question grade_reponse <pre>";print_r($numericalquestion);
+       foreach ($numericalquestion->options->answers as $key => $answer) {
+            $answer = $numericalquestion->options->answers[$key]->answer; // for PHP 4.x
+           echo "calculated3aquestion type question grade_reponse answer $key<pre>";print_r($answer);
+           echo "calculated3aquestion type question grade_reponse numerical<pre>";print_r($numericalquestion);
+          $numericalquestion->options->answers[$key]->answer = $this->substitute_variables($answer,
              $state->options->dataset);
-        }
-        return parent::grade_responses($numericalquestion, $state, $cmoptions);
+            echo "calculated3aquestion type question grade_reponse answer after<pre>";print_r($answer);
+           echo "calculated3aquestion type question grade_reponse numerical after<pre>";print_r($numericalquestion);
+       }
+          echo "calculated4question type question grade_reponse <pre>";print_r($numericalquestion);
+         $virtualqtype = $this->get_virtual_qtype();
+        return $virtualqtype->grade_responses($numericalquestion, $state, $cmoptions) ;
+      
+      //  return parent::grade_responses($numericalquestion, $state, $cmoptions);
     }
 
     function response_summary($question, $state, $length=80) {
@@ -393,7 +426,12 @@ class question_calculated_qtype extends question_dataset_dependent_questiontype
             $answer->answer = $this->substitute_variables($answer->answer,
              $state->options->dataset);
         }
-        return parent::check_response($numericalquestion, $state);
+                                   echo "calculated numrericalquestion check_reponse <pre>";print_r($numericalquestion);
+                                   echo "calculated numrericalquestion <pre>";print_r($state);
+        $virtualqtype = $this->get_virtual_qtype();
+        return $virtualqtype->check_response($numericalquestion, $state) ;
+
+   //     return parent::check_response($numericalquestion, $state);
     }
 
     // ULPGC ecastro
@@ -415,7 +453,7 @@ class question_calculated_qtype extends question_dataset_dependent_questiontype
              $state->options->dataset);
             // apply_unit
         }
-        $numericalquestion->questiontext = parent::substitute_variables(
+        $numericalquestion->questiontext = $this->substitute_variables(
                                   $numericalquestion->questiontext, $state->options->dataset);
         $responses = $virtualqtype->get_all_responses($numericalquestion, $state);
         $response = reset($responses->responses);