mirror of
https://github.com/moodle/moodle.git
synced 2025-02-15 21:36:58 +01:00
A mechanish to detect all the ancestors and to recover orphaned categories is now running ar backup time to force backups to be consistent.
840 lines
39 KiB
PHP
840 lines
39 KiB
PHP
<?php //$Id$
|
|
//This php script contains all the stuff to backup/restore
|
|
//quiz mods
|
|
|
|
//To see, put your terminal to 160cc
|
|
|
|
//This is the "graphical" structure of the quiz mod:
|
|
//
|
|
// quiz quiz_categories
|
|
// (CL,pk->id) (CL,pk->id)
|
|
// | |
|
|
// ----------------------------------------------- |
|
|
// | | | |.......................................
|
|
// | | | | .
|
|
// | | | | .
|
|
// quiz_attempts quiz_grades quiz_question_grades | ----quiz_question_datasets---- .
|
|
// (UL,pk->id, fk->quiz) (UL,pk->id,fk->quiz) (CL,pk->id,fk->quiz) | | (CL,pk->id,fk->question, | .
|
|
// | | | | fk->dataset_definition) | .
|
|
// | | | | | .
|
|
// | | | | | .
|
|
// | | | | | .
|
|
// quiz_responses | quiz_questions quiz_dataset_definitions
|
|
// (UL,pk->id, fk->attempt)----------------------------------------------------(CL,pk->id,fk->category,files) (CL,pk->id,fk->category)
|
|
// | |
|
|
// | |
|
|
// | |
|
|
// | quiz_dataset_items
|
|
// | (CL,pk->id,fk->definition)
|
|
// |
|
|
// |
|
|
// |
|
|
// --------------------------------------------------------------------------------------------------------------
|
|
// | | | | | | |
|
|
// | | | | | | |
|
|
// | | | | quiz_calculated | | quiz_randomsamatch
|
|
// quiz_truefalse | quiz_multichoice | (CL,pl->id,fk->question) | |--(CL,pl->id,fk->question)
|
|
// (CL,pl->id,fk->question) | (CL,pl->id,fk->question) | . | |
|
|
// . | . | . | |
|
|
// . quiz_shortanswer . quiz_numerical . quiz_multianswer. |
|
|
// . (CL,pl->id,fk->question) . (CL,pl->id,fk->question) . (CL,pl->id,fk->question) | quiz_match
|
|
// . . . . . . |--(CL,pl->id,fk->question)
|
|
// . . . . . . | .
|
|
// . . . . . . | .
|
|
// . . . . . . | .
|
|
// . . . . . . | quiz_match_sub
|
|
// . . . . . . |--(CL,pl->id,fk->question)
|
|
// ........................................................................................ |
|
|
// . |
|
|
// . |
|
|
// . | quiz_numerical_units
|
|
// quiz_answers |--(CL,pl->id,fk->question)
|
|
// (CL,pk->id,fk->question)----------------------------------------------------------
|
|
//
|
|
// Meaning: pk->primary key field of the table
|
|
// fk->foreign key to link with parent
|
|
// nt->nested field (recursive data)
|
|
// CL->course level info
|
|
// UL->user level info
|
|
// files->table may have files
|
|
//
|
|
//-----------------------------------------------------------
|
|
|
|
//THIS MOD BACKUP NEEDS TO USE THE mdl_backup_ids TABLE
|
|
|
|
//This module is special, because we make the backup in two steps:
|
|
// 1.-We backup every category and their questions (complete structure). It includes this tables:
|
|
// - quiz_categories
|
|
// - quiz_questions
|
|
// - quiz_truefalse
|
|
// - quiz_shortanswer
|
|
// - quiz_multianswer
|
|
// - quiz_multichoice
|
|
// - quiz_numerical
|
|
// - quiz_randomsamatch
|
|
// - quiz_match
|
|
// - quiz_match_sub
|
|
// - quiz_calculated
|
|
// - quiz_answers
|
|
// - quiz_numerical_units
|
|
// - quiz_question_datasets
|
|
// - quiz_dataset_definitions
|
|
// - quiz_dataset_items
|
|
// All this backup info have its own section in moodle.xml (QUESTION_CATEGORIES) and it's generated
|
|
// before every module backup standard invocation. And only if to backup quizzes has been selected !!
|
|
// It's invoked with quiz_backup_question_categories. (course independent).
|
|
|
|
// 2.-Standard module backup (Invoked via quiz_backup_mods). It includes this tables:
|
|
// - quiz
|
|
// - quiz_question_grades
|
|
// - quiz_attempts
|
|
// - quiz_grades
|
|
// - quiz_responses
|
|
// This step is the standard mod backup. (course dependent).
|
|
|
|
//STEP 1. Backup categories/questions and associated structures
|
|
// (course independent)
|
|
function quiz_backup_question_categories($bf,$preferences) {
|
|
|
|
global $CFG;
|
|
|
|
$status = true;
|
|
|
|
//First, we get the used categories from backup_ids
|
|
$categories = quiz_category_ids_by_backup ($preferences->backup_unique_code);
|
|
|
|
//If we've categories
|
|
if ($categories) {
|
|
//Write start tag
|
|
$status = fwrite($bf,start_tag("QUESTION_CATEGORIES",2,true));
|
|
//Iterate over each category
|
|
foreach ($categories as $cat) {
|
|
//Start category
|
|
$status =fwrite ($bf,start_tag("QUESTION_CATEGORY",3,true));
|
|
//Get category data from quiz_categories
|
|
$category = get_record ("quiz_categories","id",$cat->old_id);
|
|
//Print category contents
|
|
fwrite($bf,full_tag("ID",4,false,$category->id));
|
|
fwrite($bf,full_tag("NAME",4,false,$category->name));
|
|
fwrite($bf,full_tag("INFO",4,false,$category->info));
|
|
fwrite($bf,full_tag("PUBLISH",4,false,$category->publish));
|
|
fwrite($bf,full_tag("STAMP",4,false,$category->stamp));
|
|
fwrite($bf,full_tag("PARENT",4,false,$category->parent));
|
|
fwrite($bf,full_tag("SORTORDER",4,false,$category->sortorder));
|
|
//Now, backup their questions
|
|
$status = quiz_backup_question($bf,$preferences,$category->id);
|
|
//End category
|
|
$status =fwrite ($bf,end_tag("QUESTION_CATEGORY",3,true));
|
|
}
|
|
//Write end tag
|
|
$status =fwrite ($bf,end_tag("QUESTION_CATEGORIES",2,true));
|
|
}
|
|
|
|
return $status;
|
|
}
|
|
|
|
//This function backups all the questions in selected category and their
|
|
//asociated data
|
|
function quiz_backup_question($bf,$preferences,$category) {
|
|
|
|
global $CFG;
|
|
|
|
$status = true;
|
|
|
|
$questions = get_records("quiz_questions","category",$category,"id");
|
|
//If there is questions
|
|
if ($questions) {
|
|
//Write start tag
|
|
$status =fwrite ($bf,start_tag("QUESTIONS",4,true));
|
|
$counter = 0;
|
|
//Iterate over each question
|
|
foreach ($questions as $question) {
|
|
//Start question
|
|
$status =fwrite ($bf,start_tag("QUESTION",5,true));
|
|
//Print question contents
|
|
fwrite ($bf,full_tag("ID",6,false,$question->id));
|
|
fwrite ($bf,full_tag("NAME",6,false,$question->name));
|
|
fwrite ($bf,full_tag("QUESTIONTEXT",6,false,$question->questiontext));
|
|
fwrite ($bf,full_tag("QUESTIONTEXTFORMAT",6,false,$question->questiontextformat));
|
|
fwrite ($bf,full_tag("IMAGE",6,false,$question->image));
|
|
fwrite ($bf,full_tag("DEFAULTGRADE",6,false,$question->defaultgrade));
|
|
fwrite ($bf,full_tag("QTYPE",6,false,$question->qtype));
|
|
fwrite ($bf,full_tag("STAMP",6,false,$question->stamp));
|
|
fwrite ($bf,full_tag("VERSION",6,false,$question->version));
|
|
//Now, depending of the qtype, call one function or other
|
|
if ($question->qtype == "1") {
|
|
$status = quiz_backup_shortanswer($bf,$preferences,$question->id);
|
|
} else if ($question->qtype == "2") {
|
|
$status = quiz_backup_truefalse($bf,$preferences,$question->id);
|
|
} else if ($question->qtype == "3") {
|
|
$status = quiz_backup_multichoice($bf,$preferences,$question->id);
|
|
} else if ($question->qtype == "4") {
|
|
//Random question. Nothing to write.
|
|
} else if ($question->qtype == "5") {
|
|
$status = quiz_backup_match($bf,$preferences,$question->id);
|
|
} else if ($question->qtype == "6") {
|
|
$status = quiz_backup_randomsamatch($bf,$preferences,$question->id);
|
|
} else if ($question->qtype == "7") {
|
|
//Description question. Nothing to write.
|
|
} else if ($question->qtype == "8") {
|
|
$status = quiz_backup_numerical($bf,$preferences,$question->id);
|
|
} else if ($question->qtype == "9") {
|
|
$status = quiz_backup_multianswer($bf,$preferences,$question->id);
|
|
} else if ($question->qtype == "10") {
|
|
$status = quiz_backup_calculated($bf,$preferences,$question->id);
|
|
}
|
|
//End question
|
|
$status =fwrite ($bf,end_tag("QUESTION",5,true));
|
|
//Do some output
|
|
$counter++;
|
|
if ($counter % 10 == 0) {
|
|
echo ".";
|
|
if ($counter % 200 == 0) {
|
|
echo "<br />";
|
|
}
|
|
backup_flush(300);
|
|
}
|
|
}
|
|
//Write end tag
|
|
$status =fwrite ($bf,end_tag("QUESTIONS",4,true));
|
|
}
|
|
return $status;
|
|
}
|
|
|
|
//This function backups the data in a truefalse question (qtype=2) and its
|
|
//asociated data
|
|
function quiz_backup_truefalse($bf,$preferences,$question) {
|
|
|
|
global $CFG;
|
|
|
|
$status = true;
|
|
|
|
$truefalses = get_records("quiz_truefalse","question",$question,"id");
|
|
//If there are truefalses
|
|
if ($truefalses) {
|
|
//Iterate over each truefalse
|
|
foreach ($truefalses as $truefalse) {
|
|
$status =fwrite ($bf,start_tag("TRUEFALSE",6,true));
|
|
//Print truefalse contents
|
|
fwrite ($bf,full_tag("TRUEANSWER",7,false,$truefalse->trueanswer));
|
|
fwrite ($bf,full_tag("FALSEANSWER",7,false,$truefalse->falseanswer));
|
|
$status =fwrite ($bf,end_tag("TRUEFALSE",6,true));
|
|
}
|
|
//Now print quiz_answers
|
|
$status = quiz_backup_answers($bf,$preferences,$question);
|
|
}
|
|
return $status;
|
|
}
|
|
|
|
//This function backups the data in a shortanswer question (qtype=1) and its
|
|
//asociated data
|
|
function quiz_backup_shortanswer($bf,$preferences,$question,$level=6,$include_answers=true) {
|
|
|
|
global $CFG;
|
|
|
|
$status = true;
|
|
|
|
$shortanswers = get_records("quiz_shortanswer","question",$question,"id");
|
|
//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 quiz_answers
|
|
if ($include_answers) {
|
|
$status = quiz_backup_answers($bf,$preferences,$question);
|
|
}
|
|
}
|
|
return $status;
|
|
}
|
|
|
|
//This function backups the data in a multichoice question (qtype=3) and its
|
|
//asociated data
|
|
function quiz_backup_multichoice($bf,$preferences,$question,$level=6,$include_answers=true) {
|
|
|
|
global $CFG;
|
|
|
|
$status = true;
|
|
|
|
$multichoices = get_records("quiz_multichoice","question",$question,"id");
|
|
//If there are multichoices
|
|
if ($multichoices) {
|
|
//Iterate over each multichoice
|
|
foreach ($multichoices as $multichoice) {
|
|
$status =fwrite ($bf,start_tag("MULTICHOICE",$level,true));
|
|
//Print multichoice contents
|
|
fwrite ($bf,full_tag("LAYOUT",$level+1,false,$multichoice->layout));
|
|
fwrite ($bf,full_tag("ANSWERS",$level+1,false,$multichoice->answers));
|
|
fwrite ($bf,full_tag("SINGLE",$level+1,false,$multichoice->single));
|
|
$status =fwrite ($bf,end_tag("MULTICHOICE",$level,true));
|
|
}
|
|
//Now print quiz_answers
|
|
if ($include_answers) {
|
|
$status = quiz_backup_answers($bf,$preferences,$question);
|
|
}
|
|
}
|
|
return $status;
|
|
}
|
|
|
|
//This function backups the data in a randomsamatch question (qtype=6) and its
|
|
//asociated data
|
|
function quiz_backup_randomsamatch($bf,$preferences,$question) {
|
|
|
|
global $CFG;
|
|
|
|
$status = true;
|
|
|
|
$randomsamatchs = get_records("quiz_randomsamatch","question",$question,"id");
|
|
//If there are randomsamatchs
|
|
if ($randomsamatchs) {
|
|
//Iterate over each randomsamatch
|
|
foreach ($randomsamatchs as $randomsamatch) {
|
|
$status =fwrite ($bf,start_tag("RANDOMSAMATCH",6,true));
|
|
//Print randomsamatch contents
|
|
fwrite ($bf,full_tag("CHOOSE",7,false,$randomsamatch->choose));
|
|
$status =fwrite ($bf,end_tag("RANDOMSAMATCH",6,true));
|
|
}
|
|
}
|
|
return $status;
|
|
}
|
|
|
|
//This function backups the data in a match question (qtype=5) and its
|
|
//asociated data
|
|
function quiz_backup_match($bf,$preferences,$question) {
|
|
|
|
global $CFG;
|
|
|
|
$status = true;
|
|
|
|
$matchs = get_records("quiz_match_sub","question",$question,"id");
|
|
//If there are matchs
|
|
if ($matchs) {
|
|
$status =fwrite ($bf,start_tag("MATCHS",6,true));
|
|
//Iterate over each match
|
|
foreach ($matchs as $match) {
|
|
$status =fwrite ($bf,start_tag("MATCH",7,true));
|
|
//Print match contents
|
|
fwrite ($bf,full_tag("ID",8,false,$match->id));
|
|
fwrite ($bf,full_tag("QUESTIONTEXT",8,false,$match->questiontext));
|
|
fwrite ($bf,full_tag("ANSWERTEXT",8,false,$match->answertext));
|
|
$status =fwrite ($bf,end_tag("MATCH",7,true));
|
|
}
|
|
$status =fwrite ($bf,end_tag("MATCHS",6,true));
|
|
}
|
|
return $status;
|
|
}
|
|
|
|
//This function backups the data in a numerical question (qtype=8) and its
|
|
//asociated data
|
|
function quiz_backup_numerical($bf,$preferences,$question,$level=6,$include_answers=true) {
|
|
|
|
global $CFG;
|
|
|
|
$status = true;
|
|
|
|
$numericals = get_records("quiz_numerical","question",$question,"id");
|
|
//If there are numericals
|
|
if ($numericals) {
|
|
//Iterate over each numerical
|
|
foreach ($numericals as $numerical) {
|
|
$status =fwrite ($bf,start_tag("NUMERICAL",$level,true));
|
|
//Print numerical contents
|
|
fwrite ($bf,full_tag("ANSWER",$level+1,false,$numerical->answer));
|
|
fwrite ($bf,full_tag("MIN",$level+1,false,$numerical->min));
|
|
fwrite ($bf,full_tag("MAX",$level+1,false,$numerical->max));
|
|
//Now backup numerical_units
|
|
$status = quiz_backup_numerical_units($bf,$preferences,$question,7);
|
|
$status =fwrite ($bf,end_tag("NUMERICAL",$level,true));
|
|
}
|
|
//Now print quiz_answers
|
|
if ($include_answers) {
|
|
$status = quiz_backup_answers($bf,$preferences,$question);
|
|
}
|
|
}
|
|
return $status;
|
|
}
|
|
|
|
//This function backups the data in a multianswer question (qtype=9) and its
|
|
//asociated data
|
|
function quiz_backup_multianswer($bf,$preferences,$question) {
|
|
|
|
global $CFG;
|
|
|
|
$status = true;
|
|
|
|
$multianswers = get_records("quiz_multianswers","question",$question,"id");
|
|
//If there are multianswers
|
|
if ($multianswers) {
|
|
//Print multianswers header
|
|
$status =fwrite ($bf,start_tag("MULTIANSWERS",6,true));
|
|
//Iterate over each multianswer
|
|
foreach ($multianswers as $multianswer) {
|
|
$status =fwrite ($bf,start_tag("MULTIANSWER",7,true));
|
|
//Print multianswer contents
|
|
fwrite ($bf,full_tag("ID",8,false,$multianswer->id));
|
|
fwrite ($bf,full_tag("ANSWERS",8,false,$multianswer->answers));
|
|
fwrite ($bf,full_tag("POSITIONKEY",8,false,$multianswer->positionkey));
|
|
fwrite ($bf,full_tag("ANSWERTYPE",8,false,$multianswer->answertype));
|
|
fwrite ($bf,full_tag("NORM",8,false,$multianswer->norm));
|
|
//Depending of the ANSWERTYPE, we must encode different info
|
|
//to be able to re-create records in quiz_shortanswer, quiz_multichoice and
|
|
//quiz_numerical
|
|
if ($multianswer->answertype == "1") {
|
|
$status = quiz_backup_shortanswer($bf,$preferences,$question,8,false);
|
|
} else if ($multianswer->answertype == "3") {
|
|
$status = quiz_backup_multichoice($bf,$preferences,$question,8,false);
|
|
} else if ($multianswer->answertype == "8") {
|
|
$status = quiz_backup_numerical($bf,$preferences,$question,8,false);
|
|
}
|
|
|
|
$status =fwrite ($bf,end_tag("MULTIANSWER",7,true));
|
|
}
|
|
//Print multianswers footer
|
|
$status =fwrite ($bf,end_tag("MULTIANSWERS",6,true));
|
|
//Now print quiz_answers
|
|
$status = quiz_backup_answers($bf,$preferences,$question);
|
|
}
|
|
return $status;
|
|
}
|
|
|
|
//This function backups the data in a calculated question (qtype=10) and its
|
|
//asociated data
|
|
function quiz_backup_calculated($bf,$preferences,$question,$level=6,$include_answers=true) {
|
|
|
|
global $CFG;
|
|
|
|
$status = true;
|
|
|
|
$calculateds = get_records("quiz_calculated","question",$question,"id");
|
|
//If there are calculated-s
|
|
if ($calculateds) {
|
|
//Iterate over each calculateds
|
|
foreach ($calculateds as $calculated) {
|
|
$status =fwrite ($bf,start_tag("CALCULATED",$level,true));
|
|
//Print calculated contents
|
|
fwrite ($bf,full_tag("ANSWER",$level+1,false,$calculated->answer));
|
|
fwrite ($bf,full_tag("TOLERANCE",$level+1,false,$calculated->tolerance));
|
|
fwrite ($bf,full_tag("TOLERANCETYPE",$level+1,false,$calculated->tolerancetype));
|
|
fwrite ($bf,full_tag("CORRECTANSWERLENGTH",$level+1,false,$calculated->correctanswerlength));
|
|
fwrite ($bf,full_tag("CORRECTANSWERFORMAT",$level+1,false,$calculated->correctanswerformat));
|
|
//Now backup numerical_units
|
|
$status = quiz_backup_numerical_units($bf,$preferences,$question,7);
|
|
//Now backup required dataset definitions and items...
|
|
$status = quiz_backup_datasets($bf,$preferences,$question,7);
|
|
//End calculated data
|
|
$status =fwrite ($bf,end_tag("CALCULATED",$level,true));
|
|
}
|
|
//Now print quiz_answers
|
|
if ($include_answers) {
|
|
$status = quiz_backup_answers($bf,$preferences,$question);
|
|
}
|
|
}
|
|
return $status;
|
|
}
|
|
|
|
//This function backups the answers data in some question types
|
|
//(truefalse, shortanswer,multichoice,numerical,calculated)
|
|
function quiz_backup_answers($bf,$preferences,$question) {
|
|
|
|
global $CFG;
|
|
|
|
$status = true;
|
|
|
|
$answers = get_records("quiz_answers","question",$question,"id");
|
|
//If there are answers
|
|
if ($answers) {
|
|
$status =fwrite ($bf,start_tag("ANSWERS",6,true));
|
|
//Iterate over each answer
|
|
foreach ($answers as $answer) {
|
|
$status =fwrite ($bf,start_tag("ANSWER",7,true));
|
|
//Print answer contents
|
|
fwrite ($bf,full_tag("ID",8,false,$answer->id));
|
|
fwrite ($bf,full_tag("ANSWER_TEXT",8,false,$answer->answer));
|
|
fwrite ($bf,full_tag("FRACTION",8,false,$answer->fraction));
|
|
fwrite ($bf,full_tag("FEEDBACK",8,false,$answer->feedback));
|
|
$status =fwrite ($bf,end_tag("ANSWER",7,true));
|
|
}
|
|
$status =fwrite ($bf,end_tag("ANSWERS",6,true));
|
|
}
|
|
return $status;
|
|
}
|
|
|
|
//This function backups quiz_numerical_units from different question types
|
|
function quiz_backup_numerical_units($bf,$preferences,$question,$level=7) {
|
|
|
|
global $CFG;
|
|
|
|
$status = true;
|
|
|
|
$numerical_units = get_records("quiz_numerical_units","question",$question,"id");
|
|
//If there are numericals_units
|
|
if ($numerical_units) {
|
|
$status =fwrite ($bf,start_tag("NUMERICAL_UNITS",$level,true));
|
|
//Iterate over each numerical_unit
|
|
foreach ($numerical_units as $numerical_unit) {
|
|
$status =fwrite ($bf,start_tag("NUMERICAL_UNIT",$level+1,true));
|
|
//Print numerical_unit contents
|
|
fwrite ($bf,full_tag("MULTIPLIER",$level+2,false,$numerical_unit->multiplier));
|
|
fwrite ($bf,full_tag("UNIT",$level+2,false,$numerical_unit->unit));
|
|
//Now backup numerical_units
|
|
$status =fwrite ($bf,end_tag("NUMERICAL_UNIT",$level+1,true));
|
|
}
|
|
$status =fwrite ($bf,end_tag("NUMERICAL_UNITS",$level,true));
|
|
}
|
|
|
|
return $status;
|
|
|
|
}
|
|
|
|
//This function backups dataset_definitions (via question_datasets) from different question types
|
|
function quiz_backup_datasets($bf,$preferences,$question,$level=7) {
|
|
|
|
global $CFG;
|
|
|
|
$status = true;
|
|
|
|
//First, we get the used datasets for this question
|
|
$question_datasets = get_records("quiz_question_datasets","question",$question,"id");
|
|
//If there are question_datasets
|
|
if ($question_datasets) {
|
|
$status =fwrite ($bf,start_tag("DATASET_DEFINITIONS",$level,true));
|
|
//Iterate over each question_dataset
|
|
foreach ($question_datasets as $question_dataset) {
|
|
$def = NULL;
|
|
//Get dataset_definition
|
|
if ($def = get_record("quiz_dataset_definitions","id",$question_dataset->datasetdefinition)) {;
|
|
$status =fwrite ($bf,start_tag("DATASET_DEFINITION",$level+1,true));
|
|
//Print question_dataset contents
|
|
fwrite ($bf,full_tag("CATEGORY",$level+2,false,$def->category));
|
|
fwrite ($bf,full_tag("NAME",$level+2,false,$def->name));
|
|
fwrite ($bf,full_tag("TYPE",$level+2,false,$def->type));
|
|
fwrite ($bf,full_tag("OPTIONS",$level+2,false,$def->options));
|
|
fwrite ($bf,full_tag("ITEMCOUNT",$level+2,false,$def->itemcount));
|
|
//Now backup dataset_entries
|
|
$status = quiz_backup_dataset_items($bf,$preferences,$def->id,$level+2);
|
|
//End dataset definition
|
|
$status =fwrite ($bf,end_tag("DATASET_DEFINITION",$level+1,true));
|
|
}
|
|
}
|
|
$status =fwrite ($bf,end_tag("DATASET_DEFINITIONS",$level,true));
|
|
}
|
|
|
|
return $status;
|
|
|
|
}
|
|
|
|
//This function backups datases_items from dataset_definitions
|
|
function quiz_backup_dataset_items($bf,$preferences,$datasetdefinition,$level=9) {
|
|
|
|
global $CFG;
|
|
|
|
$status = true;
|
|
|
|
//First, we get the datasets_items for this dataset_definition
|
|
$dataset_items = get_records("quiz_dataset_items","definition",$datasetdefinition,"id");
|
|
//If there are dataset_items
|
|
if ($dataset_items) {
|
|
$status =fwrite ($bf,start_tag("DATASET_ITEMS",$level,true));
|
|
//Iterate over each dataset_item
|
|
foreach ($dataset_items as $dataset_item) {
|
|
$status =fwrite ($bf,start_tag("DATASET_ITEM",$level+1,true));
|
|
//Print question_dataset contents
|
|
fwrite ($bf,full_tag("NUMBER",$level+2,false,$dataset_item->number));
|
|
fwrite ($bf,full_tag("VALUE",$level+2,false,$dataset_item->value));
|
|
//End dataset definition
|
|
$status =fwrite ($bf,end_tag("DATASET_ITEM",$level+1,true));
|
|
}
|
|
$status =fwrite ($bf,end_tag("DATASET_ITEMS",$level,true));
|
|
}
|
|
|
|
return $status;
|
|
|
|
}
|
|
|
|
//STEP 2. Backup quizzes and associated structures
|
|
// (course dependent)
|
|
function quiz_backup_mods($bf,$preferences) {
|
|
|
|
global $CFG;
|
|
|
|
$status = true;
|
|
|
|
//Iterate over quiz table
|
|
$quizzes = get_records ("quiz","course",$preferences->backup_course,"id");
|
|
if ($quizzes) {
|
|
foreach ($quizzes as $quiz) {
|
|
//Start mod
|
|
fwrite ($bf,start_tag("MOD",3,true));
|
|
//Print quiz data
|
|
fwrite ($bf,full_tag("ID",4,false,$quiz->id));
|
|
fwrite ($bf,full_tag("MODTYPE",4,false,"quiz"));
|
|
fwrite ($bf,full_tag("NAME",4,false,$quiz->name));
|
|
fwrite ($bf,full_tag("INTRO",4,false,$quiz->intro));
|
|
fwrite ($bf,full_tag("TIMEOPEN",4,false,$quiz->timeopen));
|
|
fwrite ($bf,full_tag("TIMECLOSE",4,false,$quiz->timeclose));
|
|
fwrite ($bf,full_tag("ATTEMPTS_NUMBER",4,false,$quiz->attempts));
|
|
fwrite ($bf,full_tag("ATTEMPTONLAST",4,false,$quiz->attemptonlast));
|
|
fwrite ($bf,full_tag("FEEDBACK",4,false,$quiz->feedback));
|
|
fwrite ($bf,full_tag("CORRECTANSWERS",4,false,$quiz->correctanswers));
|
|
fwrite ($bf,full_tag("GRADEMETHOD",4,false,$quiz->grademethod));
|
|
fwrite ($bf,full_tag("DECIMALPOINTS",4,false,$quiz->decimalpoints));
|
|
fwrite ($bf,full_tag("REVIEW",4,false,$quiz->review));
|
|
fwrite ($bf,full_tag("QUESTIONSPERPAGE",4,false,$quiz->questionsperpage));
|
|
fwrite ($bf,full_tag("SHUFFLEQUESTIONS",4,false,$quiz->shufflequestions));
|
|
fwrite ($bf,full_tag("SHUFFLEANSWERS",4,false,$quiz->shuffleanswers));
|
|
fwrite ($bf,full_tag("QUESTIONS",4,false,$quiz->questions));
|
|
fwrite ($bf,full_tag("SUMGRADES",4,false,$quiz->sumgrades));
|
|
fwrite ($bf,full_tag("GRADE",4,false,$quiz->grade));
|
|
fwrite ($bf,full_tag("TIMECREATED",4,false,$quiz->timecreated));
|
|
fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$quiz->timemodified));
|
|
fwrite ($bf,full_tag("TIMELIMIT",4,false,$quiz->timelimit));
|
|
fwrite ($bf,full_tag("PASSWORD",4,false,$quiz->password));
|
|
fwrite ($bf,full_tag("SUBNET",4,false,$quiz->subnet));
|
|
fwrite ($bf,full_tag("POPUP",4,false,$quiz->popup));
|
|
//Now we print to xml question_grades (Course Level)
|
|
$status = backup_quiz_question_grades($bf,$preferences,$quiz->id);
|
|
//if we've selected to backup users info, then execute:
|
|
// - backup_quiz_grades
|
|
// - backup_quiz_attempts
|
|
if ($preferences->mods["quiz"]->userinfo and $status) {
|
|
$status = backup_quiz_grades($bf,$preferences,$quiz->id);
|
|
if ($status) {
|
|
$status = backup_quiz_attempts($bf,$preferences,$quiz->id);
|
|
}
|
|
}
|
|
//End mod
|
|
$status =fwrite ($bf,end_tag("MOD",3,true));
|
|
}
|
|
}
|
|
return $status;
|
|
}
|
|
|
|
//Backup quiz_question_grades contents (executed from quiz_backup_mods)
|
|
function backup_quiz_question_grades ($bf,$preferences,$quiz) {
|
|
|
|
global $CFG;
|
|
|
|
$status = true;
|
|
|
|
$quiz_question_grades = get_records("quiz_question_grades","quiz",$quiz,"id");
|
|
//If there are question_grades
|
|
if ($quiz_question_grades) {
|
|
//Write start tag
|
|
$status =fwrite ($bf,start_tag("QUESTION_GRADES",4,true));
|
|
//Iterate over each question_grade
|
|
foreach ($quiz_question_grades as $que_gra) {
|
|
//Start question grade
|
|
$status =fwrite ($bf,start_tag("QUESTION_GRADE",5,true));
|
|
//Print question_grade contents
|
|
fwrite ($bf,full_tag("ID",6,false,$que_gra->id));
|
|
fwrite ($bf,full_tag("QUESTION",6,false,$que_gra->question));
|
|
fwrite ($bf,full_tag("GRADE",6,false,$que_gra->grade));
|
|
//End question grade
|
|
$status =fwrite ($bf,end_tag("QUESTION_GRADE",5,true));
|
|
}
|
|
//Write end tag
|
|
$status =fwrite ($bf,end_tag("QUESTION_GRADES",4,true));
|
|
}
|
|
return $status;
|
|
}
|
|
|
|
//Backup quiz_grades contents (executed from quiz_backup_mods)
|
|
function backup_quiz_grades ($bf,$preferences,$quiz) {
|
|
|
|
global $CFG;
|
|
|
|
$status = true;
|
|
|
|
$quiz_grades = get_records("quiz_grades","quiz",$quiz,"id");
|
|
//If there are grades
|
|
if ($quiz_grades) {
|
|
//Write start tag
|
|
$status =fwrite ($bf,start_tag("GRADES",4,true));
|
|
//Iterate over each grade
|
|
foreach ($quiz_grades as $gra) {
|
|
//Start grade
|
|
$status =fwrite ($bf,start_tag("GRADE",5,true));
|
|
//Print grade contents
|
|
fwrite ($bf,full_tag("ID",6,false,$gra->id));
|
|
fwrite ($bf,full_tag("USERID",6,false,$gra->userid));
|
|
fwrite ($bf,full_tag("GRADEVAL",6,false,$gra->grade));
|
|
fwrite ($bf,full_tag("TIMEMODIFIED",6,false,$gra->timemodified));
|
|
//End question grade
|
|
$status =fwrite ($bf,end_tag("GRADE",5,true));
|
|
}
|
|
//Write end tag
|
|
$status =fwrite ($bf,end_tag("GRADES",4,true));
|
|
}
|
|
return $status;
|
|
}
|
|
|
|
//Backup quiz_attempts contents (executed from quiz_backup_mods)
|
|
function backup_quiz_attempts ($bf,$preferences,$quiz) {
|
|
|
|
global $CFG;
|
|
|
|
$status = true;
|
|
|
|
$quiz_attempts = get_records("quiz_attempts","quiz",$quiz,"id");
|
|
//If there are attempts
|
|
if ($quiz_attempts) {
|
|
//Write start tag
|
|
$status =fwrite ($bf,start_tag("ATTEMPTS",4,true));
|
|
//Iterate over each attempt
|
|
foreach ($quiz_attempts as $attempt) {
|
|
//Start attempt
|
|
$status =fwrite ($bf,start_tag("ATTEMPT",5,true));
|
|
//Print attempt contents
|
|
fwrite ($bf,full_tag("ID",6,false,$attempt->id));
|
|
fwrite ($bf,full_tag("USERID",6,false,$attempt->userid));
|
|
fwrite ($bf,full_tag("ATTEMPTNUM",6,false,$attempt->attempt));
|
|
fwrite ($bf,full_tag("SUMGRADES",6,false,$attempt->sumgrades));
|
|
fwrite ($bf,full_tag("TIMESTART",6,false,$attempt->timestart));
|
|
fwrite ($bf,full_tag("TIMEFINISH",6,false,$attempt->timefinish));
|
|
fwrite ($bf,full_tag("TIMEMODIFIED",6,false,$attempt->timemodified));
|
|
//Now write to xml the responses (in this attempt)
|
|
$status = backup_quiz_responses ($bf,$preferences,$attempt->id);
|
|
//End attempt
|
|
$status =fwrite ($bf,end_tag("ATTEMPT",5,true));
|
|
}
|
|
//Write end tag
|
|
$status =fwrite ($bf,end_tag("ATTEMPTS",4,true));
|
|
}
|
|
return $status;
|
|
}
|
|
|
|
//Backup quiz_responses contents (executed from backup_quiz_attempts)
|
|
function backup_quiz_responses ($bf,$preferences,$attempt) {
|
|
|
|
global $CFG;
|
|
|
|
$status = true;
|
|
|
|
$quiz_responses = get_records("quiz_responses","attempt",$attempt,"id");
|
|
//If there are responses
|
|
if ($quiz_responses) {
|
|
//Write start tag
|
|
$status =fwrite ($bf,start_tag("RESPONSES",6,true));
|
|
//Iterate over each response
|
|
foreach ($quiz_responses as $response) {
|
|
//Start response
|
|
$status =fwrite ($bf,start_tag("RESPONSE",7,true));
|
|
//Print response contents
|
|
fwrite ($bf,full_tag("ID",8,false,$response->id));
|
|
fwrite ($bf,full_tag("QUESTION",8,false,$response->question));
|
|
fwrite ($bf,full_tag("ANSWER",8,false,$response->answer));
|
|
fwrite ($bf,full_tag("GRADE",8,false,$response->grade));
|
|
//End response
|
|
$status =fwrite ($bf,end_tag("RESPONSE",7,true));
|
|
}
|
|
//Write end tag
|
|
$status =fwrite ($bf,end_tag("RESPONSES",6,true));
|
|
}
|
|
return $status;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
////Return an array of info (name,value)
|
|
function quiz_check_backup_mods($course,$user_data=false,$backup_unique_code) {
|
|
//Deletes data from mdl_backup_ids (categories section)
|
|
delete_category_ids ($backup_unique_code);
|
|
//Create date into mdl_backup_ids (categories section)
|
|
insert_category_ids ($course,$backup_unique_code);
|
|
//First the course data
|
|
$info[0][0] = get_string("modulenameplural","quiz");
|
|
if ($ids = quiz_ids ($course)) {
|
|
$info[0][1] = count($ids);
|
|
} else {
|
|
$info[0][1] = 0;
|
|
}
|
|
//Categories
|
|
$info[1][0] = get_string("categories","quiz");
|
|
if ($ids = quiz_category_ids_by_backup ($backup_unique_code)) {
|
|
$info[1][1] = count($ids);
|
|
} else {
|
|
$info[1][1] = 0;
|
|
}
|
|
//Questions
|
|
$info[2][0] = get_string("questions","quiz");
|
|
if ($ids = quiz_question_ids_by_backup ($backup_unique_code)) {
|
|
$info[2][1] = count($ids);
|
|
} else {
|
|
$info[2][1] = 0;
|
|
}
|
|
|
|
//Now, if requested, the user_data
|
|
if ($user_data) {
|
|
//Grades
|
|
$info[3][0] = get_string("grades");
|
|
if ($ids = quiz_grade_ids_by_course ($course)) {
|
|
$info[3][1] = count($ids);
|
|
} else {
|
|
$info[3][1] = 0;
|
|
}
|
|
}
|
|
|
|
return $info;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// INTERNAL FUNCTIONS. BASED IN THE MOD STRUCTURE
|
|
|
|
//Returns an array of quiz id
|
|
function quiz_ids ($course) {
|
|
|
|
global $CFG;
|
|
|
|
return get_records_sql ("SELECT a.id, a.course
|
|
FROM {$CFG->prefix}quiz a
|
|
WHERE a.course = '$course'");
|
|
}
|
|
|
|
//Returns an array of categories id
|
|
function quiz_category_ids_by_backup ($backup_unique_code) {
|
|
|
|
global $CFG;
|
|
|
|
return get_records_sql ("SELECT a.old_id, a.backup_code
|
|
FROM {$CFG->prefix}backup_ids a
|
|
WHERE a.backup_code = '$backup_unique_code' AND
|
|
a.table_name = 'quiz_categories'");
|
|
}
|
|
|
|
function quiz_question_ids_by_backup ($backup_unique_code) {
|
|
|
|
global $CFG;
|
|
|
|
return get_records_sql ("SELECT q.id, q.category
|
|
FROM {$CFG->prefix}backup_ids a,
|
|
{$CFG->prefix}quiz_questions q
|
|
WHERE a.backup_code = '$backup_unique_code' AND
|
|
q.category = a.old_id AND
|
|
a.table_name = 'quiz_categories'");
|
|
}
|
|
|
|
function quiz_grade_ids_by_course ($course) {
|
|
|
|
global $CFG;
|
|
|
|
return get_records_sql ("SELECT g.id, g.quiz
|
|
FROM {$CFG->prefix}quiz a,
|
|
{$CFG->prefix}quiz_grades g
|
|
WHERE a.course = '$course' and
|
|
g.quiz = a.id");
|
|
}
|
|
|
|
?>
|