mirror of
https://github.com/moodle/moodle.git
synced 2025-08-03 08:09:47 +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
|
||||
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()));
|
||||
$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()));
|
||||
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,221 +35,257 @@ defined('MOODLE_INTERNAL') || die();
|
|||
*/
|
||||
class question_edit_multianswer_form extends question_edit_form {
|
||||
|
||||
// $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
|
||||
public $savedquestion ;
|
||||
public $savedquestiondisplay ;
|
||||
public $used_in_quiz = false ;
|
||||
public $qtype_change = false ;
|
||||
public $negative_diff = 0 ;
|
||||
// $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
|
||||
public $savedquestion;
|
||||
public $savedquestiondisplay;
|
||||
public $used_in_quiz = false;
|
||||
public $qtype_change = false;
|
||||
public $negative_diff = 0;
|
||||
public $nb_of_quiz = 0;
|
||||
public $nb_of_attempts = 0;
|
||||
public $confirm = 0 ;
|
||||
public $reload = false ;
|
||||
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 ;
|
||||
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))){
|
||||
foreach($list as $key => $li){
|
||||
|
||||
$this->used_in_quiz = false;
|
||||
|
||||
if (isset($question->id) && $question->id != 0) {
|
||||
$this->savedquestiondisplay = fullclone($question);
|
||||
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'))){
|
||||
$this->nb_of_attempts+= count($att);
|
||||
if ($att = $DB->get_records('quiz_attempts',
|
||||
array('quiz' => $li->quiz, 'preview' => '0'))) {
|
||||
$this->nb_of_attempts += count($att);
|
||||
$this->used_in_quiz = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
$mform->removeElement('defaultgrade');
|
||||
$this->confirm = optional_param('confirm','0', PARAM_RAW);
|
||||
$this->confirm = optional_param('confirm', '0', PARAM_RAW);
|
||||
|
||||
// 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>";
|
||||
if ("" != optional_param('questiontext', '', PARAM_RAW)) {
|
||||
$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)){
|
||||
} else {
|
||||
if (!$this->reload && !empty($this->savedquestiondisplay->id)) {
|
||||
// use database data as this is first pass
|
||||
// question->id == 0 so no stored datasets
|
||||
$this->questiondisplay = fullclone($this->savedquestiondisplay);
|
||||
foreach($this->questiondisplay->options->questions as $subquestion){
|
||||
if (!empty($subquestion)){
|
||||
foreach ($this->questiondisplay->options->questions as $subquestion) {
|
||||
if (!empty($subquestion)) {
|
||||
$subquestion->answer = array('');
|
||||
foreach($subquestion->options->answers as $ans){
|
||||
$subquestion->answer[]=$ans->answer ;
|
||||
foreach ($subquestion->options->answers as $ans) {
|
||||
$subquestion->answer[] = $ans->answer;
|
||||
}
|
||||
// $subquestion->answer = fullclone($subquestion->options->answers);
|
||||
}
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
$this->questiondisplay = "";
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset($this->savedquestiondisplay->options->questions) && is_array($this->savedquestiondisplay->options->questions) ) {
|
||||
$countsavedsubquestions =0;
|
||||
foreach($this->savedquestiondisplay->options->questions as $subquestion){
|
||||
if (!empty($subquestion)){
|
||||
if (isset($this->savedquestiondisplay->options->questions) &&
|
||||
is_array($this->savedquestiondisplay->options->questions)) {
|
||||
$countsavedsubquestions = 0;
|
||||
foreach ($this->savedquestiondisplay->options->questions as $subquestion) {
|
||||
if (!empty($subquestion)) {
|
||||
$countsavedsubquestions++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$countsavedsubquestions =0;
|
||||
$countsavedsubquestions = 0;
|
||||
}
|
||||
if ($this->reload){
|
||||
if ( isset($this->questiondisplay->options->questions) && is_array($this->questiondisplay->options->questions) ) {
|
||||
$countsubquestions =0;
|
||||
foreach($this->questiondisplay->options->questions as $subquestion){
|
||||
if (!empty($subquestion)){
|
||||
if ($this->reload) {
|
||||
if (isset($this->questiondisplay->options->questions) &&
|
||||
is_array($this->questiondisplay->options->questions)) {
|
||||
$countsubquestions = 0;
|
||||
foreach ($this->questiondisplay->options->questions as $subquestion) {
|
||||
if (!empty($subquestion)) {
|
||||
$countsubquestions++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$countsubquestions =0;
|
||||
$countsubquestions = 0;
|
||||
}
|
||||
}else{
|
||||
$countsubquestions =$countsavedsubquestions ;
|
||||
} 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 ){
|
||||
if ($this->reload) {
|
||||
$mform->addElement('html', '<div class="ablock clearfix">');
|
||||
$mform->addElement('html', '<div class=" clearfix">');
|
||||
for ($sub =1;$sub <=$countsubquestions ;$sub++) {
|
||||
for ($sub = 1; $sub <= $countsubquestions; $sub++) {
|
||||
|
||||
$this->editas[$sub] = 'unknown type';
|
||||
if (isset( $this->questiondisplay->options->questions[$sub]->qtype) ) {
|
||||
$this->editas[$sub] = $this->questiondisplay->options->questions[$sub]->qtype ;
|
||||
if (isset($this->questiondisplay->options->questions[$sub]->qtype)) {
|
||||
$this->editas[$sub] = $this->questiondisplay->options->questions[$sub]->qtype;
|
||||
} else if (optional_param('sub_'.$sub."_".'qtype', '', PARAM_RAW) != '') {
|
||||
$this->editas[$sub] = optional_param('sub_'.$sub."_".'qtype', '', PARAM_RAW);
|
||||
}
|
||||
$storemess = '';
|
||||
if(isset($this->savedquestiondisplay->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 >";
|
||||
}
|
||||
if (isset($this->savedquestiondisplay->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 >";
|
||||
}
|
||||
|
||||
$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']);
|
||||
if (isset ($this->questiondisplay->options->questions[$sub]->questiontext)) {
|
||||
$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'));
|
||||
if ($this->questiondisplay->options->questions[$sub]->qtype == 'shortanswer') {
|
||||
$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);
|
||||
if ($this->questiondisplay->options->questions[$sub]->qtype == 'multichoice') {
|
||||
$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) {
|
||||
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'));
|
||||
$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) {
|
||||
$mform->addElement('static', 'alert1', "<strong>".get_string('questiondeleted','qtype_multianswer')."</strong>",get_string('questionsless','qtype_multianswer',$this->negative_diff));
|
||||
if ($this->negative_diff > 0) {
|
||||
$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'));
|
||||
if ($this->qtype_change) {
|
||||
$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) {
|
||||
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 = 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);
|
||||
} else {
|
||||
$mform->addElement('hidden', 'confirm', 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
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) {
|
||||
$default_values = array();
|
||||
if (isset($question->id) and $question->id and $question->qtype &&
|
||||
$question->questiontext) {
|
||||
|
||||
foreach ($question->options->questions as $key => $wrapped) {
|
||||
if(!empty($wrapped)){
|
||||
if (!empty($wrapped)) {
|
||||
// The old way of restoring the definitions is kept to gradually
|
||||
// update all multianswer questions
|
||||
if (empty($wrapped->questiontext)) {
|
||||
$parsableanswerdef = '{' . $wrapped->defaultgrade . ':';
|
||||
switch ($wrapped->qtype) {
|
||||
case 'multichoice':
|
||||
$parsableanswerdef .= 'MULTICHOICE:';
|
||||
break;
|
||||
case 'shortanswer':
|
||||
$parsableanswerdef .= 'SHORTANSWER:';
|
||||
break;
|
||||
case 'numerical':
|
||||
$parsableanswerdef .= 'NUMERICAL:';
|
||||
break;
|
||||
default:
|
||||
print_error('unknownquestiontype', 'question', '', $wrapped->qtype);
|
||||
case 'multichoice':
|
||||
$parsableanswerdef .= 'MULTICHOICE:';
|
||||
break;
|
||||
case 'shortanswer':
|
||||
$parsableanswerdef .= 'SHORTANSWER:';
|
||||
break;
|
||||
case 'numerical':
|
||||
$parsableanswerdef .= 'NUMERICAL:';
|
||||
break;
|
||||
default:
|
||||
print_error('unknownquestiontype', 'question', '',
|
||||
$wrapped->qtype);
|
||||
}
|
||||
$separator= '';
|
||||
$separator = '';
|
||||
foreach ($wrapped->options->answers as $subanswer) {
|
||||
$parsableanswerdef .= $separator
|
||||
. '%' . round(100*$subanswer->fraction) . '%';
|
||||
|
@ -268,168 +304,192 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set default to $questiondisplay questions elements
|
||||
if ( $this->reload ){
|
||||
if ($this->reload) {
|
||||
if (isset($this->questiondisplay->options->questions)) {
|
||||
$subquestions = fullclone($this->questiondisplay->options->questions) ;
|
||||
$subquestions = fullclone($this->questiondisplay->options->questions);
|
||||
if (count($subquestions)) {
|
||||
$sub =1;
|
||||
$sub = 1;
|
||||
foreach ($subquestions as $subquestion) {
|
||||
$prefix = 'sub_'.$sub.'_' ;
|
||||
$prefix = 'sub_'.$sub.'_';
|
||||
|
||||
// validate parameters
|
||||
$answercount = 0;
|
||||
$maxgrade = false;
|
||||
$maxfraction = -1;
|
||||
if ($subquestion->qtype =='shortanswer' ) {
|
||||
if ($subquestion->qtype == 'shortanswer') {
|
||||
switch ($subquestion->usecase) {
|
||||
case '1':
|
||||
$default_values[$prefix.'usecase']= get_string('caseyes', 'qtype_shortanswer');
|
||||
break;
|
||||
case '0':
|
||||
default :
|
||||
$default_values[$prefix.'usecase']= get_string('caseno', 'qtype_shortanswer');
|
||||
case '1':
|
||||
$default_values[$prefix.'usecase'] =
|
||||
get_string('caseyes', 'qtype_shortanswer');
|
||||
break;
|
||||
case '0':
|
||||
default :
|
||||
$default_values[$prefix.'usecase'] =
|
||||
get_string('caseno', 'qtype_shortanswer');
|
||||
}
|
||||
}
|
||||
|
||||
if ($subquestion->qtype == 'multichoice' ) {
|
||||
$default_values[$prefix.'layout'] = $subquestion->layout ;
|
||||
if ($subquestion->qtype == 'multichoice') {
|
||||
$default_values[$prefix.'layout'] = $subquestion->layout;
|
||||
switch ($subquestion->layout) {
|
||||
case '0':
|
||||
$default_values[$prefix.'layout']= get_string('layoutselectinline', 'qtype_multianswer');
|
||||
break;
|
||||
case '1':
|
||||
$default_values[$prefix.'layout']= get_string('layoutvertical', 'qtype_multianswer');
|
||||
break;
|
||||
case '2':
|
||||
$default_values[$prefix.'layout']= get_string('layouthorizontal', 'qtype_multianswer');
|
||||
break;
|
||||
default:
|
||||
$default_values[$prefix.'layout']= get_string('layoutundefined', 'qtype_multianswer');
|
||||
case '0':
|
||||
$default_values[$prefix.'layout'] =
|
||||
get_string('layoutselectinline', 'qtype_multianswer');
|
||||
break;
|
||||
case '1':
|
||||
$default_values[$prefix.'layout'] =
|
||||
get_string('layoutvertical', 'qtype_multianswer');
|
||||
break;
|
||||
case '2':
|
||||
$default_values[$prefix.'layout'] =
|
||||
get_string('layouthorizontal', 'qtype_multianswer');
|
||||
break;
|
||||
default:
|
||||
$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] ;
|
||||
foreach ($subquestion->answer as $key => $answer) {
|
||||
if ($subquestion->qtype == 'numerical' && $key == 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;
|
||||
}
|
||||
if ($subquestion->fraction[$key] > $maxfraction) {
|
||||
$maxfraction = $subquestion->fraction[$key] ;
|
||||
$maxfraction = $subquestion->fraction[$key];
|
||||
}
|
||||
}
|
||||
|
||||
$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));
|
||||
if ($subquestion->qtype == 'multichoice') {
|
||||
$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) {
|
||||
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;
|
||||
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 != "") {
|
||||
if ($default_values != "") {
|
||||
$question = (object)((array)$question + $default_values);
|
||||
}
|
||||
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) ;
|
||||
$subquestions = fullclone($questiondisplay->options->questions);
|
||||
if (count($subquestions)) {
|
||||
$sub =1;
|
||||
$sub = 1;
|
||||
foreach ($subquestions as $subquestion) {
|
||||
$prefix = 'sub_'.$sub.'_' ;
|
||||
$prefix = 'sub_'.$sub.'_';
|
||||
$answercount = 0;
|
||||
$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);
|
||||
}
|
||||
foreach ( $subquestion->answer as $key=>$answer) {
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
if ($subquestion->fraction[$key] > $maxfraction) {
|
||||
$maxfraction = $subquestion->fraction[$key] ;
|
||||
$maxfraction = $subquestion->fraction[$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($answercount==0) {
|
||||
if ( $subquestion->qtype =='multichoice' ) {
|
||||
$errors[$prefix.'answer[0]']= get_string('notenoughanswers', 'qtype_multichoice', 2);
|
||||
}else {
|
||||
$errors[$prefix.'answer[0]'] = get_string('notenoughanswers', 'question', 1);
|
||||
if ($answercount == 0) {
|
||||
if ($subquestion->qtype == 'multichoice') {
|
||||
$errors[$prefix.'answer[0]'] =
|
||||
get_string('notenoughanswers', 'qtype_multichoice', 2);
|
||||
} else {
|
||||
$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++;
|
||||
}
|
||||
} else {
|
||||
$errors['questiontext']=get_string('questionsmissing', 'qtype_multianswer');
|
||||
$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';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ $string['noquestions'] = 'The Cloze(multianswer) question "<strong>{$a}</strong>
|
|||
$string['qtypenotrecognized'] = 'questiontype {$a} not recognized';
|
||||
$string['questionnadded'] = 'Question added';
|
||||
$string['questiondefinition'] = 'Question definition';
|
||||
$string['questiondeleted'] = 'Question deleted' ;
|
||||
$string['questiondeleted'] = 'Question deleted';
|
||||
$string['questioninquiz'] = '
|
||||
|
||||
<ul>
|
||||
|
@ -61,5 +61,5 @@ $string['questiontypechanged'] = 'Question type changed';
|
|||
$string['questiontypechangedcomment'] = 'At least one question type has been changed.<br \>Did you add, delete or move a question?<br \>Look ahead.';
|
||||
$string['questionusedinquiz'] = 'This question is used in {$a->nb_of_quiz} quiz(s), total attempt(s) : {$a->nb_of_attempts} ';
|
||||
$string['unknownquestiontypeofsubquestion'] = 'Unknown question type: {$a->type} of question part # {$a->sub}';
|
||||
$string['warningquestionmodified'] = '<b>WARNING</b>' ;
|
||||
$string['warningquestionmodified'] = '<b>WARNING</b>';
|
||||
$string['youshouldnot'] = '<b>YOU SHOULD NOT</b>';
|
||||
|
|
|
@ -35,22 +35,22 @@ 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))) {
|
||||
echo $OUTPUT->notification(get_string('noquestions','qtype_multianswer',$question->name));
|
||||
$question->options->questions['1']= '';
|
||||
return true ;
|
||||
echo $OUTPUT->notification(get_string('noquestions', 'qtype_multianswer', $question->name));
|
||||
$question->options->questions['1'] = '';
|
||||
return true;
|
||||
}
|
||||
|
||||
$wrappedquestions = $DB->get_records_list('question', 'id', explode(',', $sequence), 'id ASC');
|
||||
|
@ -63,32 +63,33 @@ class embedded_cloze_qtype extends question_type {
|
|||
// before using the values.
|
||||
// first all possible questions from sequence are nulled
|
||||
// then filled with the data if available in $wrappedquestions
|
||||
$nbvaliquestion = 0 ;
|
||||
foreach($sequence as $seq){
|
||||
$question->options->questions[$seq]= '';
|
||||
$nbvaliquestion = 0;
|
||||
foreach ($sequence as $seq) {
|
||||
$question->options->questions[$seq] = '';
|
||||
}
|
||||
if (isset($wrappedquestions) && is_array($wrappedquestions)){
|
||||
if (isset($wrappedquestions) && is_array($wrappedquestions)) {
|
||||
foreach ($wrappedquestions as $wrapped) {
|
||||
if (!$QTYPES[$wrapped->qtype]->get_question_options($wrapped)) {
|
||||
echo $OUTPUT->notification("Unable to get options for questiontype {$wrapped->qtype} (id={$wrapped->id})");
|
||||
}else {
|
||||
// for wrapped questions the maxgrade is always equal to the defaultgrade,
|
||||
// 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?
|
||||
} else {
|
||||
// for wrapped questions the maxgrade is always equal to the defaultgrade,
|
||||
// there is no entry in the question_instances table for them
|
||||
$wrapped->maxgrade = $wrapped->defaultgrade;
|
||||
$nbvaliquestion++;
|
||||
// ??? Why do we need a clone here?
|
||||
$question->options->questions[$sequence[$wrapped->id]] = clone($wrapped);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($nbvaliquestion == 0 ) {
|
||||
echo $OUTPUT->notification(get_string('noquestions','qtype_multianswer',$question->name));
|
||||
if ($nbvaliquestion == 0) {
|
||||
echo $OUTPUT->notification(get_string('noquestions', 'qtype_multianswer', $question->name));
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -105,49 +106,49 @@ class embedded_cloze_qtype extends question_type {
|
|||
$oldwrappedquestions = $DB->get_records_list('question', 'id', explode(',', $oldwrappedids), 'id ASC');
|
||||
}
|
||||
$sequence = array();
|
||||
foreach($question->options->questions as $wrapped) {
|
||||
if (!empty($wrapped)){
|
||||
foreach ($question->options->questions as $wrapped) {
|
||||
if (!empty($wrapped)) {
|
||||
// if we still have some old wrapped question ids, reuse the next of them
|
||||
|
||||
if (is_array($oldwrappedquestions) && $oldwrappedquestion = array_shift($oldwrappedquestions)) {
|
||||
$wrapped->id = $oldwrappedquestion->id;
|
||||
if($oldwrappedquestion->qtype != $wrapped->qtype ) {
|
||||
if ($oldwrappedquestion->qtype != $wrapped->qtype) {
|
||||
switch ($oldwrappedquestion->qtype) {
|
||||
case 'multichoice':
|
||||
$DB->delete_records('question_multichoice', array('question' => $oldwrappedquestion->id));
|
||||
break;
|
||||
case 'shortanswer':
|
||||
$DB->delete_records('question_shortanswer', array('question' => $oldwrappedquestion->id));
|
||||
break;
|
||||
case 'numerical':
|
||||
$DB->delete_records('question_numerical', array('question' => $oldwrappedquestion->id));
|
||||
break;
|
||||
default:
|
||||
print_error('qtypenotrecognized', 'qtype_multianswer','',$oldwrappedquestion->qtype);
|
||||
$wrapped->id = 0 ;
|
||||
case 'multichoice':
|
||||
$DB->delete_records('question_multichoice', array('question' => $oldwrappedquestion->id));
|
||||
break;
|
||||
case 'shortanswer':
|
||||
$DB->delete_records('question_shortanswer', array('question' => $oldwrappedquestion->id));
|
||||
break;
|
||||
case 'numerical':
|
||||
$DB->delete_records('question_numerical', array('question' => $oldwrappedquestion->id));
|
||||
break;
|
||||
default:
|
||||
print_error('qtypenotrecognized', 'qtype_multianswer', '', $oldwrappedquestion->qtype);
|
||||
$wrapped->id = 0;
|
||||
}
|
||||
}
|
||||
}else {
|
||||
$wrapped->id = 0 ;
|
||||
} else {
|
||||
$wrapped->id = 0;
|
||||
}
|
||||
}
|
||||
$wrapped->name = $question->name;
|
||||
$wrapped->parent = $question->id;
|
||||
$previousid = $wrapped->id ;
|
||||
$previousid = $wrapped->id;
|
||||
$wrapped->category = $question->category . ',1'; // save_question strips this extra bit off again.
|
||||
$wrapped = $QTYPES[$wrapped->qtype]->save_question($wrapped, clone($wrapped));
|
||||
$sequence[] = $wrapped->id;
|
||||
if ($previousid != 0 && $previousid != $wrapped->id ) {
|
||||
if ($previousid != 0 && $previousid != $wrapped->id) {
|
||||
// for some reasons a new question has been created
|
||||
// so delete the old one
|
||||
delete_question($previousid) ;
|
||||
delete_question($previousid);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete redundant wrapped questions
|
||||
if(is_array($oldwrappedquestions) && count($oldwrappedquestions)){
|
||||
if (is_array($oldwrappedquestions) && count($oldwrappedquestions)) {
|
||||
foreach ($oldwrappedquestions as $oldwrappedquestion) {
|
||||
delete_question($oldwrappedquestion->id) ;
|
||||
delete_question($oldwrappedquestion->id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,36 +215,17 @@ 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;
|
||||
public function get_possible_responses(&$question) {
|
||||
$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;
|
||||
$responses = array();
|
||||
foreach($question->options->questions as $key => $wrapped) {
|
||||
if (!empty($wrapped)){
|
||||
foreach ($question->options->questions as $key => $wrapped) {
|
||||
if (!empty($wrapped)) {
|
||||
if ($correct = $QTYPES[$wrapped->qtype]->get_possible_responses($wrapped)) {
|
||||
$responses += $correct;
|
||||
} else {
|
||||
|
@ -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"';
|
||||
|
@ -290,7 +260,7 @@ class embedded_cloze_qtype extends question_type {
|
|||
// MDL-7497
|
||||
if (!empty($USER->screenreader)) {
|
||||
echo "<img src=\"".$OUTPUT->pix_url('icon', 'qtype_'.$question->qtype)."\" ".
|
||||
"class=\"icon\" alt=\"".get_string('clozeaid','qtype_multichoice')."\" /> ";
|
||||
"class=\"icon\" alt=\"".get_string('clozeaid', 'qtype_multichoice')."\" /> ";
|
||||
}
|
||||
|
||||
echo '<div class="ablock clearfix">';
|
||||
|
@ -309,290 +279,266 @@ class embedded_cloze_qtype extends question_type {
|
|||
$qtextremaining = $qtextsplits[1];
|
||||
|
||||
$positionkey = $regs[1];
|
||||
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);
|
||||
if (isset($question->options->questions[$positionkey]) && $question->options->questions[$positionkey] != '') {
|
||||
$wrapped = &$question->options->questions[$positionkey];
|
||||
$answers = &$wrapped->options->answers;
|
||||
|
||||
$inputname = $nameprefix.$positionkey;
|
||||
if (isset($state->responses[$positionkey])) {
|
||||
$response = $state->responses[$positionkey];
|
||||
} else {
|
||||
$response = null;
|
||||
}
|
||||
// echo "<p> multianswer positionkey $positionkey response $response state <pre>";print_r($state);echo "</pre></p>";
|
||||
$inputname = $nameprefix.$positionkey;
|
||||
if (isset($state->responses[$positionkey])) {
|
||||
$response = $state->responses[$positionkey];
|
||||
} else {
|
||||
$response = null;
|
||||
}
|
||||
|
||||
// Determine feedback popup if any
|
||||
$popup = '';
|
||||
$style = '';
|
||||
$feedbackimg = '';
|
||||
$feedback = '' ;
|
||||
$correctanswer = '';
|
||||
$strfeedbackwrapped = $strfeedback;
|
||||
// Determine feedback popup if any
|
||||
$popup = '';
|
||||
$style = '';
|
||||
$feedbackimg = '';
|
||||
$feedback = '';
|
||||
$correctanswer = '';
|
||||
$strfeedbackwrapped = $strfeedback;
|
||||
$testedstate = clone($state);
|
||||
if ($correctanswers = $QTYPES[$wrapped->qtype]->get_correct_responses($wrapped, $state)) {
|
||||
if ($options->readonly && $options->correct_responses) {
|
||||
$delimiter = '';
|
||||
if ($correctanswers) {
|
||||
foreach ($correctanswers as $ca) {
|
||||
switch($wrapped->qtype){
|
||||
switch($wrapped->qtype) {
|
||||
case 'numerical':
|
||||
case 'shortanswer':
|
||||
$correctanswer .= $delimiter.$ca;
|
||||
break ;
|
||||
break;
|
||||
case 'multichoice':
|
||||
if (isset($answers[$ca])){
|
||||
if (isset($answers[$ca])) {
|
||||
$correctanswer .= $delimiter.$answers[$ca]->answer;
|
||||
}
|
||||
break ;
|
||||
break;
|
||||
}
|
||||
$delimiter = ', ';
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($correctanswer != '' ) {
|
||||
if ($correctanswer != '') {
|
||||
$feedback = '<div class="correctness">';
|
||||
$feedback .= get_string('correctansweris', 'question', s($correctanswer));
|
||||
$feedback .= '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
if ($options->feedback) {
|
||||
$chosenanswer = null;
|
||||
if ($options->feedback) {
|
||||
$chosenanswer = null;
|
||||
switch ($wrapped->qtype) {
|
||||
case 'numerical':
|
||||
case 'shortanswer':
|
||||
$testedstate = clone($state);
|
||||
$testedstate->responses[''] = $response;
|
||||
foreach ($answers as $answer) {
|
||||
if ($QTYPES[$wrapped->qtype]->test_response($wrapped, $testedstate, $answer)) {
|
||||
$chosenanswer = clone($answer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'multichoice':
|
||||
if (isset($answers[$response])) {
|
||||
$chosenanswer = clone($answers[$response]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Set up a default chosenanswer so that all non-empty wrong
|
||||
// answers are highlighted red
|
||||
if (empty($chosenanswer) && $response != '') {
|
||||
$chosenanswer = new stdClass();
|
||||
$chosenanswer->fraction = 0.0;
|
||||
}
|
||||
|
||||
if (!empty($chosenanswer->feedback)) {
|
||||
$feedback = s(str_replace(array("\\", "'"), array("\\\\", "\\'"), $feedback.$chosenanswer->feedback));
|
||||
if ($options->readonly && $options->correct_responses) {
|
||||
$strfeedbackwrapped = get_string('correctanswerandfeedback', 'qtype_multianswer');
|
||||
} else {
|
||||
$strfeedbackwrapped = get_string('feedback', 'question');
|
||||
}
|
||||
$popup = " onmouseover=\"return overlib('$feedback', STICKY, MOUSEOFF, CAPTION, '$strfeedbackwrapped', FGCOLOR, '#FFFFFF');\" ".
|
||||
" onmouseout=\"return nd();\" ";
|
||||
}
|
||||
|
||||
/// Determine style
|
||||
if ($options->feedback && $response != '') {
|
||||
$style = 'class = "'.question_get_feedback_class($chosenanswer->fraction).'"';
|
||||
$feedbackimg = question_get_feedback_image($chosenanswer->fraction);
|
||||
} else {
|
||||
$style = '';
|
||||
$feedbackimg = '';
|
||||
}
|
||||
}
|
||||
if ($feedback != '' && $popup == '') {
|
||||
$strfeedbackwrapped = get_string('correctanswer', 'qtype_multianswer');
|
||||
$feedback = s(str_replace(array("\\", "'"), array("\\\\", "\\'"), $feedback));
|
||||
$popup = " onmouseover=\"return overlib('$feedback', STICKY, MOUSEOFF, CAPTION, '$strfeedbackwrapped', FGCOLOR, '#FFFFFF');\" ".
|
||||
" onmouseout=\"return nd();\" ";
|
||||
}
|
||||
|
||||
// Print the input control
|
||||
switch ($wrapped->qtype) {
|
||||
case 'numerical':
|
||||
case 'shortanswer':
|
||||
$testedstate = clone($state);
|
||||
$testedstate->responses[''] = $response;
|
||||
case 'numerical':
|
||||
$size = 1;
|
||||
foreach ($answers as $answer) {
|
||||
if($QTYPES[$wrapped->qtype]
|
||||
->test_response($wrapped, $testedstate, $answer)) {
|
||||
$chosenanswer = clone($answer);
|
||||
break;
|
||||
if (strlen(trim($answer->answer)) > $size) {
|
||||
$size = strlen(trim($answer->answer));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'multichoice':
|
||||
if (isset($answers[$response])) {
|
||||
$chosenanswer = clone($answers[$response]);
|
||||
if (strlen(trim($response))> $size) {
|
||||
$size = strlen(trim($response))+1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
$size = $size + rand(0, $size*0.15);
|
||||
$size > 60 ? $size = 60 : $size = $size;
|
||||
$styleinfo = "size=\"$size\"";
|
||||
|
||||
// Set up a default chosenanswer so that all non-empty wrong
|
||||
// answers are highlighted red
|
||||
if (empty($chosenanswer) && $response != '') {
|
||||
$chosenanswer = new stdClass();
|
||||
$chosenanswer->fraction = 0.0;
|
||||
}
|
||||
|
||||
if (!empty($chosenanswer->feedback)) {
|
||||
$feedback = s(str_replace(array("\\", "'"), array("\\\\", "\\'"), $feedback.$chosenanswer->feedback));
|
||||
if ($options->readonly && $options->correct_responses) {
|
||||
$strfeedbackwrapped = get_string('correctanswerandfeedback', 'qtype_multianswer');
|
||||
}else {
|
||||
$strfeedbackwrapped = get_string('feedback', 'question');
|
||||
}
|
||||
$popup = " onmouseover=\"return overlib('$feedback', STICKY, MOUSEOFF, CAPTION, '$strfeedbackwrapped', FGCOLOR, '#FFFFFF');\" ".
|
||||
" onmouseout=\"return nd();\" ";
|
||||
}
|
||||
|
||||
/// Determine style
|
||||
if ($options->feedback && $response != '') {
|
||||
$style = 'class = "'.question_get_feedback_class($chosenanswer->fraction).'"';
|
||||
$feedbackimg = question_get_feedback_image($chosenanswer->fraction);
|
||||
} else {
|
||||
$style = '';
|
||||
$feedbackimg = '';
|
||||
}
|
||||
}
|
||||
if ($feedback !='' && $popup == ''){
|
||||
$strfeedbackwrapped = get_string('correctanswer', 'qtype_multianswer');
|
||||
$feedback = s(str_replace(array("\\", "'"), array("\\\\", "\\'"), $feedback));
|
||||
$popup = " onmouseover=\"return overlib('$feedback', STICKY, MOUSEOFF, CAPTION, '$strfeedbackwrapped', FGCOLOR, '#FFFFFF');\" ".
|
||||
" onmouseout=\"return nd();\" ";
|
||||
}
|
||||
|
||||
// Print the input control
|
||||
switch ($wrapped->qtype) {
|
||||
case 'shortanswer':
|
||||
case 'numerical':
|
||||
$size = 1 ;
|
||||
foreach ($answers as $answer) {
|
||||
if (strlen(trim($answer->answer)) > $size ){
|
||||
$size = strlen(trim($answer->answer));
|
||||
}
|
||||
}
|
||||
if (strlen(trim($response))> $size ){
|
||||
$size = strlen(trim($response))+1;
|
||||
}
|
||||
$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." /> ";
|
||||
if (!empty($feedback) && !empty($USER->screenreader)) {
|
||||
echo "<img src=\"" . $OUTPUT->pix_url('i/feedback') . "\" alt=\"$feedback\" />";
|
||||
}
|
||||
echo $feedbackimg;
|
||||
break;
|
||||
case 'multichoice':
|
||||
if ($wrapped->options->layout == 0 ){
|
||||
$outputoptions = '<option></option>'; // Default empty option
|
||||
foreach ($answers as $mcanswer) {
|
||||
$selected = '';
|
||||
if ($response == $mcanswer->id) {
|
||||
$selected = ' selected="selected"';
|
||||
}
|
||||
$outputoptions .= "<option value=\"$mcanswer->id\"$selected>" .
|
||||
s($mcanswer->answer) . '</option>';
|
||||
}
|
||||
// In the next line, $readonly is invalid HTML, but it works in
|
||||
// all browsers. $disabled would be valid, but then the JS for
|
||||
// displaying the feedback does not work. Of course, we should
|
||||
// not be relying on JS (for accessibility reasons), but that is
|
||||
// a bigger problem.
|
||||
//
|
||||
// The span is used for safari, which does not allow styling of
|
||||
// selects.
|
||||
echo "<span $style><select $popup $readonly $style name=\"$inputname\">";
|
||||
echo $outputoptions;
|
||||
echo '</select></span>';
|
||||
echo "<input $style $readonly $popup name=\"$inputname\"";
|
||||
echo " type=\"text\" value=\"".s($response)."\" ".$styleinfo." /> ";
|
||||
if (!empty($feedback) && !empty($USER->screenreader)) {
|
||||
echo "<img src=\"" . $OUTPUT->pix_url('i/feedback') . "\" alt=\"$feedback\" />";
|
||||
}
|
||||
echo $feedbackimg;
|
||||
}else if ($wrapped->options->layout == 1 || $wrapped->options->layout == 2){
|
||||
$ordernumber=0;
|
||||
$anss = Array();
|
||||
foreach ($answers as $mcanswer) {
|
||||
$ordernumber++;
|
||||
$checked = '';
|
||||
$chosen = false;
|
||||
$type = 'type="radio"';
|
||||
$name = "name=\"{$inputname}\"";
|
||||
if ($response == $mcanswer->id) {
|
||||
$checked = 'checked="checked"';
|
||||
$chosen = true;
|
||||
break;
|
||||
case 'multichoice':
|
||||
if ($wrapped->options->layout == 0) {
|
||||
$outputoptions = '<option></option>'; // Default empty option
|
||||
foreach ($answers as $mcanswer) {
|
||||
$selected = '';
|
||||
if ($response == $mcanswer->id) {
|
||||
$selected = ' selected="selected"';
|
||||
}
|
||||
$outputoptions .= "<option value=\"$mcanswer->id\"$selected>" .
|
||||
s($mcanswer->answer) . '</option>';
|
||||
}
|
||||
$a = new stdClass();
|
||||
$a->id = $question->name_prefix . $mcanswer->id;
|
||||
$a->class = '';
|
||||
$a->feedbackimg = '';
|
||||
// In the next line, $readonly is invalid HTML, but it works in
|
||||
// all browsers. $disabled would be valid, but then the JS for
|
||||
// displaying the feedback does not work. Of course, we should
|
||||
// not be relying on JS (for accessibility reasons), but that is
|
||||
// a bigger problem.
|
||||
//
|
||||
// The span is used for safari, which does not allow styling of
|
||||
// selects.
|
||||
echo "<span $style><select $popup $readonly $style name=\"$inputname\">";
|
||||
echo $outputoptions;
|
||||
echo '</select></span>';
|
||||
if (!empty($feedback) && !empty($USER->screenreader)) {
|
||||
echo "<img src=\"" . $OUTPUT->pix_url('i/feedback') . "\" alt=\"$feedback\" />";
|
||||
}
|
||||
echo $feedbackimg;
|
||||
} else if ($wrapped->options->layout == 1 || $wrapped->options->layout == 2) {
|
||||
$ordernumber = 0;
|
||||
$anss = Array();
|
||||
foreach ($answers as $mcanswer) {
|
||||
$ordernumber++;
|
||||
$checked = '';
|
||||
$chosen = false;
|
||||
$type = 'type="radio"';
|
||||
$name = "name=\"{$inputname}\"";
|
||||
if ($response == $mcanswer->id) {
|
||||
$checked = 'checked="checked"';
|
||||
$chosen = true;
|
||||
}
|
||||
$a = new stdClass();
|
||||
$a->id = $question->name_prefix . $mcanswer->id;
|
||||
$a->class = '';
|
||||
$a->feedbackimg = '';
|
||||
|
||||
// Print the control
|
||||
$a->control = "<input $readonly id=\"$a->id\" $name $checked $type value=\"$mcanswer->id\" />";
|
||||
if ($options->correct_responses && $mcanswer->fraction > 0) {
|
||||
$a->class = question_get_feedback_class(1);
|
||||
// Print the control
|
||||
$a->control = "<input $readonly id=\"$a->id\" $name $checked $type value=\"$mcanswer->id\" />";
|
||||
if ($options->correct_responses && $mcanswer->fraction > 0) {
|
||||
$a->class = question_get_feedback_class(1);
|
||||
}
|
||||
if (($options->feedback && $chosen) || $options->correct_responses) {
|
||||
if ($type == ' type="checkbox" ') {
|
||||
$a->feedbackimg = question_get_feedback_image($mcanswer->fraction > 0 ? 1 : 0, $chosen && $options->feedback);
|
||||
} else {
|
||||
$a->feedbackimg = question_get_feedback_image($mcanswer->fraction, $chosen && $options->feedback);
|
||||
}
|
||||
}
|
||||
|
||||
// Print the answer text: no automatic numbering
|
||||
$a->text = format_text($mcanswer->answer, $mcanswer->answerformat, $formatoptions, $cmoptions->course);
|
||||
|
||||
// Print feedback if feedback is on
|
||||
if (($options->feedback || $options->correct_responses) && ($checked)) { //|| $options->readonly
|
||||
$a->feedback = format_text($mcanswer->feedback, $mcanswer->feedbackformat, $formatoptions, $cmoptions->course);
|
||||
} else {
|
||||
$a->feedback = '';
|
||||
}
|
||||
|
||||
$anss[] = clone($a);
|
||||
}
|
||||
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>
|
||||
<td class="c1 text <?php echo $answer->class ?>">
|
||||
<label for="<?php echo $answer->id ?>">
|
||||
<?php echo $answer->text; ?>
|
||||
<?php echo $answer->feedbackimg; ?>
|
||||
</label>
|
||||
</td>
|
||||
<td class="c0 feedback">
|
||||
<?php echo $answer->feedback; ?>
|
||||
</td>
|
||||
</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) { ?>
|
||||
<td class="c0 control">
|
||||
<?php echo $answer->control; ?>
|
||||
</td>
|
||||
<td class="c1 text <?php echo $answer->class ?>">
|
||||
<label for="<?php echo $answer->id ?>">
|
||||
<?php echo $answer->text; ?>
|
||||
<?php echo $answer->feedbackimg; ?>
|
||||
</label>
|
||||
</td>
|
||||
<td class="c0 feedback">
|
||||
<?php echo $answer->feedback; ?>
|
||||
</td><?php
|
||||
}
|
||||
?>
|
||||
</tr>
|
||||
</table><?php
|
||||
}
|
||||
|
||||
} else {
|
||||
echo "no valid layout";
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
$a = new stdClass();
|
||||
$a->type = $wrapped->qtype;
|
||||
$a->sub = $positionkey;
|
||||
print_error('unknownquestiontypeofsubquestion', 'qtype_multianswer', '', $a);
|
||||
break;
|
||||
}
|
||||
if (($options->feedback && $chosen) || $options->correct_responses) {
|
||||
if ($type == ' type="checkbox" ') {
|
||||
$a->feedbackimg = question_get_feedback_image($mcanswer->fraction > 0 ? 1 : 0, $chosen && $options->feedback);
|
||||
} else {
|
||||
$a->feedbackimg = question_get_feedback_image($mcanswer->fraction, $chosen && $options->feedback);
|
||||
}
|
||||
}
|
||||
|
||||
// Print the answer text: no automatic numbering
|
||||
|
||||
$a->text = format_text($mcanswer->answer, $mcanswer->answerformat, $formatoptions, $cmoptions->course);
|
||||
|
||||
// Print feedback if feedback is on
|
||||
if (($options->feedback || $options->correct_responses) && ($checked )) { //|| $options->readonly
|
||||
$a->feedback = format_text($mcanswer->feedback, $mcanswer->feedbackformat, $formatoptions, $cmoptions->course);
|
||||
echo "</label>"; // MDL-7497
|
||||
} else {
|
||||
if (! isset($question->options->questions[$positionkey])) {
|
||||
echo $regs[0]."</label>";
|
||||
} else {
|
||||
$a->feedback = '';
|
||||
echo '</label><div class="error" >'.get_string('questionnotfound', 'qtype_multianswer', $positionkey).'</div>';
|
||||
}
|
||||
|
||||
$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; ?>">
|
||||
<td class="c0 control">
|
||||
<?php echo $answer->control; ?>
|
||||
</td>
|
||||
<td class="c1 text <?php echo $answer->class ?>">
|
||||
<label for="<?php echo $answer->id ?>">
|
||||
<?php echo $answer->text; ?>
|
||||
<?php echo $answer->feedbackimg; ?>
|
||||
</label>
|
||||
</td>
|
||||
<td class="c0 feedback">
|
||||
<?php echo $answer->feedback; ?>
|
||||
</td>
|
||||
</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) { ?>
|
||||
<td class="c0 control">
|
||||
<?php echo $answer->control; ?>
|
||||
</td>
|
||||
<td class="c1 text <?php echo $answer->class ?>">
|
||||
<label for="<?php echo $answer->id ?>">
|
||||
<?php echo $answer->text; ?>
|
||||
<?php echo $answer->feedbackimg; ?>
|
||||
</label>
|
||||
</td>
|
||||
<td class="c0 feedback">
|
||||
<?php echo $answer->feedback; ?>
|
||||
</td>
|
||||
<?php } ?>
|
||||
</tr>
|
||||
</table>
|
||||
<?php }
|
||||
|
||||
}else {
|
||||
echo "no valid layout";
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
$a = new stdClass();
|
||||
$a->type = $wrapped->qtype ;
|
||||
$a->sub = $positionkey;
|
||||
print_error('unknownquestiontypeofsubquestion', 'qtype_multianswer','',$a);
|
||||
break;
|
||||
}
|
||||
echo "</label>"; // MDL-7497
|
||||
}
|
||||
else {
|
||||
if(! isset($question->options->questions[$positionkey])){
|
||||
echo $regs[0]."</label>";
|
||||
}else {
|
||||
echo '</label><div class="error" >'.get_string('questionnotfound','qtype_multianswer',$positionkey).'</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Print the final piece of question text:
|
||||
echo $qtextremaining;
|
||||
|
@ -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,21 +583,19 @@ 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) {
|
||||
if (!empty($wrapped)){
|
||||
if(isset($state->responses[$key])){
|
||||
foreach ($question->options->questions as $key => $wrapped) {
|
||||
if (!empty($wrapped)) {
|
||||
if (isset($state->responses[$key])) {
|
||||
$state->responses[$key] = $state->responses[$key];
|
||||
}else {
|
||||
$state->responses[$key] = '' ;
|
||||
} else {
|
||||
$state->responses[$key] = '';
|
||||
}
|
||||
$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,73 +616,21 @@ 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){
|
||||
foreach (array_keys($question->options->questions) as $key) {
|
||||
$totalfraction += question_get_random_guess_score($question->options->questions[$key]);
|
||||
}
|
||||
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",
|
||||
|
@ -783,7 +673,7 @@ define("ANSWER_REGEX",
|
|||
. '(' . ANSWER_ALTERNATIVE_REGEX
|
||||
. '(~'
|
||||
. ANSWER_ALTERNATIVE_REGEX
|
||||
. ')*)\}' );
|
||||
. ')*)\}');
|
||||
|
||||
// Parenthesis positions for singulars in ANSWER_REGEX
|
||||
define("ANSWER_REGEX_NORM", 1);
|
||||
|
@ -803,16 +693,16 @@ function qtype_multianswer_extract_question($text) {
|
|||
$question->generalfeedback['text'] = '';
|
||||
$question->generalfeedback['format'] = '1';
|
||||
$question->generalfeedback['itemid'] = '';
|
||||
|
||||
$question->options->questions = array();
|
||||
|
||||
$question->options->questions = array();
|
||||
$question->defaultgrade = 0; // Will be increased for each answer norm
|
||||
|
||||
for ($positionkey=1; preg_match('/'.ANSWER_REGEX.'/', $question->questiontext['text'], $answerregs); ++$positionkey ) {
|
||||
for ($positionkey = 1; preg_match('/'.ANSWER_REGEX.'/', $question->questiontext['text'], $answerregs); ++$positionkey) {
|
||||
$wrapped = new stdClass();
|
||||
$wrapped->generalfeedback['text'] = '';
|
||||
$wrapped->generalfeedback['format'] = '1';
|
||||
$wrapped->generalfeedback['itemid'] = '';
|
||||
if (isset($answerregs[ANSWER_REGEX_NORM])&& $answerregs[ANSWER_REGEX_NORM]!== ''){
|
||||
if (isset($answerregs[ANSWER_REGEX_NORM])&& $answerregs[ANSWER_REGEX_NORM]!== '') {
|
||||
$wrapped->defaultgrade = $answerregs[ANSWER_REGEX_NORM];
|
||||
} else {
|
||||
$wrapped->defaultgrade = '1';
|
||||
|
@ -824,13 +714,13 @@ function qtype_multianswer_extract_question($text) {
|
|||
$wrapped->instructions['text'] = '';
|
||||
$wrapped->instructions['format'] = '1';
|
||||
$wrapped->instructions['itemid'] = '';
|
||||
} else if(!empty($answerregs[ANSWER_REGEX_ANSWER_TYPE_SHORTANSWER])) {
|
||||
} else if (!empty($answerregs[ANSWER_REGEX_ANSWER_TYPE_SHORTANSWER])) {
|
||||
$wrapped->qtype = 'shortanswer';
|
||||
$wrapped->usecase = 0;
|
||||
} else if(!empty($answerregs[ANSWER_REGEX_ANSWER_TYPE_SHORTANSWER_C])) {
|
||||
} else if (!empty($answerregs[ANSWER_REGEX_ANSWER_TYPE_SHORTANSWER_C])) {
|
||||
$wrapped->qtype = 'shortanswer';
|
||||
$wrapped->usecase = 1;
|
||||
} else if(!empty($answerregs[ANSWER_REGEX_ANSWER_TYPE_MULTICHOICE])) {
|
||||
} else if (!empty($answerregs[ANSWER_REGEX_ANSWER_TYPE_MULTICHOICE])) {
|
||||
$wrapped->qtype = 'multichoice';
|
||||
$wrapped->single = 1;
|
||||
$wrapped->answernumbering = 0;
|
||||
|
@ -844,7 +734,7 @@ function qtype_multianswer_extract_question($text) {
|
|||
$wrapped->incorrectfeedback['format'] = '1';
|
||||
$wrapped->incorrectfeedback['itemid'] = '';
|
||||
$wrapped->layout = 0;
|
||||
} else if(!empty($answerregs[ANSWER_REGEX_ANSWER_TYPE_MULTICHOICE_REGULAR])) {
|
||||
} else if (!empty($answerregs[ANSWER_REGEX_ANSWER_TYPE_MULTICHOICE_REGULAR])) {
|
||||
$wrapped->qtype = 'multichoice';
|
||||
$wrapped->single = 1;
|
||||
$wrapped->answernumbering = 0;
|
||||
|
@ -858,7 +748,7 @@ function qtype_multianswer_extract_question($text) {
|
|||
$wrapped->incorrectfeedback['format'] = '1';
|
||||
$wrapped->incorrectfeedback['itemid'] = '';
|
||||
$wrapped->layout = 1;
|
||||
} else if(!empty($answerregs[ANSWER_REGEX_ANSWER_TYPE_MULTICHOICE_HORIZONTAL])) {
|
||||
} else if (!empty($answerregs[ANSWER_REGEX_ANSWER_TYPE_MULTICHOICE_HORIZONTAL])) {
|
||||
$wrapped->qtype = 'multichoice';
|
||||
$wrapped->single = 1;
|
||||
$wrapped->answernumbering = 0;
|
||||
|
@ -885,15 +775,15 @@ function qtype_multianswer_extract_question($text) {
|
|||
$wrapped->feedback = array();
|
||||
$wrapped->shuffleanswers = 1;
|
||||
$wrapped->questiontext['text'] = $answerregs[0];
|
||||
$wrapped->questiontext['format'] = 0 ;
|
||||
$wrapped->questiontext['itemid'] = '' ;
|
||||
$answerindex = 0 ;
|
||||
$wrapped->questiontext['format'] = 0;
|
||||
$wrapped->questiontext['itemid'] = '';
|
||||
$answerindex = 0;
|
||||
|
||||
$remainingalts = $answerregs[ANSWER_REGEX_ALTERNATIVES];
|
||||
while (preg_match('/~?'.ANSWER_ALTERNATIVE_REGEX.'/', $remainingalts, $altregs)) {
|
||||
if ('=' == $altregs[ANSWER_ALTERNATIVE_REGEX_FRACTION]) {
|
||||
$wrapped->fraction["$answerindex"] = '1';
|
||||
} else if ($percentile = $altregs[ANSWER_ALTERNATIVE_REGEX_PERCENTILE_FRACTION]){
|
||||
} else if ($percentile = $altregs[ANSWER_ALTERNATIVE_REGEX_PERCENTILE_FRACTION]) {
|
||||
$wrapped->fraction["$answerindex"] = .01 * $percentile;
|
||||
} else {
|
||||
$wrapped->fraction["$answerindex"] = '0';
|
||||
|
@ -927,17 +817,14 @@ function qtype_multianswer_extract_question($text) {
|
|||
}
|
||||
$tmp = explode($altregs[0], $remainingalts, 2);
|
||||
$remainingalts = $tmp[1];
|
||||
$answerindex++ ;
|
||||
$answerindex++;
|
||||
}
|
||||
|
||||
$question->defaultgrade += $wrapped->defaultgrade;
|
||||
$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,22 +63,22 @@ 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){
|
||||
if ($saquestions === false) {
|
||||
$a = new stdClass();
|
||||
$a->catname = $DB->get_field('question_categories', 'name', array('id' => $category));
|
||||
$errors['choose'] = get_string('nosaincategory', 'qtype_randomsamatch', $a);
|
||||
|
||||
} elseif ($numberavailable < $data['choose']){
|
||||
} else if ($numberavailable < $data['choose']) {
|
||||
$a = new stdClass();
|
||||
$a->catname = $DB->get_field('question_categories', 'name', array('id' => $category));
|
||||
$a->nosaquestions = $numberavailable;
|
||||
|
|
|
@ -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:
|
||||
|
@ -190,7 +185,7 @@ class question_randomsamatch_qtype extends qtype_match {
|
|||
foreach ($responses as $response) {
|
||||
$wqid = $response[0];
|
||||
$state->responses[$wqid] = $response[1];
|
||||
if (!isset($wrappedquestions[$wqid])){
|
||||
if (!isset($wrappedquestions[$wqid])) {
|
||||
if (!$wrappedquestions[$wqid] = $DB->get_record('question', array('id' => $wqid))) {
|
||||
echo $OUTPUT->notification("Couldn't get question (id=$wqid)!");
|
||||
return false;
|
||||
|
@ -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