From: jamiesensei Date: Wed, 17 Jan 2007 18:28:51 +0000 (+0000) Subject: more work on the datasetdependent / calculated question creation forms X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=60b5ecd3cf29cc4898f9958d75220e9d18d8b3af;p=moodle.git more work on the datasetdependent / calculated question creation forms --- diff --git a/lang/en_utf8/qtype_calculated.php b/lang/en_utf8/qtype_calculated.php index 2b2a509182..43dd4de688 100644 --- a/lang/en_utf8/qtype_calculated.php +++ b/lang/en_utf8/qtype_calculated.php @@ -10,5 +10,6 @@ $string['mustbenumeric'] = 'You must enter a number here.'; $string['mustnotbenumeric'] = 'This can\'t be a number.'; $string['youmustenteramultiplierhere'] = 'You must enter a multiplier here.'; $string['nextpage'] = 'Next Page'; +$string['nextitemtoadd'] = 'Next \'Item to Add\''; $string['makecopynextpage'] = 'Next Page (new question)'; ?> \ No newline at end of file diff --git a/lang/en_utf8/qtype_datasetdependent.php b/lang/en_utf8/qtype_datasetdependent.php index cc46217bc0..f743468b3b 100644 --- a/lang/en_utf8/qtype_datasetdependent.php +++ b/lang/en_utf8/qtype_datasetdependent.php @@ -2,13 +2,18 @@ $string['itemno'] = 'Item $a'; $string['param'] = 'Param {$a}'; $string['additem'] = 'Add Item'; +$string['deletelastitem'] = 'Delete Last Item'; $string['itemtoadd'] = 'Item To Add'; -$string['calclength'] = 'Significant Figures'; +$string['calclength'] = 'Decimal Places'; $string['calcdistribution'] = 'Distribution'; $string['uniform'] = 'Uniform'; $string['loguniform'] = 'Loguniform'; -$string['generate'] = 'Generate'; $string['calcmin'] = 'Minimum'; $string['calcmax'] = 'Maximum'; $string['minmax'] = 'Range of Values'; +$string['replacewithrandom'] = 'Replace with a random value'; +$string['getnextnow'] = 'Get New \'Item to Add\' Now'; +$string['forceregeneration'] = 'force regeneration'; +$string['reuseifpossible'] = 'reuse previous value if available'; +$string['youmustaddatleastoneitem'] = 'You must add at least one dataset item before you can save this question.'; ?> \ No newline at end of file diff --git a/question/question2.php b/question/question2.php index 4c4e0ed885..28b8f26480 100644 --- a/question/question2.php +++ b/question/question2.php @@ -24,20 +24,18 @@ if (!$returnurl && isset($SESSION->fromurl)) { $id = optional_param('id', 0, PARAM_INT); // question id $qtype = optional_param('qtype', '', PARAM_FILE); $categoryid = optional_param('category', 0, PARAM_INT); -$wizard = optional_param('wizard', '', PARAM_ALPHA); +$wizardnow = optional_param('wizardnow', '', PARAM_ALPHA); // Validate the URL parameters. -if ($id = optional_param('id', 0, PARAM_INT)) { - if (!$question = get_record("question", "id", $id)) { +if ($id) { + if (!$question = get_record('question', 'id', $id)) { print_error('questiondoesnotexist', 'question', $returnurl); } get_question_options($question); - $submiturl = "question2.php?id=$id&returnurl=" . urlencode($returnurl).'&wizard='.$wizard; } else if ($categoryid && $qtype) { // only for creating new questions $question = new stdClass; $question->category = $categoryid; $question->qtype = $qtype; - $submiturl = "question2.php?category=$categoryid&qtype=$qtype&returnurl=" . urlencode($returnurl).'&wizard='.$wizard; } else { print_error('notenoughdatatoeditaquestion', 'question', $returnurl); } @@ -63,30 +61,32 @@ $coursecontext = get_context_instance(CONTEXT_COURSE, $category->course); require_capability('moodle/question:manage', $coursecontext); // Create the question editing form. -if ($wizard!==''){ +if ($wizardnow!==''){ if (!method_exists($QTYPES[$question->qtype], 'next_wizard_form')){ print_error('missingimportantcode', 'question', $returnurl, 'wizard form definition'); } else { - $mform = $QTYPES[$question->qtype]->next_wizard_form($submiturl, $question, $wizard); + $mform = $QTYPES[$question->qtype]->next_wizard_form('question2.php', $question, $wizardnow); } } else { - $mform = $QTYPES[$question->qtype]->create_editing_form($submiturl, $question, $category->course); + $mform = $QTYPES[$question->qtype]->create_editing_form('question2.php', $question, $category->course); } if ($mform === null) { print_error('missingimportantcode', 'question', $returnurl, 'question editing form definition'); } -$mform->set_data($question); +$toform = $question; // send the question object and a few more parameters to the form +$toform->returnurl = $returnurl; +$mform->set_data($toform); if ($mform->is_cancelled()){ redirect($returnurl); -} else if ($data = $mform->get_data()){ +} elseif ($data = $mform->get_data()){ if (!empty($data->makecopy)) { $question->id = 0; // causes a new question to be created. $question->hidden = 0; // Copies should not be hidden } - $question = $QTYPES[$qtype]->save_question($question, $data, $COURSE); - if ($QTYPES[$qtype]->finished_edit_wizard($question)){ + $question = $QTYPES[$question->qtype]->save_question($question, $data, $COURSE, $wizardnow); + if ($QTYPES[$qtype]->finished_edit_wizard($data)){ if (optional_param('inpopup', 0, PARAM_BOOL)) { notify(get_string('changessaved'), ''); close_window(3); @@ -95,7 +95,19 @@ if ($mform->is_cancelled()){ } die; } else { - redirect($submiturl.'&wizard='.$data->wizardpage); + //useful for passing data to the next page which is not saved in the database + $queryappend = ''; + if (isset($data->nextpageparam)){ + foreach ($data->nextpageparam as $key => $param){ + $queryappend .= "&".urlencode($key).'='.urlencode($param); + } + } + if ($question->id) { + $nexturl = "question2.php?id=$question->id&returnurl=" . urlencode($returnurl); + } else { // only for creating new questions + $nexturl = "question2.php?category=$question->category&qtype=$question->qtype&returnurl=".urlencode($returnurl); + } + redirect($nexturl.'&wizardnow='.$data->wizard.$queryappend, '', 20); } } else { // Display the question editing form diff --git a/question/type/calculated/edit_calculated_form.php b/question/type/calculated/edit_calculated_form.php index fc9442db7a..2bd209b10d 100644 --- a/question/type/calculated/edit_calculated_form.php +++ b/question/type/calculated/edit_calculated_form.php @@ -118,8 +118,8 @@ class question_edit_calculated_form extends question_edit_form { $firstunit->setPersistantFreeze(true); //hidden elements - $mform->addElement('hidden', 'wizardpage', 'question'); - $mform->setType('wizardpage', PARAM_ALPHA); + $mform->addElement('hidden', 'wizard', 'datasetdefinitions'); + $mform->setType('wizard', PARAM_ALPHA); } diff --git a/question/type/calculated/questiontype.php b/question/type/calculated/questiontype.php index 66b51882bc..31d493e055 100644 --- a/question/type/calculated/questiontype.php +++ b/question/type/calculated/questiontype.php @@ -216,8 +216,7 @@ class question_calculated_qtype extends question_dataset_dependent_questiontype return true; } - function print_question_formulation_and_controls(&$question, &$state, $cmoptions, - $options) { + function print_question_formulation_and_controls(&$question, &$state, $cmoptions, $options) { // Substitute variables in questiontext before giving the data to the // virtual type for printing $virtualqtype = $this->get_virtual_qtype(); @@ -239,8 +238,7 @@ class question_calculated_qtype extends question_dataset_dependent_questiontype } $numericalquestion->questiontext = parent::substitute_variables( $numericalquestion->questiontext, $state->options->dataset); - $virtualqtype->print_question_formulation_and_controls($numericalquestion, - $state, $cmoptions, $options); + $virtualqtype->print_question_formulation_and_controls($numericalquestion, $state, $cmoptions, $options); } function grade_responses(&$question, &$state, $cmoptions) { @@ -326,6 +324,40 @@ class question_calculated_qtype extends question_dataset_dependent_questiontype // Calcualted support generation of randomly distributed number data return true; } + function custom_generator_tools_part(&$mform, $idx, $j){ + + $minmaxgrp = array(); + $minmaxgrp[] =& $mform->createElement('text', "calcmin[$idx]", get_string('calcmin', 'qtype_datasetdependent'), 'size="3"'); + $minmaxgrp[] =& $mform->createElement('text', "calcmax[$idx]", get_string('calcmax', 'qtype_datasetdependent'), 'size="3"'); + $mform->addGroup($minmaxgrp, 'minmaxgrp', get_string('minmax', 'qtype_datasetdependent'), ' - ', false); + + $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('select', "calcdistribution[$idx]", get_string('calcdistribution', 'qtype_datasetdependent'), $distriboptions); + + + $mform->addElement('hidden', "definition[$j]"); + $mform->addElement('hidden', "itemid[$j]"); + + + } + + function custom_generator_set_data($datasetdefs, $formdata){ + $idx = 1; + foreach ($datasetdefs as $datasetdef){ + if (ereg('^(uniform|loguniform):([^:]*):([^:]*):([0-9]*)$', $datasetdef->options, $regs)) { + $defid = "$datasetdef->type-$datasetdef->category-$datasetdef->name"; + $formdata["calcdistribution[$idx]"] = $regs[1]; + $formdata["calcmin[$idx]"] = $regs[2]; + $formdata["calcmax[$idx]"] = $regs[3]; + $formdata["calclength[$idx]"] = $regs[4]; + } + $idx++; + } + return $formdata; + } function custom_generator_tools($datasetdef) { if (ereg('^(uniform|loguniform):([^:]*):([^:]*):([0-9]*)$', @@ -355,6 +387,7 @@ class question_calculated_qtype extends question_dataset_dependent_questiontype } } + function update_dataset_options($datasetdefs, $form) { // Do we have informatin about new options??? if (empty($form->definition) || empty($form->calcmin) @@ -364,21 +397,22 @@ class question_calculated_qtype extends question_dataset_dependent_questiontype } else { // Looks like we just could have some new information here - foreach ($form->definition as $key => $defid) { + $uniquedefs = array_values(array_unique($form->definition)); + foreach ($uniquedefs as $key => $defid) { if (isset($datasetdefs[$defid]) - && is_numeric($form->calcmin[$key]) - && is_numeric($form->calcmax[$key]) - && is_numeric($form->calclength[$key])) { - switch ($form->calcdistribution[$key]) { + && is_numeric($form->calcmin[$key+1]) + && is_numeric($form->calcmax[$key+1]) + && is_numeric($form->calclength[$key+1])) { + switch ($form->calcdistribution[$key+1]) { case 'uniform': case 'loguniform': $datasetdefs[$defid]->options = - $form->calcdistribution[$key] . ':' - . $form->calcmin[$key] . ':' - . $form->calcmax[$key] . ':' - . $form->calclength[$key]; + $form->calcdistribution[$key+1] . ':' + . $form->calcmin[$key+1] . ':' + . $form->calcmax[$key+1] . ':' + . $form->calclength[$key+1]; break; default: - notify("Unexpected distribution $form->calcdistribution[$key]"); + notify("Unexpected distribution ".$form->calcdistribution[$key+1]); } } } @@ -393,6 +427,79 @@ class question_calculated_qtype extends question_dataset_dependent_questiontype return $datasetdefs; } + function save_dataset_items($question, $fromform){ + if (empty($question->options)) { + $this->get_question_options($question); + } + //get the old datasets for this question + $datasetdefs = $this->get_dataset_definitions($question->id, array()); + // Handle generator options... + $olddatasetdefs = fullclone($datasetdefs); + $datasetdefs = $this->update_dataset_options($datasetdefs, $fromform); + $maxnumber = -1; + foreach ($datasetdefs as $defid => $datasetdef) { + if (isset($datasetdef->id) + && $datasetdef->options != $olddatasetdefs[$defid]->options) { + // Save the new value for options + update_record('question_dataset_definitions', $datasetdef); + + } + // Get maxnumber + if ($maxnumber == -1 || $datasetdef->itemcount < $maxnumber) { + $maxnumber = $datasetdef->itemcount; + } + } + // Handle adding and removing of dataset items + $i = 1; + foreach ($fromform->definition as $key => $defid) { + //if the delete button has not been pressed then skip the datasetitems + //in the 'add item' part of the form. + if ((!isset($fromform->addbutton)) && ($i > (count($datasetdefs)*$maxnumber))) { + break; + } + $addeditem = new stdClass(); + $addeditem->definition = $datasetdefs[$defid]->id; + $addeditem->value = $fromform->number[$i]; + $addeditem->itemnumber = ceil($i / count($datasetdefs)); + + if ($fromform->itemid[$i]) { + // Reuse any previously used record + $addeditem->id = $fromform->itemid[$i]; + if (!update_record('question_dataset_items', $addeditem)) { + error("Error: Unable to update dataset item"); + } + } else { + if (!insert_record('question_dataset_items', $addeditem)) { + error("Error: Unable to insert dataset item"); + } + } + + $i++; + } + if ($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 + update_record('question_dataset_definitions', $newdef); + } + } + } + if (isset($fromform->deletebutton)) { + // Simply decrease itemcount where == $maxnumber + foreach ($datasetdefs as $datasetdef) { + if ($datasetdef->itemcount == $maxnumber) { + $datasetdef->itemcount--; + if (!update_record('question_dataset_definitions', + $datasetdef)) { + error("Error: Unable to update itemcount"); + } + } + } + --$maxnumber; + } + } function generate_dataset_item($options) { if (!ereg('^(uniform|loguniform):([^:]*):([^:]*):([0-9]*)$', $options, $regs)) { @@ -469,11 +576,9 @@ class question_calculated_qtype extends question_dataset_dependent_questiontype global $SESSION; $strheader = ''; $delimiter = ''; - if (empty($question->id)) { - $answers = $SESSION->datasetdependent->questionform->answers; - } else { - $answers = $question->options->answers; - } + + $answers = $question->options->answers; + foreach ($answers as $answer) { if (is_string($answer)) { $strheader .= $delimiter.$answer; @@ -495,13 +600,17 @@ class question_calculated_qtype extends question_dataset_dependent_questiontype } $answers = $question->options->answers; - $stranswers = get_string('answer', 'quiz'); + $stranswers = ''; $strmin = get_string('min', 'quiz'); $strmax = get_string('max', 'quiz'); $errors = ''; $delimiter = ': '; $virtualqtype = $this->get_virtual_qtype(); foreach ($answers as $answer) { + $formula = $answer->answer; + foreach ($data as $name => $value) { + $formula = str_replace('{'.$name.'}', $value, $formula); + } $calculated = qtype_calculated_calculate_answer( $answer->answer, $data, $answer->tolerance, $answer->tolerancetype, $answer->correctanswerlength, @@ -516,12 +625,12 @@ class question_calculated_qtype extends question_dataset_dependent_questiontype $errors .= " -$calculated->answer"; $stranswers .= $delimiter; } else { - $stranswers .= $delimiter.$calculated->answer; + $stranswers .= $formula.' = '.$calculated->answer. '
'; $strmin .= $delimiter.$calculated->min; $strmax .= $delimiter.$calculated->max; } } - return "$stranswers
$strmin
$strmax
$errors"; + return "$stranswers$strmin
$strmax
$errors"; } function tolerance_types() { diff --git a/question/type/datasetdependent/abstractqtype.php b/question/type/datasetdependent/abstractqtype.php index 5e5c29ee6b..bbcc1bfba0 100644 --- a/question/type/datasetdependent/abstractqtype.php +++ b/question/type/datasetdependent/abstractqtype.php @@ -146,11 +146,11 @@ class question_dataset_dependent_questiontype extends default_questiontype { // This gets called by editquestion.php after the standard question is saved function print_next_wizard_page(&$question, &$form, $course) { - global $CFG, $USER, $SESSION; + global $CFG, $USER, $SESSION, $COURSE; // Catch invalid navigation & reloads if (empty($question->id) && empty($SESSION->datasetdependent)) { - redirect('edit.php', 'The page you are loading has expired.', 3); + redirect('edit.php?courseid='.$COURSE->id, 'The page you are loading has expired.', 3); } // See where we're coming from @@ -169,28 +169,28 @@ class question_dataset_dependent_questiontype extends default_questiontype { } // This gets called by question2.php after the standard question is saved - function &next_wizard_form($submiturl, $question, $wizard){ - global $CFG, $SESSION; + function &next_wizard_form($submiturl, $question, $wizardnow){ + global $CFG, $SESSION, $COURSE; // Catch invalid navigation & reloads if (empty($question->id) && empty($SESSION->datasetdependent)) { - redirect('edit.php', 'The page you are loading has expired.', 3); + redirect('edit.php?courseid='.$COURSE->id, 'The page you are loading has expired. Cannot get next wizard form.', 3); } - if (!isset($question->id)){ + if (empty($question->id)){ $question =& $SESSION->datasetdependent->questionform; } // See where we're coming from - switch($wizard) { - case 'question': + switch($wizardnow) { + case 'datasetdefinitions': require("$CFG->dirroot/question/type/datasetdependent/datasetdefinitions_form.php"); - $mform =& new question_dataset_dependent_definitions_form($submiturl, $question); + $mform =& new question_dataset_dependent_definitions_form("$submiturl?wizardnow=datasetdefinitions", $question); $mform->heading = print_heading_with_help(get_string("choosedatasetproperties", "quiz"), "questiondatasets", "quiz", '', true); break; - case 'datasetdefinitions': case 'datasetitems': require("$CFG->dirroot/question/type/datasetdependent/datasetitems_form.php"); - $mform =& new question_dataset_dependent_items_form($submiturl, $question); + $regenerate = optional_param('forceregeneration', 0, PARAM_BOOL); + $mform =& new question_dataset_dependent_items_form("$submiturl?wizardnow=datasetitems", $question, $regenerate); $streditdatasets = get_string("editdatasets", "quiz"); $mform->heading = print_heading_with_help($streditdatasets, 'questiondatasets', "quiz", '', true); break; @@ -201,21 +201,35 @@ class question_dataset_dependent_questiontype extends default_questiontype { return $mform; } - function save_question($question, &$form, $course) { + function save_question($question, $form, $course) { // For dataset dependent questions a wizard is used for editing // questions. Therefore saving the question is delayed until // we're through with the whole wizard. global $SESSION; - // $this->validate_form($form); + $wizardnow = optional_param('wizardnow', '', PARAM_ALPHA); + // We need to return a valid question object (incl. id) if we're in the // edit case. If it is a new question we don't necessarily need to // return a valid question object // See where we're coming from - switch($form->wizardpage) { + switch($wizardnow) { + case '' : case 'question': // coming from the first page, creating the second if (empty($form->id)) { + $form->options = new stdClass; + $form->options->answers = array(); + foreach (array_keys($form->answers) as $i){ + $form->options->answers[$i] = new stdClass; + $form->options->answers[$i]->answer = $form->answers[$i]; + $form->options->answers[$i]->tolerance = $form->tolerance[$i]; + $form->options->answers[$i]->tolerancetype = $form->tolerancetype[$i]; + $form->options->answers[$i]->correctanswerlength = $form->correctanswerlength[$i]; + $form->options->answers[$i]->correctanswerformat = $form->correctanswerformat[$i]; + $form->options->answers[$i]->feedback = $form->feedback[$i]; + } + $SESSION->datasetdependent = new stdClass; $SESSION->datasetdependent->questionform = $form; } else { @@ -223,12 +237,12 @@ class question_dataset_dependent_questiontype extends default_questiontype { } break; case 'datasetdefinitions': - if (empty($form->id)) { + if (empty($question->id)) { if (isset($SESSION->datasetdependent->questionform)) { $SESSION->datasetdependent->definitionform = $form; } else { // Something went wrong, go back to the first page - redirect("question.php?category={$question->category}" ."&qtype={$question->qtype}"); + redirect("question2.php?category={$question->category}" ."&qtype={$question->qtype}"); } } else { $this->save_dataset_definitions($form); @@ -241,6 +255,7 @@ class question_dataset_dependent_questiontype extends default_questiontype { $this->save_dataset_definitions($SESSION->datasetdependent->definitionform); unset($SESSION->datasetdependent); } + $this->save_dataset_items($question, $form); break; default: error('Incorrect or no wizard page specified!'); @@ -249,14 +264,19 @@ class question_dataset_dependent_questiontype extends default_questiontype { return $question; } - function get_dataset_definitions($form) { + function save_dataset_items($question, $fromform){ + //overridden in child classes + } + + function get_dataset_definitions($questionid, $newdatasets) { + //get the existing datasets for this question $datasetdefs = array(); - if (!empty($form->id)) { + if (!empty($questionid)) { global $CFG; $sql = "SELECT i.* FROM {$CFG->prefix}question_datasets d, {$CFG->prefix}question_dataset_definitions i - WHERE d.question = '$form->id' + WHERE d.question = '$questionid' AND d.datasetdefinition = i.id "; if ($records = get_records_sql($sql)) { @@ -266,20 +286,20 @@ class question_dataset_dependent_questiontype extends default_questiontype { } } - $datasets = empty($form->dataset) ? $form->definition : $form->dataset; - foreach ($datasets as $dataset) { + foreach ($newdatasets as $dataset) { if (!$dataset) { continue; // The no dataset case... } if (!isset($datasetdefs[$dataset])) { + //make new datasetdef list($type, $category, $name) = explode('-', $dataset, 3); $datasetdef = new stdClass; $datasetdef->type = $type; $datasetdef->name = $name; $datasetdef->category = $category; $datasetdef->itemcount = 0; - $datasetdef->options = ''; + $datasetdef->options = 'uniform:1.0:10.0:1'; $datasetdefs[$dataset] = clone($datasetdef); } } @@ -288,7 +308,7 @@ class question_dataset_dependent_questiontype extends default_questiontype { function save_dataset_definitions($form) { // Save datasets - $datasetdefinitions = $this->get_dataset_definitions($form); + $datasetdefinitions = $this->get_dataset_definitions($form->id, $form->dataset); $tmpdatasets = array_flip($form->dataset); $defids = array_keys($datasetdefinitions); foreach ($defids as $defid) { diff --git a/question/type/datasetdependent/datasetdefinitions_form.php b/question/type/datasetdependent/datasetdefinitions_form.php index 73e61b726c..2c45304cdf 100644 --- a/question/type/datasetdependent/datasetdefinitions_form.php +++ b/question/type/datasetdependent/datasetdefinitions_form.php @@ -26,13 +26,21 @@ class question_dataset_dependent_definitions_form extends moodleform { parent::moodleform($submiturl); } function definition() { + global $SESSION; $mform =& $this->_form; $possibledatasets = $this->qtypeobj->find_dataset_names($this->question->questiontext); $mandatorydatasets = array(); - foreach ($this->question->answers as $answer) { - $mandatorydatasets += $this->qtypeobj->find_dataset_names($answer); + if (isset($this->question->options->answers)){ + foreach ($this->question->options->answers as $answer) { + $mandatorydatasets += $this->qtypeobj->find_dataset_names($answer->answer); + } + }else{ + foreach ($SESSION->datasetdependent->questionform->answers as $answer){ + $mandatorydatasets += $this->qtypeobj->find_dataset_names($answer); + } } + $key = 0; $datasetmenus = array(); foreach ($mandatorydatasets as $datasetname) { @@ -58,10 +66,20 @@ class question_dataset_dependent_definitions_form extends moodleform { $key++; } } - //hidden elements - $mform->addElement('hidden', 'wizardpage', 'datasetdefinitions'); - $mform->setType('wizardpage', PARAM_ALPHA); $this->add_action_buttons(true, get_string('nextpage', 'qtype_calculated')); + + + //hidden elements + $mform->addElement('hidden', 'returnurl'); + $mform->setType('returnurl', PARAM_URL); + $mform->addElement('hidden', 'qtype'); + $mform->setType('qtype', PARAM_ALPHA); + $mform->addElement('hidden', 'category'); + $mform->setType('category', PARAM_INT); + $mform->addElement('hidden', 'id'); + $mform->setType('id', PARAM_INT); + $mform->addElement('hidden', 'wizard', 'datasetitems'); + $mform->setType('wizard', PARAM_ALPHA); } } diff --git a/question/type/datasetdependent/datasetitems_form.php b/question/type/datasetdependent/datasetitems_form.php index 719c30131b..c043140cc8 100644 --- a/question/type/datasetdependent/datasetitems_form.php +++ b/question/type/datasetdependent/datasetitems_form.php @@ -14,84 +14,204 @@ class question_dataset_dependent_items_form extends moodleform { * @var question_dataset_dependent_questiontype */ var $qtypeobj; + + var $datasetdefs; + + var $maxnumber = -1; + + var $regenerate; + + var $noofitems; /** * Add question-type specific form fields. * * @param MoodleQuickForm $mform the form being built. */ - function question_dataset_dependent_items_form($submiturl, $question){ - global $QTYPES; + function question_dataset_dependent_items_form($submiturl, $question, $regenerate){ + global $QTYPES, $SESSION, $CFG; + $this->regenerate = $regenerate; $this->question = $question; $this->qtypeobj =& $QTYPES[$this->question->qtype]; + //get the dataset defintions for this question + if (empty($question->id)) { + $this->datasetdefs = $this->qtypeobj->get_dataset_definitions($question->id, $SESSION->datasetdependent->definitionform->dataset); + } else { + if (empty($question->options)) { + $this->get_question_options($question); + } + $this->datasetdefs = $this->qtypeobj->get_dataset_definitions($question->id, array()); + } + + 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 = get_records_sql( // Use number as key!! + " SELECT itemnumber, definition, id, value + FROM {$CFG->prefix}question_dataset_items + WHERE definition = $datasetdef->id "); + } + } parent::moodleform($submiturl); } function definition() { $mform =& $this->_form; + $strquestionlabel = $this->qtypeobj->comment_header($this->question); - $repeated = array(); - $repeatedoptions = array(); - $repeated[] =& $mform->createElement('header', 'itemhdr', get_string('itemno', 'qtype_datasetdependent', '{no}')); - $params = array('a', 'b', 'c'); - foreach ($params as $paramno => $param){ - $idx = $paramno +1; - $repeated[] =& $mform->createElement('text', "number[$idx]", get_string('param', 'qtype_datasetdependent', $param)); - $repeated[] =& $mform->createElement('hidden', "itemid[$idx]"); - $repeated[] =& $mform->createElement('hidden', "definition[$idx]"); - - $repeatedoptions["number[$idx]"]['type'] = PARAM_NUMBER; - //$repeatedoptions["number[$idx]"]['rule'] = 'numeric'; - $repeatedoptions["itemid[$idx]"]['type'] = PARAM_INT; - $repeatedoptions["definition[$idx]"]['type'] = PARAM_NOTAGS; +//------------------------------------------------------------------------------------------------------------------------------ + if ($this->maxnumber != -1){ + $this->noofitems = $this->maxnumber; + } else { + $this->noofitems = 0; } + $j = 1; + for ($i=1; $i <= $this->noofitems; $i++){ + $mform->addElement('header', 'itemhdr', get_string('itemno', 'qtype_datasetdependent', $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); - /*if (isset($this->question->options)){ - $countanswers = count($this->question->options->answers); - } else { - $countanswers = 0; + $mform->addElement('hidden', "itemid[$j]"); + + $mform->addElement('hidden', "definition[$j]"); + + $j++; + } + if ('' != $strquestionlabel){ + $repeated[] =& $mform->addElement('static', "answercomment[$i]", $strquestionlabel); + } + if ($i == $this->noofitems) {//last item + $mform->addElement('submit', 'deletebutton', get_string('deletelastitem', 'qtype_datasetdependent')); + + } } - $repeatsatstart = (QUESTION_NUMANS_START > ($countanswers + QUESTION_NUMANS_ADD))? - QUESTION_NUMANS_START : ($countanswers + QUESTION_NUMANS_ADD); - */ - $repeatsatstart = 3; - $this->repeat_elements($repeated, $repeatsatstart, $repeatedoptions, 'itemsno', 'itemsadd', 1, get_string('additem', 'qtype_datasetdependent')); + $mform->setType("itemid", PARAM_INT); + $mform->setType("definition", PARAM_NOTAGS); + + $mform->addElement('submit', 'addbutton', get_string('additem', 'qtype_datasetdependent')); + $mform->closeHeaderBefore('addbutton'); +//------------------------------------------------------------------------------------------------------------------------------ + $mform->addElement('header', 'additemhdr', get_string('itemtoadd', 'qtype_datasetdependent')); + $idx = 1; + foreach ($this->datasetdefs as $defkey => $datasetdef){ + $mform->addElement('text', "number[$j]", get_string('param', 'qtype_datasetdependent', $datasetdef->name)); + $this->qtypeobj->custom_generator_tools_part(&$mform, $idx, $j); + $idx++; + $j++; + $mform->addElement('static', "divider[$j]", '', '
'); + + } + + if ('' != $strquestionlabel){ + $mform->addElement('static', 'answercomment['.($this->noofitems+1).']', $strquestionlabel); + } + + $mform->closeHeaderBefore('forceregenerationgrp'); + if ($this->qtypeobj->supports_dataset_item_generation()){ $radiogrp = array(); - $radiogrp[] =& $mform->createElement('radio', "forceregeneration", 0, get_string('reuseifpossible', 'quiz')); - $radiogrp[] =& $mform->createElement('radio', "forceregeneration", 1, get_string('forceregeneration', 'quiz')); - $mform->addGroup($radiogrp, 'forceregenerationgrp', '', null, false); + $radiogrp[] =& $mform->createElement('radio', 'nextpageparam[forceregeneration]', null, get_string('reuseifpossible', 'qtype_datasetdependent'), 0); + $radiogrp[] =& $mform->createElement('radio', 'nextpageparam[forceregeneration]', null, get_string('forceregeneration', 'qtype_datasetdependent'), 1); + $mform->addGroup($radiogrp, 'forceregenerationgrp', get_string('nextitemtoadd', 'qtype_calculated'), null, false); + $mform->setDefault('nextpageparam[forceregeneration]', 0); } - $mform->addElement('header', 'additemhdr', get_string('itemtoadd', 'qtype_datasetdependent')); - foreach ($params as $paramno => $param){ - $idx = $paramno +1; - $mform->addElement('text', "numbertoadd[$idx]", get_string('param', 'qtype_datasetdependent', $param)); + $mform->addElement('submit', 'getnextbutton', get_string('getnextnow', 'qtype_datasetdependent')); - $minmaxgrp = array(); - $minmaxgrp[] =& $mform->createElement('text', "calcmin[$idx]", get_string('calcmin', 'qtype_datasetdependent'), 'size="3"'); - $minmaxgrp[] =& $mform->createElement('text', "calcmax[$idx]", get_string('calcmax', 'qtype_datasetdependent'), 'size="3"'); - $mform->addGroup($minmaxgrp, 'minmaxgrp', get_string('minmax', 'qtype_datasetdependent'), ' - ', false); + //non standard name for button element needed so not using add_action_buttons + $buttonarray=array(); + $buttonarray[] = &$mform->createElement('submit', 'backtoquiz', get_string('savechanges')); + $buttonarray[] = &$mform->createElement('cancel'); + $mform->addGroup($buttonarray, 'buttonar', '', array(' '), false); - $precisionoptions = range(0, 10); - $mform->addElement('select', "calclength[$idx]", get_string('calclength', 'qtype_datasetdependent'), $precisionoptions); + //hidden elements + $mform->addElement('hidden', 'returnurl'); + $mform->setType('returnurl', PARAM_URL); + $mform->addElement('hidden', 'qtype'); + $mform->setType('qtype', PARAM_ALPHA); + $mform->addElement('hidden', 'category'); + $mform->setType('category', PARAM_INT); + $mform->addElement('hidden', 'id'); + $mform->setType('id', PARAM_INT); + $mform->addElement('hidden', 'wizard', 'datasetitems'); + $mform->setType('wizard', PARAM_ALPHA); + } - $distriboptions = array('uniform' => get_string('uniform', 'qtype_datasetdependent'), 'loguniform' => get_string('loguniform', 'qtype_datasetdependent')); - $mform->addElement('select', "calcdistribution[$idx]", get_string('calcdistribution', 'qtype_datasetdependent'), $distriboptions); + function set_data($question){ + $formdata = array(); + //fill out all data sets and also the fields for the next item to add. + $j = 1; + for ($itemnumber = 1; $itemnumber <= $this->noofitems; $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++; + } + $formdata['answercomment['.$itemnumber.']'] = $this->qtypeobj->comment_on_datasetitems($this->question, $data, $itemnumber); + } - $mform->addElement('submit', "generate[$idx]", get_string('generate', 'qtype_datasetdependent')); - $mform->addElement('hidden', "definition[$idx]"); + $formdata['nextpageparam[forceregeneration]'] = $this->regenerate; - $repeatedoptions["number[$idx]"]['type'] = PARAM_NUMBER; - //$repeatedoptions["number[$idx]"]['rule'] = 'numeric'; - $repeatedoptions["itemid[$idx]"]['type'] = PARAM_INT; - $repeatedoptions["definition[$idx]"]['type'] = PARAM_NOTAGS; + $savej = $j; + $data = array(); // data for comment_on_datasetitems later + //dataset generation dafaults + if ($this->qtypeobj->supports_dataset_item_generation()) { + $itemnumber = $this->noofitems+1; + foreach ($this->datasetdefs as $defid => $datasetdef){ + $formdata["number[$j]"] = $this->qtypeobj->generate_dataset_item($datasetdef->options); + $formdata["definition[$j]"] = $defid; + $formdata["itemid[$j]"] = + isset($datasetdef->items[$itemnumber])?$datasetdef->items[$itemnumber]->id:0; + $data[$datasetdef->name] = $formdata["number[$j]"]; + $j++; + } } - $mform->addElement('hidden', 'wizardpage', 'datasetitems'); - $mform->setType('wizardpage', PARAM_ALPHA); - $this->add_action_buttons(true); + + //existing records override generated data depending on radio element + $j = $savej; + if (!$this->regenerate){ + $idx = 1; + $itemnumber = $this->noofitems+1; + 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++; + } + + } + //default answercomment will get ignored if answer element is not in the form. + $formdata['answercomment['.($this->noofitems+1).']'] = $this->qtypeobj->comment_on_datasetitems($this->question, $data, ($this->noofitems+1)); + + $formdata = $this->qtypeobj->custom_generator_set_data($this->datasetdefs, $formdata); + + parent::set_data((object)($formdata + (array)$question)); } + function validation($data){ + $errors = array(); + if (isset($data['backtoquiz'])){ + $errors['addbutton'] = get_string('youmustaddatleastoneitem', 'qtype_datasetdependent'); + } + return $errors; + } + + } ?> \ No newline at end of file