MDL-20636 Fix @package names and PHPdoc layout.
[moodle.git] / question / type / multianswer / backup / moodle2 / restore_qtype_multianswer_plugin.class.php
CommitLineData
41941110
EL
1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
18/**
19 * @package moodlecore
20 * @subpackage backup-moodle2
21 * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 */
24
25defined('MOODLE_INTERNAL') || die();
26
27/**
28 * restore plugin class that provides the necessary information
29 * needed to restore one multianswer qtype plugin
30 */
31class restore_qtype_multianswer_plugin extends restore_qtype_plugin {
32
33 /**
34 * Returns the paths to be handled by the plugin at question level
35 */
36 protected function define_question_plugin_structure() {
37
38 $paths = array();
39
40 // This qtype uses question_answers, add them
41 $this->add_question_question_answers($paths);
42
43 // Add own qtype stuff
44 $elename = 'multianswer';
45 $elepath = $this->get_pathfor('/multianswer'); // we used get_recommended_name() so this works
46 $paths[] = new restore_path_element($elename, $elepath);
47
48
49 return $paths; // And we return the interesting paths
50 }
51
52 /**
53 * Process the qtype/multianswer element
54 */
55 public function process_multianswer($data) {
56 global $DB;
57
58 $data = (object)$data;
59 $oldid = $data->id;
60
61 // Detect if the question is created or mapped
62 $oldquestionid = $this->get_old_parentid('question');
63 $newquestionid = $this->get_new_parentid('question');
64 $questioncreated = $this->get_mappingid('question_created', $oldquestionid) ? true : false;
65
66 // If the question has been created by restore, we need to create its question_multianswer too
67 if ($questioncreated) {
68 // Adjust some columns
69 $data->question = $newquestionid;
70 // Note: multianswer->sequence is a list of question->id values. We aren't
71 // recoding them here (because some questions can be missing yet). Instead
72 // we'll perform the recode in the {@link after_execute} method of the plugin
73 // that gets executed once all questions have been created
74 // Insert record
75 $newitemid = $DB->insert_record('question_multianswer', $data);
76 // Create mapping (need it for after_execute recode of sequence)
77 $this->set_mapping('question_multianswer', $oldid, $newitemid);
78 } else {
79 // Nothing to remap if the question already existed
80 }
81 }
82
83 /**
84 * This method is executed once the whole restore_structure_step
85 * this step is part of ({@link restore_create_categories_and_questions})
86 * has ended processing the whole xml structure. Its name is:
87 * "after_execute_" + connectionpoint ("question")
88 *
89 * For multianswer qtype we use it to restore the sequence column,
90 * containing one list of question ids
91 */
92 public function after_execute_question() {
93 global $DB;
94 // Now that all the questions have been restored, let's process
95 // the created question_multianswer sequences (list of question ids)
96 $rs = $DB->get_recordset_sql("SELECT qma.id, qma.sequence
97 FROM {question_multianswer} qma
98 JOIN {backup_ids_temp} bi ON bi.newitemid = qma.question
99 WHERE bi.backupid = ?
100 AND bi.itemname = 'question_created'", array($this->get_restoreid()));
101 foreach ($rs as $rec) {
102 $sequencearr = explode(',', $rec->sequence);
103 foreach ($sequencearr as $key => $question) {
104 $sequencearr[$key] = $this->get_mappingid('question', $question);
105 }
106 $sequence = implode(',', $sequencearr);
107 $DB->set_field('question_multianswer', 'sequence', $sequence, array('id' => $rec->id));
108 }
109 $rs->close();
110 }
111
112 /**
113 * Given one question_states record, return the answer
114 * recoded pointing to all the restored stuff for multianswer questions
115 *
116 * answer is one comma separated list of hypen separated pairs
117 * containing sequence (pointing to questions sequence in question_multianswer)
118 * and mixed answers. We'll delegate
119 * the recoding of answers to the proper qtype
120 */
121 public function recode_state_answer($state) {
122 global $DB;
123 $answer = $state->answer;
124 $resultarr = array();
125 // Get sequence of questions
126 $sequence = $DB->get_field('question_multianswer', 'sequence', array('question' => $state->question));
127 $sequencearr = explode(',', $sequence);
128 // Let's process each pair
129 foreach (explode(',', $answer) as $pair) {
130 $pairarr = explode('-', $pair);
131 $sequenceid = $pairarr[0];
132 $subanswer = $pairarr[1];
133 // Calculate the questionid based on sequenceid
134 // Note it is already one *new* questionid that doesn't need mapping
135 $questionid = $sequencearr[$sequenceid-1];
136 // Fetch qtype of the question (needed for delegation)
137 $questionqtype = $DB->get_field('question', 'qtype', array('id' => $questionid));
138 // Delegate subanswer recode to proper qtype, faking one question_states record
139 $substate = new stdClass();
140 $substate->question = $questionid;
141 $substate->answer = $subanswer;
142 $newanswer = $this->step->restore_recode_answer($substate, $questionqtype);
143 $resultarr[] = implode('-', array($sequenceid, $newanswer));
144 }
145 return implode(',', $resultarr);
146 }
147
148}