mirror of
https://github.com/moodle/moodle.git
synced 2025-08-03 16:13:28 +02:00
MDL-20636 Fix a lot more coding style issues.
This commit is contained in:
parent
e0736817f0
commit
59a3fcd3eb
9 changed files with 601 additions and 750 deletions
|
@ -59,7 +59,8 @@ class backup_qtype_multianswer_plugin extends backup_qtype_plugin {
|
|||
$pluginwrapper->add_child($multianswer);
|
||||
|
||||
// set source to populate the data
|
||||
$multianswer->set_source_table('question_multianswer', array('question' => backup::VAR_PARENTID));
|
||||
$multianswer->set_source_table('question_multianswer',
|
||||
array('question' => backup::VAR_PARENTID));
|
||||
|
||||
// don't need to annotate ids nor files
|
||||
|
||||
|
|
|
@ -38,7 +38,6 @@ class restore_qtype_multianswer_plugin extends restore_qtype_plugin {
|
|||
* Returns the paths to be handled by the plugin at question level
|
||||
*/
|
||||
protected function define_question_plugin_structure() {
|
||||
|
||||
$paths = array();
|
||||
|
||||
// This qtype uses question_answers, add them
|
||||
|
@ -46,10 +45,9 @@ class restore_qtype_multianswer_plugin extends restore_qtype_plugin {
|
|||
|
||||
// Add own qtype stuff
|
||||
$elename = 'multianswer';
|
||||
$elepath = $this->get_pathfor('/multianswer'); // we used get_recommended_name() so this works
|
||||
$elepath = $this->get_pathfor('/multianswer');
|
||||
$paths[] = new restore_path_element($elename, $elepath);
|
||||
|
||||
|
||||
return $paths; // And we return the interesting paths
|
||||
}
|
||||
|
||||
|
@ -67,7 +65,8 @@ class restore_qtype_multianswer_plugin extends restore_qtype_plugin {
|
|||
$newquestionid = $this->get_new_parentid('question');
|
||||
$questioncreated = $this->get_mappingid('question_created', $oldquestionid) ? true : false;
|
||||
|
||||
// If the question has been created by restore, we need to create its question_multianswer too
|
||||
// If the question has been created by restore, we need to create its
|
||||
// question_multianswer too
|
||||
if ($questioncreated) {
|
||||
// Adjust some columns
|
||||
$data->question = $newquestionid;
|
||||
|
@ -79,8 +78,6 @@ class restore_qtype_multianswer_plugin extends restore_qtype_plugin {
|
|||
$newitemid = $DB->insert_record('question_multianswer', $data);
|
||||
// Create mapping (need it for after_execute recode of sequence)
|
||||
$this->set_mapping('question_multianswer', $oldid, $newitemid);
|
||||
} else {
|
||||
// Nothing to remap if the question already existed
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,18 +94,21 @@ class restore_qtype_multianswer_plugin extends restore_qtype_plugin {
|
|||
global $DB;
|
||||
// Now that all the questions have been restored, let's process
|
||||
// the created question_multianswer sequences (list of question ids)
|
||||
$rs = $DB->get_recordset_sql("SELECT qma.id, qma.sequence
|
||||
$rs = $DB->get_recordset_sql("
|
||||
SELECT qma.id, qma.sequence
|
||||
FROM {question_multianswer} qma
|
||||
JOIN {backup_ids_temp} bi ON bi.newitemid = qma.question
|
||||
WHERE bi.backupid = ?
|
||||
AND bi.itemname = 'question_created'", array($this->get_restoreid()));
|
||||
AND bi.itemname = 'question_created'",
|
||||
array($this->get_restoreid()));
|
||||
foreach ($rs as $rec) {
|
||||
$sequencearr = explode(',', $rec->sequence);
|
||||
foreach ($sequencearr as $key => $question) {
|
||||
$sequencearr[$key] = $this->get_mappingid('question', $question);
|
||||
}
|
||||
$sequence = implode(',', $sequencearr);
|
||||
$DB->set_field('question_multianswer', 'sequence', $sequence, array('id' => $rec->id));
|
||||
$DB->set_field('question_multianswer', 'sequence', $sequence,
|
||||
array('id' => $rec->id));
|
||||
}
|
||||
$rs->close();
|
||||
}
|
||||
|
@ -127,7 +127,8 @@ class restore_qtype_multianswer_plugin extends restore_qtype_plugin {
|
|||
$answer = $state->answer;
|
||||
$resultarr = array();
|
||||
// Get sequence of questions
|
||||
$sequence = $DB->get_field('question_multianswer', 'sequence', array('question' => $state->question));
|
||||
$sequence = $DB->get_field('question_multianswer', 'sequence',
|
||||
array('question' => $state->question));
|
||||
$sequencearr = explode(',', $sequence);
|
||||
// Let's process each pair
|
||||
foreach (explode(',', $answer) as $pair) {
|
||||
|
|
|
@ -35,9 +35,11 @@ defined('MOODLE_INTERNAL') || die();
|
|||
*/
|
||||
class question_edit_multianswer_form extends question_edit_form {
|
||||
|
||||
// $questiondisplay will contain the qtype_multianswer_extract_question from the questiontext
|
||||
// $questiondisplay will contain the qtype_multianswer_extract_question from
|
||||
// the questiontext
|
||||
public $questiondisplay;
|
||||
// $savedquestiondisplay will contain the qtype_multianswer_extract_question from the questiontext in database
|
||||
// $savedquestiondisplay will contain the qtype_multianswer_extract_question
|
||||
// from the questiontext in database
|
||||
public $savedquestion;
|
||||
public $savedquestiondisplay;
|
||||
public $used_in_quiz = false;
|
||||
|
@ -48,23 +50,25 @@ class question_edit_multianswer_form extends question_edit_form {
|
|||
public $confirm = 0;
|
||||
public $reload = false;
|
||||
|
||||
function question_edit_multianswer_form(&$submiturl, &$question, &$category, &$contexts, $formeditable = true){
|
||||
global $QTYPES, $SESSION, $CFG, $DB;
|
||||
public function __construct($submiturl, $question, $category, $contexts, $formeditable = true) {
|
||||
global $SESSION, $CFG, $DB;
|
||||
$this->regenerate = true;
|
||||
if ("1" == optional_param('reload', '', PARAM_INT)) {
|
||||
$this->reload = true;
|
||||
} else {
|
||||
$this->reload = false;
|
||||
}
|
||||
// $this->question = $question;
|
||||
|
||||
$this->used_in_quiz = false;
|
||||
// echo "<p> question <pre>";print_r($question);echo "</pre></p>";
|
||||
|
||||
if (isset($question->id) && $question->id != 0) {
|
||||
$this->savedquestiondisplay = fullclone($question);
|
||||
if ($list = $DB->get_records('quiz_question_instances', array( 'question'=> $question->id))){
|
||||
if ($list = $DB->get_records('quiz_question_instances',
|
||||
array('question' => $question->id))) {
|
||||
foreach ($list as $key => $li) {
|
||||
$this->nb_of_quiz ++;
|
||||
if($att = $DB->get_records('quiz_attempts',array( 'quiz'=> $li->quiz, 'preview'=> '0'))){
|
||||
if ($att = $DB->get_records('quiz_attempts',
|
||||
array('quiz' => $li->quiz, 'preview' => '0'))) {
|
||||
$this->nb_of_attempts += count($att);
|
||||
$this->used_in_quiz = true;
|
||||
}
|
||||
|
@ -72,12 +76,11 @@ class question_edit_multianswer_form extends question_edit_form {
|
|||
}
|
||||
}
|
||||
|
||||
parent::question_edit_form($submiturl, $question, $category, $contexts, $formeditable);
|
||||
parent::__construct($submiturl, $question, $category, $contexts, $formeditable);
|
||||
}
|
||||
|
||||
protected function definition_inner($mform) {
|
||||
$mform->addElement('hidden', 'reload', 1);
|
||||
// $mform->addElement('hidden', 'generalfeedback','');
|
||||
$mform->setType('reload', PARAM_INT);
|
||||
|
||||
// Remove meaningless defaultgrade field.
|
||||
|
@ -86,9 +89,8 @@ class question_edit_multianswer_form extends question_edit_form {
|
|||
|
||||
// display the questions from questiontext;
|
||||
if ("" != optional_param('questiontext', '', PARAM_RAW)) {
|
||||
// echo "<p> optional_param('questiontext' <pre>";print_r(optional_param('questiontext','', PARAM_RAW));echo "</pre></p>";
|
||||
|
||||
$this->questiondisplay = fullclone(qtype_multianswer_extract_question(optional_param('questiontext','', PARAM_RAW))) ;
|
||||
$this->questiondisplay = fullclone(qtype_multianswer_extract_question(
|
||||
optional_param('questiontext', '', PARAM_RAW)));
|
||||
|
||||
} else {
|
||||
if (!$this->reload && !empty($this->savedquestiondisplay->id)) {
|
||||
|
@ -101,7 +103,6 @@ class question_edit_multianswer_form extends question_edit_form {
|
|||
foreach ($subquestion->options->answers as $ans) {
|
||||
$subquestion->answer[] = $ans->answer;
|
||||
}
|
||||
// $subquestion->answer = fullclone($subquestion->options->answers);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -109,7 +110,8 @@ class question_edit_multianswer_form extends question_edit_form {
|
|||
}
|
||||
}
|
||||
|
||||
if ( isset($this->savedquestiondisplay->options->questions) && is_array($this->savedquestiondisplay->options->questions) ) {
|
||||
if (isset($this->savedquestiondisplay->options->questions) &&
|
||||
is_array($this->savedquestiondisplay->options->questions)) {
|
||||
$countsavedsubquestions = 0;
|
||||
foreach ($this->savedquestiondisplay->options->questions as $subquestion) {
|
||||
if (!empty($subquestion)) {
|
||||
|
@ -120,7 +122,8 @@ class question_edit_multianswer_form extends question_edit_form {
|
|||
$countsavedsubquestions = 0;
|
||||
}
|
||||
if ($this->reload) {
|
||||
if ( isset($this->questiondisplay->options->questions) && is_array($this->questiondisplay->options->questions) ) {
|
||||
if (isset($this->questiondisplay->options->questions) &&
|
||||
is_array($this->questiondisplay->options->questions)) {
|
||||
$countsubquestions = 0;
|
||||
foreach ($this->questiondisplay->options->questions as $subquestion) {
|
||||
if (!empty($subquestion)) {
|
||||
|
@ -133,11 +136,9 @@ class question_edit_multianswer_form extends question_edit_form {
|
|||
} else {
|
||||
$countsubquestions = $countsavedsubquestions;
|
||||
}
|
||||
// echo "<p> count subquestion $countsubquestions <pre>";print_r($this->savedquestiondisplay);echo "</pre></p>";
|
||||
// // echo "<p> saved question $countsubquestions <pre>";print_r($this->questiondisplay);echo "</pre></p>";
|
||||
|
||||
|
||||
$mform->addElement('submit', 'analyzequestion', get_string('decodeverifyquestiontext','qtype_multianswer'));
|
||||
$mform->addElement('submit', 'analyzequestion',
|
||||
get_string('decodeverifyquestiontext', 'qtype_multianswer'));
|
||||
$mform->registerNoSubmitButton('analyzequestion');
|
||||
if ($this->reload) {
|
||||
$mform->addElement('html', '<div class="ablock clearfix">');
|
||||
|
@ -152,71 +153,104 @@ class question_edit_multianswer_form extends question_edit_form {
|
|||
}
|
||||
$storemess = '';
|
||||
if (isset($this->savedquestiondisplay->options->questions[$sub]->qtype) &&
|
||||
$this->savedquestiondisplay->options->questions[$sub]->qtype != $this->questiondisplay->options->questions[$sub]->qtype ){
|
||||
$this->savedquestiondisplay->options->questions[$sub]->qtype !=
|
||||
$this->questiondisplay->options->questions[$sub]->qtype) {
|
||||
$this->qtype_change = true;
|
||||
$storemess = "<font class=\"error\"> STORED QTYPE ".question_bank::get_qtype_name($this->savedquestiondisplay->options->questions[$sub]->qtype)."</font >";
|
||||
$storemess = "<font class=\"error\"> STORED QTYPE " .
|
||||
question_bank::get_qtype_name(
|
||||
$this->savedquestiondisplay->options->questions[$sub]->qtype).
|
||||
"</font >";
|
||||
}
|
||||
|
||||
$mform->addElement('header', 'subhdr'.$sub, get_string('questionno', 'question',
|
||||
'{#'.$sub.'}').' '.question_bank::get_qtype_name($this->questiondisplay->options->questions[$sub]->qtype).$storemess);
|
||||
'{#'.$sub.'}').' '.question_bank::get_qtype_name(
|
||||
$this->questiondisplay->options->questions[$sub]->qtype).$storemess);
|
||||
|
||||
$mform->addElement('static', 'sub_'.$sub."_".'questiontext', get_string('questiondefinition','qtype_multianswer'),array('cols'=>60, 'rows'=>3));
|
||||
$mform->addElement('static', 'sub_'.$sub."_".'questiontext',
|
||||
get_string('questiondefinition', 'qtype_multianswer'),
|
||||
array('cols' => 60, 'rows' => 3));
|
||||
|
||||
if (isset ($this->questiondisplay->options->questions[$sub]->questiontext)) {
|
||||
$mform->setDefault('sub_'.$sub."_".'questiontext', $this->questiondisplay->options->questions[$sub]->questiontext['text']);
|
||||
$mform->setDefault('sub_'.$sub."_".'questiontext',
|
||||
$this->questiondisplay->options->questions[$sub]->questiontext['text']);
|
||||
}
|
||||
|
||||
$mform->addElement('static', 'sub_'.$sub."_".'defaultgrade', get_string('defaultgrade', 'question'));
|
||||
$mform->setDefault('sub_'.$sub."_".'defaultgrade',$this->questiondisplay->options->questions[$sub]->defaultgrade);
|
||||
$mform->addElement('static', 'sub_'.$sub."_".'defaultgrade',
|
||||
get_string('defaultgrade', 'question'));
|
||||
$mform->setDefault('sub_'.$sub."_".'defaultgrade',
|
||||
$this->questiondisplay->options->questions[$sub]->defaultgrade);
|
||||
|
||||
if ($this->questiondisplay->options->questions[$sub]->qtype == 'shortanswer') {
|
||||
$mform->addElement('static', 'sub_'.$sub."_".'usecase', get_string('casesensitive', 'question'));
|
||||
$mform->addElement('static', 'sub_'.$sub."_".'usecase',
|
||||
get_string('casesensitive', 'question'));
|
||||
}
|
||||
|
||||
if ($this->questiondisplay->options->questions[$sub]->qtype == 'multichoice') {
|
||||
$mform->addElement('static', 'sub_'.$sub."_".'layout', get_string('layout', 'qtype_multianswer'),array('cols'=>60, 'rows'=>1)) ;//, $gradeoptions);
|
||||
$mform->addElement('static', 'sub_'.$sub."_".'layout',
|
||||
get_string('layout', 'qtype_multianswer'),
|
||||
array('cols' => 60, 'rows' => 1));
|
||||
}
|
||||
foreach ($this->questiondisplay->options->questions[$sub]->answer as $key => $ans) {
|
||||
|
||||
$mform->addElement('static', 'sub_'.$sub."_".'answer['.$key.']', get_string('answer', 'question'), array('cols'=>60, 'rows'=>1));
|
||||
$mform->addElement('static', 'sub_'.$sub."_".'answer['.$key.']',
|
||||
get_string('answer', 'question'), array('cols' => 60, 'rows' => 1));
|
||||
|
||||
if ($this->questiondisplay->options->questions[$sub]->qtype =='numerical' && $key == 0 ) {
|
||||
$mform->addElement('static', 'sub_'.$sub."_".'tolerance['.$key.']', get_string('acceptederror', 'quiz')) ;//, $gradeoptions);
|
||||
if ($this->questiondisplay->options->questions[$sub]->qtype == 'numerical' &&
|
||||
$key == 0) {
|
||||
$mform->addElement('static', 'sub_'.$sub."_".'tolerance['.$key.']',
|
||||
get_string('acceptederror', 'quiz'));
|
||||
}
|
||||
|
||||
$mform->addElement('static', 'sub_'.$sub."_".'fraction['.$key.']', get_string('grade')) ;//, $gradeoptions);
|
||||
$mform->addElement('static', 'sub_'.$sub."_".'fraction['.$key.']',
|
||||
get_string('grade'));
|
||||
|
||||
$mform->addElement('static', 'sub_'.$sub."_".'feedback['.$key.']', get_string('feedback', 'question'));
|
||||
$mform->addElement('static', 'sub_'.$sub."_".'feedback['.$key.']',
|
||||
get_string('feedback', 'question'));
|
||||
}
|
||||
|
||||
}
|
||||
$mform->addElement('html', '</div>');
|
||||
$this->negative_diff = $countsavedsubquestions - $countsubquestions;
|
||||
if ( ($this->negative_diff > 0 ) ||$this->qtype_change || ($this->used_in_quiz && $this->negative_diff != 0)){
|
||||
$mform->addElement('header', 'additemhdr', get_string('warningquestionmodified','qtype_multianswer'));
|
||||
if (($this->negative_diff > 0) ||$this->qtype_change ||
|
||||
($this->used_in_quiz && $this->negative_diff != 0)) {
|
||||
$mform->addElement('header', 'additemhdr',
|
||||
get_string('warningquestionmodified', 'qtype_multianswer'));
|
||||
}
|
||||
if ($this->negative_diff > 0) {
|
||||
$mform->addElement('static', 'alert1', "<strong>".get_string('questiondeleted','qtype_multianswer')."</strong>",get_string('questionsless','qtype_multianswer',$this->negative_diff));
|
||||
$mform->addElement('static', 'alert1', "<strong>".
|
||||
get_string('questiondeleted', 'qtype_multianswer')."</strong>",
|
||||
get_string('questionsless', 'qtype_multianswer', $this->negative_diff));
|
||||
}
|
||||
if ($this->qtype_change) {
|
||||
$mform->addElement('static', 'alert1', "<strong>".get_string('questiontypechanged','qtype_multianswer')."</strong>",get_string('questiontypechangedcomment','qtype_multianswer'));
|
||||
$mform->addElement('static', 'alert1', "<strong>".
|
||||
get_string('questiontypechanged', 'qtype_multianswer')."</strong>",
|
||||
get_string('questiontypechangedcomment', 'qtype_multianswer'));
|
||||
}
|
||||
$mform->addElement('html', '</div>');
|
||||
}
|
||||
if ($this->used_in_quiz) {
|
||||
if ($this->negative_diff < 0) {
|
||||
$diff = $countsubquestions - $countsavedsubquestions;
|
||||
$mform->addElement('static', 'alert1', "<strong>".get_string('questionsadded','qtype_multianswer')."</strong>","<strong>".get_string('questionsmore','qtype_multianswer',$diff)."</strong>");
|
||||
$mform->addElement('static', 'alert1', "<strong>".
|
||||
get_string('questionsadded', 'qtype_multianswer')."</strong>",
|
||||
"<strong>".get_string('questionsmore', 'qtype_multianswer', $diff).
|
||||
"</strong>");
|
||||
}
|
||||
$a = new stdClass();
|
||||
$a->nb_of_quiz = $this->nb_of_quiz;
|
||||
$a->nb_of_attempts = $this->nb_of_attempts;
|
||||
$mform->addElement('header', 'additemhdr2', get_string('questionusedinquiz','qtype_multianswer',$a));
|
||||
$mform->addElement('static', 'alertas', get_string('youshouldnot','qtype_multianswer'));
|
||||
$mform->addElement('header', 'additemhdr2',
|
||||
get_string('questionusedinquiz', 'qtype_multianswer', $a));
|
||||
$mform->addElement('static', 'alertas',
|
||||
get_string('youshouldnot', 'qtype_multianswer'));
|
||||
}
|
||||
if ( ($this->negative_diff > 0 || $this->used_in_quiz && ($this->negative_diff > 0 ||$this->negative_diff < 0 || $this->qtype_change ) ) && $this->reload ){
|
||||
$mform->addElement('header', 'additemhdr', get_string('questionsaveasedited', 'qtype_multianswer'));
|
||||
$mform->addElement('checkbox', 'confirm','' ,get_string('confirmquestionsaveasedited', 'qtype_multianswer'));
|
||||
if (($this->negative_diff > 0 || $this->used_in_quiz &&
|
||||
($this->negative_diff > 0 || $this->negative_diff < 0 || $this->qtype_change)) &&
|
||||
$this->reload) {
|
||||
$mform->addElement('header', 'additemhdr',
|
||||
get_string('questionsaveasedited', 'qtype_multianswer'));
|
||||
$mform->addElement('checkbox', 'confirm', '',
|
||||
get_string('confirmquestionsaveasedited', 'qtype_multianswer'));
|
||||
$mform->setDefault('confirm', 0);
|
||||
} else {
|
||||
$mform->addElement('hidden', 'confirm', 0);
|
||||
|
@ -225,10 +259,11 @@ class question_edit_multianswer_form extends question_edit_form {
|
|||
}
|
||||
|
||||
|
||||
function set_data($question) {
|
||||
public function set_data($question) {
|
||||
global $DB;
|
||||
$default_values = array();
|
||||
if (isset($question->id) and $question->id and $question->qtype and $question->questiontext) {
|
||||
if (isset($question->id) and $question->id and $question->qtype &&
|
||||
$question->questiontext) {
|
||||
|
||||
foreach ($question->options->questions as $key => $wrapped) {
|
||||
if (!empty($wrapped)) {
|
||||
|
@ -247,7 +282,8 @@ class question_edit_multianswer_form extends question_edit_form {
|
|||
$parsableanswerdef .= 'NUMERICAL:';
|
||||
break;
|
||||
default:
|
||||
print_error('unknownquestiontype', 'question', '', $wrapped->qtype);
|
||||
print_error('unknownquestiontype', 'question', '',
|
||||
$wrapped->qtype);
|
||||
}
|
||||
$separator = '';
|
||||
foreach ($wrapped->options->answers as $subanswer) {
|
||||
|
@ -268,11 +304,13 @@ class question_edit_multianswer_form extends question_edit_form {
|
|||
}
|
||||
$parsableanswerdef .= '}';
|
||||
// Fix the questiontext fields of old questions
|
||||
$DB->set_field('question', 'questiontext', $parsableanswerdef, array('id' => $wrapped->id));
|
||||
$DB->set_field('question', 'questiontext', $parsableanswerdef,
|
||||
array('id' => $wrapped->id));
|
||||
} else {
|
||||
$parsableanswerdef = str_replace('&#', '&\#', $wrapped->questiontext);
|
||||
}
|
||||
$question->questiontext = str_replace("{#$key}", $parsableanswerdef, $question->questiontext);
|
||||
$question->questiontext = str_replace("{#$key}", $parsableanswerdef,
|
||||
$question->questiontext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -293,11 +331,13 @@ class question_edit_multianswer_form extends question_edit_form {
|
|||
if ($subquestion->qtype == 'shortanswer') {
|
||||
switch ($subquestion->usecase) {
|
||||
case '1':
|
||||
$default_values[$prefix.'usecase']= get_string('caseyes', 'qtype_shortanswer');
|
||||
$default_values[$prefix.'usecase'] =
|
||||
get_string('caseyes', 'qtype_shortanswer');
|
||||
break;
|
||||
case '0':
|
||||
default :
|
||||
$default_values[$prefix.'usecase']= get_string('caseno', 'qtype_shortanswer');
|
||||
$default_values[$prefix.'usecase'] =
|
||||
get_string('caseno', 'qtype_shortanswer');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -305,27 +345,35 @@ class question_edit_multianswer_form extends question_edit_form {
|
|||
$default_values[$prefix.'layout'] = $subquestion->layout;
|
||||
switch ($subquestion->layout) {
|
||||
case '0':
|
||||
$default_values[$prefix.'layout']= get_string('layoutselectinline', 'qtype_multianswer');
|
||||
$default_values[$prefix.'layout'] =
|
||||
get_string('layoutselectinline', 'qtype_multianswer');
|
||||
break;
|
||||
case '1':
|
||||
$default_values[$prefix.'layout']= get_string('layoutvertical', 'qtype_multianswer');
|
||||
$default_values[$prefix.'layout'] =
|
||||
get_string('layoutvertical', 'qtype_multianswer');
|
||||
break;
|
||||
case '2':
|
||||
$default_values[$prefix.'layout']= get_string('layouthorizontal', 'qtype_multianswer');
|
||||
$default_values[$prefix.'layout'] =
|
||||
get_string('layouthorizontal', 'qtype_multianswer');
|
||||
break;
|
||||
default:
|
||||
$default_values[$prefix.'layout']= get_string('layoutundefined', 'qtype_multianswer');
|
||||
$default_values[$prefix.'layout'] =
|
||||
get_string('layoutundefined', 'qtype_multianswer');
|
||||
}
|
||||
}
|
||||
foreach ($subquestion->answer as $key => $answer) {
|
||||
if ($subquestion->qtype == 'numerical' && $key == 0) {
|
||||
$default_values[$prefix.'tolerance['.$key.']'] = $subquestion->tolerance[0] ;
|
||||
$default_values[$prefix.'tolerance['.$key.']'] =
|
||||
$subquestion->tolerance[0];
|
||||
}
|
||||
$trimmedanswer = trim($answer);
|
||||
if ($trimmedanswer !== '') {
|
||||
$answercount++;
|
||||
if ($subquestion->qtype == 'numerical' && !(is_numeric($trimmedanswer) || $trimmedanswer == '*')) {
|
||||
$this->_form->setElementError($prefix.'answer['.$key.']' , get_string('answermustbenumberorstar', 'qtype_numerical'));
|
||||
if ($subquestion->qtype == 'numerical' &&
|
||||
!(is_numeric($trimmedanswer) || $trimmedanswer == '*')) {
|
||||
$this->_form->setElementError($prefix.'answer['.$key.']',
|
||||
get_string('answermustbenumberorstar',
|
||||
'qtype_numerical'));
|
||||
}
|
||||
if ($subquestion->fraction[$key] == 1) {
|
||||
$maxgrade = true;
|
||||
|
@ -335,33 +383,38 @@ class question_edit_multianswer_form extends question_edit_form {
|
|||
}
|
||||
}
|
||||
|
||||
$default_values[$prefix.'answer['.$key.']'] = htmlspecialchars ($answer);
|
||||
$default_values[$prefix.'answer['.$key.']'] =
|
||||
htmlspecialchars($answer);
|
||||
}
|
||||
if ($answercount == 0) {
|
||||
if ($subquestion->qtype == 'multichoice') {
|
||||
$this->_form->setElementError($prefix.'answer[0]' , get_string('notenoughanswers', 'qtype_multichoice', 2));
|
||||
$this->_form->setElementError($prefix.'answer[0]',
|
||||
get_string('notenoughanswers', 'qtype_multichoice', 2));
|
||||
} else {
|
||||
$this->_form->setElementError($prefix.'answer[0]' , get_string('notenoughanswers', 'question', 1));
|
||||
$this->_form->setElementError($prefix.'answer[0]',
|
||||
get_string('notenoughanswers', 'question', 1));
|
||||
}
|
||||
}
|
||||
if ($maxgrade == false) {
|
||||
$this->_form->setElementError($prefix.'fraction[0]' ,get_string('fractionsnomax', 'question'));
|
||||
$this->_form->setElementError($prefix.'fraction[0]',
|
||||
get_string('fractionsnomax', 'question'));
|
||||
}
|
||||
foreach ($subquestion->feedback as $key => $answer) {
|
||||
|
||||
$default_values[$prefix.'feedback['.$key.']'] = htmlspecialchars ($answer['text']);
|
||||
$default_values[$prefix.'feedback['.$key.']'] =
|
||||
htmlspecialchars ($answer['text']);
|
||||
}
|
||||
foreach ($subquestion->fraction as $key => $answer) {
|
||||
$default_values[$prefix.'fraction['.$key.']'] = $answer;
|
||||
}
|
||||
|
||||
|
||||
$sub++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$default_values['alertas']= "<strong>".get_string('questioninquiz','qtype_multianswer')."</strong>";
|
||||
$default_values['alertas']= "<strong>".get_string('questioninquiz', 'qtype_multianswer').
|
||||
"</strong>";
|
||||
|
||||
if ($default_values != "") {
|
||||
$question = (object)((array)$question + $default_values);
|
||||
|
@ -369,11 +422,10 @@ class question_edit_multianswer_form extends question_edit_form {
|
|||
parent::set_data($question);
|
||||
}
|
||||
|
||||
function validation($data, $files) {
|
||||
public function validation($data, $files) {
|
||||
$errors = parent::validation($data, $files);
|
||||
|
||||
$questiondisplay = qtype_multianswer_extract_question($data['questiontext']);
|
||||
// echo "<p> questiondisplay ".$data['questiontext']['text']." <pre>";print_r($questiondisplay);echo "</pre></p>";
|
||||
|
||||
if (isset($questiondisplay->options->questions)) {
|
||||
$subquestions = fullclone($questiondisplay->options->questions);
|
||||
|
@ -385,15 +437,19 @@ class question_edit_multianswer_form extends question_edit_form {
|
|||
$maxgrade = false;
|
||||
$maxfraction = -1;
|
||||
if (isset($this->savedquestiondisplay->options->questions[$sub]->qtype) &&
|
||||
$this->savedquestiondisplay->options->questions[$sub]->qtype != $questiondisplay->options->questions[$sub]->qtype ){
|
||||
$storemess = " STORED QTYPE ".question_bank::get_qtype_name($this->savedquestiondisplay->options->questions[$sub]->qtype);
|
||||
$this->savedquestiondisplay->options->questions[$sub]->qtype !=
|
||||
$questiondisplay->options->questions[$sub]->qtype) {
|
||||
$storemess = " STORED QTYPE ".question_bank::get_qtype_name(
|
||||
$this->savedquestiondisplay->options->questions[$sub]->qtype);
|
||||
}
|
||||
foreach ($subquestion->answer as $key => $answer) {
|
||||
$trimmedanswer = trim($answer);
|
||||
if ($trimmedanswer !== '') {
|
||||
$answercount++;
|
||||
if ($subquestion->qtype =='numerical' && !(is_numeric($trimmedanswer) || $trimmedanswer == '*')) {
|
||||
$errors[$prefix.'answer['.$key.']']= get_string('answermustbenumberorstar', 'qtype_numerical');
|
||||
if ($subquestion->qtype == 'numerical' &&
|
||||
!(is_numeric($trimmedanswer) || $trimmedanswer == '*')) {
|
||||
$errors[$prefix.'answer['.$key.']'] =
|
||||
get_string('answermustbenumberorstar', 'qtype_numerical');
|
||||
}
|
||||
if ($subquestion->fraction[$key] == 1) {
|
||||
$maxgrade = true;
|
||||
|
@ -405,13 +461,16 @@ class question_edit_multianswer_form extends question_edit_form {
|
|||
}
|
||||
if ($answercount == 0) {
|
||||
if ($subquestion->qtype == 'multichoice') {
|
||||
$errors[$prefix.'answer[0]']= get_string('notenoughanswers', 'qtype_multichoice', 2);
|
||||
$errors[$prefix.'answer[0]'] =
|
||||
get_string('notenoughanswers', 'qtype_multichoice', 2);
|
||||
} else {
|
||||
$errors[$prefix.'answer[0]'] = get_string('notenoughanswers', 'question', 1);
|
||||
$errors[$prefix.'answer[0]'] =
|
||||
get_string('notenoughanswers', 'question', 1);
|
||||
}
|
||||
}
|
||||
if ($maxgrade == false) {
|
||||
$errors[$prefix.'fraction[0]']=get_string('fractionsnomax', 'question');
|
||||
$errors[$prefix.'fraction[0]'] =
|
||||
get_string('fractionsnomax', 'question');
|
||||
}
|
||||
$sub++;
|
||||
}
|
||||
|
@ -419,17 +478,18 @@ class question_edit_multianswer_form extends question_edit_form {
|
|||
$errors['questiontext'] = get_string('questionsmissing', 'qtype_multianswer');
|
||||
}
|
||||
}
|
||||
// $question = qtype_multianswer_extract_question($data['questiontext']);
|
||||
// if (isset $question->options->questions
|
||||
if (( $this->negative_diff > 0 || $this->used_in_quiz && ($this->negative_diff > 0 ||$this->negative_diff < 0 || $this->qtype_change ))&& $this->confirm == 0 ){
|
||||
$errors['confirm']=get_string('confirmsave', 'qtype_multianswer',$this->negative_diff);
|
||||
}
|
||||
|
||||
if (($this->negative_diff > 0 || $this->used_in_quiz &&
|
||||
($this->negative_diff > 0 || $this->negative_diff < 0 ||
|
||||
$this->qtype_change))&& $this->confirm == 0) {
|
||||
$errors['confirm'] =
|
||||
get_string('confirmsave', 'qtype_multianswer', $this->negative_diff);
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
function qtype() {
|
||||
public function qtype() {
|
||||
return 'multianswer';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,16 +35,16 @@ defined('MOODLE_INTERNAL') || die();
|
|||
*/
|
||||
class embedded_cloze_qtype extends question_type {
|
||||
|
||||
function name() {
|
||||
public function name() {
|
||||
return 'multianswer';
|
||||
}
|
||||
|
||||
function requires_qtypes() {
|
||||
public function requires_qtypes() {
|
||||
return array('shortanswer', 'numerical', 'multichoice');
|
||||
}
|
||||
|
||||
function get_question_options(&$question) {
|
||||
global $QTYPES, $DB, $OUTPUT;
|
||||
public function get_question_options($question) {
|
||||
global $DB, $OUTPUT;
|
||||
|
||||
// Get relevant data indexed by positionkey from the multianswers table
|
||||
if (!$sequence = $DB->get_field('question_multianswer', 'sequence', array('question' => $question->id))) {
|
||||
|
@ -76,7 +76,8 @@ class embedded_cloze_qtype extends question_type {
|
|||
// there is no entry in the question_instances table for them
|
||||
$wrapped->maxgrade = $wrapped->defaultgrade;
|
||||
$nbvaliquestion++;
|
||||
$question->options->questions[$sequence[$wrapped->id]] = clone($wrapped); // ??? Why do we need a clone here?
|
||||
// ??? Why do we need a clone here?
|
||||
$question->options->questions[$sequence[$wrapped->id]] = clone($wrapped);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,8 +88,8 @@ class embedded_cloze_qtype extends question_type {
|
|||
return true;
|
||||
}
|
||||
|
||||
function save_question_options($question) {
|
||||
global $QTYPES, $DB;
|
||||
public function save_question_options($question) {
|
||||
global $DB;
|
||||
$result = new stdClass();
|
||||
|
||||
// This function needs to be able to handle the case where the existing set of wrapped
|
||||
|
@ -164,7 +165,7 @@ class embedded_cloze_qtype extends question_type {
|
|||
}
|
||||
}
|
||||
|
||||
function save_question($authorizedquestion, $form) {
|
||||
public function save_question($authorizedquestion, $form) {
|
||||
$question = qtype_multianswer_extract_question($form->questiontext);
|
||||
if (isset($authorizedquestion->id)) {
|
||||
$question->id = $authorizedquestion->id;
|
||||
|
@ -179,7 +180,7 @@ class embedded_cloze_qtype extends question_type {
|
|||
return parent::save_question($question, $form);
|
||||
}
|
||||
|
||||
function create_session_and_responses(&$question, &$state, $cmoptions, $attempt) {
|
||||
public function create_session_and_responses(&$question, &$state, $cmoptions, $attempt) {
|
||||
$state->responses = array();
|
||||
foreach ($question->options->questions as $key => $wrapped) {
|
||||
$state->responses[$key] = '';
|
||||
|
@ -187,7 +188,7 @@ class embedded_cloze_qtype extends question_type {
|
|||
return true;
|
||||
}
|
||||
|
||||
function restore_session_and_responses(&$question, &$state) {
|
||||
public function restore_session_and_responses(&$question, &$state) {
|
||||
$responses = explode(',', $state->responses['']);
|
||||
$state->responses = array();
|
||||
foreach ($responses as $response) {
|
||||
|
@ -199,7 +200,7 @@ class embedded_cloze_qtype extends question_type {
|
|||
return true;
|
||||
}
|
||||
|
||||
function save_session_and_responses(&$question, &$state) {
|
||||
public function save_session_and_responses(&$question, &$state) {
|
||||
global $DB;
|
||||
$responses = $state->responses;
|
||||
// encode - (hyphen) and , (comma) to - because they are used as
|
||||
|
@ -214,33 +215,14 @@ class embedded_cloze_qtype extends question_type {
|
|||
return true;
|
||||
}
|
||||
|
||||
function delete_question($questionid, $contextid) {
|
||||
public function delete_question($questionid, $contextid) {
|
||||
global $DB;
|
||||
$DB->delete_records("question_multianswer", array("question" => $questionid));
|
||||
|
||||
parent::delete_question($questionid, $contextid);
|
||||
}
|
||||
|
||||
function get_correct_responses(&$question, &$state) {
|
||||
global $QTYPES;
|
||||
$responses = array();
|
||||
foreach($question->options->questions as $key => $wrapped) {
|
||||
if (!empty($wrapped)){
|
||||
if ($correct = $QTYPES[$wrapped->qtype]->get_correct_responses($wrapped, $state)) {
|
||||
$responses[$key] = $correct[''];
|
||||
} else {
|
||||
// if there is no correct answer to this subquestion then there
|
||||
// can not be a correct answer to the whole question either, so
|
||||
// we have to return null.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $responses;
|
||||
}
|
||||
|
||||
function get_possible_responses(&$question) {
|
||||
global $QTYPES;
|
||||
public function get_possible_responses(&$question) {
|
||||
$responses = array();
|
||||
foreach ($question->options->questions as $key => $wrapped) {
|
||||
if (!empty($wrapped)) {
|
||||
|
@ -256,28 +238,16 @@ class embedded_cloze_qtype extends question_type {
|
|||
}
|
||||
return $responses;
|
||||
}
|
||||
function get_actual_response_details($question, $state){
|
||||
global $QTYPES;
|
||||
$details = array();
|
||||
foreach($question->options->questions as $key => $wrapped) {
|
||||
if (!empty($wrapped)){
|
||||
$stateforquestion = clone($state);
|
||||
$stateforquestion->responses[''] = $state->responses[$key];
|
||||
$details = array_merge($details, $QTYPES[$wrapped->qtype]->get_actual_response_details($wrapped, $stateforquestion));
|
||||
}
|
||||
}
|
||||
return $details;
|
||||
}
|
||||
|
||||
function get_html_head_contributions(&$question, &$state) {
|
||||
public function get_html_head_contributions(&$question, &$state) {
|
||||
global $PAGE;
|
||||
parent::get_html_head_contributions($question, $state);
|
||||
$PAGE->requires->js('/lib/overlib/overlib.js', true);
|
||||
$PAGE->requires->js('/lib/overlib/overlib_cssstyle.js', true);
|
||||
}
|
||||
|
||||
function print_question_formulation_and_controls(&$question, &$state, $cmoptions, $options) {
|
||||
global $QTYPES, $CFG, $USER, $OUTPUT, $PAGE;
|
||||
public function print_question_formulation_and_controls(&$question, &$state, $cmoptions, $options) {
|
||||
global $CFG, $USER, $OUTPUT, $PAGE;
|
||||
|
||||
$readonly = empty($options->readonly) ? '' : 'readonly="readonly"';
|
||||
$disabled = empty($options->readonly) ? '' : 'disabled="disabled"';
|
||||
|
@ -312,7 +282,6 @@ class embedded_cloze_qtype extends question_type {
|
|||
if (isset($question->options->questions[$positionkey]) && $question->options->questions[$positionkey] != '') {
|
||||
$wrapped = &$question->options->questions[$positionkey];
|
||||
$answers = &$wrapped->options->answers;
|
||||
// $correctanswers = $QTYPES[$wrapped->qtype]->get_correct_responses($wrapped, $state);
|
||||
|
||||
$inputname = $nameprefix.$positionkey;
|
||||
if (isset($state->responses[$positionkey])) {
|
||||
|
@ -320,7 +289,6 @@ class embedded_cloze_qtype extends question_type {
|
|||
} else {
|
||||
$response = null;
|
||||
}
|
||||
// echo "<p> multianswer positionkey $positionkey response $response state <pre>";print_r($state);echo "</pre></p>";
|
||||
|
||||
// Determine feedback popup if any
|
||||
$popup = '';
|
||||
|
@ -365,8 +333,7 @@ class embedded_cloze_qtype extends question_type {
|
|||
$testedstate = clone($state);
|
||||
$testedstate->responses[''] = $response;
|
||||
foreach ($answers as $answer) {
|
||||
if($QTYPES[$wrapped->qtype]
|
||||
->test_response($wrapped, $testedstate, $answer)) {
|
||||
if ($QTYPES[$wrapped->qtype]->test_response($wrapped, $testedstate, $answer)) {
|
||||
$chosenanswer = clone($answer);
|
||||
break;
|
||||
}
|
||||
|
@ -431,24 +398,6 @@ class embedded_cloze_qtype extends question_type {
|
|||
$size = $size + rand(0, $size*0.15);
|
||||
$size > 60 ? $size = 60 : $size = $size;
|
||||
$styleinfo = "size=\"$size\"";
|
||||
/**
|
||||
* Uncomment the following lines if you want to limit for small sizes.
|
||||
* Results may vary with browsers see MDL-3274
|
||||
*/
|
||||
/*
|
||||
if ($size < 2) {
|
||||
$styleinfo = 'style="width: 1.1em;"';
|
||||
}
|
||||
if ($size == 2) {
|
||||
$styleinfo = 'style="width: 1.9em;"';
|
||||
}
|
||||
if ($size == 3) {
|
||||
$styleinfo = 'style="width: 2.3em;"';
|
||||
}
|
||||
if ($size == 4) {
|
||||
$styleinfo = 'style="width: 2.8em;"';
|
||||
}
|
||||
*/
|
||||
|
||||
echo "<input $style $readonly $popup name=\"$inputname\"";
|
||||
echo " type=\"text\" value=\"".s($response)."\" ".$styleinfo." /> ";
|
||||
|
@ -515,7 +464,6 @@ class embedded_cloze_qtype extends question_type {
|
|||
}
|
||||
|
||||
// Print the answer text: no automatic numbering
|
||||
|
||||
$a->text = format_text($mcanswer->answer, $mcanswer->answerformat, $formatoptions, $cmoptions->course);
|
||||
|
||||
// Print feedback if feedback is on
|
||||
|
@ -527,12 +475,11 @@ class embedded_cloze_qtype extends question_type {
|
|||
|
||||
$anss[] = clone($a);
|
||||
}
|
||||
?>
|
||||
<?php if ($wrapped->options->layout == 1 ){
|
||||
?>
|
||||
<table class="answer">
|
||||
<?php $row = 1; foreach ($anss as $answer) { ?>
|
||||
<tr class="<?php echo 'r'.$row = $row ? 0 : 1; ?>">
|
||||
if ($wrapped->options->layout == 1) {
|
||||
?><table class="answer"><?php
|
||||
$row = 1;
|
||||
foreach ($anss as $answer) {
|
||||
?><tr class="<?php echo 'r'.$row = $row ? 0 : 1; ?>">
|
||||
<td class="c0 control">
|
||||
<?php echo $answer->control; ?>
|
||||
</td>
|
||||
|
@ -545,15 +492,14 @@ class embedded_cloze_qtype extends question_type {
|
|||
<td class="c0 feedback">
|
||||
<?php echo $answer->feedback; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</table>
|
||||
<?php }else if ($wrapped->options->layout == 2 ){
|
||||
?>
|
||||
|
||||
<table class="answer">
|
||||
</tr><?php
|
||||
}
|
||||
?></table><?php
|
||||
} else if ($wrapped->options->layout == 2) {
|
||||
?><table class="answer">
|
||||
<tr class="<?php echo 'r'.$row = $row ? 0 : 1; ?>">
|
||||
<?php $row = 1; foreach ($anss as $answer) { ?>
|
||||
<?php $row = 1;
|
||||
foreach ($anss as $answer) { ?>
|
||||
<td class="c0 control">
|
||||
<?php echo $answer->control; ?>
|
||||
</td>
|
||||
|
@ -565,11 +511,12 @@ class embedded_cloze_qtype extends question_type {
|
|||
</td>
|
||||
<td class="c0 feedback">
|
||||
<?php echo $answer->feedback; ?>
|
||||
</td>
|
||||
<?php } ?>
|
||||
</td><?php
|
||||
}
|
||||
?>
|
||||
</tr>
|
||||
</table>
|
||||
<?php }
|
||||
</table><?php
|
||||
}
|
||||
|
||||
} else {
|
||||
echo "no valid layout";
|
||||
|
@ -584,8 +531,7 @@ class embedded_cloze_qtype extends question_type {
|
|||
break;
|
||||
}
|
||||
echo "</label>"; // MDL-7497
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (! isset($question->options->questions[$positionkey])) {
|
||||
echo $regs[0]."</label>";
|
||||
} else {
|
||||
|
@ -601,8 +547,6 @@ class embedded_cloze_qtype extends question_type {
|
|||
}
|
||||
|
||||
public function compare_responses($question, $state, $teststate) {
|
||||
global $QTYPES;
|
||||
|
||||
foreach ($question->options->questions as $key => $wrapped) {
|
||||
if (empty($wrapped)) {
|
||||
continue;
|
||||
|
@ -639,8 +583,7 @@ class embedded_cloze_qtype extends question_type {
|
|||
return true;
|
||||
}
|
||||
|
||||
function grade_responses(&$question, &$state, $cmoptions) {
|
||||
global $QTYPES;
|
||||
public function grade_responses(&$question, &$state, $cmoptions) {
|
||||
$teststate = clone($state);
|
||||
$state->raw_grade = 0;
|
||||
foreach ($question->options->questions as $key => $wrapped) {
|
||||
|
@ -652,8 +595,7 @@ class embedded_cloze_qtype extends question_type {
|
|||
}
|
||||
$teststate->responses = array('' => $state->responses[$key]);
|
||||
$teststate->raw_grade = 0;
|
||||
if (false === $QTYPES[$wrapped->qtype]
|
||||
->grade_responses($wrapped, $teststate, $cmoptions)) {
|
||||
if (false === $QTYPES[$wrapped->qtype]->grade_responses($wrapped, $teststate, $cmoptions)) {
|
||||
return false;
|
||||
}
|
||||
$state->raw_grade += $teststate->raw_grade;
|
||||
|
@ -674,26 +616,13 @@ class embedded_cloze_qtype extends question_type {
|
|||
return true;
|
||||
}
|
||||
|
||||
function get_actual_response($question, $state) {
|
||||
global $QTYPES;
|
||||
$teststate = clone($state);
|
||||
foreach($question->options->questions as $key => $wrapped) {
|
||||
$state->responses[$key] = html_entity_decode($state->responses[$key]);
|
||||
$teststate->responses = array('' => $state->responses[$key]);
|
||||
$correct = $QTYPES[$wrapped->qtype]
|
||||
->get_actual_response($wrapped, $teststate);
|
||||
$responses[$key] = implode(';', $correct);
|
||||
}
|
||||
return $responses;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $question
|
||||
* @return mixed either a integer score out of 1 that the average random
|
||||
* guess by a student might give or an empty string which means will not
|
||||
* calculate.
|
||||
*/
|
||||
function get_random_guess_score($question) {
|
||||
public function get_random_guess_score($question) {
|
||||
$totalfraction = 0;
|
||||
foreach (array_keys($question->options->questions) as $key) {
|
||||
$totalfraction += question_get_random_guess_score($question->options->questions[$key]);
|
||||
|
@ -701,47 +630,8 @@ class embedded_cloze_qtype extends question_type {
|
|||
return $totalfraction / count($question->options->questions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs all the code required to set up and save an essay question for testing purposes.
|
||||
* Alternate DB table prefix may be used to facilitate data deletion.
|
||||
*/
|
||||
function generate_test($name, $courseid = null) {
|
||||
global $DB;
|
||||
list($form, $question) = parent::generate_test($name, $courseid);
|
||||
$question->category = $form->category;
|
||||
$form->questiontext = "This question consists of some text with an answer embedded right here {1:MULTICHOICE:Wrong answer#Feedback for this wrong answer~Another wrong answer#Feedback for the other wrong answer~=Correct answer#Feedback for correct answer~%50%Answer that gives half the credit#Feedback for half credit answer} and right after that you will have to deal with this short answer {1:SHORTANSWER:Wrong answer#Feedback for this wrong answer~=Correct answer#Feedback for correct answer~%50%Answer that gives half the credit#Feedback for half credit answer} and finally we have a floating point number {2:NUMERICAL:=23.8:0.1#Feedback for correct answer 23.8~%50%23.8:2#Feedback for half credit answer in the nearby region of the correct answer}.
|
||||
|
||||
Note that addresses like www.moodle.org and smileys :-) all work as normal:
|
||||
a) How good is this? {:MULTICHOICE:=Yes#Correct~No#We have a different opinion}
|
||||
b) What grade would you give it? {3:NUMERICAL:=3:2}
|
||||
|
||||
Good luck!
|
||||
";
|
||||
$form->feedback = "feedback";
|
||||
$form->generalfeedback = "General feedback";
|
||||
$form->fraction = 0;
|
||||
$form->penalty = 0.1;
|
||||
$form->versioning = 0;
|
||||
|
||||
if ($courseid) {
|
||||
$course = $DB->get_record('course', array('id' => $courseid));
|
||||
}
|
||||
|
||||
return $this->save_question($question, $form);
|
||||
}
|
||||
|
||||
}
|
||||
//// END OF CLASS ////
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//// ADDITIONAL FUNCTIONS
|
||||
//// The functions below deal exclusivly with editing
|
||||
//// of questions with question type 'multianswer'.
|
||||
//// Therefore they are kept in this file.
|
||||
//// They are not in the class as they are not
|
||||
//// likely to be subject for overriding.
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
// ANSWER_ALTERNATIVE regexes
|
||||
define("ANSWER_ALTERNATIVE_FRACTION_REGEX",
|
||||
'=|%(-?[0-9]+)%');
|
||||
|
@ -934,10 +824,7 @@ function qtype_multianswer_extract_question($text) {
|
|||
$question->options->questions[$positionkey] = clone($wrapped);
|
||||
$question->questiontext['text'] = implode("{#$positionkey}",
|
||||
explode($answerregs[0], $question->questiontext['text'], 2));
|
||||
// echo"<p>questiontext 2 <pre>";print_r($question->questiontext);echo"<pre></p>";
|
||||
}
|
||||
// echo"<p>questiontext<pre>";print_r($question->questiontext);echo"<pre></p>";
|
||||
$question->questiontext = $question->questiontext;
|
||||
// echo"<p>question<pre>";print_r($question);echo"<pre></p>";
|
||||
return $question;
|
||||
}
|
||||
|
|
|
@ -55,9 +55,8 @@ class backup_qtype_randomsamatch_plugin extends backup_qtype_plugin {
|
|||
$pluginwrapper->add_child($randomsamatch);
|
||||
|
||||
// set source to populate the data
|
||||
$randomsamatch->set_source_table('question_randomsamatch', array('question' => backup::VAR_PARENTID));
|
||||
|
||||
// don't need to annotate ids nor files
|
||||
$randomsamatch->set_source_table('question_randomsamatch',
|
||||
array('question' => backup::VAR_PARENTID));
|
||||
|
||||
return $plugin;
|
||||
}
|
||||
|
|
|
@ -43,10 +43,9 @@ class restore_qtype_randomsamatch_plugin extends restore_qtype_plugin {
|
|||
|
||||
// Add own qtype stuff
|
||||
$elename = 'randomsamatch';
|
||||
$elepath = $this->get_pathfor('/randomsamatch'); // we used get_recommended_name() so this works
|
||||
$elepath = $this->get_pathfor('/randomsamatch');
|
||||
$paths[] = new restore_path_element($elename, $elepath);
|
||||
|
||||
|
||||
return $paths; // And we return the interesting paths
|
||||
}
|
||||
|
||||
|
@ -64,7 +63,8 @@ class restore_qtype_randomsamatch_plugin extends restore_qtype_plugin {
|
|||
$newquestionid = $this->get_new_parentid('question');
|
||||
$questioncreated = $this->get_mappingid('question_created', $oldquestionid) ? true : false;
|
||||
|
||||
// If the question has been created by restore, we need to create its question_randomsamatch too
|
||||
// If the question has been created by restore, we need to create its
|
||||
// question_randomsamatch too
|
||||
if ($questioncreated) {
|
||||
// Adjust some columns
|
||||
$data->question = $newquestionid;
|
||||
|
@ -72,8 +72,6 @@ class restore_qtype_randomsamatch_plugin extends restore_qtype_plugin {
|
|||
$newitemid = $DB->insert_record('question_randomsamatch', $data);
|
||||
// Create mapping
|
||||
$this->set_mapping('question_randomsamatch', $oldid, $newitemid);
|
||||
} else {
|
||||
// Nothing to remap if the question already existed
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,19 +33,15 @@ defined('MOODLE_INTERNAL') || die();
|
|||
* @copyright 2007 Jamie Pratt me@jamiep.org
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*/
|
||||
class question_edit_randomsamatch_form extends question_edit_form {
|
||||
/**
|
||||
* Add question-type specific form fields.
|
||||
*
|
||||
* @param MoodleQuickForm $mform the form being built.
|
||||
*/
|
||||
protected function definition_inner(&$mform) {
|
||||
class qtype_randomsamatch_edit_form extends question_edit_form {
|
||||
protected function definition_inner($mform) {
|
||||
$questionstoselect = array();
|
||||
for ($i=2; $i<=QUESTION_NUMANS; $i++){
|
||||
for ($i = 2; $i <= qtype_randomsamatch::MAX_SUBQUESTIONS; $i++) {
|
||||
$questionstoselect[$i] = $i;
|
||||
}
|
||||
|
||||
$mform->addElement('select', 'choose', get_string("randomsamatchnumber", "quiz"), $questionstoselect);
|
||||
$mform->addElement('select', 'choose',
|
||||
get_string('randomsamatchnumber', 'quiz'), $questionstoselect);
|
||||
$mform->setType('feedback', PARAM_RAW);
|
||||
|
||||
$mform->addElement('hidden', 'fraction', 0);
|
||||
|
@ -54,11 +50,11 @@ class question_edit_randomsamatch_form extends question_edit_form {
|
|||
|
||||
protected function data_preprocessing($question) {
|
||||
if (empty($question->name)) {
|
||||
$question->name = get_string("randomsamatch", "quiz");
|
||||
$question->name = get_string('randomsamatch', 'quiz');
|
||||
}
|
||||
|
||||
if (empty($question->questiontext)) {
|
||||
$question->questiontext = get_string("randomsamatchintro", "quiz");
|
||||
$question->questiontext = get_string('randomsamatchintro', 'quiz');
|
||||
}
|
||||
return $question;
|
||||
}
|
||||
|
@ -67,15 +63,15 @@ class question_edit_randomsamatch_form extends question_edit_form {
|
|||
return 'randomsamatch';
|
||||
}
|
||||
|
||||
function validation($data, $files) {
|
||||
global $QTYPES, $DB;
|
||||
public function validation($data, $files) {
|
||||
global $DB;
|
||||
$errors = parent::validation($data, $files);
|
||||
if (isset($data->categorymoveto)) {
|
||||
list($category) = explode(',', $data['categorymoveto']);
|
||||
} else {
|
||||
list($category) = explode(',', $data['category']);
|
||||
}
|
||||
$saquestions = $QTYPES['randomsamatch']->get_sa_candidates($category);
|
||||
$saquestions = question_bank::get_qtype('randomsamatch')->get_sa_candidates($category);
|
||||
$numberavailable = count($saquestions);
|
||||
if ($saquestions === false) {
|
||||
$a = new stdClass();
|
||||
|
|
|
@ -36,27 +36,21 @@ defined('MOODLE_INTERNAL') || die();
|
|||
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class question_randomsamatch_qtype extends qtype_match {
|
||||
/// Extends 'match' as there are quite a few simularities...
|
||||
class qtype_randomsamatch extends question_type {
|
||||
const MAX_SUBQUESTIONS = 10;
|
||||
|
||||
function name() {
|
||||
return 'randomsamatch';
|
||||
public function requires_qtypes() {
|
||||
return array('shortanswer', 'match');
|
||||
}
|
||||
|
||||
function requires_qtypes() {
|
||||
return array('shortanswer');
|
||||
}
|
||||
|
||||
function is_usable_by_random() {
|
||||
public function is_usable_by_random() {
|
||||
return false;
|
||||
}
|
||||
|
||||
function get_question_options(&$question) {
|
||||
global $DB, $OUTPUT;
|
||||
if (!$question->options = $DB->get_record('question_randomsamatch', array('question' => $question->id))) {
|
||||
echo $OUTPUT->notification('Error: Missing question options for random short answer question '.$question->id.'!');
|
||||
return false;
|
||||
}
|
||||
public function get_question_options($question) {
|
||||
global $DB;
|
||||
$question->options = $DB->get_record('question_randomsamatch',
|
||||
array('question' => $question->id), '*', MUST_EXIST);
|
||||
|
||||
// This could be included as a flag in the database. It's already
|
||||
// supported by the code.
|
||||
|
@ -66,7 +60,7 @@ class question_randomsamatch_qtype extends qtype_match {
|
|||
|
||||
}
|
||||
|
||||
function save_question_options($question) {
|
||||
public function save_question_options($question) {
|
||||
global $DB;
|
||||
$options->question = $question->id;
|
||||
$options->choose = $question->choose;
|
||||
|
@ -76,23 +70,24 @@ class question_randomsamatch_qtype extends qtype_match {
|
|||
return $result;
|
||||
}
|
||||
|
||||
if ($existing = $DB->get_record("question_randomsamatch", array("question" => $options->question))) {
|
||||
if ($existing = $DB->get_record('question_randomsamatch',
|
||||
array('question' => $options->question))) {
|
||||
$options->id = $existing->id;
|
||||
$DB->update_record("question_randomsamatch", $options);
|
||||
$DB->update_record('question_randomsamatch', $options);
|
||||
} else {
|
||||
$DB->insert_record("question_randomsamatch", $options);
|
||||
$DB->insert_record('question_randomsamatch', $options);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function delete_question($questionid, $contextid) {
|
||||
public function delete_question($questionid, $contextid) {
|
||||
global $DB;
|
||||
$DB->delete_records('question_randomsamatch', array('question' => $questionid));
|
||||
|
||||
parent::delete_question($questionid, $contextid);
|
||||
}
|
||||
|
||||
function create_session_and_responses(&$question, &$state, $cmoptions, $attempt) {
|
||||
public function create_session_and_responses(&$question, &$state, $cmoptions, $attempt) {
|
||||
// Choose a random shortanswer question from the category:
|
||||
// We need to make sure that no question is used more than once in the
|
||||
// quiz. Therfore the following need to be excluded:
|
||||
|
@ -231,23 +226,11 @@ class question_randomsamatch_qtype extends qtype_match {
|
|||
return true;
|
||||
}
|
||||
|
||||
function extract_response($rawresponse, $nameprefix) {
|
||||
/// Simple implementation that does not check with the database
|
||||
/// and thus - does not bother to check whether there has been
|
||||
/// any changes to the question options.
|
||||
$response = array();
|
||||
$rawitems = explode(',', $rawresponse->answer);
|
||||
foreach ($rawitems as $rawitem) {
|
||||
$splits = explode('-', $rawitem, 2);
|
||||
$response[$nameprefix.$splits[0]] = $splits[1];
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
function get_sa_candidates($categorylist, $questionsinuse = 0) {
|
||||
public function get_sa_candidates($categorylist, $questionsinuse = 0) {
|
||||
global $DB;
|
||||
list ($usql, $params) = $DB->get_in_or_equal($categorylist);
|
||||
list ($ques_usql, $ques_params) = $DB->get_in_or_equal(explode(',', $questionsinuse), SQL_PARAMS_QM, null, false);
|
||||
list ($ques_usql, $ques_params) = $DB->get_in_or_equal(explode(',', $questionsinuse),
|
||||
SQL_PARAMS_QM, null, false);
|
||||
$params = array_merge($params, $ques_params);
|
||||
return $DB->get_records_select('question',
|
||||
"qtype = 'shortanswer' " .
|
||||
|
@ -256,80 +239,6 @@ class question_randomsamatch_qtype extends qtype_match {
|
|||
"AND hidden = '0'" .
|
||||
"AND id $ques_usql", $params);
|
||||
}
|
||||
function get_all_responses($question, $state) {
|
||||
$answers = array();
|
||||
if (is_array($question->options->subquestions)) {
|
||||
foreach ($question->options->subquestions as $aid => $answer) {
|
||||
if ($answer->questiontext) {
|
||||
foreach($answer->options->answers as $ans ){
|
||||
$answer->answertext = $ans->answer ;
|
||||
}
|
||||
$r = new stdClass();
|
||||
$r->answer = $answer->questiontext . ": " . $answer->answertext;
|
||||
$r->credit = 1;
|
||||
$answers[$aid] = $r;
|
||||
}
|
||||
}
|
||||
}
|
||||
$result = new stdClass();
|
||||
$result->id = $question->id;
|
||||
$result->responses = $answers;
|
||||
return $result;
|
||||
}
|
||||
/**
|
||||
* The difference between this method an get_all_responses is that this
|
||||
* method is not passed a state object. It is the possible answers to a
|
||||
* question no matter what the state.
|
||||
* This method is not called for random questions.
|
||||
* @return array of possible answers.
|
||||
*/
|
||||
function get_possible_responses(&$question) {
|
||||
global $QTYPES;
|
||||
static $answers = array();
|
||||
if (!isset($answers[$question->id])){
|
||||
if ($question->options->subcats) {
|
||||
// recurse into subcategories
|
||||
$categorylist = question_categorylist($question->category);
|
||||
} else {
|
||||
$categorylist = array($question->category);
|
||||
}
|
||||
|
||||
$question->options->subquestions = $this->get_sa_candidates($categorylist);
|
||||
foreach ($question->options->subquestions as $key => $wrappedquestion) {
|
||||
if (!$QTYPES[$wrappedquestion->qtype]
|
||||
->get_question_options($wrappedquestion)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now we overwrite the $question->options->answers field to only
|
||||
// *one* (the first) correct answer. This loop can be deleted to
|
||||
// take all answers into account (i.e. put them all into the
|
||||
// drop-down menu.
|
||||
$foundcorrect = false;
|
||||
foreach ($wrappedquestion->options->answers as $answer) {
|
||||
if ($foundcorrect || $answer->fraction != 1.0) {
|
||||
unset($wrappedquestion->options->answers[$answer->id]);
|
||||
} else if (!$foundcorrect) {
|
||||
$foundcorrect = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
$answers[$question->id] = array();
|
||||
if (is_array($question->options->subquestions)) {
|
||||
foreach ($question->options->subquestions as $subqid => $answer) {
|
||||
if ($answer->questiontext) {
|
||||
$ans = array_shift($answer->options->answers);
|
||||
$answer->answertext = $ans->answer ;
|
||||
$r = new stdClass();
|
||||
$r->answer = $answer->questiontext . ": " . $answer->answertext;
|
||||
$r->credit = 1;
|
||||
$answers[$question->id][$subqid] = array($ans->id => $r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $answers[$question->id];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $question
|
||||
|
@ -337,7 +246,7 @@ class question_randomsamatch_qtype extends qtype_match {
|
|||
* guess by a student might give or an empty string which means will not
|
||||
* calculate.
|
||||
*/
|
||||
function get_random_guess_score($question) {
|
||||
public function get_random_guess_score($question) {
|
||||
return 1/$question->options->choose;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue