Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
use mod_questionnaire\feedback\section;
17
 
18
/**
19
 * Define all the restore steps that will be used by the restore_questionnaire_activity_task.
20
 *
21
 * Structure step to restore one questionnaire activity.
22
 *
23
 * @package mod_questionnaire
24
 * @copyright  2016 Mike Churchward (mike.churchward@poetgroup.org)
25
 * @author     Mike Churchward
26
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27
 */
28
class restore_questionnaire_activity_structure_step extends restore_activity_structure_step {
29
 
30
    /**
31
     * @var array $olddependquestions Contains any question id's with dependencies.
32
     */
33
    protected $olddependquestions = [];
34
 
35
    /**
36
     * @var array $olddependchoices Contains any choice id's for questions with dependencies.
37
     */
38
    protected $olddependchoices = [];
39
 
40
    /**
41
     * @var array $olddependencies Contains the old id's from the dependencies array.
42
     */
43
    protected $olddependencies = [];
44
 
45
    /**
46
     * Implementation of define_structure.
47
     * @return mixed
48
     */
49
    protected function define_structure() {
50
 
51
        $paths = array();
52
        $userinfo = $this->get_setting_value('userinfo');
53
 
54
        $paths[] = new restore_path_element('questionnaire', '/activity/questionnaire');
55
        $paths[] = new restore_path_element('questionnaire_survey', '/activity/questionnaire/surveys/survey');
56
        $paths[] = new restore_path_element('questionnaire_fb_sections',
57
                        '/activity/questionnaire/surveys/survey/fb_sections/fb_section');
58
        $paths[] = new restore_path_element('questionnaire_feedback',
59
                        '/activity/questionnaire/surveys/survey/fb_sections/fb_section/feedbacks/feedback');
60
        $paths[] = new restore_path_element('questionnaire_question',
61
                        '/activity/questionnaire/surveys/survey/questions/question');
62
        $paths[] = new restore_path_element('questionnaire_quest_choice',
63
                        '/activity/questionnaire/surveys/survey/questions/question/quest_choices/quest_choice');
64
        $paths[] = new restore_path_element('questionnaire_dependency',
65
                '/activity/questionnaire/surveys/survey/questions/question/quest_dependencies/quest_dependency');
66
 
67
        if ($userinfo) {
68
            if ($this->task->get_old_moduleversion() < 2018050102) {
69
                // Old system.
70
                $paths[] = new restore_path_element('questionnaire_attempt', '/activity/questionnaire/attempts/attempt');
71
                $paths[] = new restore_path_element('questionnaire_response',
72
                    '/activity/questionnaire/attempts/attempt/responses/response');
73
                $paths[] = new restore_path_element('questionnaire_response_bool',
74
                    '/activity/questionnaire/attempts/attempt/responses/response/response_bools/response_bool');
75
                $paths[] = new restore_path_element('questionnaire_response_date',
76
                    '/activity/questionnaire/attempts/attempt/responses/response/response_dates/response_date');
77
                $paths[] = new restore_path_element('questionnaire_response_multiple',
78
                    '/activity/questionnaire/attempts/attempt/responses/response/response_multiples/response_multiple');
79
                $paths[] = new restore_path_element('questionnaire_response_other',
80
                    '/activity/questionnaire/attempts/attempt/responses/response/response_others/response_other');
81
                $paths[] = new restore_path_element('questionnaire_response_rank',
82
                    '/activity/questionnaire/attempts/attempt/responses/response/response_ranks/response_rank');
83
                $paths[] = new restore_path_element('questionnaire_response_single',
84
                    '/activity/questionnaire/attempts/attempt/responses/response/response_singles/response_single');
85
                $paths[] = new restore_path_element('questionnaire_response_text',
86
                    '/activity/questionnaire/attempts/attempt/responses/response/response_texts/response_text');
87
 
88
            } else {
89
                // New system.
90
                $paths[] = new restore_path_element('questionnaire_response', '/activity/questionnaire/responses/response');
91
                $paths[] = new restore_path_element('questionnaire_response_bool',
92
                    '/activity/questionnaire/responses/response/response_bools/response_bool');
93
                $paths[] = new restore_path_element('questionnaire_response_date',
94
                    '/activity/questionnaire/responses/response/response_dates/response_date');
95
                $paths[] = new restore_path_element('questionnaire_response_multiple',
96
                    '/activity/questionnaire/responses/response/response_multiples/response_multiple');
97
                $paths[] = new restore_path_element('questionnaire_response_other',
98
                    '/activity/questionnaire/responses/response/response_others/response_other');
99
                $paths[] = new restore_path_element('questionnaire_response_rank',
100
                    '/activity/questionnaire/responses/response/response_ranks/response_rank');
101
                $paths[] = new restore_path_element('questionnaire_response_single',
102
                    '/activity/questionnaire/responses/response/response_singles/response_single');
103
                $paths[] = new restore_path_element('questionnaire_response_text',
104
                    '/activity/questionnaire/responses/response/response_texts/response_text');
105
            }
106
        }
107
 
108
        // Return the paths wrapped into standard activity structure.
109
        return $this->prepare_activity_structure($paths);
110
    }
111
 
112
    /**
113
     * Implementation of process_questionnaire.
114
     * @param array $data
115
     */
116
    protected function process_questionnaire($data) {
117
        global $DB;
118
 
119
        $data = (object)$data;
120
        $data->course = $this->get_courseid();
121
 
122
        $data->opendate = $this->apply_date_offset($data->opendate);
123
        $data->closedate = $this->apply_date_offset($data->closedate);
124
        $data->timemodified = $this->apply_date_offset($data->timemodified);
125
 
126
        // Insert the questionnaire record.
127
        $newitemid = $DB->insert_record('questionnaire', $data);
128
        // Immediately after inserting "activity" record, call this.
129
        $this->apply_activity_instance($newitemid);
130
    }
131
 
132
    /**
133
     * Process the survey table.
134
     * @param array $data
135
     */
136
    protected function process_questionnaire_survey($data) {
137
        global $DB;
138
 
139
        $data = (object)$data;
140
        $oldid = $data->id;
141
        $data->courseid = $this->get_courseid();
142
 
143
        // Check for a 'feedbacksections' value larger than 2, and limit it to 2. As of 3.5.1 this has a different meaning.
144
        if ($data->feedbacksections > 2) {
145
            $data->feedbacksections = 2;
146
        }
147
 
148
        // Insert the questionnaire_survey record.
149
        $newitemid = $DB->insert_record('questionnaire_survey', $data);
150
        $this->set_mapping('questionnaire_survey', $oldid, $newitemid, true);
151
 
152
        // Update the questionnaire record we just created with the new survey id.
153
        $DB->set_field('questionnaire', 'sid', $newitemid, array('id' => $this->get_new_parentid('questionnaire')));
154
    }
155
 
156
    /**
157
     * Process the questions.
158
     * @param array $data
159
     */
160
    protected function process_questionnaire_question($data) {
161
        global $DB;
162
 
163
        $data = (object)$data;
164
        $oldid = $data->id;
165
        $data->surveyid = $this->get_new_parentid('questionnaire_survey');
166
 
167
        // Insert the questionnaire_question record.
168
        $newitemid = $DB->insert_record('questionnaire_question', $data);
169
        $this->set_mapping('questionnaire_question', $oldid, $newitemid, true);
170
 
171
        if (isset($data->dependquestion) && ($data->dependquestion > 0)) {
172
            // Questions using the old dependency system will need to be processed and restored using the new system.
173
            // See CONTRIB-6787.
174
            $this->olddependquestions[$newitemid] = $data->dependquestion;
175
            $this->olddependchoices[$newitemid] = $data->dependchoice;
176
        }
177
    }
178
 
179
    /**
180
     * Process the feedback sections.
181
     * $qid is unused, but is needed in order to get the $key elements of the array. Suppress PHPMD warning.
182
     * @param array $data
183
     */
184
    protected function process_questionnaire_fb_sections($data) {
185
        global $DB;
186
 
187
        $data = (object)$data;
188
        $oldid = $data->id;
189
        $data->surveyid = $this->get_new_parentid('questionnaire_survey');
190
 
191
        // If this questionnaire has separate sections feedbacks.
192
        if (isset($data->scorecalculation)) {
193
            $scorecalculation = section::decode_scorecalculation($data->scorecalculation);
194
            $newscorecalculation = array();
195
            foreach ($scorecalculation as $qid => $val) {
196
                $newqid = $this->get_mappingid('questionnaire_question', $qid);
197
                $newscorecalculation[$newqid] = $val;
198
            }
199
            $data->scorecalculation = serialize($newscorecalculation);
200
        }
201
 
202
        // Insert the questionnaire_fb_sections record.
203
        $newitemid = $DB->insert_record('questionnaire_fb_sections', $data);
204
        $this->set_mapping('questionnaire_fb_sections', $oldid, $newitemid, true);
205
    }
206
 
207
    /**
208
     * Process feedback.
209
     * @param array $data
210
     */
211
    protected function process_questionnaire_feedback($data) {
212
        global $DB;
213
 
214
        $data = (object)$data;
215
        $oldid = $data->id;
216
        $data->sectionid = $this->get_new_parentid('questionnaire_fb_sections');
217
 
218
        // Insert the questionnaire_feedback record.
219
        $newitemid = $DB->insert_record('questionnaire_feedback', $data);
220
        $this->set_mapping('questionnaire_feedback', $oldid, $newitemid, true);
221
    }
222
 
223
    /**
224
     * Process question choices.
225
     * @param array $data
226
     */
227
    protected function process_questionnaire_quest_choice($data) {
228
        global $CFG, $DB;
229
 
230
        $data = (object)$data;
231
 
232
        require_once($CFG->dirroot.'/mod/questionnaire/locallib.php');
233
 
234
        // Some old systems had '' instead of NULL. Change it to NULL.
235
        if ($data->value === '') {
236
            $data->value = null;
237
        }
238
 
239
        // Replace the = separator with :: separator in quest_choice content.
240
        // This fixes radio button options using old "value"="display" formats.
241
        if (($data->value == null || $data->value == 'NULL') && !preg_match("/^([0-9]{1,3}=.*|!other=.*)$/", $data->content)) {
242
            $content = questionnaire_choice_values($data->content);
243
            if (strpos($content->text, '=')) {
244
                $data->content = str_replace('=', '::', $content->text);
245
            }
246
        }
247
 
248
        $oldid = $data->id;
249
        $data->question_id = $this->get_new_parentid('questionnaire_question');
250
 
251
        // Insert the questionnaire_quest_choice record.
252
        $newitemid = $DB->insert_record('questionnaire_quest_choice', $data);
253
        $this->set_mapping('questionnaire_quest_choice', $oldid, $newitemid);
254
    }
255
 
256
    /**
257
     * Process dependencies.
258
     * @param array $data
259
     */
260
    protected function process_questionnaire_dependency($data) {
261
        $data = (object)$data;
262
 
263
        $data->questionid = $this->get_new_parentid('questionnaire_question');
264
        $data->surveyid = $this->get_new_parentid('questionnaire_survey');
265
 
266
        if (isset($data)) {
267
            $this->olddependencies[] = $data;
268
        }
269
    }
270
 
271
    /**
272
     * Process attempts (these are no longer used).
273
     * @param array $data
274
     * @return bool
275
     */
276
    protected function process_questionnaire_attempt($data) {
277
        // New structure will be completed in process_questionnaire_response. Nothing to do here any more.
278
        return true;
279
    }
280
 
281
    /**
282
     * Process responses.
283
     * @param array $data
284
     */
285
    protected function process_questionnaire_response($data) {
286
        global $DB;
287
 
288
        $data = (object)$data;
289
 
290
        // Older versions of questionnaire used 'username' instead of 'userid'. If 'username' exists, change it to 'userid'.
291
        if (isset($data->username) && !isset($data->userid)) {
292
            $data->userid = $data->username;
293
        }
294
 
295
        $oldid = $data->id;
296
        $data->questionnaireid = $this->get_new_parentid('questionnaire');
297
        $data->userid = $this->get_mappingid('user', $data->userid);
298
 
299
        // Insert the questionnaire_response record.
300
        $newitemid = $DB->insert_record('questionnaire_response', $data);
301
        $this->set_mapping('questionnaire_response', $oldid, $newitemid);
302
    }
303
 
304
    /**
305
     * Process boolean responses.
306
     * @param array $data
307
     * @throws dml_exception
308
     */
309
    protected function process_questionnaire_response_bool($data) {
310
        global $DB;
311
 
312
        $data = (object)$data;
313
        $data->response_id = $this->get_new_parentid('questionnaire_response');
314
        $data->question_id = $this->get_mappingid('questionnaire_question', $data->question_id);
315
 
316
        // Insert the questionnaire_response_bool record.
317
        $DB->insert_record('questionnaire_response_bool', $data);
318
    }
319
 
320
    /**
321
     * Process date responses.
322
     * @param array $data
323
     * @throws dml_exception
324
     */
325
    protected function process_questionnaire_response_date($data) {
326
        global $DB;
327
 
328
        $data = (object)$data;
329
        $data->response_id = $this->get_new_parentid('questionnaire_response');
330
        $data->question_id = $this->get_mappingid('questionnaire_question', $data->question_id);
331
 
332
        // Insert the questionnaire_response_date record.
333
        $DB->insert_record('questionnaire_response_date', $data);
334
    }
335
 
336
    /**
337
     * Process multiple responses.
338
     * @param array $data
339
     * @throws dml_exception
340
     */
341
    protected function process_questionnaire_response_multiple($data) {
342
        global $DB;
343
 
344
        $data = (object)$data;
345
        $data->response_id = $this->get_new_parentid('questionnaire_response');
346
        $data->question_id = $this->get_mappingid('questionnaire_question', $data->question_id);
347
        $data->choice_id = $this->get_mappingid('questionnaire_quest_choice', $data->choice_id);
348
 
349
        // Insert the questionnaire_resp_multiple record.
350
        $DB->insert_record('questionnaire_resp_multiple', $data);
351
    }
352
 
353
    /**
354
     * Process other responses.
355
     * @param array $data
356
     * @throws dml_exception
357
     */
358
    protected function process_questionnaire_response_other($data) {
359
        global $DB;
360
 
361
        $data = (object)$data;
362
        $data->response_id = $this->get_new_parentid('questionnaire_response');
363
        $data->question_id = $this->get_mappingid('questionnaire_question', $data->question_id);
364
        $data->choice_id = $this->get_mappingid('questionnaire_quest_choice', $data->choice_id);
365
 
366
        // Insert the questionnaire_response_other record.
367
        $DB->insert_record('questionnaire_response_other', $data);
368
    }
369
 
370
    /**
371
     * Process rank responses.
372
     * @param array $data
373
     * @throws dml_exception
374
     */
375
    protected function process_questionnaire_response_rank($data) {
376
        global $DB;
377
 
378
        $data = (object)$data;
379
 
380
        // Older versions of questionnaire used 'rank' instead of 'rankvalue'. If 'rank' exists, change it to 'rankvalue'.
381
        if (isset($data->rank) && !isset($data->rankvalue)) {
382
            $data->rankvalue = $data->rank;
383
        }
384
 
385
        $data->response_id = $this->get_new_parentid('questionnaire_response');
386
        $data->question_id = $this->get_mappingid('questionnaire_question', $data->question_id);
387
        $data->choice_id = $this->get_mappingid('questionnaire_quest_choice', $data->choice_id);
388
 
389
        // Insert the questionnaire_response_rank record.
390
        $DB->insert_record('questionnaire_response_rank', $data);
391
    }
392
 
393
    /**
394
     * Process single responses.
395
     * @param array $data
396
     * @throws dml_exception
397
     */
398
    protected function process_questionnaire_response_single($data) {
399
        global $DB;
400
 
401
        $data = (object)$data;
402
        $data->response_id = $this->get_new_parentid('questionnaire_response');
403
        $data->question_id = $this->get_mappingid('questionnaire_question', $data->question_id);
404
        $data->choice_id = $this->get_mappingid('questionnaire_quest_choice', $data->choice_id);
405
 
406
        // Insert the questionnaire_resp_single record.
407
        $DB->insert_record('questionnaire_resp_single', $data);
408
    }
409
 
410
    /**
411
     * Process text answers.
412
     * @param array $data
413
     */
414
    protected function process_questionnaire_response_text($data) {
415
        global $DB;
416
 
417
        $data = (object)$data;
418
        $data->response_id = $this->get_new_parentid('questionnaire_response');
419
        $data->question_id = $this->get_mappingid('questionnaire_question', $data->question_id);
420
 
421
        // Insert the questionnaire_response_text record.
422
        $DB->insert_record('questionnaire_response_text', $data);
423
    }
424
 
425
    /**
426
     * Stuff to do after execution.
427
     */
428
    protected function after_execute() {
429
        global $DB;
430
 
431
        // Process any question dependencies after all questions and choices have already been processed to ensure we have all of
432
        // the new id's.
433
 
434
        // First, process any old system question dependencies into the new system.
435
        foreach ($this->olddependquestions as $newid => $olddependid) {
436
            $newrec = new stdClass();
437
            $newrec->questionid = $newid;
438
            $newrec->surveyid = $this->get_new_parentid('questionnaire_survey');
439
            $newrec->dependquestionid = $this->get_mappingid('questionnaire_question', $olddependid);
440
            // Only change mapping for RADIO and DROP question types, not for YESNO question.
441
            $dependqtype = $DB->get_field('questionnaire_question', 'type_id', ['id' => $newrec->dependquestionid]);
442
            if (($dependqtype !== false) && ($dependqtype != 1)) {
443
                $newrec->dependchoiceid = $this->get_mappingid('questionnaire_quest_choice',
444
                    $this->olddependchoices[$newid]);
445
            } else {
446
                $newrec->dependchoiceid = $this->olddependchoices[$newid];
447
            }
448
            $newrec->dependlogic = 1; // Set to "answer given", previously the only option.
449
            $newrec->dependandor = 'and'; // Not used previously.
450
            $DB->insert_record('questionnaire_dependency', $newrec);
451
        }
452
 
453
        // Next process all new system dependencies.
454
        foreach ($this->olddependencies as $data) {
455
            $data->dependquestionid = $this->get_mappingid('questionnaire_question', $data->dependquestionid);
456
 
457
            // Only change mapping for RADIO and DROP question types, not for YESNO question.
458
            $dependqtype = $DB->get_field('questionnaire_question', 'type_id', ['id' => $data->dependquestionid]);
459
            if (($dependqtype !== false) && ($dependqtype != 1)) {
460
                $data->dependchoiceid = $this->get_mappingid('questionnaire_quest_choice', $data->dependchoiceid);
461
            }
462
            $DB->insert_record('questionnaire_dependency', $data);
463
        }
464
 
465
        // Add questionnaire related files, no need to match by itemname (just internally handled context).
466
        $this->add_related_files('mod_questionnaire', 'intro', null);
467
        $this->add_related_files('mod_questionnaire', 'info', 'questionnaire_survey');
468
        $this->add_related_files('mod_questionnaire', 'thankbody', 'questionnaire_survey');
469
        $this->add_related_files('mod_questionnaire', 'feedbacknotes', 'questionnaire_survey');
470
        $this->add_related_files('mod_questionnaire', 'question', 'questionnaire_question');
471
        $this->add_related_files('mod_questionnaire', 'sectionheading', 'questionnaire_fb_sections');
472
        $this->add_related_files('mod_questionnaire', 'feedback', 'questionnaire_feedback');
473
 
474
        // Process any old rate question named degree choices after all questions and choices have been restored.
475
        if ($this->task->get_old_moduleversion() < 2018110103) {
476
            \mod_questionnaire\question\rate::move_all_nameddegree_choices($this->get_new_parentid('questionnaire_survey'));
477
        }
478
    }
479
}