Exemple #1
0
function restore_questions($old_category_id, $best_question_cat, $info, $restore)
{
    global $CFG, $QTYPES;
    $status = true;
    $restored_questions = array();
    //Get the questions array
    if (!empty($info['QUESTION_CATEGORY']['#']['QUESTIONS'])) {
        $questions = $info['QUESTION_CATEGORY']['#']['QUESTIONS']['0']['#']['QUESTION'];
    } else {
        $questions = array();
    }
    //Iterate over questions
    for ($i = 0; $i < sizeof($questions); $i++) {
        $que_info = $questions[$i];
        //traverse_xmlize($que_info);                                                                 //Debug
        //print_object ($GLOBALS['traverse_array']);                                                  //Debug
        //$GLOBALS['traverse_array']="";                                                              //Debug
        //We'll need this later!!
        $oldid = backup_todb($que_info['#']['ID']['0']['#']);
        //Now, build the question record structure
        $question = new object();
        $question->parent = backup_todb($que_info['#']['PARENT']['0']['#']);
        $question->name = backup_todb($que_info['#']['NAME']['0']['#']);
        $question->questiontext = backup_todb($que_info['#']['QUESTIONTEXT']['0']['#']);
        $question->questiontextformat = backup_todb($que_info['#']['QUESTIONTEXTFORMAT']['0']['#']);
        $question->image = backup_todb($que_info['#']['IMAGE']['0']['#']);
        $question->generalfeedback = backup_todb_optional_field($que_info, 'GENERALFEEDBACK', '');
        $question->defaultgrade = backup_todb($que_info['#']['DEFAULTGRADE']['0']['#']);
        $question->penalty = backup_todb($que_info['#']['PENALTY']['0']['#']);
        $question->qtype = backup_todb($que_info['#']['QTYPE']['0']['#']);
        $question->length = backup_todb($que_info['#']['LENGTH']['0']['#']);
        $question->stamp = backup_todb($que_info['#']['STAMP']['0']['#']);
        $question->version = backup_todb($que_info['#']['VERSION']['0']['#']);
        $question->hidden = backup_todb($que_info['#']['HIDDEN']['0']['#']);
        $question->timecreated = backup_todb_optional_field($que_info, 'TIMECREATED', 0);
        $question->timemodified = backup_todb_optional_field($que_info, 'TIMEMODIFIED', 0);
        $question->createdby = backup_todb_optional_field($que_info, 'CREATEDBY', null);
        $question->modifiedby = backup_todb_optional_field($que_info, 'MODIFIEDBY', null);
        if ($restore->backup_version < 2006032200) {
            // The qtype was an integer that now needs to be converted to the name
            $qtypenames = array(1 => 'shortanswer', 2 => 'truefalse', 3 => 'multichoice', 4 => 'random', 5 => 'match', 6 => 'randomsamatch', 7 => 'description', 8 => 'numerical', 9 => 'multianswer', 10 => 'calculated', 11 => 'rqp', 12 => 'essay');
            $question->qtype = $qtypenames[$question->qtype];
        }
        //Check if the question exists by category, stamp, and version
        //first check for the question in the context specified in backup
        $existingquestion = get_record("question", "category", $best_question_cat->id, "stamp", $question->stamp, "version", $question->version);
        //If the question exists, only record its id
        //always use existing question, no permissions check here
        if ($existingquestion) {
            $question = $existingquestion;
            $creatingnewquestion = false;
        } else {
            //then if context above course level check permissions and if no permission
            //to restore above course level then restore to cat in course context.
            $bestcontext = get_context_instance_by_id($best_question_cat->contextid);
            if (($bestcontext->contextlevel == CONTEXT_SYSTEM || $bestcontext->contextlevel == CONTEXT_COURSECAT) && !has_capability('moodle/question:add', $bestcontext)) {
                if (!isset($course_question_cat)) {
                    $coursecontext = get_context_instance(CONTEXT_COURSE, $restore->course_id);
                    $course_question_cat = clone $best_question_cat;
                    $course_question_cat->contextid = $coursecontext->id;
                    //create cat if it doesn't exist
                    if (!($fcat = get_record('question_categories', 'contextid', $course_question_cat->contextid, 'stamp', $course_question_cat->stamp))) {
                        $course_question_cat->id = insert_record("question_categories", $course_question_cat);
                        backup_putid($restore->backup_unique_code, "question_categories", $old_category_id, $course_question_cat->id);
                    } else {
                        $course_question_cat = $fcat;
                    }
                    //will fix category parents after all questions and categories restored. Will set parent to 0 if
                    //no parent in same context.
                }
                $question->category = $course_question_cat->id;
                //does question already exist in course cat
                $existingquestion = get_record("question", "category", $question->category, "stamp", $question->stamp, "version", $question->version);
            } else {
                //permissions ok, restore to best cat
                $question->category = $best_question_cat->id;
            }
            if (!$existingquestion) {
                //The structure is equal to the db, so insert the question
                $question->id = insert_record("question", $question);
                $creatingnewquestion = true;
            } else {
                $question = $existingquestion;
                $creatingnewquestion = false;
            }
        }
        // Fixing bug #5482: random questions have parent field set to its own id,
        //                   see: $QTYPES['random']->get_question_options()
        if ($question->qtype == 'random' && $creatingnewquestion) {
            $question->parent = $question->id;
            $status = set_field('question', 'parent', $question->parent, 'id', $question->id);
        }
        //Save newid to backup tables
        if ($question->id) {
            //We have the newid, update backup_ids
            backup_putid($restore->backup_unique_code, "question", $oldid, $question->id);
        }
        $restored_questions[$i] = new stdClass();
        $restored_questions[$i]->newid = $question->id;
        $restored_questions[$i]->oldid = $oldid;
        $restored_questions[$i]->qtype = $question->qtype;
        $restored_questions[$i]->parent = $question->parent;
        $restored_questions[$i]->is_new = $creatingnewquestion;
    }
    backup_flush(300);
    // Loop again, now all the question id mappings exist, so everything can
    // be restored.
    for ($i = 0; $i < sizeof($questions); $i++) {
        $que_info = $questions[$i];
        $newid = $restored_questions[$i]->newid;
        $oldid = $restored_questions[$i]->oldid;
        $question = new object();
        $question->qtype = $restored_questions[$i]->qtype;
        $question->parent = $restored_questions[$i]->parent;
        /// If it's a new question in the DB, restore it
        if ($restored_questions[$i]->is_new) {
            /// We have to recode the parent field
            if ($question->parent && $question->qtype != 'random') {
                /// If the parent field needs to be changed, do it here. Random questions are dealt with above.
                if ($parent = backup_getid($restore->backup_unique_code, "question", $question->parent)) {
                    $question->parent = $parent->new_id;
                    if ($question->parent != $restored_questions[$i]->parent) {
                        if (!set_field('question', 'parent', $question->parent, 'id', $newid)) {
                            echo 'Could not update parent ' . $question->parent . ' for question ' . $oldid . '<br />';
                            $status = false;
                        }
                    }
                } else {
                    echo 'Could not recode parent ' . $question->parent . ' for question ' . $oldid . '<br />';
                    $status = false;
                }
            }
            //Now, restore every question_answers in this question
            $status = question_restore_answers($oldid, $newid, $que_info, $restore);
            // Restore questiontype specific data
            if (array_key_exists($question->qtype, $QTYPES)) {
                $status = $QTYPES[$question->qtype]->restore($oldid, $newid, $que_info, $restore);
            } else {
                echo 'Unknown question type ' . $question->qtype . ' for question ' . $oldid . '<br />';
                $status = false;
            }
        } else {
            //We are NOT creating the question, but we need to know every question_answers
            //map between the XML file and the database to be able to restore the states
            //in each attempt.
            $status = question_restore_map_answers($oldid, $newid, $que_info, $restore);
            // Do the questiontype specific mapping
            if (array_key_exists($question->qtype, $QTYPES)) {
                $status = $QTYPES[$question->qtype]->restore_map($oldid, $newid, $que_info, $restore);
            } else {
                echo 'Unknown question type ' . $question->qtype . ' for question ' . $oldid . '<br />';
                $status = false;
            }
        }
        //Do some output
        if (($i + 1) % 2 == 0) {
            if (!defined('RESTORE_SILENTLY')) {
                echo ".";
                if (($i + 1) % 40 == 0) {
                    echo "<br />";
                }
            }
            backup_flush(300);
        }
    }
    return $status;
}
Exemple #2
0
function restore_questions($old_category_id, $new_category_id, $info, $restore)
{
    global $CFG, $QTYPES;
    $status = true;
    $restored_questions = array();
    //Get the questions array
    if (!empty($info['QUESTION_CATEGORY']['#']['QUESTIONS'])) {
        $questions = $info['QUESTION_CATEGORY']['#']['QUESTIONS']['0']['#']['QUESTION'];
    } else {
        $questions = array();
    }
    //Iterate over questions
    for ($i = 0; $i < sizeof($questions); $i++) {
        $que_info = $questions[$i];
        //traverse_xmlize($que_info);                                                                 //Debug
        //print_object ($GLOBALS['traverse_array']);                                                  //Debug
        //$GLOBALS['traverse_array']="";                                                              //Debug
        //We'll need this later!!
        $oldid = backup_todb($que_info['#']['ID']['0']['#']);
        //Now, build the question record structure
        $question = new object();
        $question->category = $new_category_id;
        $question->parent = backup_todb($que_info['#']['PARENT']['0']['#']);
        $question->name = backup_todb($que_info['#']['NAME']['0']['#']);
        $question->questiontext = backup_todb($que_info['#']['QUESTIONTEXT']['0']['#']);
        $question->questiontextformat = backup_todb($que_info['#']['QUESTIONTEXTFORMAT']['0']['#']);
        $question->image = backup_todb($que_info['#']['IMAGE']['0']['#']);
        if (array_key_exists('GENERALFEEDBACK', $que_info['#'])) {
            $question->generalfeedback = backup_todb($que_info['#']['GENERALFEEDBACK']['0']['#']);
        } else {
            $question->generalfeedback = '';
        }
        $question->defaultgrade = backup_todb($que_info['#']['DEFAULTGRADE']['0']['#']);
        $question->penalty = backup_todb($que_info['#']['PENALTY']['0']['#']);
        $question->qtype = backup_todb($que_info['#']['QTYPE']['0']['#']);
        $question->length = backup_todb($que_info['#']['LENGTH']['0']['#']);
        $question->stamp = backup_todb($que_info['#']['STAMP']['0']['#']);
        $question->version = backup_todb($que_info['#']['VERSION']['0']['#']);
        $question->hidden = backup_todb($que_info['#']['HIDDEN']['0']['#']);
        if ($restore->backup_version < 2006032200) {
            // The qtype was an integer that now needs to be converted to the name
            $qtypenames = array(1 => 'shortanswer', 2 => 'truefalse', 3 => 'multichoice', 4 => 'random', 5 => 'match', 6 => 'randomsamatch', 7 => 'description', 8 => 'numerical', 9 => 'multianswer', 10 => 'calculated', 11 => 'rqp', 12 => 'essay');
            $question->qtype = $qtypenames[$question->qtype];
        }
        //Check if the question exists
        //by category, stamp, and version
        $question_exists = get_record("question", "category", $question->category, "stamp", $question->stamp, "version", $question->version);
        //If the question exists, only record its id
        if ($question_exists) {
            $newid = $question_exists->id;
            $creatingnewquestion = false;
            //Else, create a new question
        } else {
            //The structure is equal to the db, so insert the question
            $newid = insert_record("question", $question);
            $creatingnewquestion = true;
        }
        // Fixing bug #5482: random questions have parent field set to its own id,
        //                   see: $QTYPES['random']->get_question_options()
        if ($question->qtype == 'random') {
            $question->parent = $newid;
            //we have to update the random question if the question has been inserted
            if ($creatingnewquestion && $newid) {
                $status = set_field('question', 'parent', $question->parent, 'id', $newid);
            }
        }
        //Save newid to backup tables
        if ($newid) {
            //We have the newid, update backup_ids
            backup_putid($restore->backup_unique_code, "question", $oldid, $newid);
        }
        $restored_questions[$i] = new stdClass();
        $restored_questions[$i]->newid = $newid;
        $restored_questions[$i]->oldid = $oldid;
        $restored_questions[$i]->qtype = $question->qtype;
        $restored_questions[$i]->parent = $question->parent;
        $restored_questions[$i]->is_new = $creatingnewquestion;
    }
    // Loop again, now all the question id mappings exist, so everything can
    // be restored.
    for ($i = 0; $i < sizeof($questions); $i++) {
        $que_info = $questions[$i];
        $newid = $restored_questions[$i]->newid;
        $oldid = $restored_questions[$i]->oldid;
        $question = new object();
        $question->qtype = $restored_questions[$i]->qtype;
        $question->parent = $restored_questions[$i]->parent;
        /// If it's a new question in the DB, restore it
        if ($restored_questions[$i]->is_new) {
            /// We have to recode the parent field
            if ($question->parent && $question->qtype != 'random') {
                /// If the parent field needs to be changed, do it here. Random questions are dealt with above.
                if ($parent = backup_getid($restore->backup_unique_code, "question", $question->parent)) {
                    $question->parent = $parent->new_id;
                    if ($question->parent != $restored_questions[$i]->parent) {
                        if (!set_field('question', 'parent', $question->parent, 'id', $newid)) {
                            echo 'Could not update parent ' . $question->parent . ' for question ' . $oldid . '<br />';
                            $status = false;
                        }
                    }
                } else {
                    echo 'Could not recode parent ' . $question->parent . ' for question ' . $oldid . '<br />';
                    $status = false;
                }
            }
            //Now, restore every question_answers in this question
            $status = question_restore_answers($oldid, $newid, $que_info, $restore);
            // Restore questiontype specific data
            if (array_key_exists($question->qtype, $QTYPES)) {
                $status = $QTYPES[$question->qtype]->restore($oldid, $newid, $que_info, $restore);
            } else {
                echo 'Unknown question type ' . $question->qtype . ' for question ' . $oldid . '<br />';
                $status = false;
            }
        } else {
            //We are NOT creating the question, but we need to know every question_answers
            //map between the XML file and the database to be able to restore the states
            //in each attempt.
            $status = question_restore_map_answers($oldid, $newid, $que_info, $restore);
            // Do the questiontype specific mapping
            if (array_key_exists($question->qtype, $QTYPES)) {
                $status = $QTYPES[$question->qtype]->restore_map($oldid, $newid, $que_info, $restore);
            } else {
                echo 'Unknown question type ' . $question->qtype . ' for question ' . $oldid . '<br />';
                $status = false;
            }
        }
        //Do some output
        if (($i + 1) % 2 == 0) {
            if (!defined('RESTORE_SILENTLY')) {
                echo ".";
                if (($i + 1) % 40 == 0) {
                    echo "<br />";
                }
            }
            backup_flush(300);
        }
    }
    return $status;
}