public function import_from_xml($data, $question, qformat_xml $format, $extra = null) { global $CFG; if (!array_key_exists('@', $data)) { return false; } if (!array_key_exists('type', $data['@'])) { return false; } if ($data['@']['type'] == 'jme') { // Get common parts. $question = $format->import_headers($data); // Header parts particular to jme. $question->qtype = 'jme'; $question->jmeoptions = $format->getpath($data, array('#', 'jmeoptions', 0, '#'), $CFG->qtype_jme_options); $question->width = $format->getpath($data, array('#', 'width', 0, '#'), QTYPE_JME_APPLET_WIDTH); $question->height = $format->getpath($data, array('#', 'height', 0, '#'), QTYPE_JME_APPLET_HEIGHT); // Run through the answers. $answers = $data['#']['answer']; $anscount = 0; foreach ($answers as $answer) { $ans = $format->import_answer($answer); $question->answer[$anscount] = $ans->answer['text']; $question->fraction[$anscount] = $ans->fraction; $question->feedback[$anscount] = $ans->feedback; ++$anscount; } $format->import_hints($question, $data); return $question; } return false; }
public function export_to_xml($question, qformat_xml $format, $extra = null) { $output = ''; $output .= ' <shuffleanswers>' . $question->options->shuffleanswers . "</shuffleanswers>\n"; $output .= $format->write_combined_feedback($question->options, $question->id, $question->contextid); foreach ($question->options->answers as $answer) { $output .= " <selectoption>\n"; $output .= $format->writetext($answer->answer, 3); $output .= " <group>{$answer->feedback}</group>\n"; $output .= " </selectoption>\n"; } return $output; }
public function import_from_xml($data, $question, qformat_xml $format, $extra = null) { $question_type = $format->getpath($data, array('@', 'type'), ''); if ($question_type != 'ordering') { return false; } $newquestion = $format->import_headers($data); $newquestion->qtype = $question_type; // fix empty or long question name $newquestion->name = $this->fix_questionname($newquestion->name, $newquestion->questiontext); // extra fields fields fields - "selecttype" and "selectcount" // (these fields used to be called "logical" and "studentsee") if (isset($data['#']['selecttype'])) { $selecttype = 'selecttype'; $selectcount = 'selectcount'; } else { $selecttype = 'logical'; $selectcount = 'studentsee'; } $selecttype = $format->getpath($data, array('#', $selecttype, 0, '#'), 'RANDOM'); $selectcount = $format->getpath($data, array('#', $selectcount, 0, '#'), 6); $this->set_count_and_type($newquestion, $selectcount, $selecttype); $newquestion->answer = array(); $newquestion->answerformat = array(); $newquestion->fraction = array(); $newquestion->feedback = array(); $newquestion->feedbackformat = array(); $i = 0; while ($answer = $format->getpath($data, array('#', 'answer', $i), '')) { if ($text = $format->getpath($answer, array('#', 'text', 0, '#'), '')) { $newquestion->answer[] = $text; $answerformat = $format->getpath($answer, array('@', 'format'), 'moodle_auto_format'); $newquestion->answerformat[] = $format->trans_format($answerformat); $newquestion->fraction[] = 1; // will be reset later in save_question_options() $newquestion->feedback[] = $format->getpath($answer, array('#', 'feedback', 0, '#', 'text', 0, '#'), ''); $feedbackformat = $format->getpath($answer, array('#', 'format', 0, '@', 'format'), 'moodle_auto_format'); $newquestion->feedbackformat[] = $format->trans_format($feedbackformat); } $i++; } return $newquestion; }
public function test_import_truefalse_wih_files() { $this->resetAfterTest(); $this->setAdminUser(); $xml = '<question type="truefalse"> <name> <text>truefalse</text> </name> <questiontext format="html"> <text><![CDATA[<p><a href="@@PLUGINFILE@@/myfolder/moodle.txt">This text file</a> contains the word Moodle.</p>]]></text> <file name="moodle.txt" path="/myfolder/" encoding="base64">TW9vZGxl</file> </questiontext> <generalfeedback format="html"> <text><![CDATA[<p>For further information, see the documentation about Moodle.</p>]]></text> </generalfeedback> <defaultgrade>1.0000000</defaultgrade> <penalty>1.0000000</penalty> <hidden>0</hidden> <answer fraction="100" format="moodle_auto_format"> <text>true</text> <feedback format="html"> <text></text> </feedback> </answer> <answer fraction="0" format="moodle_auto_format"> <text>false</text> <feedback format="html"> <text></text> </feedback> </answer> </question>'; $xmldata = xmlize($xml); $importer = new qformat_xml(); $q = $importer->import_truefalse($xmldata['question']); $draftitemid = $q->questiontextitemid; $files = file_get_drafarea_files($draftitemid, '/myfolder/'); $this->assertEquals(1, count($files->list)); $file = $files->list[0]; $this->assertEquals('moodle.txt', $file->filename); $this->assertEquals('/myfolder/', $file->filepath); $this->assertEquals(6, $file->size); }
$questiondata = $DB->get_record('question', array('id' => $questionid), '*', MUST_EXIST); get_question_options($questiondata); $question = question_bank::load_question($questionid); // Process any other URL parameters, and do require_login. list($context, $seed, $urlparams) = qtype_stack_setup_question_test_page($question); $contexts = new question_edit_contexts($context); // Check permissions. question_require_capability_on($questiondata, 'edit'); require_sesskey(); // Initialise $PAGE. $nexturl = new moodle_url('/question/type/stack/questiontestrun.php', $urlparams); $PAGE->set_url($nexturl); // Since this script always ends in a redirect. $PAGE->set_heading($COURSE->fullname); $PAGE->set_pagelayout('admin'); // Set up the export format. $qformat = new qformat_xml(); $filename = question_default_export_filename($COURSE, $questiondata) . $qformat->export_file_extension(); $qformat->setContexts($contexts->having_one_edit_tab_cap('export')); $qformat->setCourse($COURSE); $qformat->setQuestions(array($questiondata)); $qformat->setCattofile(false); $qformat->setContexttofile(false); // Do the export. if (!$qformat->exportpreprocess()) { send_file_not_found(); } if (!($content = $qformat->exportprocess(true))) { send_file_not_found(); } send_file($content, $filename, 0, 0, true, true, $qformat->mime_type());
public function import_from_xml($data, $question, qformat_xml $format, $extra = null) { if (!isset($data['@']['type']) || $data['@']['type'] != 'ddmarker') { return false; } $question = $format->import_headers($data); $question->qtype = 'ddmarker'; $question->shuffleanswers = array_key_exists('shuffleanswers', $format->getpath($data, array('#'), array())); $question->showmisplaced = array_key_exists('showmisplaced', $format->getpath($data, array('#'), array())); $filexml = $format->getpath($data, array('#', 'file'), array()); $question->bgimage = $this->import_files_to_draft_file_area($format, $filexml); $drags = $data['#']['drag']; $question->drags = array(); foreach ($drags as $dragxml) { $dragno = $format->getpath($dragxml, array('#', 'no', 0, '#'), 0); $dragindex = $dragno - 1; $question->drags[$dragindex] = array(); $question->drags[$dragindex]['label'] = $format->getpath($dragxml, array('#', 'text', 0, '#'), '', true); $question->drags[$dragindex]['infinite'] = array_key_exists('infinite', $dragxml['#']); } $drops = $data['#']['drop']; $question->drops = array(); foreach ($drops as $dropxml) { $dropno = $format->getpath($dropxml, array('#', 'no', 0, '#'), 0); $dropindex = $dropno - 1; $question->drops[$dropindex] = array(); $question->drops[$dropindex]['choice'] = $format->getpath($dropxml, array('#', 'choice', 0, '#'), 0); $question->drops[$dropindex]['shape'] = $format->getpath($dropxml, array('#', 'shape', 0, '#'), ''); $question->drops[$dropindex]['coords'] = $format->getpath($dropxml, array('#', 'coords', 0, '#'), ''); } $format->import_combined_feedback($question, $data, true); $format->import_hints($question, $data, true, true, $format->get_format($question->questiontextformat)); return $question; }
/** * Exports the question to Moodle XML format. * * @param object $question question to be exported into XML format * @param qformat_xml $format format class exporting the question * @param object $extra extra information (not required for exporting this question in this format) * @return string containing the question data in XML format */ public function export_to_xml($question, qformat_xml $format, $extra = null) { $expout = ''; $expout .= $format->write_combined_feedback($question->options, $question->id, $question->contextid); $extraquestionfields = $this->extra_question_fields(); array_shift($extraquestionfields); foreach ($extraquestionfields as $extra) { $expout .= " <{$extra}>" . $question->options->{$extra} . "</{$extra}>\n"; } return $expout; }
public function export_to_xml($question, qformat_xml $format, $extra=null) { $extraquestionfields = $this->extra_question_fields(); if (!is_array($extraquestionfields)) { return false; } // Omit table name. array_shift($extraquestionfields); $expout=''; foreach ($extraquestionfields as $field) { $exportedvalue = $format->xml_escape($question->options->$field); $expout .= " <$field>{$exportedvalue}</$field>\n"; } $extraanswersfields = $this->extra_answer_fields(); if (is_array($extraanswersfields)) { array_shift($extraanswersfields); } foreach ($question->options->answers as $answer) { $extra = ''; if (is_array($extraanswersfields)) { foreach ($extraanswersfields as $field) { $exportedvalue = $format->xml_escape($answer->$field); $extra .= " <{$field}>{$exportedvalue}</{$field}>\n"; } } $expout .= $format->write_answer($answer, $extra); } return $expout; }
public function import_from_xml($data, $question, qformat_xml $format, $extra = null) { if (!isset($data['@']['type']) || $data['@']['type'] != 'ddimageortext') { return false; } $question = $format->import_headers($data); $question->qtype = 'ddimageortext'; $question->shuffleanswers = array_key_exists('shuffleanswers', $format->getpath($data, array('#'), array())); $filexml = $format->getpath($data, array('#', 'file'), array()); $question->bgimage = $format->import_files_as_draft($filexml); $drags = $data['#']['drag']; $question->drags = array(); foreach ($drags as $dragxml) { $dragno = $format->getpath($dragxml, array('#', 'no', 0, '#'), 0); $dragindex = $dragno - 1; $question->drags[$dragindex] = array(); $question->draglabel[$dragindex] = $format->getpath($dragxml, array('#', 'text', 0, '#'), '', true); $question->drags[$dragindex]['infinite'] = array_key_exists('infinite', $dragxml['#']); $question->drags[$dragindex]['draggroup'] = $format->getpath($dragxml, array('#', 'draggroup', 0, '#'), 1); $filexml = $format->getpath($dragxml, array('#', 'file'), array()); $question->dragitem[$dragindex] = $format->import_files_as_draft($filexml); if (count($filexml)) { $question->drags[$dragindex]['dragitemtype'] = 'image'; } else { $question->drags[$dragindex]['dragitemtype'] = 'word'; } } $drops = $data['#']['drop']; $question->drops = array(); foreach ($drops as $dropxml) { $dropno = $format->getpath($dropxml, array('#', 'no', 0, '#'), 0); $dropindex = $dropno - 1; $question->drops[$dropindex] = array(); $question->drops[$dropindex]['choice'] = $format->getpath($dropxml, array('#', 'choice', 0, '#'), 0); $question->drops[$dropindex]['droplabel'] = $format->getpath($dropxml, array('#', 'text', 0, '#'), '', true); $question->drops[$dropindex]['xleft'] = $format->getpath($dropxml, array('#', 'xleft', 0, '#'), ''); $question->drops[$dropindex]['ytop'] = $format->getpath($dropxml, array('#', 'ytop', 0, '#'), ''); } $format->import_combined_feedback($question, $data, true); $format->import_hints($question, $data, true, false, $format->get_format($question->questiontextformat)); return $question; }
/** * Provide import functionality for xml format * @param data mixed the segment of data containing the question * @param question object question object processed (so far) by standard import code * @param format object the format object so that helper methods can be used (in particular error()) * @param extra mixed any additional format specific data that may be passed by the format (see format code for info) * @return object question object suitable for save_options() call or false if cannot handle */ public function import_from_xml($data, $question, qformat_xml $format, $extra = null) { // Check question is for us. if (!isset($data['@']['type']) || $data['@']['type'] != 'multichoiceset') { return false; } $question = $format->import_headers($data); $question->qtype = 'multichoiceset'; $question->shuffleanswers = $format->trans_single($format->getpath($data, array('#', 'shuffleanswers', 0, '#'), 1)); $question->answernumbering = $format->getpath($data, array('#', 'answernumbering', 0, '#'), 'abc'); $question->correctfeedback = array(); $question->correctfeedback['text'] = $format->getpath($data, array('#', 'correctfeedback', 0, '#', 'text', 0, '#'), '', true); $question->correctfeedback['format'] = $format->trans_format($format->getpath($data, array('#', 'correctfeedback', 0, '@', 'format'), $format->get_format($question->questiontextformat))); $question->correctfeedback['files'] = array(); // Restore files in correctfeedback. $files = $format->getpath($data, array('#', 'correctfeedback', 0, '#', 'file'), array(), false); foreach ($files as $file) { $filesdata = new stdclass(); $filesdata->content = $file['#']; $filesdata->encoding = $file['@']['encoding']; $filesdata->name = $file['@']['name']; $question->correctfeedback['files'][] = $filesdata; } $question->incorrectfeedback = array(); $question->incorrectfeedback['text'] = $format->getpath($data, array('#', 'incorrectfeedback', 0, '#', 'text', 0, '#'), '', true); $question->incorrectfeedback['format'] = $format->trans_format($format->getpath($data, array('#', 'incorrectfeedback', 0, '@', 'format'), $format->get_format($question->questiontextformat))); $question->incorrectfeedback['files'] = array(); // Restore files in incorrectfeedback. $files = $format->getpath($data, array('#', 'incorrectfeedback', 0, '#', 'file'), array(), false); foreach ($files as $file) { $filesdata = new stdclass(); $filesdata->content = $file['#']; $filesdata->encoding = $file['@']['encoding']; $filesdata->name = $file['@']['name']; $question->incorrectfeedback['files'][] = $filesdata; } $question->shownumcorrect = array_key_exists('shownumcorrect', $data['#']); // Run through the answers. $answers = $data['#']['answer']; foreach ($answers as $answer) { $ans = $format->import_answer($answer, true, $format->get_format($question->questiontextformat)); $question->answer[] = $ans->answer; $question->correctanswer[] = !empty($ans->fraction); $question->feedback[] = $ans->feedback; // Backwards compatibility. if (array_key_exists('correctanswer', $answer['#'])) { $key = end(array_keys($question->correctanswer)); $question->correctanswer[$key] = $format->getpath($answer, array('#', 'correctanswer', 0, '#'), 0); } } $format->import_hints($question, $data, true, true, $format->get_format($question->questiontextformat)); // Get extra choicefeedback setting from each hint. if (!empty($question->hintoptions)) { foreach ($question->hintoptions as $key => $options) { $question->hintshowchoicefeedback[$key] = !empty($options); } } return $question; }
function import_from_xml($data, $question, qformat_xml $format, $extra = null) { if ($extra != null) { throw new coding_exception("coderunner:import_from_xml: unexpected 'extra' parameter"); } $questiontype = $data['@']['type']; if ($questiontype != $this->name()) { return false; } $extraquestionfields = $this->extra_question_fields(); if (!is_array($extraquestionfields)) { return false; } //omit table name array_shift($extraquestionfields); $qo = $format->import_headers($data); $qo->qtype = $questiontype; $newdefaults = array('allornothing' => 1, 'answerboxlines' => 15, 'answerboxcolumns' => 90, 'useace' => 1); foreach ($extraquestionfields as $field) { if ($field === 'pertesttemplate' && isset($data['#']['custom_template'])) { // Legacy import $qo->pertesttemplate = $format->getpath($data, array('#', 'custom_template', 0, '#'), ''); } else { $map = $this->legacy_field_name_map(); if (isset($map[$field]) && isset($data['#'][$map[$field]])) { $data['#'][$field] = $data['#'][$map[$field]]; // Map old field names to new unset($data['#'][$map[$field]]); } if (array_key_exists($field, $newdefaults)) { $default = $newdefaults[$field]; } else { $default = ''; } $qo->{$field} = $format->getpath($data, array('#', $field, 0, '#'), $default); } } $qo->isnew = true; $qo->testcases = array(); if (isset($data['#']['testcases'][0]['#']['testcase']) && is_array($data['#']['testcases'][0]['#']['testcase'])) { $testcases = $data['#']['testcases'][0]['#']['testcase']; foreach ($testcases as $testcase) { $tc = new stdClass(); $tc->testcode = $testcase['#']['testcode'][0]['#']['text'][0]['#']; $tc->stdin = $testcase['#']['stdin'][0]['#']['text'][0]['#']; if (isset($testcase['#']['output'])) { // Handle old exports $tc->expected = $testcase['#']['output'][0]['#']['text'][0]['#']; } else { $tc->expected = $testcase['#']['expected'][0]['#']['text'][0]['#']; } $tc->extra = $testcase['#']['extra'][0]['#']['text'][0]['#']; $tc->display = 'SHOW'; $tc->mark = 1.0; if (isset($testcase['@']['mark'])) { $tc->mark = floatval($testcase['@']['mark']); } if (isset($testcase['@']['hidden']) && $testcase['@']['hidden'] == "1") { $tc->display = 'HIDE'; // Handle old-style export too } if (isset($testcase['#']['display'])) { $tc->display = $testcase['#']['display'][0]['#']['text'][0]['#']; } if (isset($testcase['@']['hiderestiffail'])) { $tc->hiderestiffail = $testcase['@']['hiderestiffail'] == "1" ? 1 : 0; } else { $tc->hiderestiffail = 0; } $tc->useasexample = $testcase['@']['useasexample'] == "1" ? 1 : 0; $qo->testcases[] = $tc; } } $datafiles = $format->getpath($data, array('#', 'testcases', 0, '#', 'file'), array()); if (is_array($datafiles)) { // Seems like a non-array does occur in some versions of PHP :-/ $qo->datafiles = $format->import_files_as_draft($datafiles); } return $qo; }
public function test_export_truefalse() { $qdata = new stdClass(); $qdata->id = 12; $qdata->contextid = 0; $qdata->qtype = 'truefalse'; $qdata->name = 'True false question'; $qdata->questiontext = 'The answer is true.'; $qdata->questiontextformat = FORMAT_HTML; $qdata->generalfeedback = 'General feedback: You should have chosen true.'; $qdata->generalfeedbackformat = FORMAT_HTML; $qdata->defaultmark = 1; $qdata->length = 1; $qdata->penalty = 1; $qdata->hidden = 0; $qdata->options->answers = array( 1 => new question_answer(1, 'True', 1, 'Well done!', FORMAT_HTML), 2 => new question_answer(2, 'False', 0, 'Doh!', FORMAT_HTML), ); $qdata->options->trueanswer = 1; $qdata->options->falseanswer = 2; $exporter = new qformat_xml(); $xml = $exporter->writequestion($qdata); $expectedxml = '<!-- question: 12 --> <question type="truefalse"> <name> <text>True false question</text> </name> <questiontext format="html"> <text>The answer is true.</text> </questiontext> <generalfeedback format="html"> <text>General feedback: You should have chosen true.</text> </generalfeedback> <defaultgrade>1</defaultgrade> <penalty>1</penalty> <hidden>0</hidden> <answer fraction="100" format="plain_text"> <text>true</text> <feedback format="html"> <text>Well done!</text> </feedback> </answer> <answer fraction="0" format="plain_text"> <text>false</text> <feedback format="html"> <text>Doh!</text> </feedback> </answer> </question> '; $this->assert_same_xml($expectedxml, $xml); }
public function ximport_from_xml($data, $question, qformat_xml $format, $extra = null) { $question_type = "poodllrecording"; $extraquestionfields = $this->extra_question_fields(); if (!is_array($extraquestionfields)) { return false; } //omit table name array_shift($extraquestionfields); $qo = $format->import_headers($data); $qo->qtype = $question_type; foreach ($extraquestionfields as $field) { if ($field == 'backimage') { //this probably wont work, it might save the file, but the id will not get stored in the backimage field //maybe do as we do in save_question_options above, see base 64 decode logic in questiontypebase.php import_file $qo->backimage['files'] = $format->import_files($format->getpath($question, array('#', 'backimage', '0', '#', 'file'), array())); } else { $qo->{$field} = $format->getpath($data, array('#', $field, 0, '#'), ''); } //end of if back image } //end of for each return $qo; }
public function test_xml_import() { $xml = '<!-- question: 0 --> <question type="stack"> <name> <text>test-0</text> </name> <questiontext format="html"> <text>What is $1+1$? [[input:ans1]] [[validation:ans1]]</text> </questiontext> <generalfeedback format="html"> <text></text> </generalfeedback> <defaultgrade>1</defaultgrade> <penalty>0.3333333</penalty> <hidden>0</hidden> <questionvariables> <text></text> </questionvariables> <specificfeedback format="html"> <text>[[feedback:firsttree]]</text> </specificfeedback> <questionnote> <text></text> </questionnote> <questionsimplify>1</questionsimplify> <assumepositive>0</assumepositive> <prtcorrect format="html"> <text><![CDATA[<p>Correct answer, well done.</p>]]></text> </prtcorrect> <prtpartiallycorrect format="html"> <text><![CDATA[<p>Your answer is partially correct.</p>]]></text> </prtpartiallycorrect> <prtincorrect format="html"> <text><![CDATA[<p>Incorrect answer.</p>]]></text> </prtincorrect> <multiplicationsign>dot</multiplicationsign> <sqrtsign>1</sqrtsign> <complexno>i</complexno> <inversetrig>cos-1</inversetrig> <matrixparens>[</matrixparens> <variantsselectionseed></variantsselectionseed> <input> <name>ans1</name> <type>algebraic</type> <tans>2</tans> <boxsize>5</boxsize> <strictsyntax>1</strictsyntax> <insertstars>0</insertstars> <syntaxhint></syntaxhint> <forbidwords></forbidwords> <allowwords></allowwords> <forbidfloat>1</forbidfloat> <requirelowestterms>0</requirelowestterms> <checkanswertype>0</checkanswertype> <mustverify>1</mustverify> <showvalidation>1</showvalidation> <options></options> </input> <prt> <name>firsttree</name> <value>1</value> <autosimplify>1</autosimplify> <feedbackvariables> <text></text> </feedbackvariables> <node> <name>0</name> <answertest>EqualComAss</answertest> <sans>ans1</sans> <tans>2</tans> <testoptions></testoptions> <quiet>0</quiet> <truescoremode>=</truescoremode> <truescore>1</truescore> <truepenalty>0</truepenalty> <truenextnode>-1</truenextnode> <trueanswernote>firsttree-1-T</trueanswernote> <truefeedback format="html"> <text></text> </truefeedback> <falsescoremode>=</falsescoremode> <falsescore>0</falsescore> <falsepenalty>0</falsepenalty> <falsenextnode>-1</falsenextnode> <falseanswernote>firsttree-1-F</falseanswernote> <falsefeedback format="html"> <text></text> </falsefeedback> </node> </prt> <deployedseed>12345</deployedseed> <qtest> <testcase>1</testcase> <testinput> <name>ans1</name> <value>2</value> </testinput> <expected> <name>firsttree</name> <expectedscore>1</expectedscore> <expectedpenalty>0</expectedpenalty> <expectedanswernote>firsttree-1-T</expectedanswernote> </expected> </qtest> </question> '; $xmldata = xmlize($xml); $importer = new qformat_xml(); $q = $importer->try_importing_using_qtypes($xmldata['question'], null, null, 'stack'); $expectedq = new stdClass(); $expectedq->qtype = 'stack'; $expectedq->name = 'test-0'; $expectedq->questiontext = 'What is $1+1$? [[input:ans1]] [[validation:ans1]]'; $expectedq->questiontextformat = FORMAT_HTML; $expectedq->generalfeedback = ''; $expectedq->generalfeedbackformat = FORMAT_HTML; $expectedq->defaultmark = 1; $expectedq->length = 1; $expectedq->penalty = 0.3333333; $expectedq->questionvariables = ''; $expectedq->specificfeedback = array('text' => '[[feedback:firsttree]]', 'format' => FORMAT_HTML, 'files' => array()); $expectedq->questionnote = ''; $expectedq->questionsimplify = 1; $expectedq->assumepositive = 0; $expectedq->prtcorrect = array('text' => '<p>Correct answer, well done.</p>', 'format' => FORMAT_HTML, 'files' => array()); $expectedq->prtpartiallycorrect = array('text' => '<p>Your answer is partially correct.</p>', 'format' => FORMAT_HTML, 'files' => array()); $expectedq->prtincorrect = array('text' => '<p>Incorrect answer.</p>', 'format' => FORMAT_HTML, 'files' => array()); $expectedq->multiplicationsign = 'dot'; $expectedq->sqrtsign = 1; $expectedq->complexno = 'i'; $expectedq->inversetrig = 'cos-1'; $expectedq->matrixparens = '['; $expectedq->variantsselectionseed = ''; $expectedq->ans1type = 'algebraic'; $expectedq->ans1modelans = 2; $expectedq->ans1boxsize = 5; $expectedq->ans1strictsyntax = 1; $expectedq->ans1insertstars = 0; $expectedq->ans1syntaxhint = ''; $expectedq->ans1forbidwords = ''; $expectedq->ans1allowwords = ''; $expectedq->ans1forbidfloat = 1; $expectedq->ans1requirelowestterms = 0; $expectedq->ans1checkanswertype = 0; $expectedq->ans1mustverify = 1; $expectedq->ans1showvalidation = 1; $expectedq->ans1options = ''; $expectedq->firsttreevalue = 1; $expectedq->firsttreeautosimplify = 1; $expectedq->firsttreefeedbackvariables = ''; $expectedq->firsttreeanswertest[0] = 'EqualComAss'; $expectedq->firsttreesans[0] = 'ans1'; $expectedq->firsttreetans[0] = '2'; $expectedq->firsttreetestoptions[0] = ''; $expectedq->firsttreequiet[0] = 0; $expectedq->firsttreetruescoremode[0] = '='; $expectedq->firsttreetruescore[0] = 1; $expectedq->firsttreetruepenalty[0] = 0; $expectedq->firsttreetruenextnode[0] = -1; $expectedq->firsttreetrueanswernote[0] = 'firsttree-1-T'; $expectedq->firsttreetruefeedback[0] = array('text' => '', 'format' => FORMAT_HTML, 'files' => array()); $expectedq->firsttreefalsescoremode[0] = '='; $expectedq->firsttreefalsescore[0] = 0; $expectedq->firsttreefalsepenalty[0] = 0; $expectedq->firsttreefalsenextnode[0] = -1; $expectedq->firsttreefalseanswernote[0] = 'firsttree-1-F'; $expectedq->firsttreefalsefeedback[0] = array('text' => '', 'format' => FORMAT_HTML, 'files' => array()); $expectedq->deployedseeds = array('12345'); $qtest = new stack_question_test(array('ans1' => '2')); $qtest->add_expected_result('firsttree', new stack_potentialresponse_tree_state(1, true, 1, 0, '', array('firsttree-1-T'))); $expectedq->testcases[1] = $qtest; $this->assert(new question_check_specified_fields_expectation($expectedq), $q); $this->assertEquals($expectedq->deployedseeds, $q->deployedseeds); // Redundant, but gives better fail messages. $this->assertEquals($expectedq->testcases, $q->testcases); // Redundant, but gives better fail messages. }
function wrsqz_import_from_xml($questionType, $dbType, &$data, &$question, &$format, &$extra) { if (isset($data['@']['type']) && $data['@']['type'] == $questionType . 'wiris') { $qfxml = new qformat_xml(); if ($questionType == 'essay') { $question = $qfxml->import_essay($data); }else if ($questionType == 'match') { $question = $qfxml->import_matching($data); }else if ($questionType == 'multichoice') { $question = $qfxml->import_multichoice($data); }else if ($questionType == 'truefalse') { $question = $qfxml->import_truefalse($data); }else if ($questionType == 'shortanswer') { $question = $qfxml->import_shortanswer($data); }else if ($questionType == 'multianswer') { $questiontext = $data['#']['wirisquestiontext'][0]['#']['text']; $container = new stdClass; $container->questiontext = $qfxml->import_text($questiontext); $question = wrsqz_qtype_multianswer_extract_question($container); $question->course = $qfxml->course; $question->generalfeedback = $qfxml->getpath($data, array('#','generalfeedback',0,'#','text',0,'#'), '', true ); $question->name = $qfxml->import_text( $data['#']['name'][0]['#']['text'] ); } unset($qfxml); $question->qtype = $questionType . 'wiris'; $program = wrsqz_mathmlDecode($format->getpath($data, array('#', 'wirisquestion', 0, '#'), 0)); $imported = wrsqz_importCASSession($program); if($imported===false) return false; $question->hiddenCASValue = $imported[0]; $translation = $imported[1]; if ($questionType == 'shortanswer') { mb_parse_str($format->getpath($data, array('#', 'wiriseditor', 0, '#'), 0), $eqoptionArray); $question->wirisEditor = (isset($eqoptionArray['editor']) && $eqoptionArray['editor'] == 'true') ? 'editor=true' : ''; $question->multipleAnswers = (isset($eqoptionArray['multipleAnswers']) && $eqoptionArray['multipleAnswers'] == 'true') ? 'multipleAnswers=true' : ''; $question->wirisCASForComputations = (isset($eqoptionArray['wirisCASForComputations']) && $eqoptionArray['wirisCASForComputations'] == 'true') ? 'wirisCASForComputations=true' : ''; if(isset($eqoptionArray['testFunctionName'])){ foreach ($eqoptionArray['testFunctionName'] as $index => $functionName){ if(!empty($functionName)){ $question->testFunctionName[$index]=$functionName; } } } }else if ($questionType == 'multichoice') { $question->gradeOverride = explode(';', $format->getpath($data, array('#', 'wirisoverrideanswer', 0, '#'), 0)); }else if ($questionType == 'truefalse') { $question->wirisAnswer = $format->getpath($data, array('#', 'wirisoverrideanswer', 0, '#'), 0); }else if ($questionType == 'multianswer'){ //mb_parse_str($format->getpath($data, array('#', 'wiriseditor', 0, '#'), 0), $eqoptionArray); //$question->wirisEditor = (isset($eqoptionArray['editor']) && $eqoptionArray['editor'] == 'true') ? 'editor=true' : ''; } $options = $format->getpath($data, array('#', 'wirisoptions',0,'#'), array()); $question->wirisCASForComputations = $format->getpath($options, array('wirisCASForComputations',0,'#'),0); //TODO: translate cas if needed. $question->hiddenInitialCASValue = wrsqz_mathmlDecode($format->getpath($options, array('hiddenInitialCASValue',0,'#'),0)); if(!empty($translation)){ wrsqz_replaceVarReferencesInFlatQuestion($questionType, $question, $translation); } return $question; } return false; }
function import_from_xml($data, $question, qformat_xml $format, $extra = null) { // check question is for us/// $qtype = $data['@']['type']; if ($qtype == 'regexp') { $qo = $format->import_headers($data); // header parts particular to regexp $qo->qtype = "regexp"; $qo->usehint = 0; // get usehint $qo->usehint = $format->getpath($data, array('#', 'usehint', 0, '#'), $qo->usehint); // get usecase $qo->usecase = $format->getpath($data, array('#', 'usecase', 0, '#'), $qo->usecase); // get studentshowalternate $qo->studentshowalternate = $format->getpath($data, array('#', 'studentshowalternate', 0, '#'), $qo->studentshowalternate); // run through the answers $answers = $data['#']['answer']; $a_count = 0; foreach ($answers as $answer) { $ans = $format->import_answer($answer); $qo->answer[$a_count] = $ans->answer['text']; $qo->fraction[$a_count] = $ans->fraction; $qo->feedback[$a_count] = $ans->feedback; ++$a_count; } return $qo; } else { return false; } }
public function execute() { global $DB, $CFG; require_once $CFG->dirroot . '/question/editlib.php'; require_once $CFG->dirroot . '/question/import_form.php'; require_once $CFG->dirroot . '/question/format.php'; $arguments = $this->arguments; $this->checkFileArg($arguments[0]); $file = $arguments[0]; $quiz = $arguments[1]; $quiz = $DB->get_record('quiz', array('id' => $quiz), '*', MUST_EXIST); $course = $DB->get_record('course', array('id' => $quiz->course), '*', MUST_EXIST); $coursecontext = \context_course::instance($course->id); $coursemodule = get_coursemodule_from_instance('quiz', $quiz->id); $quizcontext = \context_module::instance($coursemodule->id, MUST_EXIST); // Use existing questions category for quiz. $category = $DB->get_record('question_categories', array('contextid' => $coursecontext->id)); //$category = $DB->get_record("question_categories", array('id' => $category),MUST_EXIST); $formatfile = $CFG->dirroot . '/question/format/xml/format.php'; if (!is_readable($formatfile)) { throw new moodle_exception('formatnotfound', 'question', '', 'xml'); } require_once $formatfile; $qformat = new \qformat_xml(); // load data into class $qformat->setCategory($category); $qformat->setContexts(array($quizcontext)); $qformat->setCourse($course); $qformat->setFilename($file); $qformat->setRealfilename($file); $qformat->setMatchgrades('nearest'); $qformat->setStoponerror(true); // Do anything before that we need to if (!$qformat->importpreprocess()) { print_error('cannotimport', ''); } // Process the uploaded file if (!$qformat->importprocess($category)) { print_error('cannotimport', ''); } // In case anything needs to be done after if (!$qformat->importpostprocess()) { print_error('cannotimport', ''); } }
/** * Helper method used by {@link export_to_xml()}. Handle the data for one question text. * @param array $xml the bit of the XML representing one question text. * @param qformat_xml $format the importer/exporter object. * @return stack_question_test the question test. */ protected function import_xml_qtest($xml, qformat_xml $format) { $number = $format->getpath($xml, array('#', 'testcase', 0, '#'), null, false, 'Missing testcase number in the XML.'); $inputs = array(); if (isset($xml['#']['testinput'])) { foreach ($xml['#']['testinput'] as $inputxml) { $name = $format->getpath($inputxml, array('#', 'name', 0, '#'), ''); $value = $format->getpath($inputxml, array('#', 'value', 0, '#'), ''); $inputs[$name] = $value; } } $testcase = new stack_question_test($inputs); if (isset($xml['#']['expected'])) { foreach ($xml['#']['expected'] as $expectedxml) { $name = $format->getpath($expectedxml, array('#', 'name', 0, '#'), ''); $expectedscore = $format->getpath($expectedxml, array('#', 'expectedscore', 0, '#'), ''); $expectedpenalty = $format->getpath($expectedxml, array('#', 'expectedpenalty', 0, '#'), ''); $expectedanswernote = $format->getpath($expectedxml, array('#', 'expectedanswernote', 0, '#'), ''); $testcase->add_expected_result($name, new stack_potentialresponse_tree_state(1, true, $expectedscore, $expectedpenalty, '', array($expectedanswernote))); } } return array($number, $testcase); }
public function import_from_xml($data, $question, qformat_xml $format, $extra = null) { global $CFG; $question_type = "poodllrecording"; //omit table name $qo = $format->import_headers($data); $qo->qtype = $question_type; $q = $data; $qo->responseformat = $format->getpath($q, array('#', 'responseformat', 0, '#'), 'picture'); $qo->responsefieldlines = $format->getpath($q, array('#', 'responsefieldlines', 0, '#'), 15); $qo->attachments = $format->getpath($q, array('#', 'attachments', 0, '#'), 0); //older versions handled files diff. SeeM DL-39-57 if ($CFG->version < 2013051400) { $qo->graderinfo['text'] = $format->getpath($q, array('#', 'graderinfo', 0, '#', 'text', 0, '#'), '', true); $qo->graderinfo['format'] = $format->trans_format($format->getpath($q, array('#', 'graderinfo', 0, '@', 'format'), $format->get_format($qo->questiontextformat))); $qo->graderinfo['files'] = $format->import_files($format->getpath($q, array('#', 'graderinfo', '0', '#', 'file'), array())); $qo->backimage = $format->import_files($format->getpath($q, array('#', 'backimage', '0', '#', 'file'), array())); } else { $qo->graderinfo = $format->import_text_with_files($q, array('#', 'graderinfo', 0), '', $qo->questiontextformat); $qo->backimage = $format->import_files_as_draft($format->getpath($q, array('#', 'backimage', '0', '#', 'file'), array())); } $qo->boardsize = $format->getpath($q, array('#', 'boardsize', 0, '#'), '320x320'); $qo->timelimit = $format->getpath($q, array('#', 'timelimit', 0, '#'), 0); return $qo; }
public function export_to_xml($question, qformat_xml $format, $extra = null) { $output = ''; $output .= ' <shuffleanswers>' . $question->options->shuffleanswers . "</shuffleanswers>\n"; $output .= $format->write_combined_feedback($question->options, $question->id, $question->contextid); foreach ($question->options->answers as $answer) { $options = unserialize($answer->feedback); $output .= " <dragbox>\n"; $output .= $format->writetext($answer->answer, 3); $output .= " <group>{$options->draggroup}</group>\n"; if ($options->infinite) { $output .= " <infinite/>\n"; } $output .= " </dragbox>\n"; } return $output; }
/** * Create a draft files area, import files into it and return the draft item id. * @param qformat_xml $format * @param array $xml an array of <file> nodes from the the parsed XML. * @return integer draftitemid */ public function import_files_to_draft_file_area($format, $xml) { global $USER; $fs = get_file_storage(); $files = $format->import_files($xml); $usercontext = get_context_instance(CONTEXT_USER, $USER->id); $draftitemid = file_get_unused_draft_itemid(); foreach ($files as $file) { $record = new stdClass(); $record->contextid = $usercontext->id; $record->component = 'user'; $record->filearea = 'draft'; $record->itemid = $draftitemid; $record->filename = $file->name; $record->filepath = '/'; $fs->create_file_from_string($record, $this->decode_file($file)); } return $draftitemid; }
public function test_export_multianswer() { $qdata = test_question_maker::get_question_data('multianswer', 'twosubq'); $exporter = new qformat_xml(); $xml = $exporter->writequestion($qdata); $expectedxml = '<!-- question: 0 --> <question type="cloze"> <name> <text>Simple multianswer</text> </name> <questiontext format="html"> <text><![CDATA[Complete this opening line of verse: "The {1:SHORTANSWER:Dog#Wrong, silly!~=Owl#Well done!~*#Wrong answer} and the {1:MULTICHOICE:Bow-wow#You seem to have a dog obsessions!~Wiggly worm#Now you are just being ridiculous!~=Pussy-cat#Well done!} went to sea".]]></text> </questiontext> <generalfeedback format="html"> <text><![CDATA[General feedback: It\'s from "The Owl and the Pussy-cat" by Lear: "The owl and the pussycat went to sea]]></text> </generalfeedback> <penalty>0.3333333</penalty> <hidden>0</hidden> <hint format="html"> <text>Hint 1</text> </hint> <hint format="html"> <text>Hint 2</text> </hint> </question> '; $this->assert_same_xml($expectedxml, $xml); }
function load_questions($category, $importfilename, $contextid) { // Load all the questions from the given import file into the given category // The category from the import file will be ignored if present. global $COURSE; $qformat = new qformat_xml(); $qformat->setCategory($category); $systemcontext = context::instance_by_id($contextid); $contexts = new question_edit_contexts($systemcontext); $qformat->setContexts($contexts->having_one_edit_tab_cap('import')); $qformat->setCourse($COURSE); $qformat->setFilename($importfilename); $qformat->setRealfilename($importfilename); $qformat->setMatchgrades('error'); $qformat->setCatfromfile(false); $qformat->setContextfromfile(false); $qformat->setStoponerror(true); // Do anything before that we need to if (!$qformat->importpreprocess()) { throw new coding_exception('Upgrade failed: error preprocessing prototype upload'); } // Process the given file if (!$qformat->importprocess($category)) { throw new coding_exception('Upgrade failed: error uploading prototype questions'); } // In case anything needs to be done after if (!$qformat->importpostprocess()) { throw new coding_exception('Upgrade failed: error postprocessing prototype upload'); } }
/** * Provide import functionality for xml format * @param $xml mixed the segment of data containing the question * @param $fromform object question object processed (so far) by standard import code * @param $format object the format object so that helper methods can be used (in particular error() ) * @param $extra mixed any additional format specific data that may be passed by the format (see format code for info) * @return object question object suitable for save_options() call or false if cannot handle */ public function import_from_xml($xml, $fromform, qformat_xml $format, $extra = null) { // Check question is for us. $qtype = $xml['@']['type']; if ($qtype == 'ddmatch') { $fromform = $format->import_headers($xml); // Header parts particular to ddmatch qtype. $fromform->qtype = $this->name(); $fromform->shuffleanswers = $format->getpath($xml, array('#', 'shuffleanswers', 0, '#'), 1); // Run through subquestions. $fromform->subquestions = array(); $fromform->subanswers = array(); foreach ($xml['#']['subquestion'] as $subqxml) { $fromform->subquestions[] = $format->import_text_with_files($subqxml, array(), '', $format->get_format($fromform->questiontextformat)); $answers = $format->getpath($subqxml, array('#', 'answer', 0), array()); $fromform->subanswers[] = $format->import_text_with_files($answers, array(), '', $format->get_format($fromform->questiontextformat)); } $format->import_combined_feedback($fromform, $xml, true); $format->import_hints($fromform, $xml, true); return $fromform; } else { return false; } }
public function test_xml_export() { $qdata = new stdClass(); $qdata->id = 123; $qdata->contextid = 0; $qdata->qtype = 'ddwtos'; $qdata->name = 'A drag-and-drop question'; $qdata->questiontext = 'Put these in order: [[1]], [[2]], [[3]].'; $qdata->questiontextformat = FORMAT_MOODLE; $qdata->generalfeedback = 'The answer is Alpha, Beta, Gamma.'; $qdata->generalfeedbackformat = FORMAT_MOODLE; $qdata->defaultmark = 3; $qdata->length = 1; $qdata->penalty = 0.3333333; $qdata->hidden = 0; $qdata->options = new stdClass(); $qdata->options->shuffleanswers = 1; $qdata->options->correctfeedback = '<p>Your answer is correct.</p>'; $qdata->options->correctfeedbackformat = FORMAT_MOODLE; $qdata->options->partiallycorrectfeedback = '<p>Your answer is partially correct.</p>'; $qdata->options->partiallycorrectfeedbackformat = FORMAT_MOODLE; $qdata->options->shownumcorrect = 1; $qdata->options->incorrectfeedback = '<p>Your answer is incorrect.</p>'; $qdata->options->incorrectfeedbackformat = FORMAT_MOODLE; $qdata->options->answers = array(13 => new question_answer(13, 'Alpha', 0, 'O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";b:0;}', FORMAT_MOODLE), 14 => new question_answer(14, 'Beta', 0, 'O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";b:0;}', FORMAT_MOODLE), 15 => new question_answer(15, 'Gamma', 0, 'O:8:"stdClass":2:{s:9:"draggroup";s:1:"1";s:8:"infinite";b:1;}', FORMAT_MOODLE)); $qdata->hints = array(1 => new question_hint_with_parts(1, 'Try again.', FORMAT_MOODLE, true, false), 2 => new question_hint_with_parts(2, 'These are the first three letters of the Greek alphabet.', FORMAT_MOODLE, true, true)); $exporter = new qformat_xml(); $xml = $exporter->writequestion($qdata); $expectedxml = '<!-- question: 123 --> <question type="ddwtos"> <name> <text>A drag-and-drop question</text> </name> <questiontext format="moodle_auto_format"> <text>Put these in order: [[1]], [[2]], [[3]].</text> </questiontext> <generalfeedback format="moodle_auto_format"> <text>The answer is Alpha, Beta, Gamma.</text> </generalfeedback> <defaultgrade>3</defaultgrade> <penalty>0.3333333</penalty> <hidden>0</hidden> <shuffleanswers>1</shuffleanswers> <correctfeedback format="moodle_auto_format"> <text><![CDATA[<p>Your answer is correct.</p>]]></text> </correctfeedback> <partiallycorrectfeedback format="moodle_auto_format"> <text><![CDATA[<p>Your answer is partially correct.</p>]]></text> </partiallycorrectfeedback> <incorrectfeedback format="moodle_auto_format"> <text><![CDATA[<p>Your answer is incorrect.</p>]]></text> </incorrectfeedback> <shownumcorrect/> <dragbox> <text>Alpha</text> <group>1</group> </dragbox> <dragbox> <text>Beta</text> <group>1</group> </dragbox> <dragbox> <text>Gamma</text> <group>1</group> <infinite/> </dragbox> <hint format="moodle_auto_format"> <text>Try again.</text> <shownumcorrect/> </hint> <hint format="moodle_auto_format"> <text>These are the first three letters of the Greek alphabet.</text> <shownumcorrect/> <clearwrong/> </hint> </question> '; $this->assert_same_xml($expectedxml, $xml); }
public function test_import_files_as_draft() { $this->resetAfterTest(); $this->setAdminUser(); $xml = <<<END <questiontext format="html"> <text><![CDATA[<p><a href="@@PLUGINFILE@@/moodle.txt">This text file</a> contains the word 'Moodle'.</p>]]></text> <file name="moodle.txt" encoding="base64">TW9vZGxl</file> </questiontext> END; $textxml = xmlize($xml); $qo = new stdClass(); $importer = new qformat_xml(); $draftitemid = $importer->import_files_as_draft($textxml['questiontext']['#']['file']); $files = file_get_drafarea_files($draftitemid); $this->assertEquals(1, count($files->list)); $file = $files->list[0]; $this->assertEquals('moodle.txt', $file->filename); $this->assertEquals('/', $file->filepath); $this->assertEquals(6, $file->size); }
public function test_export() { $q = $this->make_parent_and_child(); $q->qtype = $q->qtype->name(); // TODO: Why does qformat_xml expect this field to be a string?! $exporter = new qformat_xml(); $xml = $exporter->writequestion($q); $bits = preg_split("/<!-- question: [0-9]* -->/", $xml); $xml_no_line1 = $bits[1]; $expectedxml = ' <question type="coderunner"> <name> <text>Program to test prototype</text> </name> <questiontext format="html"> <text>Answer should (somehow) produce the expected answer below</text> </questiontext> <generalfeedback format="html"> <text>No feedback available for coderunner questions.</text> </generalfeedback> <defaultgrade>1</defaultgrade> <penalty>0.3333333</penalty> <hidden>0</hidden> <coderunnertype>sqr_user_prototype</coderunnertype> <prototypetype>0</prototypetype> <allornothing>1</allornothing> <penaltyregime></penaltyregime> <showsource></showsource> <answerboxlines></answerboxlines> <answerboxcolumns></answerboxcolumns> <useace>1</useace> <resultcolumns></resultcolumns> <answer></answer> <combinatortemplate></combinatortemplate> <testsplitterre></testsplitterre> <enablecombinator></enablecombinator> <pertesttemplate></pertesttemplate> <language></language> <acelang></acelang> <sandbox></sandbox> <grader></grader> <cputimelimitsecs></cputimelimitsecs> <memlimitmb></memlimitmb> <sandboxparams></sandboxparams> <templateparams></templateparams> <testcases> <testcase useasexample="0" hiderestiffail="0" mark="1.0000000" > <testcode> <text></text> </testcode> <stdin> <text></text> </stdin> <expected> <text>This is data Line 2</text> </expected> <extra> <text></text> </extra> <display> <text>SHOW</text> </display> </testcase> </testcases> </question> '; $this->assert_same_xml($expectedxml, $xml_no_line1); }