<?php //$Id$
- //This php script contains all the stuff to backup/restore
- //quiz mods
+ //This php script contains all the stuff to backup quizzes
//This is the "graphical" structure of the quiz mod:
//To see, put your terminal to 160cc
//
- // quiz question_categories
- // (CL,pk->id) (CL,pk->id)
- // | |
- // ------------------------------------------------------------------- |
- // | | | | |.......................................
- // | quiz_grades | quiz_question_versions | .
- // | (UL,pk->id,fk->quiz) | (CL,pk->id,fk->quiz) | .
- // | | . | ----question_datasets---- .
- // quiz_attempts quiz_question_instances . | | (CL,pk->id,fk->question, | .
- // (UL,pk->id,fk->quiz) (CL,pk->id,fk->quiz,question) . | | fk->dataset_definition) | .
- // | | . | | | .
- // | question_sessions | . | | | .
- // |---------(UL,pk->id,fk->attempt,question)-----| . | | | .
- // | . | . | | question_dataset_definitions
- // | . | . | | (CL,pk->id,fk->category)
- // | question_states | question |
- // ----------(UL,pk->id,fk->attempt,question)--------------------------(CL,pk->id,fk->category,files) |
- // | | question_dataset_items
- // | | (CL,pk->id,fk->definition)
- // --------- |
- // | |
- // question_rqp_states |
- // (UL,pk->id,fk->stateid) | question_rqp_type
- // | (SL,pk->id)
- // | |
- // -------------------------------------------------------------------------------------------------------------- |
- // | | | | | | | question_rqp
- // | | | | | | |--(CL,pk->id,fk->question)
- // | | | | question_calculated | |
- // question_truefalse | question_multichoice | (CL,pl->id,fk->question) | |
- // (CL,pk->id,fk->question) | (CL,pk->id,fk->question) | . | | question_randomsamatch
- // . | . | . | |--(CL,pk->id,fk->question)
- // . question_shortanswer . question_numerical . question_multianswer. |
- // . (CL,pk->id,fk->question) . (CL,pk->id,fk->question) . (CL,pk->id,fk->question) |
- // . . . . . . | question_match
- // . . . . . . |--(CL,pk->id,fk->question)
- // . . . . . . | .
- // . . . . . . | .
- // . . . . . . | .
- // . . . . . . | question_match_sub
- // ........................................................................................ |--(CL,pk->id,fk->question)
- // . |
- // . |
- // . | question_numerical_units
- // question_answers |--(CL,pk->id,fk->question)
- // (CL,pk->id,fk->question)----------------------------------------------------------
+ // quiz
+ // (CL,pk->id)
+ // |
+ // -------------------------------------------------------------------
+ // | | | |
+ // | quiz_grades | quiz_question_versions
+ // | (UL,pk->id,fk->quiz) | (CL,pk->id,fk->quiz)
+ // | |
+ // quiz_attempts quiz_question_instances
+ // (UL,pk->id,fk->quiz) (CL,pk->id,fk->quiz,question)
//
// Meaning: pk->primary key field of the table
// fk->foreign key to link with parent
//
//-----------------------------------------------------------
-// Comments:
- //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:
- // - question_categories
- // - question
- // - question_rqp
- // - question_truefalse
- // - question_shortanswer
- // - question_multianswer
- // - question_multichoice
- // - question_numerical
- // - question_randomsamatch
- // - question_match
- // - question_match_sub
- // - question_calculated
- // - question_answers
- // - question_numerical_units
- // - question_datasets
- // - question_dataset_definitions
- // - question_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_versions
- // - quiz_question_instances
- // - quiz_attempts
- // - quiz_grades
- // - question_states
- // - question_sessions
- // This step is the standard mod backup. (course dependent).
+ // When we backup a quiz we also need to backup the questions and possibly
+ // the data about student interaction with the questions. The functions to do
+ // that are included with the following library
+ include_once("$CFG->dirroot/question/backuplib.php");
//STEP 1. Backup categories/questions and associated structures
// (course independent)
}
}
- //Delete category ids from backup_ids table
- function delete_category_ids ($backup_unique_code) {
- global $CFG;
- $status = true;
- $status = execute_sql("DELETE FROM {$CFG->prefix}backup_ids
- WHERE backup_code = '$backup_unique_code'",false);
- return $status;
- }
-
- function quiz_backup_question_categories($bf,$preferences) {
-
- global $CFG;
-
- $status = true;
-
- //First, we get the used categories from backup_ids
- $categories = question_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 question_categories
- $category = get_record ("question_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;
-
- // We'll fetch the questions sorted by parent so that questions with no parents
- // (these are the ones which could be parents themselves) are backed up first. This
- // is important for the recoding of the parent field during the restore process
- $questions = get_records("question","category",$category,"parent ASC, id");
- //If there are 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("PARENT",6,false,$question->parent));
- 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("PENALTY",6,false,$question->penalty));
- fwrite ($bf,full_tag("QTYPE",6,false,$question->qtype));
- fwrite ($bf,full_tag("LENGTH",6,false,$question->length));
- fwrite ($bf,full_tag("STAMP",6,false,$question->stamp));
- fwrite ($bf,full_tag("VERSION",6,false,$question->version));
- fwrite ($bf,full_tag("HIDDEN",6,false,$question->hidden));
- //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);
- } else if ($question->qtype == "11") {
- $status = quiz_backup_rqp($bf,$preferences,$question->id);
- } else if ($question->qtype == "12") {
- $status = quiz_backup_essay($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("question_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 question_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("question_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 question_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("question_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));
- fwrite ($bf,full_tag("SHUFFLEANSWERS",$level+1,false,$randomsamatch->shuffleanswers));
- $status = fwrite ($bf,end_tag("MULTICHOICE",$level,true));
- }
- //Now print question_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("question_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));
- fwrite ($bf,full_tag("SHUFFLEANSWERS",7,false,$randomsamatch->shuffleanswers));
- $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("question_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("CODE",8,false,$match->code));
- 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) {
-
- global $CFG;
-
- $status = true;
-
- $numericals = get_records("question_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("TOLERANCE",$level+1,false,$numerical->tolerance));
- //Now backup numerical_units
- $status = quiz_backup_numerical_units($bf,$preferences,$question,7);
- $status = fwrite ($bf,end_tag("NUMERICAL",$level,true));
- }
- //Now print question_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("question_multianswer","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("QUESTION",8,false,$multianswer->question));
- fwrite ($bf,full_tag("SEQUENCE",8,false,$multianswer->sequence));
- $status = fwrite ($bf,end_tag("MULTIANSWER",7,true));
- }
- //Print multianswers footer
- $status = fwrite ($bf,end_tag("MULTIANSWERS",6,true));
- //Now print question_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("question_calculated","question",$question,"id");
- //If there are calculated-s
- if ($calculateds) {
- //Iterate over each calculateds
- foreach ($calculateds as $calculated) {
- $status = $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 = $status &&fwrite ($bf,end_tag("CALCULATED",$level,true));
- }
- //Now print question_answers
- if ($include_answers) {
- $status = quiz_backup_answers($bf,$preferences,$question);
- }
- }
- return $status;
- }
-
- //This function backups the data in an rqp question (qtype=11) and its
- //asociated data
- function quiz_backup_rqp($bf,$preferences,$question) {
-
- global $CFG;
-
- $status = true;
-
- $rqp = get_records("question_rqp","question",$question,"id");
- //If there are rqps
- if ($rqps) {
- //Iterate over each rqp
- foreach ($rqps as $rqp) {
- $status = fwrite ($bf,start_tag("RQP",6,true));
- //Print rqp contents
- fwrite ($bf,full_tag("TYPE",7,false,$rqp->type));
- fwrite ($bf,full_tag("SOURCE",7,false,$rqp->source));
- fwrite ($bf,full_tag("FORMAT",7,false,$rqp->format));
- fwrite ($bf,full_tag("FLAGS",7,false,$rqp->flags));
- fwrite ($bf,full_tag("MAXSCORE",7,false,$rqp->maxscore));
- $status = fwrite ($bf,end_tag("RQP",6,true));
- }
- }
- return $status;
- }
-
- //This function backups the data in an essay question (qtype=12) and its
- //asociated data
- function quiz_backup_essay($bf,$preferences,$question,$level=6) {
-
- global $CFG;
-
- $status = true;
-
- $essays = get_records('question_essay', 'question', $question, "id");
- //If there are essays
- if ($essays) {
- //Iterate over each essay
- foreach ($essays as $essay) {
- $status = fwrite ($bf,start_tag("ESSAY",$level,true));
- //Print essay contents
- fwrite ($bf,full_tag("ANSWER",$level+1,false,$essay->answer));
- $status = fwrite ($bf,end_tag("ESSAY",$level,true));
- }
- //Now print question_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("question_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 question_numerical_units from different question types
- function quiz_backup_numerical_units($bf,$preferences,$question,$level=7) {
-
- global $CFG;
-
- $status = true;
-
- $numerical_units = get_records("question_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("question_datasets","question",$question,"id");
- //If there are question_datasets
- if ($question_datasets) {
- $status = $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("question_dataset_definitions","id",$question_dataset->datasetdefinition)) {;
- $status = $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 = $status &&fwrite ($bf,end_tag("DATASET_DEFINITION",$level+1,true));
- }
- }
- $status = $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("question_dataset_items","definition",$datasetdefinition,"id");
- //If there are dataset_items
- if ($dataset_items) {
- $status = $status &&fwrite ($bf,start_tag("DATASET_ITEMS",$level,true));
- //Iterate over each dataset_item
- foreach ($dataset_items as $dataset_item) {
- $status = $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 = $status &&fwrite ($bf,end_tag("DATASET_ITEM",$level+1,true));
- }
- $status = $status &&fwrite ($bf,end_tag("DATASET_ITEMS",$level,true));
- }
-
- return $status;
-
- }
//STEP 2. Backup quizzes and associated structures
// (course dependent)
return $status;
}
- //Backup question_states contents (executed from backup_quiz_attempts)
- function backup_question_states ($bf,$preferences,$attempt) {
-
- global $CFG;
-
- $status = true;
-
- $question_states = get_records("question_states","attempt",$attempt,"id");
- //If there are states
- if ($question_states) {
- //Write start tag
- $status = fwrite ($bf,start_tag("STATES",6,true));
- //Iterate over each state
- foreach ($question_states as $state) {
- //Start state
- $status = fwrite ($bf,start_tag("STATE",7,true));
- //Print state contents
- fwrite ($bf,full_tag("ID",8,false,$state->id));
- fwrite ($bf,full_tag("QUESTION",8,false,$state->question));
- fwrite ($bf,full_tag("ORIGINALQUESTION",8,false,$state->originalquestion));
- fwrite ($bf,full_tag("SEQ_NUMBER",8,false,$state->seq_number));
- fwrite ($bf,full_tag("ANSWER",8,false,$state->answer));
- fwrite ($bf,full_tag("TIMESTAMP",8,false,$state->timestamp));
- fwrite ($bf,full_tag("EVENT",8,false,$state->event));
- fwrite ($bf,full_tag("GRADE",8,false,$state->grade));
- fwrite ($bf,full_tag("RAW_GRADE",8,false,$state->raw_grade));
- fwrite ($bf,full_tag("PENALTY",8,false,$state->penalty));
- // now back up question type specific state information
- $status = backup_question_rqp_state ($bf,$preferences,$state->id);
- $status = backup_question_essay_state ($bf,$preferences,$state->id);
- //End state
- $status = fwrite ($bf,end_tag("STATE",7,true));
- }
- //Write end tag
- $status = fwrite ($bf,end_tag("STATES",6,true));
- }
- }
-
- //Backup question_sessions contents (executed from backup_quiz_attempts)
- function backup_question_sessions ($bf,$preferences,$attempt) {
- global $CFG;
-
- $status = true;
-
- $question_sessions = get_records("question_sessions","attemptid",$attempt,"id");
- //If there are sessions
- if ($question_sessions) {
- //Write start tag (the funny name 'newest states' has historical reasons)
- $status = fwrite ($bf,start_tag("NEWEST_STATES",6,true));
- //Iterate over each newest_state
- foreach ($question_sessions as $newest_state) {
- //Start newest_state
- $status = fwrite ($bf,start_tag("NEWEST_STATE",7,true));
- //Print newest_state contents
- fwrite ($bf,full_tag("ID",8,false,$newest_state->id));
- fwrite ($bf,full_tag("QUESTIONID",8,false,$newest_state->questionid));
- fwrite ($bf,full_tag("NEWEST",8,false,$newest_state->newest));
- fwrite ($bf,full_tag("NEWGRADED",8,false,$newest_state->newgraded));
- fwrite ($bf,full_tag("SUMPENALTY",8,false,$newest_state->sumpenalty));
- //End newest_state
- $status = fwrite ($bf,end_tag("NEWEST_STATE",7,true));
- }
- //Write end tag
- $status = fwrite ($bf,end_tag("NEWEST_STATES",6,true));
- }
- return $status;
- }
-
function quiz_check_backup_mods_instances($instance,$backup_unique_code) {
// the keys in this array need to be unique as they get merged...
$info[$instance->id.'0'][0] = '<b>'.$instance->name.'</b>';
}
//Questions
$info[$instance->id.'2'][0] = get_string("questionsinclhidden","quiz");
- if ($ids = quiz_question_ids_by_backup ($backup_unique_code)) {
+ if ($ids = question_ids_by_backup ($backup_unique_code)) {
$info[$instance->id.'2'][1] = count($ids);
} else {
$info[$instance->id.'2'][1] = 0;
}
return $info;
}
-
- //Backup question_rqp_state contents (executed from backup_question_states)
- function backup_question_rqp_state ($bf,$preferences,$state) {
-
- global $CFG;
-
- $status = true;
-
- $rqp_state = get_record("question_rqp_states","stateid",$state);
- //If there is a state
- if ($rqp_state) {
- //Write start tag
- $status = fwrite ($bf,start_tag("RQP_STATE",8,true));
- //Print state contents
- fwrite ($bf,full_tag("RESPONSES",9,false,$rqp_state->responses));
- fwrite ($bf,full_tag("PERSISTENT_DATA",9,false,$rqp_state->persistent_data));
- fwrite ($bf,full_tag("TEMPLATE_VARS",9,false,$rqp_state->template_vars));
- //Write end tag
- $status = fwrite ($bf,end_tag("RQP_STATE",8,true));
- }
- return $status;
- }
-
- //Backup question_essay_state contents (executed from backup_question_states)
- function backup_question_essay_state ($bf,$preferences,$state) {
-
- global $CFG;
-
- $status = true;
-
- $essay_state = get_record("question_essay_states", "stateid", $state);
- //If there is a state
- if ($essay_state) {
- //Write start tag
- $status = fwrite ($bf,start_tag("ESSAY_STATE",8,true));
- //Print state contents
- fwrite ($bf,full_tag("GRADED",9,false,$essay_state->graded));
- fwrite ($bf,full_tag("FRACTION",9,false,$essay_state->fraction));
- fwrite ($bf,full_tag("RESPONSE",9,false,$essay_state->response));
- //Write end tag
- $status = fwrite ($bf,end_tag("ESSAY_STATE",8,true));
- }
- return $status;
- }
////Return an array of info (name,value)
/// $instances is an array with key = instanceid, value = object (name,id,userdata)
}
//Questions
$info[2][0] = get_string("questions","quiz");
- if ($ids = quiz_question_ids_by_backup ($backup_unique_code)) {
+ if ($ids = question_ids_by_backup ($backup_unique_code)) {
$info[2][1] = count($ids);
} else {
$info[2][1] = 0;
WHERE a.course = '$course'");
}
- //Returns an array of categories id
- function question_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 = 'question_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}question q
- WHERE a.backup_code = '$backup_unique_code' AND
- q.category = a.old_id AND
- a.table_name = 'question_categories'");
- }
-
function quiz_grade_ids_by_course ($course) {
global $CFG;
<?php //$Id$
- //This php script contains all the stuff to backup/restore
- //quiz mods
+ //This php script contains all the stuff to backup questions
-//This is the "graphical" structure of the quiz mod:
+//This is the "graphical" structure of the question database:
//To see, put your terminal to 160cc
+ // The following holds student-independent information about the questions
//
- // quiz question_categories
- // (CL,pk->id) (CL,pk->id)
- // | |
- // ------------------------------------------------------------------- |
- // | | | | |.......................................
- // | quiz_grades | quiz_question_versions | .
- // | (UL,pk->id,fk->quiz) | (CL,pk->id,fk->quiz) | .
- // | | . | ----question_datasets---- .
- // quiz_attempts quiz_question_instances . | | (CL,pk->id,fk->question, | .
- // (UL,pk->id,fk->quiz) (CL,pk->id,fk->quiz,question) . | | fk->dataset_definition) | .
- // | | . | | | .
- // | question_sessions | . | | | .
- // |---------(UL,pk->id,fk->attempt,question)-----| . | | | .
- // | . | . | | question_dataset_definitions
- // | . | . | | (CL,pk->id,fk->category)
- // | question_states | question |
- // ----------(UL,pk->id,fk->attempt,question)--------------------------(CL,pk->id,fk->category,files) |
- // | | question_dataset_items
- // | | (CL,pk->id,fk->definition)
- // --------- |
- // | |
- // question_rqp_states |
- // (UL,pk->id,fk->stateid) | question_rqp_type
- // | (SL,pk->id)
- // | |
+ // question_categories
+ // (CL,pk->id)
+ // |
+ // |
+ // |.......................................
+ // | .
+ // | .
+ // | -------question_datasets------ .
+ // | | (CL,pk->id,fk->question, | .
+ // | | fk->dataset_definition) | .
+ // | | | .
+ // | | | .
+ // | | | .
+ // | | question_dataset_definitions
+ // | | (CL,pk->id,fk->category)
+ // question |
+ // (CL,pk->id,fk->category,files) |
+ // | question_dataset_items
+ // | (CL,pk->id,fk->definition)
+ // | question_rqp_type
+ // | (SL,pk->id)
+ // | |
// -------------------------------------------------------------------------------------------------------------- |
// | | | | | | | question_rqp
// | | | | | | |--(CL,pk->id,fk->question)
- // | | | | question_calculated | |
- // question_truefalse | question_multichoice | (CL,pl->id,fk->question) | |
- // (CL,pk->id,fk->question) | (CL,pk->id,fk->question) | . | | question_randomsamatch
+ // | | | | question_calculated | |
+ // question_truefalse | question_multichoice | (CL,pl->id,fk->question) | |
+ // (CL,pk->id,fk->question) | (CL,pk->id,fk->question) | . | | question_randomsamatch
// . | . | . | |--(CL,pk->id,fk->question)
- // . question_shortanswer . question_numerical . question_multianswer. |
+ // . question_shortanswer . question_numerical . question_multianswer. |
// . (CL,pk->id,fk->question) . (CL,pk->id,fk->question) . (CL,pk->id,fk->question) |
- // . . . . . . | question_match
+ // . . . . . . | question_match
// . . . . . . |--(CL,pk->id,fk->question)
// . . . . . . | .
// . . . . . . | .
// . . . . . . | .
- // . . . . . . | question_match_sub
+ // . . . . . . | question_match_sub
// ........................................................................................ |--(CL,pk->id,fk->question)
// . |
// . |
- // . | question_numerical_units
- // question_answers |--(CL,pk->id,fk->question)
+ // . | question_numerical_units
+ // question_answers |--(CL,pk->id,fk->question)
// (CL,pk->id,fk->question)----------------------------------------------------------
//
+ //
+ // The following holds the information about student interaction with the questions
+ //
+ // question_sessions
+ // (UL,pk->id,fk->attempt,question)
+ // .
+ // .
+ // question_states
+ // (UL,pk->id,fk->attempt,question)
+ // |
+ // question_rqp_states
+ // (UL,pk->id,fk->stateid)
+ //
// Meaning: pk->primary key field of the table
// fk->foreign key to link with parent
// nt->nested field (recursive data)
//
//-----------------------------------------------------------
-// Comments:
- //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:
- // - question_categories
- // - question
- // - question_rqp
- // - question_truefalse
- // - question_shortanswer
- // - question_multianswer
- // - question_multichoice
- // - question_numerical
- // - question_randomsamatch
- // - question_match
- // - question_match_sub
- // - question_calculated
- // - question_answers
- // - question_numerical_units
- // - question_datasets
- // - question_dataset_definitions
- // - question_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_versions
- // - quiz_question_instances
- // - quiz_attempts
- // - quiz_grades
- // - question_states
- // - question_sessions
- // This step is the standard mod backup. (course dependent).
-
-//STEP 1. Backup categories/questions and associated structures
- // (course independent)
-
- //Insert necessary category ids to backup_ids table
- function insert_category_ids ($course,$backup_unique_code,$instances=null) {
- global $CFG;
- include_once("$CFG->dirroot/mod/quiz/lib.php");
-
- //Create missing categories and reasign orphaned questions
- fix_orphaned_questions($course);
-
- // defaults
- $where = "q.course = '$course' AND g.quiz = q.id AND ";
- $from = ", {$CFG->prefix}quiz q";
- // but if we have an array of quiz ids, use those instead.
- if (!empty($instances) && is_array($instances) && count($instances)) {
- $where = ' g.quiz IN ('.implode(',',array_keys($instances)).') AND ';
- $from = '';
- }
-
- //Detect used categories (by category in questions)
- $status = execute_sql("INSERT INTO {$CFG->prefix}backup_ids
- (backup_code, table_name, old_id)
- SELECT DISTINCT $backup_unique_code,'question_categories',t.category
- FROM {$CFG->prefix}question t,
- {$CFG->prefix}quiz_question_instances g
- $from
- WHERE $where g.question = t.id",false);
-
- //Now, foreach detected category, we look for their parents upto 0 (top category)
- $categories = get_records_sql("SELECT old_id, old_id
- FROM {$CFG->prefix}backup_ids
- WHERE backup_code = $backup_unique_code AND
- table_name = 'question_categories'");
-
- if ($categories) {
- foreach ($categories as $category) {
- if ($dbcat = get_record('question_categories','id',$category->old_id)) {
- //echo $dbcat->name; //Debug
- //Go up to 0
- while ($dbcat->parent != 0) {
- //echo '->'; //Debug
- $current = $dbcat->id;
- if ($dbcat = get_record('question_categories','id',$dbcat->parent)) {
- //Found parent, add it to backup_ids (by using backup_putid
- //we ensure no duplicates!)
- $status = backup_putid($backup_unique_code,'question_categories',$dbcat->id,0);
- //echo $dbcat->name; //Debug
- } else {
- //Parent not found, fix it (set its parent to 0)
- set_field ('question_categories','parent',0,'id',$current);
- //echo 'assigned to top!'; //Debug
- }
- }
- //echo '<br />'; //Debug
- }
- }
- }
-
- // Now we look for random questions that can use questions from subcategories
- // because we will have to add these subcategories
- $sql = "SELECT t.id, t.category
- FROM {$CFG->prefix}quiz_question_instances AS g,
- {$CFG->prefix}question AS t
- $from
- WHERE $where t.id = g.question
- AND t.qtype = '".RANDOM."'
- AND t.questiontext = '1'";
- if ($randoms = get_records_sql($sql)) {
- foreach ($randoms as $random) {
- $status = quiz_backup_add_category_tree($backup_unique_code, $random->category);
- }
- }
-
- return $status;
- }
-
- /**
- * Helper function adding the id of a category and all its descendents to the backup_ids
- */
- function quiz_backup_add_category_tree($backup_unique_code, $categoryid) {
- $status = backup_putid($backup_unique_code,'question_categories',$categoryid,0);
- if ($subcategories = get_records('question_categories', 'parent', $categoryid, 'sortorder ASC', 'id, id')) {
- foreach ($subcategories as $subcategory) {
- $status = quiz_backup_add_category_tree($backup_unique_code, $subcategory->id);
- }
- }
- return $status;
- }
-
-
- //This function is used to detect orphaned questions (pointing to a
- //non existing category) and to recreate such category. This function
- //is used by the backup process, to ensure consistency and should be
- //executed in the upgrade process and, perhaps in the health center.
- function fix_orphaned_questions ($course) {
-
- global $CFG;
-
- $categories = get_records_sql("SELECT DISTINCT t.category, t.category
- FROM {$CFG->prefix}question t,
- {$CFG->prefix}quiz_question_instances g,
- {$CFG->prefix}quiz q
- WHERE q.course = '$course' AND
- g.quiz = q.id AND
- g.question = t.id",false);
- if ($categories) {
- foreach ($categories as $key => $category) {
- $exist = get_record('question_categories','id', $key);
- //If the category doesn't exist
- if (!$exist) {
- //Build a new category
- $db_cat->course = $course;
- $db_cat->name = get_string('recreatedcategory','',$key);
- $db_cat->info = get_string('recreatedcategory','',$key);
- $db_cat->publish = 1;
- $db_cat->stamp = make_unique_id_code();
- //Insert the new category
- $catid = insert_record('question_categories',$db_cat);
- unset ($db_cat);
- if ($catid) {
- //Reasign orphaned questions to their new category
- set_field ('question','category',$catid,'category',$key);
- }
- }
- }
- }
- }
-
- //Delete category ids from backup_ids table
- function delete_category_ids ($backup_unique_code) {
- global $CFG;
- $status = true;
- $status = execute_sql("DELETE FROM {$CFG->prefix}backup_ids
- WHERE backup_code = '$backup_unique_code'",false);
- return $status;
- }
+ include_once($CFG->libdir.'/questionlib.php');
- function quiz_backup_question_categories($bf,$preferences) {
+ function backup_question_categories($bf,$preferences) {
global $CFG;
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);
+ $status = backup_question($bf,$preferences,$category->id);
//End category
$status = fwrite ($bf,end_tag("QUESTION_CATEGORY",3,true));
}
//This function backups all the questions in selected category and their
//asociated data
- function quiz_backup_question($bf,$preferences,$category) {
+ function backup_question($bf,$preferences,$category) {
- global $CFG;
+ global $CFG, $QTYPES;
$status = true;
fwrite ($bf,full_tag("HIDDEN",6,false,$question->hidden));
//Now, depending of the qtype, call one function or other
if ($question->qtype == "1") {
- $status = quiz_backup_shortanswer($bf,$preferences,$question->id);
+ $status = question_backup_shortanswer($bf,$preferences,$question->id);
} else if ($question->qtype == "2") {
- $status = quiz_backup_truefalse($bf,$preferences,$question->id);
+ $status = question_backup_truefalse($bf,$preferences,$question->id);
} else if ($question->qtype == "3") {
- $status = quiz_backup_multichoice($bf,$preferences,$question->id);
+ $status = question_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);
+ $status = question_backup_match($bf,$preferences,$question->id);
} else if ($question->qtype == "6") {
- $status = quiz_backup_randomsamatch($bf,$preferences,$question->id);
+ $status = question_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);
+ $status = question_backup_numerical($bf,$preferences,$question->id);
} else if ($question->qtype == "9") {
- $status = quiz_backup_multianswer($bf,$preferences,$question->id);
+ $status = question_backup_multianswer($bf,$preferences,$question->id);
} else if ($question->qtype == "10") {
- $status = quiz_backup_calculated($bf,$preferences,$question->id);
+ $status = question_backup_calculated($bf,$preferences,$question->id);
} else if ($question->qtype == "11") {
- $status = quiz_backup_rqp($bf,$preferences,$question->id);
+ $status = question_backup_rqp($bf,$preferences,$question->id);
} else if ($question->qtype == "12") {
- $status = quiz_backup_essay($bf,$preferences,$question->id);
+ $status = question_backup_essay($bf,$preferences,$question->id);
}
//End question
$status = fwrite ($bf,end_tag("QUESTION",5,true));
//This function backups the data in a truefalse question (qtype=2) and its
//asociated data
- function quiz_backup_truefalse($bf,$preferences,$question) {
+ function question_backup_truefalse($bf,$preferences,$question) {
global $CFG;
$status = fwrite ($bf,end_tag("TRUEFALSE",6,true));
}
//Now print question_answers
- $status = quiz_backup_answers($bf,$preferences,$question);
+ $status = question_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) {
+ function question_backup_shortanswer($bf,$preferences,$question,$level=6,$include_answers=true) {
global $CFG;
}
//Now print question_answers
if ($include_answers) {
- $status = quiz_backup_answers($bf,$preferences,$question);
+ $status = question_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) {
+ function question_backup_multichoice($bf,$preferences,$question,$level=6,$include_answers=true) {
global $CFG;
}
//Now print question_answers
if ($include_answers) {
- $status = quiz_backup_answers($bf,$preferences,$question);
+ $status = question_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) {
+ function question_backup_randomsamatch($bf,$preferences,$question) {
global $CFG;
//This function backups the data in a match question (qtype=5) and its
//asociated data
- function quiz_backup_match($bf,$preferences,$question) {
+ function question_backup_match($bf,$preferences,$question) {
global $CFG;
//This function backups the data in a numerical question (qtype=8) and its
//asociated data
- function quiz_backup_numerical($bf,$preferences,$question,$level=6) {
+ function question_backup_numerical($bf,$preferences,$question,$level=6) {
global $CFG;
fwrite ($bf,full_tag("ANSWER",$level+1,false,$numerical->answer));
fwrite ($bf,full_tag("TOLERANCE",$level+1,false,$numerical->tolerance));
//Now backup numerical_units
- $status = quiz_backup_numerical_units($bf,$preferences,$question,7);
+ $status = question_backup_numerical_units($bf,$preferences,$question,7);
$status = fwrite ($bf,end_tag("NUMERICAL",$level,true));
}
//Now print question_answers
- $status = quiz_backup_answers($bf,$preferences,$question);
+ $status = question_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) {
+ function question_backup_multianswer($bf,$preferences,$question) {
global $CFG;
//Print multianswers footer
$status = fwrite ($bf,end_tag("MULTIANSWERS",6,true));
//Now print question_answers
- $status = quiz_backup_answers($bf,$preferences,$question);
+ $status = question_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) {
+ function question_backup_calculated($bf,$preferences,$question,$level=6,$include_answers=true) {
global $CFG;
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);
+ $status = question_backup_numerical_units($bf,$preferences,$question,7);
//Now backup required dataset definitions and items...
- $status = quiz_backup_datasets($bf,$preferences,$question,7);
+ $status = question_backup_datasets($bf,$preferences,$question,7);
//End calculated data
$status = $status &&fwrite ($bf,end_tag("CALCULATED",$level,true));
}
//Now print question_answers
if ($include_answers) {
- $status = quiz_backup_answers($bf,$preferences,$question);
+ $status = question_backup_answers($bf,$preferences,$question);
}
}
return $status;
//This function backups the data in an rqp question (qtype=11) and its
//asociated data
- function quiz_backup_rqp($bf,$preferences,$question) {
+ function question_backup_rqp($bf,$preferences,$question) {
global $CFG;
//This function backups the data in an essay question (qtype=12) and its
//asociated data
- function quiz_backup_essay($bf,$preferences,$question,$level=6) {
+ function question_backup_essay($bf,$preferences,$question,$level=6) {
global $CFG;
$status = fwrite ($bf,end_tag("ESSAY",$level,true));
}
//Now print question_answers
- $status = quiz_backup_answers($bf,$preferences,$question);
+ $status = question_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) {
+ function question_backup_answers($bf,$preferences,$question) {
global $CFG;
}
//This function backups question_numerical_units from different question types
- function quiz_backup_numerical_units($bf,$preferences,$question,$level=7) {
+ function question_backup_numerical_units($bf,$preferences,$question,$level=7) {
global $CFG;
}
//This function backups dataset_definitions (via question_datasets) from different question types
- function quiz_backup_datasets($bf,$preferences,$question,$level=7) {
+ function question_backup_datasets($bf,$preferences,$question,$level=7) {
global $CFG;
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);
+ $status = question_backup_dataset_items($bf,$preferences,$def->id,$level+2);
//End dataset definition
$status = $status &&fwrite ($bf,end_tag("DATASET_DEFINITION",$level+1,true));
}
}
//This function backups datases_items from dataset_definitions
- function quiz_backup_dataset_items($bf,$preferences,$datasetdefinition,$level=9) {
+ function question_backup_dataset_items($bf,$preferences,$datasetdefinition,$level=9) {
global $CFG;
}
-//STEP 2. Backup quizzes and associated structures
- // (course dependent)
-
- function quiz_backup_one_mod($bf,$preferences,$quiz) {
- $status = true;
-
- if (is_numeric($quiz)) {
- $quiz = get_record('quiz','id',$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("OPTIONFLAGS",4,false,$quiz->optionflags));
- fwrite ($bf,full_tag("PENALTYSCHEME",4,false,$quiz->penaltyscheme));
- fwrite ($bf,full_tag("ATTEMPTS_NUMBER",4,false,$quiz->attempts));
- fwrite ($bf,full_tag("ATTEMPTONLAST",4,false,$quiz->attemptonlast));
- 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));
- fwrite ($bf,full_tag("DELAY1",4,false,$quiz->delay1));
- fwrite ($bf,full_tag("DELAY2",4,false,$quiz->delay2));
- //Now we print to xml question_instances (Course Level)
- $status = backup_quiz_question_instances($bf,$preferences,$quiz->id);
- //Now we print to xml question_versions (Course Level)
- $status = backup_quiz_question_versions($bf,$preferences,$quiz->id);
- //if we've selected to backup users info, then execute:
- // - backup_quiz_grades
- // - backup_quiz_attempts
- if (backup_userdata_selected($preferences,'quiz',$quiz->id) && $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;
- }
-
-
- 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) {
- if (backup_mod_selected($preferences,'quiz',$quiz->id)) {
- $status = quiz_backup_one_mod($bf,$preferences,$quiz);
- }
- }
- }
- return $status;
- }
-
- //Backup quiz_question_instances contents (executed from quiz_backup_mods)
- function backup_quiz_question_instances ($bf,$preferences,$quiz) {
-
- global $CFG;
-
- $status = true;
-
- $quiz_question_instances = get_records("quiz_question_instances","quiz",$quiz,"id");
- //If there are question_instances
- if ($quiz_question_instances) {
- //Write start tag
- $status = fwrite ($bf,start_tag("QUESTION_INSTANCES",4,true));
- //Iterate over each question_instance
- foreach ($quiz_question_instances as $que_ins) {
- //Start question instance
- $status = fwrite ($bf,start_tag("QUESTION_INSTANCE",5,true));
- //Print question_instance contents
- fwrite ($bf,full_tag("ID",6,false,$que_ins->id));
- fwrite ($bf,full_tag("QUESTION",6,false,$que_ins->question));
- fwrite ($bf,full_tag("GRADE",6,false,$que_ins->grade));
- //End question instance
- $status = fwrite ($bf,end_tag("QUESTION_INSTANCE",5,true));
- }
- //Write end tag
- $status = fwrite ($bf,end_tag("QUESTION_INSTANCES",4,true));
- }
- return $status;
- }
-
- //Backup quiz_question_versions contents (executed from quiz_backup_mods)
- function backup_quiz_question_versions ($bf,$preferences,$quiz) {
-
- global $CFG;
-
- $status = true;
-
- $quiz_question_versions = get_records("quiz_question_versions","quiz",$quiz,"id");
- //If there are question_versions
- if ($quiz_question_versions) {
- //Write start tag
- $status = fwrite ($bf,start_tag("QUESTION_VERSIONS",4,true));
- //Iterate over each question_version
- foreach ($quiz_question_versions as $que_ver) {
- //Start question version
- $status = fwrite ($bf,start_tag("QUESTION_VERSION",5,true));
- //Print question_version contents
- fwrite ($bf,full_tag("ID",6,false,$que_ver->id));
- fwrite ($bf,full_tag("OLDQUESTION",6,false,$que_ver->oldquestion));
- fwrite ($bf,full_tag("NEWQUESTION",6,false,$que_ver->newquestion));
- fwrite ($bf,full_tag("ORIGINALQUESTION",6,false,$que_ver->originalquestion));
- fwrite ($bf,full_tag("USERID",6,false,$que_ver->userid));
- fwrite ($bf,full_tag("TIMESTAMP",6,false,$que_ver->timestamp));
- //End question version
- $status = fwrite ($bf,end_tag("QUESTION_VERSION",5,true));
- }
- //Write end tag
- $status = fwrite ($bf,end_tag("QUESTION_VERSIONS",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("UNIQUEID",6,false,$attempt->uniqueid));
- 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));
- fwrite ($bf,full_tag("LAYOUT",6,false,$attempt->layout));
- fwrite ($bf,full_tag("PREVIEW",6,false,$attempt->preview));
- //Now write to xml the states (in this attempt)
- $status = backup_question_states ($bf,$preferences,$attempt->uniqueid);
- //Now write to xml the sessions (in this attempt)
- $status = backup_question_sessions ($bf,$preferences,$attempt->uniqueid);
- //End attempt
- $status = fwrite ($bf,end_tag("ATTEMPT",5,true));
- }
- //Write end tag
- $status = fwrite ($bf,end_tag("ATTEMPTS",4,true));
- }
- return $status;
- }
//Backup question_states contents (executed from backup_quiz_attempts)
function backup_question_states ($bf,$preferences,$attempt) {
return $status;
}
- function quiz_check_backup_mods_instances($instance,$backup_unique_code) {
- // the keys in this array need to be unique as they get merged...
- $info[$instance->id.'0'][0] = '<b>'.$instance->name.'</b>';
- $info[$instance->id.'0'][1] = '';
-
- //Categories
- $info[$instance->id.'1'][0] = get_string("categories","quiz");
- if ($ids = question_category_ids_by_backup ($backup_unique_code)) {
- $info[$instance->id.'1'][1] = count($ids);
- } else {
- $info[$instance->id.'1'][1] = 0;
- }
- //Questions
- $info[$instance->id.'2'][0] = get_string("questionsinclhidden","quiz");
- if ($ids = quiz_question_ids_by_backup ($backup_unique_code)) {
- $info[$instance->id.'2'][1] = count($ids);
- } else {
- $info[$instance->id.'2'][1] = 0;
- }
-
- //Now, if requested, the user_data
- if (!empty($instance->userdata)) {
- //Grades
- $info[$instance->id.'3'][0] = get_string("grades");
- if ($ids = quiz_grade_ids_by_instance ($instance->id)) {
- $info[$instance->id.'3'][1] = count($ids);
- } else {
- $info[$instance->id.'3'][1] = 0;
- }
- }
- return $info;
- }
-
//Backup question_rqp_state contents (executed from backup_question_states)
function backup_question_rqp_state ($bf,$preferences,$state) {
}
return $status;
}
-
- ////Return an array of info (name,value)
-/// $instances is an array with key = instanceid, value = object (name,id,userdata)
- function quiz_check_backup_mods($course,$user_data= false,$backup_unique_code,$instances=null) {
-
- //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,$instances);
- if (!empty($instances) && is_array($instances) && count($instances)) {
- $info = array();
- foreach ($instances as $id => $instance) {
- $info += quiz_check_backup_mods_instances($instance,$backup_unique_code);
- }
- return $info;
- }
- //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 = question_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;
- }
-
- //Return a content encoded to support interactivities linking. Every module
- //should have its own. They are called automatically from the backup procedure.
- function quiz_encode_content_links ($content,$preferences) {
-
- global $CFG;
-
- $base = preg_quote($CFG->wwwroot,"/");
-
- //Link to the list of quizs
- $buscar="/(".$base."\/mod\/quiz\/index.php\?id\=)([0-9]+)/";
- $result= preg_replace($buscar,'$@QUIZINDEX*$2@$',$content);
-
- //Link to quiz view by moduleid
- $buscar="/(".$base."\/mod\/quiz\/view.php\?id\=)([0-9]+)/";
- $result= preg_replace($buscar,'$@QUIZVIEWBYID*$2@$',$result);
-
- return $result;
- }
-
-// 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 question_category_ids_by_backup ($backup_unique_code) {
a.table_name = 'question_categories'");
}
- function quiz_question_ids_by_backup ($backup_unique_code) {
+ function question_ids_by_backup ($backup_unique_code) {
global $CFG;
a.table_name = 'question_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");
- }
-
- function quiz_grade_ids_by_instance($instanceid) {
-
+ //Delete category ids from backup_ids table
+ function delete_category_ids ($backup_unique_code) {
global $CFG;
-
- return get_records_sql ("SELECT g.id, g.quiz
- FROM {$CFG->prefix}quiz_grades g
- WHERE g.quiz = $instanceid");
+ $status = true;
+ $status = execute_sql("DELETE FROM {$CFG->prefix}backup_ids
+ WHERE backup_code = '$backup_unique_code'",false);
+ return $status;
}
?>