MDL-39404 Update question/format files to match codechecker standards

This commit is contained in:
Jean-Michel Vedrine 2013-04-29 10:43:45 +02:00
parent bdd045c5ec
commit d2fd7262af
31 changed files with 633 additions and 669 deletions

View File

@ -17,8 +17,7 @@
/**
* Aiken format question importer.
*
* @package qformat
* @subpackage aiken
* @package qformat_aiken
* @copyright 2003 Tom Robb <tom@robb.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@ -65,17 +64,16 @@ class qformat_aiken extends qformat_default {
foreach ($lines as $line) {
$stp = strpos($line, $endchar, 0);
$newlines = explode($endchar, $line);
$foundQ = 0;
$linescount = count($newlines);
for ($i=0; $i < $linescount; $i++) {
$nowline = trim($newlines[$i]);
// Go through the array and build an object called $question
// When done, add $question to $questions
// When done, add $question to $questions.
if (strlen($nowline) < 2) {
continue;
}
if (preg_match('/^[A-Z][).][ \t]/', $nowline)) {
// A choice. Trim off the label and space, then save
// A choice. Trim off the label and space, then save.
$question->answer[] = $this->text_field(
htmlspecialchars(trim(substr($nowline, 2)), ENT_NOQUOTES));
$question->fraction[] = 0;
@ -89,7 +87,7 @@ class qformat_aiken extends qformat_default {
$question->fraction[$rightans] = 1;
$questions[] = $question;
// Clear array for next question set
// Clear array for next question set.
$question = $this->defaultquestion();
continue;
} else {
@ -122,7 +120,7 @@ class qformat_aiken extends qformat_default {
}
public function readquestion($lines) {
//this is no longer needed but might still be called by default.php
// This is no longer needed but might still be called by default.php.
return;
}
}

View File

@ -17,8 +17,7 @@
/**
* Strings for component 'qformat_aiken', language 'en', branch 'MOODLE_20_STABLE'
*
* @package qformat
* @subpackage aiken
* @package qformat_aiken
* @copyright 2010 Helen Foster
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

View File

@ -17,8 +17,7 @@
/**
* Version information for the calculated question type.
*
* @package qformat
* @subpackage aiken
* @package qformat_aiken
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

View File

@ -91,8 +91,8 @@ class qformat_blackboard_six extends qformat_blackboard_six_base {
}
// We are importing a zip file.
// Create name for temporary directory.
$unique_code = time();
$this->tempdir = make_temp_directory('bbquiz_import/' . $unique_code);
$uniquecode = time();
$this->tempdir = make_temp_directory('bbquiz_import/' . $uniquecode);
if (is_readable($filename)) {
if (!copy($filename, $this->tempdir . '/bboard.zip')) {
$this->error(get_string('cannotcopybackup', 'question'));
@ -113,7 +113,7 @@ class qformat_blackboard_six extends qformat_blackboard_six_base {
// We starts from the root element.
$query = '//resources/resource';
$q_file = array();
$qfile = array();
$examfiles = $xpath->query($query);
foreach ($examfiles as $examfile) {
@ -126,7 +126,7 @@ class qformat_blackboard_six extends qformat_blackboard_six_base {
$fileobj->filetype = self::FILETYPE_QTI;
$fileobj->filebase = $this->tempdir;
$fileobj->text = $content;
$q_file[] = $fileobj;
$qfile[] = $fileobj;
}
}
if ($examfile->getAttribute('type') == 'assessment/x-bb-pool') {
@ -136,13 +136,13 @@ class qformat_blackboard_six extends qformat_blackboard_six_base {
if ($content = $this->get_filecontent($examfile->getAttribute('file'))) {
$fileobj->filetype = self::FILETYPE_POOL;
$fileobj->text = $content;
$q_file[] = $fileobj;
$qfile[] = $fileobj;
}
}
}
if ($q_file) {
return $q_file;
if ($qfile) {
return $qfile;
} else {
$this->error(get_string('cannotfindquestionfile', 'question'));
fulldelete($this->tempdir);

View File

@ -141,26 +141,25 @@ class qformat_blackboard_six_qti extends qformat_blackboard_six_base {
$bbsubquestions = $this->getpath($pblock,
array('#', 'flow'),
array(), false);
$sub_questions = array();
foreach ($bbsubquestions as $bbsubquestion) {
$sub_question = new stdClass();
$sub_question->ident = $this->getpath($bbsubquestion,
$subquestion = new stdClass();
$subquestion->ident = $this->getpath($bbsubquestion,
array('#', 'response_lid', 0, '@', 'ident'),
'', true);
$this->process_block($this->getpath($bbsubquestion,
array('#', 'flow', 0),
false, false), $sub_question);
false, false), $subquestion);
$bbchoices = $this->getpath($bbsubquestion,
array('#', 'response_lid', 0, '#', 'render_choice', 0,
'#', 'flow_label', 0, '#', 'response_label'),
array(), false);
$choices = array();
$this->process_choices($bbchoices, $choices);
$sub_question->choices = $choices;
$subquestion->choices = $choices;
if (!isset($block->subquestions)) {
$block->subquestions = array();
}
$block->subquestions[] = $sub_question;
$block->subquestions[] = $subquestion;
}
break;
case 'Multiple Answer':
@ -483,18 +482,18 @@ class qformat_blackboard_six_qti extends qformat_blackboard_six_base {
* @param array $feedbacks array of feedbacks suitable for a rawquestion.
*/
public function process_feedback($feedbackset, &$feedbacks) {
foreach ($feedbackset as $bb_feedback) {
foreach ($feedbackset as $bbfeedback) {
$feedback = new stdClass();
$feedback->ident = $this->getpath($bb_feedback,
$feedback->ident = $this->getpath($bbfeedback,
array('@', 'ident'), '', true);
$feedback->text = '';
if ($this->getpath($bb_feedback,
if ($this->getpath($bbfeedback,
array('#', 'flow_mat', 0), false, false)) {
$this->process_block($this->getpath($bb_feedback,
$this->process_block($this->getpath($bbfeedback,
array('#', 'flow_mat', 0), false, false), $feedback);
} else if ($this->getpath($bb_feedback,
} else if ($this->getpath($bbfeedback,
array('#', 'solution', 0, '#', 'solutionmaterial', 0, '#', 'flow_mat', 0), false, false)) {
$this->process_block($this->getpath($bb_feedback,
$this->process_block($this->getpath($bbfeedback,
array('#', 'solution', 0, '#', 'solutionmaterial', 0, '#', 'flow_mat', 0), false, false), $feedback);
}

View File

@ -51,7 +51,7 @@ class qformat_examview extends qformat_based_on_xml {
'sa' => 'shortanswer',
);
public $matching_questions = array();
public $matchingquestions = array();
public function provide_import() {
return true;
@ -87,19 +87,19 @@ class qformat_examview extends qformat_based_on_xml {
return $text;
}
public function parse_matching_groups($matching_groups) {
if (empty($matching_groups)) {
public function parse_matching_groups($matchinggroups) {
if (empty($matchinggroups)) {
return;
}
foreach ($matching_groups as $match_group) {
foreach ($matchinggroups as $matchgroup) {
$newgroup = new stdClass();
$groupname = trim($match_group['@']['name']);
$questiontext = $this->unxmlise($match_group['#']['text'][0]['#']);
$groupname = trim($matchgroup['@']['name']);
$questiontext = $this->unxmlise($matchgroup['#']['text'][0]['#']);
$newgroup->questiontext = trim($questiontext);
$newgroup->subchoices = array();
$newgroup->subquestions = array();
$newgroup->subanswers = array();
$choices = $match_group['#']['choices']['0']['#'];
$choices = $matchgroup['#']['choices']['0']['#'];
foreach ($choices as $key => $value) {
if (strpos(trim($key), 'choice-') !== false) {
$key = strtoupper(trim(str_replace('choice-', '', $key)));
@ -111,12 +111,12 @@ class qformat_examview extends qformat_based_on_xml {
}
protected function parse_ma($qrec, $groupname) {
$match_group = $this->matching_questions[$groupname];
$matchgroup = $this->matching_questions[$groupname];
$phrase = trim($this->unxmlise($qrec['text']['0']['#']));
$answer = trim($this->unxmlise($qrec['answer']['0']['#']));
$answer = strip_tags( $answer );
$match_group->mappings[$phrase] = $match_group->subchoices[$answer];
$this->matching_questions[$groupname] = $match_group;
$matchgroup->mappings[$phrase] = $matchgroup->subchoices[$answer];
$this->matching_questions[$groupname] = $matchgroup;
return null;
}
@ -125,9 +125,9 @@ class qformat_examview extends qformat_based_on_xml {
return;
}
foreach ($this->matching_questions as $match_group) {
foreach ($this->matching_questions as $matchgroup) {
$question = $this->defaultquestion();
$htmltext = s($match_group->questiontext);
$htmltext = s($matchgroup->questiontext);
$question->questiontext = $htmltext;
$question->questiontextformat = FORMAT_HTML;
$question->questiontextfiles = array();
@ -136,8 +136,8 @@ class qformat_examview extends qformat_based_on_xml {
$question = $this->add_blank_combined_feedback($question);
$question->subquestions = array();
$question->subanswers = array();
foreach ($match_group->subchoices as $subchoice) {
$fiber = array_keys ($match_group->mappings, $subchoice);
foreach ($matchgroup->subchoices as $subchoice) {
$fiber = array_keys ($matchgroup->mappings, $subchoice);
$subquestion = '';
foreach ($fiber as $subquestion) {
$question->subquestions[] = $this->text_field($subquestion);

View File

@ -17,8 +17,7 @@
/**
* GIFT format question importer/exporter.
*
* @package qformat
* @subpackage gift
* @package qformat_gift
* @copyright 2003 Paul Tsuchido Shew
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@ -75,12 +74,12 @@ class qformat_gift extends qformat_default {
}
protected function answerweightparser(&$answer) {
$answer = substr($answer, 1); // removes initial %
$end_position = strpos($answer, "%");
$answer_weight = substr($answer, 0, $end_position); // gets weight as integer
$answer_weight = $answer_weight/100; // converts to percent
$answer = substr($answer, $end_position+1); // removes comment from answer
return $answer_weight;
$answer = substr($answer, 1); // Removes initial %.
$endposition = strpos($answer, "%");
$answerweight = substr($answer, 0, $endposition); // Gets weight as integer.
$answerweight = $answerweight/100; // Converts to percent.
$answer = substr($answer, $endposition+1); // Removes comment from answer.
return $answerweight;
}
protected function commentparser($answer, $defaultformat) {
@ -111,10 +110,10 @@ class qformat_gift extends qformat_default {
}
protected function escapedchar_pre($string) {
//Replaces escaped control characters with a placeholder BEFORE processing
// Replaces escaped control characters with a placeholder BEFORE processing.
$escapedcharacters = array("\\:", "\\#", "\\=", "\\{", "\\}", "\\~", "\\n" ); //dlnsk
$placeholders = array("&&058;", "&&035;", "&&061;", "&&123;", "&&125;", "&&126;", "&&010"); //dlnsk
$escapedcharacters = array("\\:", "\\#", "\\=", "\\{", "\\}", "\\~", "\\n" );
$placeholders = array("&&058;", "&&035;", "&&061;", "&&123;", "&&125;", "&&126;", "&&010");
$string = str_replace("\\\\", "&&092;", $string);
$string = str_replace($escapedcharacters, $placeholders, $string);
@ -123,9 +122,9 @@ class qformat_gift extends qformat_default {
}
protected function escapedchar_post($string) {
//Replaces placeholders with corresponding character AFTER processing is done
$placeholders = array("&&058;", "&&035;", "&&061;", "&&123;", "&&125;", "&&126;", "&&010"); //dlnsk
$characters = array(":", "#", "=", "{", "}", "~", "\n" ); //dlnsk
// Replaces placeholders with corresponding character AFTER processing is done.
$placeholders = array("&&058;", "&&035;", "&&061;", "&&123;", "&&125;", "&&126;", "&&010");
$characters = array(":", "#", "=", "{", "}", "~", "\n" );
$string = str_replace($placeholders, $characters, $string);
return $string;
}
@ -160,15 +159,15 @@ class qformat_gift extends qformat_default {
}
public function readquestion($lines) {
// Given an array of lines known to define a question in this format, this function
// converts it into a question object suitable for processing and insertion into Moodle.
// Given an array of lines known to define a question in this format, this function
// converts it into a question object suitable for processing and insertion into Moodle.
$question = $this->defaultquestion();
$comment = NULL;
// define replaced by simple assignment, stop redefine notices
$gift_answerweight_regex = '/^%\-*([0-9]{1,2})\.?([0-9]*)%/';
$comment = null;
// Define replaced by simple assignment, stop redefine notices.
$giftanswerweightregex = '/^%\-*([0-9]{1,2})\.?([0-9]*)%/';
// REMOVED COMMENTED LINES and IMPLODE
// REMOVED COMMENTED LINES and IMPLODE.
foreach ($lines as $key => $line) {
$line = trim($line);
if (substr($line, 0, 2) == '//') {
@ -182,32 +181,31 @@ class qformat_gift extends qformat_default {
return false;
}
// Substitute escaped control characters with placeholders
// Substitute escaped control characters with placeholders.
$text = $this->escapedchar_pre($text);
// Look for category modifier
// Look for category modifier.
if (preg_match('~^\$CATEGORY:~', $text)) {
// $newcategory = $matches[1];
$newcategory = trim(substr($text, 10));
// build fake question to contain category
// Build fake question to contain category.
$question->qtype = 'category';
$question->category = $newcategory;
return $question;
}
// QUESTION NAME parser
// Question name parser.
if (substr($text, 0, 2) == '::') {
$text = substr($text, 2);
$namefinish = strpos($text, '::');
if ($namefinish === false) {
$question->name = false;
// name will be assigned after processing question text below
// Name will be assigned after processing question text below.
} else {
$questionname = substr($text, 0, $namefinish);
$question->name = $this->clean_question_name($this->escapedchar_post($questionname));
$text = trim(substr($text, $namefinish+2)); // Remove name from text
$text = trim(substr($text, $namefinish+2)); // Remove name from text.
}
} else {
$question->name = false;
@ -263,19 +261,20 @@ class qformat_gift extends qformat_default {
$question->generalfeedback = $text['text'];
$question->generalfeedbackformat = $text['format'];
// set question name if not already set
// Set question name if not already set.
if ($question->name === false) {
$question->name = $this->create_default_question_name($question->questiontext, get_string('questionname', 'question'));
}
// determine QUESTION TYPE
$question->qtype = NULL;
// Determine question type.
$question->qtype = null;
// give plugins first try
// plugins must promise not to intercept standard qtypes
// MDL-12346, this could be called from lesson mod which has its own base class =(
if (method_exists($this, 'try_importing_using_qtypes') && ($try_question = $this->try_importing_using_qtypes($lines, $question, $answertext))) {
return $try_question;
// Give plugins first try.
// Plugins must promise not to intercept standard qtypes
// MDL-12346, this could be called from lesson mod which has its own base class =(.
if (method_exists($this, 'try_importing_using_qtypes')
&& ($tryquestion = $this->try_importing_using_qtypes($lines, $question, $answertext))) {
return $tryquestion;
}
if ($description) {
@ -287,29 +286,29 @@ class qformat_gift extends qformat_default {
} else if ($answertext{0} == '#') {
$question->qtype = 'numerical';
} else if (strpos($answertext, '~') !== false) {
// only Multiplechoice questions contain tilde ~
} else if (strpos($answertext, '~') !== false) {
// Only Multiplechoice questions contain tilde ~.
$question->qtype = 'multichoice';
} else if (strpos($answertext, '=') !== false
&& strpos($answertext, '->') !== false) {
// only Matching contains both = and ->
// Only Matching contains both = and ->.
$question->qtype = 'match';
} else { // either truefalse or shortanswer
} else { // Either truefalse or shortanswer.
// truefalse question check
$truefalse_check = $answertext;
// Truefalse question check.
$truefalsecheck = $answertext;
if (strpos($answertext, '#') > 0) {
// strip comments to check for TrueFalse question
$truefalse_check = trim(substr($answertext, 0, strpos($answertext,"#")));
// Strip comments to check for TrueFalse question.
$truefalsecheck = trim(substr($answertext, 0, strpos($answertext, "#")));
}
$valid_tf_answers = array('T', 'TRUE', 'F', 'FALSE');
if (in_array($truefalse_check, $valid_tf_answers)) {
$validtfanswers = array('T', 'TRUE', 'F', 'FALSE');
if (in_array($truefalsecheck, $validtfanswers)) {
$question->qtype = 'truefalse';
} else { // Must be shortanswer
} else { // Must be shortanswer.
$question->qtype = 'shortanswer';
}
}
@ -337,10 +336,10 @@ class qformat_gift extends qformat_default {
return $question;
case 'multichoice':
if (strpos($answertext,"=") === false) {
$question->single = 0; // multiple answers are enabled if no single answer is 100% correct
if (strpos($answertext, "=") === false) {
$question->single = 0; // Multiple answers are enabled if no single answer is 100% correct.
} else {
$question->single = 1; // only one answer allowed (the default)
$question->single = 1; // Only one answer allowed (the default).
}
$question = $this->add_blank_combined_feedback($question);
@ -362,21 +361,21 @@ class qformat_gift extends qformat_default {
foreach ($answers as $key => $answer) {
$answer = trim($answer);
// determine answer weight
// Determine answer weight.
if ($answer[0] == '=') {
$answer_weight = 1;
$answerweight = 1;
$answer = substr($answer, 1);
} else if (preg_match($gift_answerweight_regex, $answer)) { // check for properly formatted answer weight
$answer_weight = $this->answerweightparser($answer);
} else if (preg_match($giftanswerweightregex, $answer)) { // Check for properly formatted answer weight.
$answerweight = $this->answerweightparser($answer);
} else { //default, i.e., wrong anwer
$answer_weight = 0;
} else { // Default, i.e., wrong anwer.
$answerweight = 0;
}
list($question->answer[$key], $question->feedback[$key]) =
$this->commentparser($answer, $question->questiontextformat);
$question->fraction[$key] = $answer_weight;
} // end foreach answer
$question->fraction[$key] = $answerweight;
} // End foreach answer.
return $question;
@ -391,14 +390,14 @@ class qformat_gift extends qformat_default {
array_shift($answers);
}
if (!$this->check_answer_count(2,$answers,$text)) {
if (!$this->check_answer_count(2, $answers, $text)) {
return false;
}
foreach ($answers as $key => $answer) {
$answer = trim($answer);
if (strpos($answer, "->") === false) {
$this->error(get_string('giftmatchingformat','qformat_gift'), $answer);
$this->error(get_string('giftmatchingformat', 'qformat_gift'), $answer);
return false;
}
@ -446,25 +445,25 @@ class qformat_gift extends qformat_default {
foreach ($answers as $key => $answer) {
$answer = trim($answer);
// Answer weight
if (preg_match($gift_answerweight_regex, $answer)) { // check for properly formatted answer weight
$answer_weight = $this->answerweightparser($answer);
} else { //default, i.e., full-credit anwer
$answer_weight = 1;
// Answer weight.
if (preg_match($giftanswerweightregex, $answer)) { // Check for properly formatted answer weight.
$answerweight = $this->answerweightparser($answer);
} else { // Default, i.e., full-credit anwer.
$answerweight = 1;
}
list($answer, $question->feedback[$key]) = $this->commentparser(
$answer, $question->questiontextformat);
$question->answer[$key] = $answer['text'];
$question->fraction[$key] = $answer_weight;
$question->fraction[$key] = $answerweight;
}
return $question;
case 'numerical':
// Note similarities to ShortAnswer
$answertext = substr($answertext, 1); // remove leading "#"
// Note similarities to ShortAnswer.
$answertext = substr($answertext, 1); // Remove leading "#".
// If there is feedback for a wrong answer, store it for now.
if (($pos = strpos($answertext, '~')) !== false) {
@ -483,8 +482,8 @@ class qformat_gift extends qformat_default {
}
if (count($answers) == 0) {
// invalid question
$giftnonumericalanswers = get_string('giftnonumericalanswers','qformat_gift');
// Invalid question.
$giftnonumericalanswers = get_string('giftnonumericalanswers', 'qformat_gift');
$this->error($giftnonumericalanswers, $text);
return false;
}
@ -492,30 +491,30 @@ class qformat_gift extends qformat_default {
foreach ($answers as $key => $answer) {
$answer = trim($answer);
// Answer weight
if (preg_match($gift_answerweight_regex, $answer)) { // check for properly formatted answer weight
$answer_weight = $this->answerweightparser($answer);
} else { //default, i.e., full-credit anwer
$answer_weight = 1;
// Answer weight.
if (preg_match($giftanswerweightregex, $answer)) { // Check for properly formatted answer weight.
$answerweight = $this->answerweightparser($answer);
} else { // Default, i.e., full-credit anwer.
$answerweight = 1;
}
list($answer, $question->feedback[$key]) = $this->commentparser(
$answer, $question->questiontextformat);
$question->fraction[$key] = $answer_weight;
$question->fraction[$key] = $answerweight;
$answer = $answer['text'];
//Calculate Answer and Min/Max values
if (strpos($answer,"..") > 0) { // optional [min]..[max] format
$marker = strpos($answer,"..");
$max = trim(substr($answer, $marker+2));
// Calculate Answer and Min/Max values.
if (strpos($answer, "..") > 0) { // Optional [min]..[max] format.
$marker = strpos($answer, "..");
$max = trim(substr($answer, $marker + 2));
$min = trim(substr($answer, 0, $marker));
$ans = ($max + $min)/2;
$tol = $max - $ans;
} else if (strpos($answer, ':') > 0) { // standard [answer]:[errormargin] format
} else if (strpos($answer, ':') > 0) { // Standard [answer]:[errormargin] format.
$marker = strpos($answer, ':');
$tol = trim(substr($answer, $marker+1));
$ans = trim(substr($answer, 0, $marker));
} else { // only one valid answer (zero errormargin)
} else { // Only one valid answer (zero errormargin).
$tol = 0;
$ans = trim($answer);
}
@ -526,7 +525,7 @@ class qformat_gift extends qformat_default {
return false;
}
// store results
// Store results.
$question->answer[$key] = $ans;
$question->tolerance[$key] = $tol;
}
@ -551,9 +550,9 @@ class qformat_gift extends qformat_default {
protected function repchar($text, $notused = 0) {
// Escapes 'reserved' characters # = ~ {) :
// Removes new lines
// Removes new lines.
$reserved = array( '\\', '#', '=', '~', '{', '}', ':', "\n", "\r");
$escaped = array('\\\\', '\#','\=','\~','\{','\}','\:', '\n', '' );
$escaped = array('\\\\', '\#', '\=', '\~', '\{', '\}', '\:', '\n', '');
$newtext = str_replace($reserved, $escaped, $text);
return $newtext;
@ -632,141 +631,141 @@ class qformat_gift extends qformat_default {
public function writequestion($question) {
global $OUTPUT;
// Start with a comment
// Start with a comment.
$expout = "// question: $question->id name: $question->name\n";
// output depends on question type
// Output depends on question type.
switch($question->qtype) {
case 'category':
// not a real question, used to insert category switch
$expout .= "\$CATEGORY: $question->category\n";
break;
case 'category':
// Not a real question, used to insert category switch.
$expout .= "\$CATEGORY: $question->category\n";
break;
case 'description':
$expout .= $this->write_name($question->name);
$expout .= $this->write_questiontext($question->questiontext, $question->questiontextformat);
break;
case 'description':
$expout .= $this->write_name($question->name);
$expout .= $this->write_questiontext($question->questiontext, $question->questiontextformat);
break;
case 'essay':
$expout .= $this->write_name($question->name);
$expout .= $this->write_questiontext($question->questiontext, $question->questiontextformat);
$expout .= "{";
$expout .= $this->write_general_feedback($question, '');
$expout .= "}\n";
break;
case 'essay':
$expout .= $this->write_name($question->name);
$expout .= $this->write_questiontext($question->questiontext, $question->questiontextformat);
$expout .= "{";
$expout .= $this->write_general_feedback($question, '');
$expout .= "}\n";
break;
case 'truefalse':
$trueanswer = $question->options->answers[$question->options->trueanswer];
$falseanswer = $question->options->answers[$question->options->falseanswer];
if ($trueanswer->fraction == 1) {
$answertext = 'TRUE';
$rightfeedback = $this->write_questiontext($trueanswer->feedback,
$trueanswer->feedbackformat, $question->questiontextformat);
$wrongfeedback = $this->write_questiontext($falseanswer->feedback,
$falseanswer->feedbackformat, $question->questiontextformat);
} else {
$answertext = 'FALSE';
$rightfeedback = $this->write_questiontext($falseanswer->feedback,
$falseanswer->feedbackformat, $question->questiontextformat);
$wrongfeedback = $this->write_questiontext($trueanswer->feedback,
$trueanswer->feedbackformat, $question->questiontextformat);
}
$expout .= $this->write_name($question->name);
$expout .= $this->write_questiontext($question->questiontext, $question->questiontextformat);
$expout .= '{' . $this->repchar($answertext);
if ($wrongfeedback) {
$expout .= '#' . $wrongfeedback;
} else if ($rightfeedback) {
$expout .= '#';
}
if ($rightfeedback) {
$expout .= '#' . $rightfeedback;
}
$expout .= $this->write_general_feedback($question, '');
$expout .= "}\n";
break;
case 'multichoice':
$expout .= $this->write_name($question->name);
$expout .= $this->write_questiontext($question->questiontext, $question->questiontextformat);
$expout .= "{\n";
foreach($question->options->answers as $answer) {
if ($answer->fraction == 1) {
$answertext = '=';
} else if ($answer->fraction == 0) {
$answertext = '~';
case 'truefalse':
$trueanswer = $question->options->answers[$question->options->trueanswer];
$falseanswer = $question->options->answers[$question->options->falseanswer];
if ($trueanswer->fraction == 1) {
$answertext = 'TRUE';
$rightfeedback = $this->write_questiontext($trueanswer->feedback,
$trueanswer->feedbackformat, $question->questiontextformat);
$wrongfeedback = $this->write_questiontext($falseanswer->feedback,
$falseanswer->feedbackformat, $question->questiontextformat);
} else {
$weight = $answer->fraction * 100;
$answertext = '~%' . $weight . '%';
$answertext = 'FALSE';
$rightfeedback = $this->write_questiontext($falseanswer->feedback,
$falseanswer->feedbackformat, $question->questiontextformat);
$wrongfeedback = $this->write_questiontext($trueanswer->feedback,
$trueanswer->feedbackformat, $question->questiontextformat);
}
$expout .= "\t" . $answertext . $this->write_questiontext($answer->answer,
$answer->answerformat, $question->questiontextformat);
if ($answer->feedback != '') {
$expout .= '#' . $this->write_questiontext($answer->feedback,
$answer->feedbackformat, $question->questiontextformat);
$expout .= $this->write_name($question->name);
$expout .= $this->write_questiontext($question->questiontext, $question->questiontextformat);
$expout .= '{' . $this->repchar($answertext);
if ($wrongfeedback) {
$expout .= '#' . $wrongfeedback;
} else if ($rightfeedback) {
$expout .= '#';
}
$expout .= "\n";
}
$expout .= $this->write_general_feedback($question);
$expout .= "}\n";
break;
if ($rightfeedback) {
$expout .= '#' . $rightfeedback;
}
$expout .= $this->write_general_feedback($question, '');
$expout .= "}\n";
break;
case 'shortanswer':
$expout .= $this->write_name($question->name);
$expout .= $this->write_questiontext($question->questiontext, $question->questiontextformat);
$expout .= "{\n";
foreach($question->options->answers as $answer) {
$weight = 100 * $answer->fraction;
$expout .= "\t=%" . $weight . '%' . $this->repchar($answer->answer) .
'#' . $this->write_questiontext($answer->feedback,
$answer->feedbackformat, $question->questiontextformat) . "\n";
}
$expout .= $this->write_general_feedback($question);
$expout .= "}\n";
break;
case 'multichoice':
$expout .= $this->write_name($question->name);
$expout .= $this->write_questiontext($question->questiontext, $question->questiontextformat);
$expout .= "{\n";
foreach ($question->options->answers as $answer) {
if ($answer->fraction == 1) {
$answertext = '=';
} else if ($answer->fraction == 0) {
$answertext = '~';
} else {
$weight = $answer->fraction * 100;
$answertext = '~%' . $weight . '%';
}
$expout .= "\t" . $answertext . $this->write_questiontext($answer->answer,
$answer->answerformat, $question->questiontextformat);
if ($answer->feedback != '') {
$expout .= '#' . $this->write_questiontext($answer->feedback,
$answer->feedbackformat, $question->questiontextformat);
}
$expout .= "\n";
}
$expout .= $this->write_general_feedback($question);
$expout .= "}\n";
break;
case 'numerical':
$expout .= $this->write_name($question->name);
$expout .= $this->write_questiontext($question->questiontext, $question->questiontextformat);
$expout .= "{#\n";
foreach ($question->options->answers as $answer) {
if ($answer->answer != '' && $answer->answer != '*') {
case 'shortanswer':
$expout .= $this->write_name($question->name);
$expout .= $this->write_questiontext($question->questiontext, $question->questiontextformat);
$expout .= "{\n";
foreach ($question->options->answers as $answer) {
$weight = 100 * $answer->fraction;
$expout .= "\t=%" . $weight . '%' . $answer->answer . ':' .
(float)$answer->tolerance . '#' . $this->write_questiontext($answer->feedback,
$answer->feedbackformat, $question->questiontextformat) . "\n";
} else {
$expout .= "\t~#" . $this->write_questiontext($answer->feedback,
$answer->feedbackformat, $question->questiontextformat) . "\n";
$expout .= "\t=%" . $weight . '%' . $this->repchar($answer->answer) .
'#' . $this->write_questiontext($answer->feedback,
$answer->feedbackformat, $question->questiontextformat) . "\n";
}
}
$expout .= $this->write_general_feedback($question);
$expout .= "}\n";
break;
$expout .= $this->write_general_feedback($question);
$expout .= "}\n";
break;
case 'match':
$expout .= $this->write_name($question->name);
$expout .= $this->write_questiontext($question->questiontext, $question->questiontextformat);
$expout .= "{\n";
foreach($question->options->subquestions as $subquestion) {
$expout .= "\t=" . $this->write_questiontext($subquestion->questiontext,
$subquestion->questiontextformat, $question->questiontextformat) .
' -> ' . $this->repchar($subquestion->answertext) . "\n";
}
$expout .= $this->write_general_feedback($question);
$expout .= "}\n";
break;
case 'numerical':
$expout .= $this->write_name($question->name);
$expout .= $this->write_questiontext($question->questiontext, $question->questiontextformat);
$expout .= "{#\n";
foreach ($question->options->answers as $answer) {
if ($answer->answer != '' && $answer->answer != '*') {
$weight = 100 * $answer->fraction;
$expout .= "\t=%" . $weight . '%' . $answer->answer . ':' .
(float)$answer->tolerance . '#' . $this->write_questiontext($answer->feedback,
$answer->feedbackformat, $question->questiontextformat) . "\n";
} else {
$expout .= "\t~#" . $this->write_questiontext($answer->feedback,
$answer->feedbackformat, $question->questiontextformat) . "\n";
}
}
$expout .= $this->write_general_feedback($question);
$expout .= "}\n";
break;
default:
// Check for plugins
if ($out = $this->try_exporting_using_qtypes($question->qtype, $question)) {
$expout .= $out;
}
case 'match':
$expout .= $this->write_name($question->name);
$expout .= $this->write_questiontext($question->questiontext, $question->questiontextformat);
$expout .= "{\n";
foreach ($question->options->subquestions as $subquestion) {
$expout .= "\t=" . $this->write_questiontext($subquestion->questiontext,
$subquestion->questiontextformat, $question->questiontextformat) .
' -> ' . $this->repchar($subquestion->answertext) . "\n";
}
$expout .= $this->write_general_feedback($question);
$expout .= "}\n";
break;
default:
// Check for plugins.
if ($out = $this->try_exporting_using_qtypes($question->qtype, $question)) {
$expout .= $out;
}
}
// Add empty line to delimit questions
// Add empty line to delimit questions.
$expout .= "\n";
return $expout;
}

View File

@ -17,8 +17,7 @@
/**
* Strings for component 'qformat_gift', language 'en', branch 'MOODLE_20_STABLE'
*
* @package qformat
* @subpackage gift
* @package qformat_gift
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

View File

@ -17,8 +17,7 @@
/**
* Unit tests for the Moodle GIFT format.
*
* @package qformat
* @subpackage gift
* @package qformat_gift
* @copyright 2010 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

View File

@ -17,8 +17,7 @@
/**
* Version information for the calculated question type.
*
* @package qformat
* @subpackage gift
* @package qformat_gift
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

View File

@ -17,8 +17,7 @@
/**
* Examview question importer.
*
* @package qformat
* @subpackage learnwise
* @package qformat_learnwise
* @copyright 2005 Alton College, Hampshire, UK
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@ -54,7 +53,7 @@ class qformat_learnwise extends qformat_default {
$questions = array();
$currentquestion = array();
foreach($lines as $line) {
foreach ($lines as $line) {
$line = trim($line);
$currentquestion[] = $line;
@ -70,7 +69,7 @@ class qformat_learnwise extends qformat_default {
global $OUTPUT;
$text = implode(' ', $lines);
$text = str_replace(array('\t','\n','\r'), array('','',''), $text);
$text = str_replace(array('\t', '\n', '\r'), array('', '', ''), $text);
$startpos = strpos($text, '<question type');
$endpos = strpos($text, '</question>');
@ -79,7 +78,7 @@ class qformat_learnwise extends qformat_default {
}
preg_match("/<question type=[\"\']([^\"\']+)[\"\']>/i", $text, $matches);
$type = strtolower($matches[1]); // multichoice or multianswerchoice
$type = strtolower($matches[1]); // Multichoice or multianswerchoice.
$questiontext = textlib::entities_to_utf8($this->stringbetween($text, '<text>', '</text>'));
$questionhint = textlib::entities_to_utf8($this->stringbetween($text, '<hint>', '</hint>'));

View File

@ -17,8 +17,7 @@
/**
* Strings for component 'qformat_learnwise', language 'en', branch 'MOODLE_20_STABLE'
*
* @package qformat
* @subpackage learnwise
* @package qformat_learnwise
* @copyright 2010 Helen Foster
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

View File

@ -17,8 +17,7 @@
/**
* Version information for the calculated question type.
*
* @package qformat
* @subpackage learnwise
* @package qformat_learnwise
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

View File

@ -17,8 +17,7 @@
/**
* Missing word question importer.
*
* @package qformat
* @subpackage missingword
* @package qformat_missingword
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@ -53,20 +52,19 @@ defined('MOODLE_INTERNAL') || die();
class qformat_missingword extends qformat_default {
public function provide_import() {
return true;
return true;
}
public function readquestion($lines) {
/// Given an array of lines known to define a question in
/// this format, this function converts it into a question
/// object suitable for processing and insertion into Moodle.
// Given an array of lines known to define a question in
// this format, this function converts it into a question
// object suitable for processing and insertion into Moodle.
$question = $this->defaultquestion();
///$comment added by T Robb
$comment = NULL;
$comment = null; // Added by T Robb.
$text = implode(" ", $lines);
/// Find answer section
// Find answer section.
$answerstart = strpos($text, "{");
if ($answerstart === false) {
@ -87,7 +85,7 @@ class qformat_missingword extends qformat_default {
$question->questiontext = substr_replace($text, "_____", $answerstart, $answerlength+1);
$question->name = $this->create_default_question_name($question->questiontext, get_string('questionname', 'question'));
/// Parse the answers
// Parse the answers.
$answertext = str_replace("=", "~=", $answertext);
$answers = explode("~", $answertext);
if (isset($answers[0])) {
@ -125,40 +123,38 @@ class qformat_missingword extends qformat_default {
foreach ($answers as $key => $answer) {
$answer = trim($answer);
// Tom's addition starts here
// Tom's addition starts here.
$answeight = 0;
if (strspn($answer,"1234567890%") > 0){
//Make sure that the percent sign is the last in the span
if (strpos($answer,"%") == strspn($answer,"1234567890%") - 1) {
$answeight0 = substr($answer,0,strspn($answer,"1234567890%"));
$answeight = round(($answeight0/100),2);
$answer = substr($answer,(strspn($answer,"1234567890%")));
if (strspn($answer, "1234567890%") > 0) {
// Make sure that the percent sign is the last in the span.
if (strpos($answer, "%") == strspn($answer, "1234567890%") - 1) {
$answeight0 = substr($answer, 0, strspn($answer, "1234567890%"));
$answeight = round(($answeight0/100), 2);
$answer = substr($answer, (strspn($answer, "1234567890%")));
}
}
if ($answer[0] == "="){
if ($answer[0] == "=") {
$answeight = 1;
}
//remove the protective underscore for leading numbers in answers
if ($answer[0] == "_"){
// Remove the protective underscore for leading numbers in answers.
if ($answer[0] == "_") {
$answer = substr($answer, 1);
}
$answer = trim($answer);
if (strpos($answer,"#") > 0){
$hashpos = strpos($answer,"#");
$comment = substr(($answer),$hashpos+1);
$answer = substr($answer,0,$hashpos);
if (strpos($answer, "#") > 0) {
$hashpos = strpos($answer, "#");
$comment = substr(($answer), $hashpos+1);
$answer = substr($answer, 0, $hashpos);
} else {
$comment = " ";
}
// End of Tom's addition
// End of Tom's addition.
if ($answer[0] == "=") {
# $question->fraction[$key] = 1;
$question->fraction[$key] = $answeight;
$answer = substr($answer, 1);
} else {
# $question->fraction[$key] = 0;
$question->fraction[$key] = $answeight;
}
$question->answer[$key] = array('text' => $answer, 'format' => FORMAT_HTML);

View File

@ -17,8 +17,7 @@
/**
* Strings for component 'qformat_missingword', language 'en', branch 'MOODLE_20_STABLE'
*
* @package qformat
* @subpackage missingword
* @package qformat_missingword
* @copyright 2010 Helen Foster
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

View File

@ -17,8 +17,7 @@
/**
* Version information for the calculated question type.
*
* @package qformat
* @subpackage missingword
* @package qformat_missingword
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

View File

@ -17,8 +17,7 @@
/**
* Strings for component 'qformat_multianswer', language 'en', branch 'MOODLE_20_STABLE'
*
* @package qformat
* @subpackage multianswer
* @package qformat_multianswer
* @copyright 2010 Helen Foster
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

View File

@ -17,8 +17,7 @@
/**
* Version information for the calculated question type.
*
* @package qformat
* @subpackage multianswer
* @package qformat_multianswer
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

View File

@ -29,4 +29,3 @@ other plugin types.
$string['pluginname'] = 'Aiken format';
$string['pluginname_help'] = 'This is a simple format ...';
$string['pluginname_link'] = 'qformat/aiken';

View File

@ -1,7 +1,7 @@
- Ajouter un espace apr<70>s un symbole <= s'il pr<70>fixe une parenth<74>se ouvrante.
- G<>rer 'and', 'or', ... comme &&, ||
- Ne pas mettre de '$' sur les @param si aucun nom de variable n'esp sp<73>cifi<66>.
- Ajouter OneTrueBrace pour les if, while, for, else ... (Gustavo Carreno <gcarreno@netvisao.pt>, Richard Bateman <richard@randyb.byu.edu>, Yaroslav Shvetsov <yaro@totaldesign.ru>, Chris Small <chris@owta.net>)
- Ajouter un espace après un symbole <= s'il préfixe une parenthèse ouvrante.
- Gérer 'and', 'or', ... comme &&, ||
- Ne pas mettre de '$' sur les @param si aucun nom de variable n'est spécifié.
- Ajouter OneTrueBrace pour les if, while, for, else ... (Gustavo Carreno <gcarreno@netvisao.pt>,
Richard Bateman <richard@randyb.byu.edu>, Yaroslav Shvetsov <yaro@totaldesign.ru>, Chris Small <chris@owta.net>)
- Remove blank lines (Sergio Marchesini <smarques@tin.it>)
- Forcer une ligne vide apr<70>s une d<>claration de fonction (Richard Bateman <richard@randyb.byu.edu>)
- Forcer une ligne vide après une déclaration de fonction (Richard Bateman <richard@randyb.byu.edu>)

View File

@ -17,8 +17,7 @@
/**
* Web CT question importer.
*
* @package qformat
* @subpackage webct
* @package qformat_webct
* @copyright 2004 ASP Consulting http://www.asp-consulting.net
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@ -31,11 +30,11 @@ defined('MOODLE_INTERNAL') || die();
* @param string $string
* @return string
*/
function unhtmlentities($string){
$search = array ("'<script[?>]*?>.*?</script>'si", // remove javascript
"'<[\/\!]*?[^<?>]*?>'si", // remove HTML tags
"'([\r\n])[\s]+'", // remove spaces
"'&(quot|#34);'i", // remove HTML entites
function unhtmlentities($string) {
$search = array ("'<script[?>]*?>.*?</script>'si", // Remove javascript.
"'<[\/\!]*?[^<?>]*?>'si", // Remove HTML tags.
"'([\r\n])[\s]+'", // Remove spaces.
"'&(quot|#34);'i", // Remove HTML entites.
"'&(amp|#38);'i",
"'&(lt|#60);'i",
"'&(gt|#62);'i",
@ -44,7 +43,7 @@ function unhtmlentities($string){
"'&(cent|#162);'i",
"'&(pound|#163);'i",
"'&(copy|#169);'i",
"'&#(\d+);'e"); // Evaluate like PHP
"'&#(\d+);'e"); // Evaluate like PHP.
$replace = array ("",
"",
"\\1",
@ -67,43 +66,43 @@ function unhtmlentities($string){
*/
function qformat_webct_convert_formula($formula) {
// Remove empty space, as it would cause problems otherwise:
// Remove empty space, as it would cause problems otherwise.
$formula = str_replace(' ', '', $formula);
// Remove paranthesis after e,E and *10**:
// Remove paranthesis after e,E and *10**.
while (preg_match('~[0-9.](e|E|\\*10\\*\\*)\\([+-]?[0-9]+\\)~', $formula, $regs)) {
$formula = str_replace(
$regs[0], preg_replace('/[)(]/', '', $regs[0]), $formula);
}
// Replace *10** with e where possible
// Replace *10** with e where possible.
while (preg_match('~(^[+-]?|[^eE][+-]|[^0-9eE+-])[0-9.]+\\*10\\*\\*[+-]?[0-9]+([^0-9.eE]|$)~',
$formula, $regs)) {
$formula = str_replace(
$regs[0], str_replace('*10**', 'e', $regs[0]), $formula);
}
// Replace other 10** with 1e where possible
// Replace other 10** with 1e where possible.
while (preg_match('~(^|[^0-9.eE])10\\*\\*[+-]?[0-9]+([^0-9.eE]|$)~', $formula, $regs)) {
$formula = str_replace(
$regs[0], str_replace('10**', '1e', $regs[0]), $formula);
}
// Replace all other base**exp with the PHP equivalent function pow(base,exp)
// (Pretty tricky to exchange an operator with a function)
// (Pretty tricky to exchange an operator with a function).
while (2 == count($splits = explode('**', $formula, 2))) {
// Find $base
// Find $base.
if (preg_match('~^(.*[^0-9.eE])?(([0-9]+(\\.[0-9]*)?|\\.[0-9]+)([eE][+-]?[0-9]+)?|\\{[^}]*\\})$~',
$splits[0], $regs)) {
// The simple cases
// The simple cases.
$base = $regs[2];
$splits[0] = $regs[1];
} else if (preg_match('~\\)$~', $splits[0])) {
// Find the start of this parenthesis
// Find the start of this parenthesis.
$deep = 1;
for ($i = 1 ; $deep ; ++$i) {
for ($i = 1; $deep; ++$i) {
if (!preg_match('~^(.*[^[:alnum:]_])?([[:alnum:]_]*([)(])([^)(]*[)(]){'.$i.'})$~',
$splits[0], $regs)) {
print_error("parenthesisinproperstart", 'question', '', $splits[0]);
@ -123,17 +122,17 @@ function qformat_webct_convert_formula($formula) {
print_error('badbase', 'question', '', $splits[0]);
}
// Find $exp (similar to above but a little easier)
// Find $exp (similar to above but a little easier).
if (preg_match('~^([+-]?(\\{[^}]\\}|([0-9]+(\\.[0-9]*)?|\\.[0-9]+)([eE][+-]?[0-9]+)?))(.*)~',
$splits[1], $regs)) {
// The simple case
// The simple case.
$exp = $regs[1];
$splits[1] = $regs[6];
} else if (preg_match('~^[+-]?[[:alnum:]_]*\\(~', $splits[1])) {
// Find the end of the parenthesis
// Find the end of the parenthesis.
$deep = 1;
for ($i = 1 ; $deep ; ++$i) {
for ($i = 1; $deep; ++$i) {
if (!preg_match('~^([+-]?[[:alnum:]_]*([)(][^)(]*){'.$i.'}([)(]))(.*)~',
$splits[1], $regs)) {
print_error("parenthesisinproperclose", 'question', '', $splits[1]);
@ -154,7 +153,7 @@ function qformat_webct_convert_formula($formula) {
$formula = "$splits[0]pow($base,$exp)$splits[1]";
}
// Nothing more is known to need to be converted
// Nothing more is known to need to be converted.
return $formula;
}
@ -168,8 +167,8 @@ function qformat_webct_convert_formula($formula) {
*/
class qformat_webct extends qformat_default {
function provide_import() {
return true;
public function provide_import() {
return true;
}
protected function readquestions($lines) {
@ -179,73 +178,68 @@ class qformat_webct extends qformat_default {
$questions = array();
$errors = array();
$warnings = array();
$webct_options = array();
$webctoptions = array();
$ignore_rest_of_question = FALSE;
$ignorerestofquestion = false;
$nLineCounter = 0;
$nQuestionStartLine = 0;
$bIsHTMLText = FALSE;
$lines[] = ":EOF:"; // for an easiest processing of the last line
// $question = $this->defaultquestion();
$nlinecounter = 0;
$nquestionstartline = 0;
$bishtmltext = false;
$lines[] = ":EOF:"; // For an easiest processing of the last line.
// We don't call defaultquestion() here, it will be called later.
foreach ($lines as $line) {
$nLineCounter++;
$line = iconv("Windows-1252","UTF-8",$line);
// Processing multiples lines strings
$nlinecounter++;
$line = iconv("Windows-1252", "UTF-8", $line);
// Processing multiples lines strings.
if (isset($questiontext) and is_string($questiontext)) {
if (preg_match("~^:~",$line)) {
if (preg_match("~^:~", $line)) {
$question->questiontext = trim($questiontext);
unset($questiontext);
}
else {
} else {
$questiontext .= str_replace('\:', ':', $line);
continue;
}
}
if (isset($answertext) and is_string($answertext)) {
if (preg_match("~^:~",$line)) {
if (preg_match("~^:~", $line)) {
$answertext = trim($answertext);
$question->answer[$currentchoice] = $answertext;
$question->subanswers[$currentchoice] = $answertext;
unset($answertext);
}
else {
} else {
$answertext .= str_replace('\:', ':', $line);
continue;
}
}
if (isset($responsetext) and is_string($responsetext)) {
if (preg_match("~^:~",$line)) {
if (preg_match("~^:~", $line)) {
$question->subquestions[$currentchoice] = trim($responsetext);
unset($responsetext);
}
else {
} else {
$responsetext .= str_replace('\:', ':', $line);
continue;
}
}
if (isset($feedbacktext) and is_string($feedbacktext)) {
if (preg_match("~^:~",$line)) {
$question->feedback[$currentchoice] = trim($feedbacktext);
if (preg_match("~^:~", $line)) {
$question->feedback[$currentchoice] = trim($feedbacktext);
unset($feedbacktext);
}
else {
} else {
$feedbacktext .= str_replace('\:', ':', $line);
continue;
}
}
if (isset($generalfeedbacktext) and is_string($generalfeedbacktext)) {
if (preg_match("~^:~",$line)) {
$question->tempgeneralfeedback= trim($generalfeedbacktext);
if (preg_match("~^:~", $line)) {
$question->tempgeneralfeedback= trim($generalfeedbacktext);
unset($generalfeedbacktext);
}
else {
} else {
$generalfeedbacktext .= str_replace('\:', ':', $line);
continue;
}
@ -253,11 +247,11 @@ class qformat_webct extends qformat_default {
$line = trim($line);
if (preg_match("~^:(TYPE|EOF):~i",$line)) {
// New Question or End of File
if (isset($question)) { // if previous question exists, complete, check and save it
if (preg_match("~^:(TYPE|EOF):~i", $line)) {
// New Question or End of File.
if (isset($question)) { // If previous question exists, complete, check and save it.
// Setup default value of missing fields
// Setup default value of missing fields.
if (!isset($question->name)) {
$question->name = $this->create_default_question_name(
$question->questiontext, get_string('questionname', 'question'));
@ -269,32 +263,32 @@ class qformat_webct extends qformat_default {
$question->image = "";
}
// Perform sanity checks
$QuestionOK = TRUE;
// Perform sanity checks.
$questionok = true;
if (strlen($question->questiontext) == 0) {
$warnings[] = get_string("missingquestion", "qformat_webct", $nQuestionStartLine);
$QuestionOK = FALSE;
$warnings[] = get_string('missingquestion', 'qformat_webct', $nquestionstartline);
$questionok = false;
}
if (sizeof($question->answer) < 1) { // a question must have at least 1 answer
$errors[] = get_string("missinganswer", "qformat_webct", $nQuestionStartLine);
$QuestionOK = FALSE;
}
else {
// Create empty feedback array
if (count($question->answer) < 1) { // A question must have at least 1 answer.
$errors[] = get_string('missinganswer', 'qformat_webct', $nquestionstartline);
$questionok = false;
} else {
// Create empty feedback array.
foreach ($question->answer as $key => $dataanswer) {
if(!isset( $question->feedback[$key])){
if (!isset($question->feedback[$key])) {
$question->feedback[$key] = '';
}
}
// this tempgeneralfeedback allows the code to work with versions from 1.6 to 1.9
// when question->generalfeedback is undefined, the webct feedback is added to each answer feedback
if (isset($question->tempgeneralfeedback)){
// This tempgeneralfeedback allows the code to work with versions from 1.6 to 1.9.
// When question->generalfeedback is undefined, the webct feedback is added to each answer feedback.
if (isset($question->tempgeneralfeedback)) {
if (isset($question->generalfeedback)) {
$question->generalfeedback = $question->tempgeneralfeedback;
} else {
foreach ($question->answer as $key => $dataanswer) {
if ($question->tempgeneralfeedback !=''){
$question->feedback[$key] = $question->tempgeneralfeedback.'<br/>'.$question->feedback[$key];
if ($question->tempgeneralfeedback !='') {
$question->feedback[$key] = $question->tempgeneralfeedback
.'<br/>'.$question->feedback[$key];
}
}
}
@ -302,7 +296,7 @@ class qformat_webct extends qformat_default {
}
$maxfraction = -1;
$totalfraction = 0;
foreach($question->fraction as $fraction) {
foreach ($question->fraction as $fraction) {
if ($fraction > 0) {
$totalfraction += $fraction;
}
@ -314,8 +308,9 @@ class qformat_webct extends qformat_default {
case 'shortanswer':
if ($maxfraction != 1) {
$maxfraction = $maxfraction * 100;
$errors[] = "'$question->name': ".get_string("wronggrade", "qformat_webct", $nLineCounter).' '.get_string("fractionsnomax", "question", $maxfraction);
$QuestionOK = FALSE;
$errors[] = "'$question->name': ".get_string('wronggrade', 'qformat_webct', $nlinecounter)
.' '.get_string('fractionsnomax', 'question', $maxfraction);
$questionok = false;
}
break;
@ -323,15 +318,17 @@ class qformat_webct extends qformat_default {
if ($question->single) {
if ($maxfraction != 1) {
$maxfraction = $maxfraction * 100;
$errors[] = "'$question->name': ".get_string("wronggrade", "qformat_webct", $nLineCounter).' '.get_string("fractionsnomax", "question", $maxfraction);
$QuestionOK = FALSE;
$errors[] = "'$question->name': ".get_string('wronggrade', 'qformat_webct', $nlinecounter)
.' '.get_string('fractionsnomax', 'question', $maxfraction);
$questionok = false;
}
} else {
$totalfraction = round($totalfraction,2);
$totalfraction = round($totalfraction, 2);
if ($totalfraction != 1) {
$totalfraction = $totalfraction * 100;
$errors[] = "'$question->name': ".get_string("wronggrade", "qformat_webct", $nLineCounter).' '.get_string("fractionsaddwrong", "question", $totalfraction);
$QuestionOK = FALSE;
$errors[] = "'$question->name': ".get_string('wronggrade', 'qformat_webct', $nlinecounter)
.' '.get_string('fractionsaddwrong', 'question', $totalfraction);
$questionok = false;
}
}
break;
@ -340,151 +337,150 @@ class qformat_webct extends qformat_default {
foreach ($question->answers as $answer) {
if ($formulaerror = qtype_calculated_find_formula_errors($answer)) {
$warnings[] = "'$question->name': ". $formulaerror;
$QuestionOK = FALSE;
$questionok = false;
}
}
foreach ($question->dataset as $dataset) {
$dataset->itemcount=count($dataset->datasetitem);
}
$question->import_process=TRUE ;
unset($question->answer); //not used in calculated question
$question->import_process = true;
unset($question->answer); // Not used in calculated question.
break;
case 'match':
// MDL-10680:
// switch subquestions and subanswers
foreach ($question->subquestions as $id=>$subquestion) {
// Switch subquestions and subanswers.
foreach ($question->subquestions as $id => $subquestion) {
$temp = $question->subquestions[$id];
$question->subquestions[$id] = $question->subanswers[$id];
$question->subanswers[$id] = $temp;
}
if (count($question->answer) < 3){
// add a dummy missing question
$question->name = 'Dummy question added '.$question->name ;
if (count($question->answer) < 3) {
// Add a dummy missing question.
$question->name = 'Dummy question added '.$question->name;
$question->answer[] = 'dummy';
$question->subanswers[] = 'dummy';
$question->subquestions[] = 'dummy';
$question->fraction[] = '0.0';
$question->feedback[] = '';
}
break;
}
break;
default:
// No problemo
// No problemo.
}
}
if ($QuestionOK) {
// echo "<pre>"; print_r ($question);
$questions[] = $question; // store it
unset($question); // and prepare a new one
if ($questionok) {
$questions[] = $question; // Store it.
unset($question); // And prepare a new one.
$question = $this->defaultquestion();
}
}
$nQuestionStartLine = $nLineCounter;
$nquestionstartline = $nlinecounter;
}
// Processing Question Header
// Processing Question Header.
if (preg_match("~^:TYPE:MC:1(.*)~i",$line,$webct_options)) {
// Multiple Choice Question with only one good answer
if (preg_match("~^:TYPE:MC:1(.*)~i", $line, $webctoptions)) {
// Multiple Choice Question with only one good answer.
$question = $this->defaultquestion();
$question->feedback = array();
$question->qtype = 'multichoice';
$question->single = 1; // Only one answer is allowed
$ignore_rest_of_question = FALSE;
$question->single = 1; // Only one answer is allowed.
$ignorerestofquestion = false;
continue;
}
if (preg_match("~^:TYPE:MC:N(.*)~i",$line,$webct_options)) {
// Multiple Choice Question with several good answers
if (preg_match("~^:TYPE:MC:N(.*)~i", $line, $webctoptions)) {
// Multiple Choice Question with several good answers.
$question = $this->defaultquestion();
$question->feedback = array();
$question->qtype = 'multichoice';
$question->single = 0; // Many answers allowed
$ignore_rest_of_question = FALSE;
$question->single = 0; // Many answers allowed.
$ignorerestofquestion = false;
continue;
}
if (preg_match("~^:TYPE:S~i",$line)) {
// Short Answer Question
if (preg_match("~^:TYPE:S~i", $line)) {
// Short Answer Question.
$question = $this->defaultquestion();
$question->feedback = array();
$question->qtype = 'shortanswer';
$question->usecase = 0; // Ignore case
$ignore_rest_of_question = FALSE;
$question->usecase = 0; // Ignore case.
$ignorerestofquestion = false;
continue;
}
if (preg_match("~^:TYPE:C~i",$line)) {
// Calculated Question
if (preg_match("~^:TYPE:C~i", $line)) {
// Calculated Question.
$question = $this->defaultquestion();
$question->qtype = 'calculated';
$question->answers = array(); // No problem as they go as :FORMULA: from webct
$question->answers = array(); // No problem as they go as :FORMULA: from webct.
$question->units = array();
$question->dataset = array();
// To make us pass the end-of-question sanity checks
// To make us pass the end-of-question sanity checks.
$question->answer = array('dummy');
$question->fraction = array('1.0');
$question->feedback = array();
$currentchoice = -1;
$ignore_rest_of_question = FALSE;
$ignorerestofquestion = false;
continue;
}
if (preg_match("~^:TYPE:M~i",$line)) {
// Match Question
if (preg_match("~^:TYPE:M~i", $line)) {
// Match Question.
$question = $this->defaultquestion();
$question->qtype = 'match';
$question->feedback = array();
$ignore_rest_of_question = FALSE; // match question processing is not debugged
$ignorerestofquestion = false; // Match question processing is not debugged.
continue;
}
if (preg_match("~^:TYPE:P~i",$line)) {
// Paragraph Question
$warnings[] = get_string("paragraphquestion", "qformat_webct", $nLineCounter);
if (preg_match("~^:TYPE:P~i", $line)) {
// Paragraph question (essay).
$warnings[] = get_string("paragraphquestion", "qformat_webct", $nlinecounter);
unset($question);
$ignore_rest_of_question = TRUE; // Question Type not handled by Moodle
$ignorerestofquestion = true; // Question Type not handled by Moodle.
continue;
}
if (preg_match("~^:TYPE:~i",$line)) {
// Unknow Question
$warnings[] = get_string("unknowntype", "qformat_webct", $nLineCounter);
if (preg_match("~^:TYPE:~i", $line)) {
// Unknow question type.
$warnings[] = get_string('unknowntype', 'qformat_webct', $nlinecounter);
unset($question);
$ignore_rest_of_question = TRUE; // Question Type not handled by Moodle
$ignorerestofquestion = true; // Question Type not handled by Moodle.
continue;
}
if ($ignore_rest_of_question) {
if ($ignorerestofquestion) {
continue;
}
if (preg_match("~^:TITLE:(.*)~i",$line,$webct_options)) {
$name = trim($webct_options[1]);
if (preg_match("~^:TITLE:(.*)~i", $line, $webctoptions)) {
$name = trim($webctoptions[1]);
$question->name = $this->clean_question_name($name);
continue;
}
if (preg_match("~^:IMAGE:(.*)~i",$line,$webct_options)) {
$filename = trim($webct_options[1]);
if (preg_match("~^http://~i",$filename)) {
if (preg_match("~^:IMAGE:(.*)~i", $line, $webctoptions)) {
$filename = trim($webctoptions[1]);
if (preg_match("~^http://~i", $filename)) {
$question->image = $filename;
}
continue;
}
// Need to put the parsing of calculated items here to avoid ambitiuosness:
// if question isn't defined yet there is nothing to do here (avoid notices)
// if question isn't defined yet there is nothing to do here (avoid notices).
if (!isset($question)) {
continue;
}
if (isset($question->qtype ) && 'calculated' == $question->qtype && preg_match(
"~^:([[:lower:]].*|::.*)-(MIN|MAX|DEC|VAL([0-9]+))::?:?($webctnumberregex)~", $line, $webct_options)) {
$datasetname = preg_replace('/^::/', '', $webct_options[1]);
$datasetvalue = qformat_webct_convert_formula($webct_options[4]);
switch ($webct_options[2]) {
"~^:([[:lower:]].*|::.*)-(MIN|MAX|DEC|VAL([0-9]+))::?:?($webctnumberregex)~", $line, $webctoptions)) {
$datasetname = preg_replace('/^::/', '', $webctoptions[1]);
$datasetvalue = qformat_webct_convert_formula($webctoptions[4]);
switch ($webctoptions[2]) {
case 'MIN':
$question->dataset[$datasetname]->min = $datasetvalue;
break;
@ -492,123 +488,124 @@ class qformat_webct extends qformat_default {
$question->dataset[$datasetname]->max = $datasetvalue;
break;
case 'DEC':
$datasetvalue = floor($datasetvalue); // int only!
$datasetvalue = floor($datasetvalue); // Int only!
$question->dataset[$datasetname]->length = max(0, $datasetvalue);
break;
default:
// The VAL case:
$question->dataset[$datasetname]->datasetitem[$webct_options[3]] = new stdClass();
$question->dataset[$datasetname]->datasetitem[$webct_options[3]]->itemnumber = $webct_options[3];
$question->dataset[$datasetname]->datasetitem[$webct_options[3]]->value = $datasetvalue;
// The VAL case.
$question->dataset[$datasetname]->datasetitem[$webctoptions[3]] = new stdClass();
$question->dataset[$datasetname]->datasetitem[$webctoptions[3]]->itemnumber = $webctoptions[3];
$question->dataset[$datasetname]->datasetitem[$webctoptions[3]]->value = $datasetvalue;
break;
}
continue;
}
$bIsHTMLText = preg_match("~:H$~i",$line); // True if next lines are coded in HTML
if (preg_match("~^:QUESTION~i",$line)) {
$questiontext=""; // Start gathering next lines
$bishtmltext = preg_match("~:H$~i", $line); // True if next lines are coded in HTML.
if (preg_match("~^:QUESTION~i", $line)) {
$questiontext=''; // Start gathering next lines.
continue;
}
if (preg_match("~^:ANSWER([0-9]+):([^:]+):([0-9\.\-]+):(.*)~i",$line,$webct_options)) { // Shortanswer.
$currentchoice=$webct_options[1];
$answertext=$webct_options[2]; // Start gathering next lines
$question->fraction[$currentchoice]=($webct_options[3]/100);
if (preg_match("~^:ANSWER([0-9]+):([^:]+):([0-9\.\-]+):(.*)~i", $line, $webctoptions)) { // Shortanswer.
$currentchoice=$webctoptions[1];
$answertext=$webctoptions[2]; // Start gathering next lines.
$question->fraction[$currentchoice]=($webctoptions[3]/100);
continue;
}
if (preg_match("~^:ANSWER([0-9]+):([0-9\.\-]+)~i",$line,$webct_options)) {
$answertext=""; // Start gathering next lines
$currentchoice=$webct_options[1];
$question->fraction[$currentchoice]=($webct_options[2]/100);
if (preg_match("~^:ANSWER([0-9]+):([0-9\.\-]+)~i", $line, $webctoptions)) {
$answertext=''; // Start gathering next lines.
$currentchoice=$webctoptions[1];
$question->fraction[$currentchoice]=($webctoptions[2]/100);
continue;
}
if (preg_match('~^:FORMULA:(.*)~i', $line, $webct_options)) {
// Answer for a calculated question
if (preg_match('~^:FORMULA:(.*)~i', $line, $webctoptions)) {
// Answer for a calculated question.
++$currentchoice;
$question->answers[$currentchoice] =
qformat_webct_convert_formula($webct_options[1]);
qformat_webct_convert_formula($webctoptions[1]);
// Default settings:
// Default settings.
$question->fraction[$currentchoice] = 1.0;
$question->tolerance[$currentchoice] = 0.0;
$question->tolerancetype[$currentchoice] = 2; // nominal (units in webct)
$question->tolerancetype[$currentchoice] = 2; // Nominal (units in webct).
$question->feedback[$currentchoice] = '';
$question->correctanswerlength[$currentchoice] = 4;
$datasetnames = question_bank::get_qtype('calculated')->
find_dataset_names($webct_options[1]);
$datasetnames =
question_bank::get_qtype('calculated')->find_dataset_names($webctoptions[1]);
foreach ($datasetnames as $datasetname) {
$question->dataset[$datasetname] = new stdClass();
$question->dataset[$datasetname]->datasetitem = array();
$question->dataset[$datasetname]->name = $datasetname ;
$question->dataset[$datasetname]->name = $datasetname;
$question->dataset[$datasetname]->distribution = 'uniform';
$question->dataset[$datasetname]->status ='private';
$question->dataset[$datasetname]->status = 'private';
}
continue;
}
if (preg_match("~^:L([0-9]+)~i",$line,$webct_options)) {
$answertext=""; // Start gathering next lines
$currentchoice=$webct_options[1];
if (preg_match("~^:L([0-9]+)~i", $line, $webctoptions)) {
$answertext=''; // Start gathering next lines.
$currentchoice=$webctoptions[1];
$question->fraction[$currentchoice]=1;
continue;
}
if (preg_match("~^:R([0-9]+)~i",$line,$webct_options)) {
$responsetext=""; // Start gathering next lines
$currentchoice=$webct_options[1];
if (preg_match("~^:R([0-9]+)~i", $line, $webctoptions)) {
$responsetext=''; // Start gathering next lines.
$currentchoice=$webctoptions[1];
continue;
}
if (preg_match("~^:REASON([0-9]+):?~i",$line,$webct_options)) {
$feedbacktext=""; // Start gathering next lines
$currentchoice=$webct_options[1];
if (preg_match("~^:REASON([0-9]+):?~i", $line, $webctoptions)) {
$feedbacktext=''; // Start gathering next lines.
$currentchoice=$webctoptions[1];
continue;
}
if (preg_match("~^:FEEDBACK([0-9]+):?~i",$line,$webct_options)) {
$generalfeedbacktext=""; // Start gathering next lines
$currentchoice=$webct_options[1];
if (preg_match("~^:FEEDBACK([0-9]+):?~i", $line, $webctoptions)) {
$generalfeedbacktext=''; // Start gathering next lines.
$currentchoice=$webctoptions[1];
continue;
}
if (preg_match('~^:FEEDBACK:(.*)~i',$line,$webct_options)) {
$generalfeedbacktext=""; // Start gathering next lines
if (preg_match('~^:FEEDBACK:(.*)~i', $line, $webctoptions)) {
$generalfeedbacktext=''; // Start gathering next lines.
continue;
}
if (preg_match('~^:LAYOUT:(.*)~i',$line,$webct_options)) {
// ignore since layout in question_multichoice is no more used in moodle
// $webct_options[1] contains either vertical or horizontal ;
if (preg_match('~^:LAYOUT:(.*)~i', $line, $webctoptions)) {
// Ignore since layout in question_multichoice is no more used in Moodle.
// $webctoptions[1] contains either vertical or horizontal.
continue;
}
if (isset($question->qtype ) && 'calculated' == $question->qtype && preg_match('~^:ANS-DEC:([1-9][0-9]*)~i', $line, $webct_options)) {
// We can but hope that this always appear before the ANSTYPE property
$question->correctanswerlength[$currentchoice] = $webct_options[1];
if (isset($question->qtype ) && 'calculated' == $question->qtype
&& preg_match('~^:ANS-DEC:([1-9][0-9]*)~i', $line, $webctoptions)) {
// We can but hope that this always appear before the ANSTYPE property.
$question->correctanswerlength[$currentchoice] = $webctoptions[1];
continue;
}
if (isset($question->qtype )&& 'calculated' == $question->qtype && preg_match("~^:TOL:($webctnumberregex)~i", $line, $webct_options)) {
// We can but hope that this always appear before the TOL property
if (isset($question->qtype )&& 'calculated' == $question->qtype
&& preg_match("~^:TOL:($webctnumberregex)~i", $line, $webctoptions)) {
// We can but hope that this always appear before the TOL property.
$question->tolerance[$currentchoice] =
qformat_webct_convert_formula($webct_options[1]);
qformat_webct_convert_formula($webctoptions[1]);
continue;
}
if (isset($question->qtype )&& 'calculated' == $question->qtype && preg_match('~^:TOLTYPE:percent~i', $line)) {
// Percentage case is handled as relative in Moodle:
// Percentage case is handled as relative in Moodle.
$question->tolerance[$currentchoice] /= 100;
$question->tolerancetype[$currentchoice] = 1; // Relative
$question->tolerancetype[$currentchoice] = 1; // Relative.
continue;
}
if (preg_match('~^:UNITS:(.+)~i', $line, $webct_options)
and $webctunits = trim($webct_options[1])) {
if (preg_match('~^:UNITS:(.+)~i', $line, $webctoptions)
and $webctunits = trim($webctoptions[1])) {
// This is a guess - I really do not know how different webct units are separated...
$webctunits = explode(':', $webctunits);
$unitrec->multiplier = 1.0; // Webct does not seem to support this
$unitrec->multiplier = 1.0; // Webct does not seem to support this.
foreach ($webctunits as $webctunit) {
$unitrec->unit = trim($webctunit);
$question->units[] = $unitrec;
@ -616,10 +613,10 @@ class qformat_webct extends qformat_default {
continue;
}
if (!empty($question->units) && preg_match('~^:UNITREQ:(.*)~i', $line, $webct_options)
&& !$webct_options[1]) {
// There are units but units are not required so add the no unit alternative
// We can but hope that the UNITS property always appear before this property
if (!empty($question->units) && preg_match('~^:UNITREQ:(.*)~i', $line, $webctoptions)
&& !$webctoptions[1]) {
// There are units but units are not required so add the no unit alternative.
// We can but hope that the UNITS property always appear before this property.
$unitrec->unit = '';
$unitrec->multiplier = 1.0;
$question->units[] = $unitrec;
@ -628,7 +625,7 @@ class qformat_webct extends qformat_default {
if (!empty($question->units) && preg_match('~^:UNITCASE:~i', $line)) {
// This could be important but I was not able to figure out how
// it works so I ignore it for now
// it works so I ignore it for now.
continue;
}
@ -642,24 +639,22 @@ class qformat_webct extends qformat_default {
}
}
if (sizeof($errors) > 0) {
echo "<p>".get_string("errorsdetected", "qformat_webct", sizeof($errors))."</p><ul>";
foreach($errors as $error) {
if (count($errors) > 0) {
echo '<p>'.get_string('errorsdetected', 'qformat_webct', count($errors)).'</p><ul>';
foreach ($errors as $error) {
echo "<li>$error</li>";
}
echo "</ul>";
unset($questions); // no questions imported
echo '</ul>';
unset($questions); // No questions imported.
}
if (sizeof($warnings) > 0) {
echo "<p>".get_string("warningsdetected", "qformat_webct", sizeof($warnings))."</p><ul>";
foreach($warnings as $warning) {
if (count($warnings) > 0) {
echo '<p>'.get_string('warningsdetected', 'qformat_webct', count($warnings)).'</p><ul>';
foreach ($warnings as $warning) {
echo "<li>$warning</li>";
}
echo "</ul>";
echo '</ul>';
}
return $questions;
}
}
?>

View File

@ -17,8 +17,7 @@
/**
* Strings for component 'qformat_webct', language 'en', branch 'MOODLE_20_STABLE'
*
* @package qformat
* @subpackage webct
* @package qformat_webct
* @copyright 2010 Helen Foster
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

View File

@ -17,8 +17,7 @@
/**
* Version information for the calculated question type.
*
* @package qformat
* @subpackage webct
* @package qformat_webct
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

View File

@ -17,8 +17,7 @@
/**
* XHTML question exporter.
*
* @package qformat
* @subpackage xhtml
* @package qformat_xhtml
* @copyright 2005 Howard Miller
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@ -47,119 +46,122 @@ class qformat_xhtml extends qformat_default {
protected function writequestion($question) {
global $OUTPUT;
// turns question into string
// question reflects database fields for general question and specific to type
// Turns question into string.
// Question reflects database fields for general question and specific to type.
// if a category switch, just ignore
// If a category switch, just ignore.
if ($question->qtype=='category') {
return '';
}
// initial string;
// Initial string.
$expout = "";
$id = $question->id;
// add comment and div tags
// Add comment and div tags.
$expout .= "<!-- question: $id name: $question->name -->\n";
$expout .= "<div class=\"question\">\n";
// add header
// Add header.
$expout .= "<h3>$question->name</h3>\n";
// Format and add the question text
// Format and add the question text.
$expout .= '<p class="questiontext">' . format_text($question->questiontext,
$question->questiontextformat) . "</p>\n";
// selection depends on question type
// Selection depends on question type.
switch($question->qtype) {
case 'truefalse':
$st_true = get_string('true', 'qtype_truefalse');
$st_false = get_string('false', 'qtype_truefalse');
$expout .= "<ul class=\"truefalse\">\n";
$expout .= " <li><input name=\"quest_$id\" type=\"radio\" value=\"$st_true\" />$st_true</li>\n";
$expout .= " <li><input name=\"quest_$id\" type=\"radio\" value=\"$st_false\" />$st_false</li>\n";
$expout .= "</ul>\n";
break;
case 'multichoice':
$expout .= "<ul class=\"multichoice\">\n";
foreach($question->options->answers as $answer) {
$ans_text = $this->repchar( $answer->answer );
if ($question->options->single) {
$expout .= " <li><input name=\"quest_$id\" type=\"radio\" value=\"" . s($ans_text) . "\" />$ans_text</li>\n";
case 'truefalse':
$sttrue = get_string('true', 'qtype_truefalse');
$stfalse = get_string('false', 'qtype_truefalse');
$expout .= "<ul class=\"truefalse\">\n";
$expout .= " <li><input name=\"quest_$id\" type=\"radio\" value=\"$sttrue\" />$sttrue</li>\n";
$expout .= " <li><input name=\"quest_$id\" type=\"radio\" value=\"$stfalse\" />$stfalse</li>\n";
$expout .= "</ul>\n";
break;
case 'multichoice':
$expout .= "<ul class=\"multichoice\">\n";
foreach ($question->options->answers as $answer) {
$answertext = $this->repchar( $answer->answer );
if ($question->options->single) {
$expout .= " <li><input name=\"quest_$id\" type=\"radio\" value=\""
. s($answertext) . "\" />$answertext</li>\n";
} else {
$expout .= " <li><input name=\"quest_$id\" type=\"checkbox\" value=\""
. s($answertext) . "\" />$answertext</li>\n";
}
}
else {
$expout .= " <li><input name=\"quest_$id\" type=\"checkbox\" value=\"" . s($ans_text) . "\" />$ans_text</li>\n";
$expout .= "</ul>\n";
break;
case 'shortanswer':
$expout .= html_writer::start_tag('ul', array('class' => 'shortanswer'));
$expout .= html_writer::start_tag('li');
$expout .= html_writer::label(get_string('answer'), 'quest_'.$id, false, array('class' => 'accesshide'));
$expout .= html_writer::empty_tag('input', array('id' => "quest_$id", 'name' => "quest_$id", 'type' => 'text'));
$expout .= html_writer::end_tag('li');
$expout .= html_writer::end_tag('ul');
break;
case 'numerical':
$expout .= html_writer::start_tag('ul', array('class' => 'numerical'));
$expout .= html_writer::start_tag('li');
$expout .= html_writer::label(get_string('answer'), 'quest_'.$id, false, array('class' => 'accesshide'));
$expout .= html_writer::empty_tag('input', array('id' => "quest_$id", 'name' => "quest_$id", 'type' => 'text'));
$expout .= html_writer::end_tag('li');
$expout .= html_writer::end_tag('ul');
break;
case 'match':
$expout .= html_writer::start_tag('ul', array('class' => 'match'));
// Build answer list.
$answerlist = array();
foreach ($question->options->subquestions as $subquestion) {
$answerlist[] = $this->repchar( $subquestion->answertext );
}
}
$expout .= "</ul>\n";
break;
case 'shortanswer':
$expout .= html_writer::start_tag('ul', array('class' => 'shortanswer'));
$expout .= html_writer::start_tag('li');
$expout .= html_writer::label(get_string('answer'), 'quest_'.$id, false, array('class' => 'accesshide'));
$expout .= html_writer::empty_tag('input', array('id' => "quest_$id", 'name' => "quest_$id", 'type' => 'text'));
$expout .= html_writer::end_tag('li');
$expout .= html_writer::end_tag('ul');
break;
case 'numerical':
$expout .= html_writer::start_tag('ul', array('class' => 'numerical'));
$expout .= html_writer::start_tag('li');
$expout .= html_writer::label(get_string('answer'), 'quest_'.$id, false, array('class' => 'accesshide'));
$expout .= html_writer::empty_tag('input', array('id' => "quest_$id", 'name' => "quest_$id", 'type' => 'text'));
$expout .= html_writer::end_tag('li');
$expout .= html_writer::end_tag('ul');
break;
case 'match':
$expout .= html_writer::start_tag('ul', array('class' => 'match'));
shuffle( $answerlist ); // Random display order.
// build answer list
$ans_list = array();
foreach($question->options->subquestions as $subquestion) {
$ans_list[] = $this->repchar( $subquestion->answertext );
}
shuffle( $ans_list ); // random display order
// Build select options.
$selectoptions = array();
foreach($ans_list as $ans) {
$selectoptions[s($ans)] = s($ans);
}
// display
$option = 0;
foreach($question->options->subquestions as $subquestion) {
// build drop down for answers
$quest_text = $this->repchar( $subquestion->questiontext );
if ($quest_text != '') {
$dropdown = html_writer::label(get_string('answer', 'qtype_match', $option+1), 'quest_'.$id.'_'.$option, false, array('class' => 'accesshide'));
$dropdown .= html_writer::select($selectoptions, "quest_{$id}_{$option}", '', false, array('id' => "quest_{$id}_{$option}"));
$expout .= html_writer::tag('li', $quest_text);
$expout .= $dropdown;
$option++;
// Build select options.
$selectoptions = array();
foreach ($answerlist as $ans) {
$selectoptions[s($ans)] = s($ans);
}
}
$expout .= html_writer::end_tag('ul');
break;
case 'description':
break;
case 'multianswer':
default:
$expout .= "<!-- export of $question->qtype type is not supported -->\n";
// Display.
$option = 0;
foreach ($question->options->subquestions as $subquestion) {
// Build drop down for answers.
$questiontext = $this->repchar( $subquestion->questiontext );
if ($questiontext != '') {
$dropdown = html_writer::label(get_string('answer', 'qtype_match', $option+1), 'quest_'.$id.'_'.$option,
false, array('class' => 'accesshide'));
$dropdown .= html_writer::select($selectoptions, "quest_{$id}_{$option}", '', false,
array('id' => "quest_{$id}_{$option}"));
$expout .= html_writer::tag('li', $questiontext);
$expout .= $dropdown;
$option++;
}
}
$expout .= html_writer::end_tag('ul');
break;
case 'description':
break;
case 'multianswer':
default:
$expout .= "<!-- export of $question->qtype type is not supported -->\n";
}
// close off div
// Close off div.
$expout .= "</div>\n\n\n";
return $expout;
}
protected function presave_process($content) {
// override method to allow us to add xhtml headers and footers
// Override method to allow us to add xhtml headers and footers.
global $CFG;
// get css bit
$css_lines = file( "$CFG->dirroot/question/format/xhtml/xhtml.css" );
$css = implode( ' ',$css_lines );
// Get css bit.
$csslines = file( "$CFG->dirroot/question/format/xhtml/xhtml.css" );
$css = implode( ' ', $csslines );
$xp = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n";
$xp .= " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n";

View File

@ -17,8 +17,7 @@
/**
* Strings for component 'qformat_xhtml', language 'en', branch 'MOODLE_20_STABLE'
*
* @package qformat
* @subpackage xhtml
* @package qformat_xhtml
* @copyright 2010 Helen Foster
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

View File

@ -17,8 +17,7 @@
/**
* Version information for the calculated question type.
*
* @package qformat
* @subpackage xhtml
* @package qformat_xhtml
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

View File

@ -21,4 +21,3 @@
}
</style>

View File

@ -17,8 +17,7 @@
/**
* Code for exporting questions as Moodle XML.
*
* @package qformat
* @subpackage xml
* @package qformat_xml
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@ -59,7 +58,7 @@ class qformat_xml extends qformat_default {
return 'application/xml';
}
// IMPORT FUNCTIONS START HERE
// IMPORT FUNCTIONS START HERE.
/**
* Translate human readable format name
@ -107,7 +106,7 @@ class qformat_xml extends qformat_default {
* @return string processed text.
*/
public function import_text($text) {
// quick sanity check
// Quick sanity check.
if (empty($text)) {
return '';
}
@ -199,14 +198,10 @@ class qformat_xml extends qformat_default {
public function import_headers($question) {
global $CFG, $USER;
// get some error strings
$error_noname = get_string('xmlimportnoname', 'qformat_xml');
$error_noquestion = get_string('xmlimportnoquestion', 'qformat_xml');
// this routine initialises the question object
// This routine initialises the question object.
$qo = $this->defaultquestion();
// Question name
// Question name.
$qo->name = $this->clean_question_name($this->getpath($question,
array('#', 'name', 0, '#', 'text', 0, '#'), '', true,
get_string('xmlimportnoname', 'qformat_xml')));
@ -238,7 +233,7 @@ class qformat_xml extends qformat_default {
$qo->questiontext .= ' <img src="@@PLUGINFILE@@/' . $filename . '" />';
}
// restore files in generalfeedback
// Restore files in generalfeedback.
$generalfeedback = $this->import_text_with_files($question,
array('#', 'generalfeedback', 0), $qo->generalfeedback, $this->get_format($qo->questiontextformat));
$qo->generalfeedback = $generalfeedback['text'];
@ -252,7 +247,7 @@ class qformat_xml extends qformat_default {
$qo->penalty = $this->getpath($question,
array('#', 'penalty', 0, '#'), $qo->penalty);
// Fix problematic rounding from old files:
// Fix problematic rounding from old files.
if (abs($qo->penalty - 0.3333333) < 0.005) {
$qo->penalty = 0.3333333;
}
@ -313,7 +308,7 @@ class qformat_xml extends qformat_default {
if ($withshownumpartscorrect) {
$qo->shownumcorrect = array_key_exists('shownumcorrect', $questionxml['#']);
// Backwards compatibility:
// Backwards compatibility.
if (array_key_exists('correctresponsesfeedback', $questionxml['#'])) {
$qo->shownumcorrect = $this->trans_single($this->getpath($questionxml,
array('#', 'correctresponsesfeedback', 0, '#'), 1));
@ -330,7 +325,7 @@ class qformat_xml extends qformat_default {
public function import_hint($hintxml, $defaultformat) {
$hint = new stdClass();
if (array_key_exists('hintcontent', $hintxml['#'])) {
// Backwards compatibility:
// Backwards compatibility.
$hint->hint = $this->import_text_with_files($hintxml,
array('#', 'hintcontent', 0), '', $defaultformat);
@ -406,10 +401,10 @@ class qformat_xml extends qformat_default {
* @return object question object
*/
public function import_multichoice($question) {
// get common parts
// Get common parts.
$qo = $this->import_headers($question);
// 'header' parts particular to multichoice
// Header parts particular to multichoice.
$qo->qtype = 'multichoice';
$single = $this->getpath($question, array('#', 'single', 0, '#'), 'true');
$qo->single = $this->trans_single($single);
@ -425,7 +420,7 @@ class qformat_xml extends qformat_default {
$qo->answernumbering = 'abc';
}
// Run through the answers
// Run through the answers.
$answers = $question['#']['answer'];
$acount = 0;
foreach ($answers as $answer) {
@ -455,7 +450,7 @@ class qformat_xml extends qformat_default {
array('#', 'questiontext', 0));
$qo = qtype_multianswer_extract_question($questiontext);
// 'header' parts particular to multianswer
// Header parts particular to multianswer.
$qo->qtype = 'multianswer';
$qo->course = $this->course;
@ -487,7 +482,7 @@ class qformat_xml extends qformat_default {
$qo->questiontext .= ' <img src="@@PLUGINFILE@@/' . $filename . '" />';
}
// restore files in generalfeedback
// Restore files in generalfeedback.
$generalfeedback = $this->import_text_with_files($question,
array('#', 'generalfeedback', 0), $qo->generalfeedback, $this->get_format($qo->questiontextformat));
$qo->generalfeedback = $generalfeedback['text'];
@ -498,7 +493,7 @@ class qformat_xml extends qformat_default {
$qo->penalty = $this->getpath($question,
array('#', 'penalty', 0, '#'), $this->defaultquestion()->penalty);
// Fix problematic rounding from old files:
// Fix problematic rounding from old files.
if (abs($qo->penalty - 0.3333333) < 0.005) {
$qo->penalty = 0.3333333;
}
@ -514,11 +509,11 @@ class qformat_xml extends qformat_default {
* @return object question object
*/
public function import_truefalse($question) {
// get common parts
// Get common parts.
global $OUTPUT;
$qo = $this->import_headers($question);
// 'header' parts particular to true/false
// Header parts particular to true/false.
$qo->qtype = 'truefalse';
// In the past, it used to be assumed that the two answers were in the file
@ -573,16 +568,16 @@ class qformat_xml extends qformat_default {
* @return object question object
*/
public function import_shortanswer($question) {
// get common parts
// Get common parts.
$qo = $this->import_headers($question);
// header parts particular to shortanswer
// Header parts particular to shortanswer.
$qo->qtype = 'shortanswer';
// get usecase
// Get usecase.
$qo->usecase = $this->getpath($question, array('#', 'usecase', 0, '#'), $qo->usecase);
// Run through the answers
// Run through the answers.
$answers = $question['#']['answer'];
$acount = 0;
foreach ($answers as $answer) {
@ -604,9 +599,9 @@ class qformat_xml extends qformat_default {
* @return object question object
*/
public function import_description($question) {
// get common parts
// Get common parts.
$qo = $this->import_headers($question);
// header parts particular to shortanswer
// Header parts particular to shortanswer.
$qo->qtype = 'description';
$qo->defaultmark = 0;
$qo->length = 0;
@ -619,20 +614,20 @@ class qformat_xml extends qformat_default {
* @return object question object
*/
public function import_numerical($question) {
// get common parts
// Get common parts.
$qo = $this->import_headers($question);
// header parts particular to numerical
// Header parts particular to numerical.
$qo->qtype = 'numerical';
// get answers array
// Get answers array.
$answers = $question['#']['answer'];
$qo->answer = array();
$qo->feedback = array();
$qo->fraction = array();
$qo->tolerance = array();
foreach ($answers as $answer) {
// answer outside of <text> is deprecated
// Answer outside of <text> is deprecated.
$obj = $this->import_answer($answer, false, $this->get_format($qo->questiontextformat));
$qo->answer[] = $obj->answer['text'];
if (empty($qo->answer)) {
@ -641,13 +636,13 @@ class qformat_xml extends qformat_default {
$qo->feedback[] = $obj->feedback;
$qo->tolerance[] = $this->getpath($answer, array('#', 'tolerance', 0, '#'), 0);
// fraction as a tag is deprecated
// Fraction as a tag is deprecated.
$fraction = $this->getpath($answer, array('@', 'fraction'), 0) / 100;
$qo->fraction[] = $this->getpath($answer,
array('#', 'fraction', 0, '#'), $fraction); // deprecated
array('#', 'fraction', 0, '#'), $fraction); // Deprecated.
}
// Get the units array
// Get the units array.
$qo->unit = array();
$units = $this->getpath($question, array('#', 'units', 0, '#', 'unit'), array());
if (!empty($units)) {
@ -672,9 +667,9 @@ class qformat_xml extends qformat_default {
if (is_null($qo->showunits)) {
// Set a good default, depending on whether there are any units defined.
if (empty($qo->unit)) {
$qo->showunits = 3; // qtype_numerical::UNITNONE;
$qo->showunits = 3; // This is qtype_numerical::UNITNONE, but we cannot refer to that constant here.
} else {
$qo->showunits = 0; // qtype_numerical::UNITOPTIONAL;
$qo->showunits = 0; // This is qtype_numerical::UNITOPTIONAL, but we cannot refer to that constant here.
}
}
@ -689,15 +684,15 @@ class qformat_xml extends qformat_default {
* @return object question object
*/
public function import_match($question) {
// get common parts
// Get common parts.
$qo = $this->import_headers($question);
// header parts particular to matching
// Header parts particular to matching.
$qo->qtype = 'match';
$qo->shuffleanswers = $this->trans_single($this->getpath($question,
array('#', 'shuffleanswers', 0, '#'), 1));
// run through subquestions
// Run through subquestions.
$qo->subquestions = array();
$qo->subanswers = array();
foreach ($question['#']['subquestion'] as $subqxml) {
@ -721,10 +716,10 @@ class qformat_xml extends qformat_default {
* @return object question object
*/
public function import_essay($question) {
// get common parts
// Get common parts.
$qo = $this->import_headers($question);
// header parts particular to essay
// Header parts particular to essay.
$qo->qtype = 'essay';
$qo->responseformat = $this->getpath($question,
@ -749,10 +744,10 @@ class qformat_xml extends qformat_default {
*/
public function import_calculated($question) {
// get common parts
// Get common parts.
$qo = $this->import_headers($question);
// header parts particular to calculated
// Header parts particular to calculated.
$qo->qtype = 'calculated';
$qo->synchronize = $this->getpath($question, array('#', 'synchronize', 0, '#'), 0);
$single = $this->getpath($question, array('#', 'single', 0, '#'), 'true');
@ -776,7 +771,7 @@ class qformat_xml extends qformat_default {
array('0'), '', $this->get_format($qo->questiontextformat));
}
// get answers array
// Get answers array.
$answers = $question['#']['answer'];
$qo->answers = array();
$qo->feedback = array();
@ -788,14 +783,14 @@ class qformat_xml extends qformat_default {
$qo->feedback = array();
foreach ($answers as $answer) {
$ans = $this->import_answer($answer, true, $this->get_format($qo->questiontextformat));
// answer outside of <text> is deprecated
// Answer outside of <text> is deprecated.
if (empty($ans->answer['text'])) {
$ans->answer['text'] = '*';
}
$qo->answers[] = $ans->answer;
$qo->feedback[] = $ans->feedback;
$qo->tolerance[] = $answer['#']['tolerance'][0]['#'];
// fraction as a tag is deprecated
// Fraction as a tag is deprecated.
if (!empty($answer['#']['fraction'][0]['#'])) {
$qo->fraction[] = $answer['#']['fraction'][0]['#'];
} else {
@ -805,7 +800,7 @@ class qformat_xml extends qformat_default {
$qo->correctanswerformat[] = $answer['#']['correctanswerformat'][0]['#'];
$qo->correctanswerlength[] = $answer['#']['correctanswerlength'][0]['#'];
}
// get units array
// Get units array.
$qo->unit = array();
if (isset($question['#']['units'][0]['#']['unit'])) {
$units = $question['#']['units'][0]['#']['unit'];
@ -824,9 +819,9 @@ class qformat_xml extends qformat_default {
if (is_null($qo->unitpenalty)) {
// Set a good default, depending on whether there are any units defined.
if (empty($qo->unit)) {
$qo->showunits = 3; // qtype_numerical::UNITNONE;
$qo->showunits = 3; // This is qtype_numerical::UNITNONE, but we cannot refer to that constant here.
} else {
$qo->showunits = 0; // qtype_numerical::UNITOPTIONAL;
$qo->showunits = 0; // This is qtype_numerical::UNITOPTIONAL, but we cannot refer to that constant here.
}
}
@ -899,11 +894,11 @@ class qformat_xml extends qformat_default {
* @return array (of objects) question objects.
*/
protected function readquestions($lines) {
// We just need it as one big string
// We just need it as one big string.
$lines = implode('', $lines);
// This converts xml to big nasty data structure
// the 0 means keep white space as it is (important for markdown format)
// the 0 means keep white space as it is (important for markdown format).
try {
$xml = xmlize($lines, 0, 'UTF-8', true);
} catch (xml_format_exception $e) {
@ -921,11 +916,11 @@ class qformat_xml extends qformat_default {
public function import_questions($xml) {
$questions = array();
// Iterate through questions
// Iterate through questions.
foreach ($xml as $questionxml) {
$qo = $this->import_question($questionxml);
// Stick the result in the $questions array
// Stick the result in the $questions array.
if ($qo) {
$questions[] = $qo;
}
@ -980,7 +975,7 @@ class qformat_xml extends qformat_default {
}
}
// EXPORT FUNCTIONS START HERE
// EXPORT FUNCTIONS START HERE.
public function export_file_extension() {
return '.xml';
@ -1101,7 +1096,7 @@ class qformat_xml extends qformat_default {
}
protected function presave_process($content) {
// Override to allow us to add xml headers and footers
// Override to allow us to add xml headers and footers.
return '<?xml version="1.0" encoding="UTF-8"?>
<quiz>
' . $content . '</quiz>';
@ -1138,7 +1133,7 @@ class qformat_xml extends qformat_default {
// Add a comment linking this to the original question id.
$expout .= "<!-- question: $question->id -->\n";
// Check question type
// Check question type.
$questiontype = $this->get_qtype($question->qtype);
// Categories are a special case.
@ -1175,7 +1170,7 @@ class qformat_xml extends qformat_default {
// The rest of the output depends on question type.
switch($question->qtype) {
case 'category':
// not a qtype really - dummy used for category switching
// Not a qtype really - dummy used for category switching.
break;
case 'truefalse':
@ -1329,7 +1324,7 @@ class qformat_xml extends qformat_default {
foreach ($question->options->answers as $answer) {
$percent = 100 * $answer->fraction;
$expout .= "<answer fraction=\"$percent\">\n";
// "<text/>" tags are an added feature, old files won't have them
// The "<text/>" tags are an added feature, old files won't have them.
$expout .= " <text>{$answer->answer}</text>\n";
$expout .= " <tolerance>{$answer->tolerance}</tolerance>\n";
$expout .= " <tolerancetype>{$answer->tolerancetype}</tolerancetype>\n";
@ -1387,7 +1382,7 @@ class qformat_xml extends qformat_default {
// The tag $question->export_process has been set so we get all the
// data items in the database from the function
// qtype_calculated::get_question_options calculatedsimple defaults
// to calculated
// to calculated.
if (isset($question->options->datasets) && count($question->options->datasets)) {
$expout .= "<dataset_definitions>\n";
foreach ($question->options->datasets as $def) {
@ -1451,7 +1446,7 @@ class qformat_xml extends qformat_default {
}
}
// close the question tag
// Close the question tag.
$expout .= " </question>\n";
if ($invalidquestion) {
return '';

View File

@ -17,8 +17,7 @@
/**
* Strings for component 'qformat_xml', language 'en', branch 'MOODLE_20_STABLE'
*
* @package qformat
* @subpackage xml
* @package qformat_xml
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

View File

@ -17,8 +17,7 @@
/**
* Unit tests for the Moodle XML format.
*
* @package qformat
* @subpackage xml
* @package qformat_xml
* @copyright 2010 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@ -91,7 +90,7 @@ class qformat_xml_test extends question_testcase {
protected function itemid_to_files($var) {
if (is_object($var)) {
$newvar = new stdClass();
foreach(get_object_vars($var) as $field => $value) {
foreach (get_object_vars($var) as $field => $value) {
$newvar->$field = $this->itemid_to_files($value);
}
@ -1314,7 +1313,8 @@ END;
$expectedqa->name = 'Simple multianswer';
$expectedqa->qtype = 'multianswer';
$expectedqa->questiontext = 'Complete this opening line of verse: "The {#1} and the {#2} went to sea".';
$expectedqa->generalfeedback = 'General feedback: It\'s from "The Owl and the Pussy-cat" by Lear: "The owl and the pussycat went to sea".';
$expectedqa->generalfeedback =
'General feedback: It\'s from "The Owl and the Pussy-cat" by Lear: "The owl and the pussycat went to sea".';
$expectedqa->defaultmark = 2;
$expectedqa->penalty = 0.5;

View File

@ -17,8 +17,7 @@
/**
* Version information for the calculated question type.
*
* @package qformat
* @subpackage xml
* @package qformat_xml
* @copyright 2011 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/