Skip to content

Commit

Permalink
questiontypes: MDL-17800 Add extra_question_fields() support to backu…
Browse files Browse the repository at this point in the history
…p/restore functions.

* Implement this in the base class, and
* use this in the shortanswer type as a proof of concept.

This makes writing new question type subclasses a bit easier. Thanks to Oleg Sychev for this code.
  • Loading branch information
tjhunt committed Jan 15, 2009
1 parent 4328416 commit bf28249
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 80 deletions.
56 changes: 52 additions & 4 deletions question/type/questiontype.php
Expand Up @@ -1604,8 +1604,35 @@ function error_link($cmoptions) {
* This is used in question/backuplib.php
*/
function backup($bf,$preferences,$question,$level=6) {
// The default type has nothing to back up
return true;

$status = true;
$extraquestionfields = $this->extra_question_fields();

if (is_array($extraquestionfields)) {
$questionextensiontable = array_shift($extraquestionfields);
$record = get_record($questionextensiontable, $this->questionid_column_name(), $question);
if ($record) {
$tagname = strtoupper($this->name());
$status = $status && fwrite($bf, start_tag($tagname, $level, true));
foreach ($extraquestionfields as $field) {
if (!isset($record->$field)) {
echo "No data for field $field when backuping " .
$this->name() . ' question id ' . $question;
return false;
}
fwrite($bf, full_tag(strtoupper($field), $level + 1, false, $record->$field));
}
$status = $status && fwrite($bf, end_tag($tagname, $level, true));
}
}

$extraasnwersfields = $this->extra_answer_fields();
if (is_array($extraasnwersfields)) {
//TODO backup the answers, with any extra data.
} else {
$status = $status && question_backup_answers($bf, $preferences, $question);
}
return $status;
}

/// RESTORE FUNCTIONS /////////////////
Expand All @@ -1616,8 +1643,29 @@ function backup($bf,$preferences,$question,$level=6) {
* This is used in question/restorelib.php
*/
function restore($old_question_id,$new_question_id,$info,$restore) {
// The default question type has nothing to restore
return true;

$status = true;
$extraquestionfields = $this->extra_question_fields();

if (is_array($extraquestionfields)) {
$questionextensiontable = array_shift($extraquestionfields);
$tagname = strtoupper($this->name());
$recordinfo = $info['#'][$tagname][0];

$record = new stdClass;
$qidcolname = $this->questionid_column_name();
$record->$qidcolname = $new_question_id;
foreach ($extraquestionfields as $field) {
$record->$field = backup_todb($recordinfo['#'][strtoupper($field)]['0']['#']);
}
if (!insert_record($questionextensiontable, $record)) {
echo "Can't insert record in $questionextensiontable when restoring " .
$this->name() . ' question id ' . $question;
$status = false;
}
}
//TODO restore extra data in answers
return $status;
}

function restore_map($old_question_id,$new_question_id,$info,$restore) {
Expand Down
101 changes: 25 additions & 76 deletions question/type/shortanswer/questiontype.php
Expand Up @@ -200,34 +200,6 @@ function get_correct_responses(&$question, &$state) {
return $response;
}

/// BACKUP FUNCTIONS ////////////////////////////

/*
* Backup the data in the question
*
* This is used in question/backuplib.php
*/
function backup($bf,$preferences,$question,$level=6) {

$status = true;

$shortanswers = get_records('question_shortanswer', 'question', $question, 'id ASC');
//If there are shortanswers
if ($shortanswers) {
//Iterate over each shortanswer
foreach ($shortanswers as $shortanswer) {
$status = fwrite ($bf,start_tag("SHORTANSWER",$level,true));
//Print shortanswer contents
fwrite ($bf,full_tag("ANSWERS",$level+1,false,$shortanswer->answers));
fwrite ($bf,full_tag("USECASE",$level+1,false,$shortanswer->usecase));
$status = fwrite ($bf,end_tag("SHORTANSWER",$level,true));
}
//Now print question_answers
$status = question_backup_answers($bf,$preferences,$question);
}
return $status;
}

/// RESTORE FUNCTIONS /////////////////

/*
Expand All @@ -237,59 +209,36 @@ function backup($bf,$preferences,$question,$level=6) {
*/
function restore($old_question_id,$new_question_id,$info,$restore) {

$status = true;
$status = parent::restore($old_question_id, $new_question_id, $info, $restore);

//Get the shortanswers array
$shortanswers = $info['#']['SHORTANSWER'];

//Iterate over shortanswers
for($i = 0; $i < sizeof($shortanswers); $i++) {
$sho_info = $shortanswers[$i];

//Now, build the question_shortanswer record structure
$shortanswer = new stdClass;
$shortanswer->question = $new_question_id;
$shortanswer->answers = backup_todb($sho_info['#']['ANSWERS']['0']['#']);
$shortanswer->usecase = backup_todb($sho_info['#']['USECASE']['0']['#']);
if ($status) {
$extraquestionfields = $this->extra_question_fields();
$questionextensiontable = array_shift($extraquestionfields);

//We have to recode the answers field (a list of answers id)
//Extracts answer id from sequence
$answers_field = "";
$in_first = true;
$tok = strtok($shortanswer->answers,",");
while ($tok) {
//Get the answer from backup_ids
$answer = backup_getid($restore->backup_unique_code,"question_answers",$tok);
if ($answer) {
if ($in_first) {
$answers_field .= $answer->new_id;
$in_first = false;
} else {
$answers_field .= ",".$answer->new_id;
}
}
//check for next
$tok = strtok(",");
}
//We have the answers field recoded to its new ids
$shortanswer->answers = $answers_field;

//The structure is equal to the db, so insert the question_shortanswer
$newid = insert_record ("question_shortanswer",$shortanswer);

//Do some output
if (($i+1) % 50 == 0) {
if (!defined('RESTORE_SILENTLY')) {
echo ".";
if (($i+1) % 1000 == 0) {
echo "<br />";
$questionextradata = get_record($questionextensiontable, $this->questionid_column_name(), $new_question_id);
if (isset($questionextradata->answers)) {
$answers_field = "";
$in_first = true;
$tok = strtok($questionextradata->answers, ",");
while ($tok) {
// Get the answer from backup_ids
$answer = backup_getid($restore->backup_unique_code,"question_answers",$tok);
if ($answer) {
if ($in_first) {
$answers_field .= $answer->new_id;
$in_first = false;
} else {
$answers_field .= ",".$answer->new_id;
}
}
// Check for next
$tok = strtok(",");
}
backup_flush(300);
}

if (!$newid) {
$status = false;
// We have the answers field recoded to its new ids
$questionextradata->answers = $answers_field;
// Update the question
$status = $status && update_record($questionextensiontable, $questionextradata);
}
}

Expand Down

0 comments on commit bf28249

Please sign in to comment.