Passed
Push — 1.11.x ( df1362...89b874 )
by Julito
13:12
created

CourseRestorer::restore_gradebook()   D

Complexity

Conditions 26

Size

Total Lines 100
Code Lines 71

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 26
eloc 71
nop 1
dl 0
loc 100
rs 4.1666
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
namespace Chamilo\CourseBundle\Component\CourseCopy;
6
7
use Chamilo\CourseBundle\Component\CourseCopy\Resources\CourseCopyLearnpath;
8
use Chamilo\CourseBundle\Component\CourseCopy\Resources\GradeBookBackup;
9
use Chamilo\CourseBundle\Component\CourseCopy\Resources\LearnPathCategory;
10
use Chamilo\CourseBundle\Component\CourseCopy\Resources\QuizQuestion;
11
use Chamilo\CourseBundle\Entity\CLpCategory;
12
use Chamilo\CourseBundle\Entity\CQuizAnswer;
13
use CourseManager;
14
use Database;
15
use DocumentManager;
16
use Question;
17
use stdClass;
18
use SurveyManager;
19
use TestCategory;
20
21
/**
22
 * Class CourseRestorer.
23
 *
24
 * Class to restore items from a course object to a Chamilo-course
25
 *
26
 * @author Bart Mollet <[email protected]>
27
 * @author Julio Montoya <[email protected]> Several fixes/improvements
28
 */
29
class CourseRestorer
30
{
31
    /**
32
     * The course-object.
33
     */
34
    public $course;
35
    public $destination_course_info;
36
37
    /**
38
     * What to do with files with same name (FILE_SKIP, FILE_RENAME or
39
     * FILE_OVERWRITE).
40
     */
41
    public $file_option;
42
    public $set_tools_invisible_by_default;
43
    public $skip_content;
44
    public $tools_to_restore = [
45
        'documents', // first restore documents
46
        'announcements',
47
        'attendance',
48
        'course_descriptions',
49
        'events',
50
        'forum_category',
51
        'forums',
52
       // 'forum_topics',
53
        'glossary',
54
        'quizzes',
55
        'test_category',
56
        'links',
57
        'works',
58
        'surveys',
59
        'learnpath_category',
60
        'learnpaths',
61
        //'scorm_documents', ??
62
        'tool_intro',
63
        'thematic',
64
        'wiki',
65
        'gradebook',
66
        'assets',
67
    ];
68
69
    /** Setting per tool */
70
    public $tool_copy_settings = [];
71
72
    /**
73
     * If true adds the text "copy" in the title of an item (only for LPs right now).
74
     */
75
    public $add_text_in_items = false;
76
    public $destination_course_id;
77
78
    /**
79
     * CourseRestorer constructor.
80
     *
81
     * @param Course $course
82
     */
83
    public function __construct($course)
84
    {
85
        $this->course = $course;
86
        $courseInfo = api_get_course_info($this->course->code);
87
        $this->course_origin_id = null;
88
        if (!empty($courseInfo)) {
89
            $this->course_origin_id = $courseInfo['real_id'];
90
        }
91
        $this->file_option = FILE_RENAME;
92
        $this->set_tools_invisible_by_default = false;
93
        $this->skip_content = [];
94
95
        $forceImport = api_get_configuration_value('allow_import_scorm_package_in_course_builder');
96
        if ($forceImport) {
97
            $this->tools_to_restore[] = 'scorm_documents';
98
        }
99
    }
100
101
    /**
102
     * Set the file-option.
103
     *
104
     * @param int $option (optional) What to do with files with same name
105
     *                    FILE_SKIP, FILE_RENAME or FILE_OVERWRITE
106
     */
107
    public function set_file_option($option = FILE_OVERWRITE)
108
    {
109
        $this->file_option = $option;
110
    }
111
112
    /**
113
     * @param bool $status
114
     */
115
    public function set_add_text_in_items($status)
116
    {
117
        $this->add_text_in_items = $status;
118
    }
119
120
    /**
121
     * @param array $array
122
     */
123
    public function set_tool_copy_settings($array)
124
    {
125
        $this->tool_copy_settings = $array;
126
    }
127
128
    /**
129
     * Restore a course.
130
     *
131
     * @param string $destination_course_code code of the Chamilo-course in
132
     * @param int    $session_id
133
     * @param bool   $update_course_settings  Course settings are going to be restore?
134
     * @param bool   $respect_base_content
135
     *
136
     * @return false|null
137
     */
138
    public function restore(
139
        $destination_course_code = '',
140
        $session_id = 0,
141
        $update_course_settings = false,
142
        $respect_base_content = false
143
    ) {
144
        if ($destination_course_code == '') {
145
            $course_info = api_get_course_info();
146
            $this->destination_course_info = $course_info;
147
            $this->course->destination_path = $course_info['path'];
148
        } else {
149
            $course_info = api_get_course_info($destination_course_code);
150
            $this->destination_course_info = $course_info;
151
            $this->course->destination_path = $course_info['path'];
152
        }
153
        $this->destination_course_id = $course_info['real_id'];
154
        // Getting first teacher (for the forums)
155
        $teacher_list = CourseManager::get_teacher_list_from_course_code($course_info['code']);
156
        $this->first_teacher_id = api_get_user_id();
157
158
        if (!empty($teacher_list)) {
159
            foreach ($teacher_list as $teacher) {
160
                $this->first_teacher_id = $teacher['user_id'];
161
                break;
162
            }
163
        }
164
165
        if (empty($this->course)) {
166
            return false;
167
        }
168
169
        // Source platform encoding - reading/detection
170
        // The correspondent data field has been added as of version 1.8.6.1
171
        if (empty($this->course->encoding)) {
172
            // The archive has been created by a system which is prior to 1.8.6.1 version.
173
            // In this case we have to detect the encoding.
174
            $sample_text = $this->course->get_sample_text()."\n";
175
            // Let us exclude ASCII lines, probably they are English texts.
176
            $sample_text = explode("\n", $sample_text);
177
            foreach ($sample_text as $key => &$line) {
178
                if (api_is_valid_ascii($line)) {
179
                    unset($sample_text[$key]);
180
                }
181
            }
182
            $sample_text = implode("\n", $sample_text);
183
            $this->course->encoding = api_detect_encoding(
184
                $sample_text,
185
                $course_info['language']
186
            );
187
        }
188
189
        // Encoding conversion of the course, if it is needed.
190
        $this->course->to_system_encoding();
191
192
        foreach ($this->tools_to_restore as $tool) {
193
            $function_build = 'restore_'.$tool;
194
            $this->$function_build(
195
                $session_id,
196
                $respect_base_content,
197
                $destination_course_code
198
            );
199
        }
200
201
        if ($update_course_settings) {
202
            $this->restore_course_settings($destination_course_code);
203
        }
204
205
        // Restore the item properties
206
        $table = Database::get_course_table(TABLE_ITEM_PROPERTY);
207
        foreach ($this->course->resources as $type => $resources) {
208
            if (is_array($resources)) {
209
                foreach ($resources as $id => $resource) {
210
                    if (isset($resource->item_properties)) {
211
                        foreach ($resource->item_properties as $property) {
212
                            // First check if there isn't already a record for this resource
213
                            $sql = "SELECT * FROM $table
214
                                    WHERE
215
                                        c_id = ".$this->destination_course_id." AND
216
                                        tool = '".$property['tool']."' AND
217
                                        ref = '".$resource->destination_id."'";
218
219
                            $params = [];
220
                            if (!empty($session_id)) {
221
                                $params['session_id'] = (int) $session_id;
222
                            }
223
224
                            $res = Database::query($sql);
225
                            if (Database::num_rows($res) == 0) {
226
                                /* The to_group_id and to_user_id are set to default
227
                                values as users/groups possibly not exist in
228
                                the target course*/
229
230
                                $params['c_id'] = $this->destination_course_id;
231
                                $params['tool'] = self::DBUTF8($property['tool']);
232
                                $params['insert_user_id'] = $this->checkUserId($property['insert_user_id']) ?: null;
233
                                $params['insert_date'] = self::DBUTF8($property['insert_date']);
234
                                $params['lastedit_date'] = self::DBUTF8($property['lastedit_date']);
235
                                $params['ref'] = $resource->destination_id;
236
                                $params['lastedit_type'] = self::DBUTF8($property['lastedit_type']);
237
                                $params['lastedit_user_id'] = $this->checkUserId($property['lastedit_user_id']);
238
                                $params['visibility'] = self::DBUTF8($property['visibility']);
239
                                $params['start_visible'] = self::DBUTF8($property['start_visible']);
240
                                $params['end_visible'] = self::DBUTF8($property['end_visible']);
241
                                $params['to_user_id'] = $this->checkUserId($property['to_user_id']) ?: null;
242
243
                                $id = Database::insert($table, $params);
244
                                if ($id) {
245
                                    $sql = "UPDATE $table SET id = iid WHERE iid = $id";
246
                                    Database::query($sql);
247
                                }
248
                            }
249
                        }
250
                    }
251
                }
252
            }
253
        }
254
    }
255
256
    /**
257
     * Restore only harmless course settings:
258
     * course_language, visibility, department_name,department_url,
259
     * subscribe, unsubscribe ,category_code.
260
     *
261
     * @param string $destination_course_code
262
     */
263
    public function restore_course_settings($destination_course_code)
264
    {
265
        $origin_course_info = api_get_course_info($destination_course_code);
266
        $course_info = $this->course->info;
267
        $params['course_language'] = $course_info['language'];
268
        $params['visibility'] = $course_info['visibility'];
269
        $params['department_name'] = $course_info['department_name'];
270
        $params['department_url'] = $course_info['department_url'];
271
        $params['category_code'] = $course_info['categoryCode'];
272
        $params['subscribe'] = $course_info['subscribe_allowed'];
273
        $params['unsubscribe'] = $course_info['unsubscribe'];
274
        CourseManager::update_attributes($origin_course_info['real_id'], $params);
275
    }
276
277
    /**
278
     * Restore documents.
279
     *
280
     * @param int    $session_id
281
     * @param bool   $respect_base_content
282
     * @param string $destination_course_code
283
     */
284
    public function restore_documents(
285
        $session_id = 0,
286
        $respect_base_content = false,
287
        $destination_course_code = ''
288
    ) {
289
        $course_info = api_get_course_info($destination_course_code);
290
291
        if (!$this->course->has_resources(RESOURCE_DOCUMENT)) {
292
            return;
293
        }
294
295
        $webEditorCss = api_get_path(WEB_CSS_PATH).'editor.css';
296
        $table = Database::get_course_table(TABLE_DOCUMENT);
297
        $resources = $this->course->resources;
298
        $path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/';
299
        $originalFolderNameList = [];
300
        foreach ($resources[RESOURCE_DOCUMENT] as $id => $document) {
301
            $my_session_id = empty($document->item_properties[0]['session_id']) ? 0 : $session_id;
302
303
            if (false === $respect_base_content && $session_id) {
304
                if (empty($my_session_id)) {
305
                    $my_session_id = $session_id;
306
                }
307
            }
308
309
            if ($document->file_type == FOLDER) {
310
                $visibility = isset($document->item_properties[0]['visibility']) ? $document->item_properties[0]['visibility'] : '';
311
                $new = substr($document->path, 8);
312
                $folderList = explode('/', $new);
313
                $tempFolder = '';
314
315
                // Check if the parent path exists.
316
                foreach ($folderList as $folder) {
317
                    $folderToCreate = $tempFolder.$folder;
318
                    $sysFolderPath = $path.'document'.$folderToCreate;
319
                    $tempFolder .= $folder.'/';
320
321
                    if (empty($folderToCreate)) {
322
                        continue;
323
                    }
324
                    $title = $document->title;
325
                    $originalFolderNameList[basename($document->path)] = $document->title;
326
                    if (empty($title)) {
327
                        $title = basename($sysFolderPath);
328
                    }
329
                    //error_log($title); error_log($sysFolderPath);
330
                    // File doesn't exist in file system.
331
                    if (!is_dir($sysFolderPath)) {
332
                        /*error_log('Creating directory');
333
                        error_log("Creating $folderToCreate");*/
334
                        // Creating directory
335
                        create_unexisting_directory(
336
                            $course_info,
337
                            api_get_user_id(),
338
                            $my_session_id,
339
                            0,
340
                            0,
341
                            $path.'document',
342
                            $folderToCreate,
343
                            $title,
344
                            $visibility
345
                        );
346
                        continue;
347
                    }
348
349
                    // File exist in file system.
350
                    $documentData = DocumentManager::get_document_id(
351
                        $course_info,
352
                        $folderToCreate,
353
                        $session_id
354
                    );
355
356
                    //error_log("session_id $session_id");
357
                    if (empty($documentData)) {
358
                        if (!is_dir($sysFolderPath)) {
359
                            //error_log('$documentData empty');
360
                            //error_log('$folderToCreate '.$folderToCreate);
361
                            /* This means the folder exists in the
362
                            filesystem but not in the DB, trying to fix it */
363
                            add_document(
364
                                $course_info,
365
                                $folderToCreate,
366
                                'folder',
367
                                0,
368
                                $title,
369
                                null,
370
                                null,
371
                                false,
372
                                null,
373
                                $session_id,
374
                                0,
375
                                false
376
                            );
377
                        }
378
                    } else {
379
                        $insertUserId = isset($document->item_properties[0]['insert_user_id']) ? $document->item_properties[0]['insert_user_id'] : api_get_user_id();
380
                        $insertUserId = $this->checkUserId($insertUserId);
381
                        // Check if user exists in platform
382
                        $toUserId = isset($document->item_properties[0]['to_user_id']) ? $document->item_properties[0]['to_user_id'] : null;
383
                        $toUserId = $this->checkUserId($toUserId, true);
384
                        $groupId = isset($document->item_properties[0]['to_group_id']) ? $document->item_properties[0]['to_group_id'] : null;
385
                        $groupInfo = $this->checkGroupId($groupId);
386
                        //error_log(" if folder exists then just refresh it");
387
                        // if folder exists then just refresh it
388
                        api_item_property_update(
389
                            $course_info,
390
                            TOOL_DOCUMENT,
391
                            $documentData,
392
                            'FolderUpdated',
393
                            $insertUserId,
394
                            $groupInfo,
395
                            $toUserId,
396
                            null,
397
                            null,
398
                            $my_session_id
399
                        );
400
                    }
401
                }
402
            } elseif ($document->file_type == DOCUMENT) {
403
                // Checking if folder exists in the database otherwise we created it
404
                $dir_to_create = dirname($document->path);
405
                $originalFolderNameList[basename($document->path)] = $document->title;
406
                if (!empty($dir_to_create) && $dir_to_create != 'document' && $dir_to_create != '/') {
407
                    if (is_dir($path.dirname($document->path))) {
408
                        $sql = "SELECT id FROM $table
409
                                WHERE
410
                                    c_id = ".$this->destination_course_id." AND
411
                                    path = '/".self::DBUTF8escapestring(substr(dirname($document->path), 9))."'";
412
                        $res = Database::query($sql);
413
414
                        if (Database::num_rows($res) == 0) {
415
                            //continue;
416
                            $visibility = $document->item_properties[0]['visibility'];
417
                            $new = '/'.substr(dirname($document->path), 9);
418
                            $title = $document->title;
419
                            if (empty($title)) {
420
                                $title = str_replace('/', '', $new);
421
                            }
422
423
                            // This code fixes the possibility for a file without a directory entry to be
424
                            $document_id = add_document(
425
                                $course_info,
426
                                $new,
427
                                'folder',
428
                                0,
429
                                $title,
430
                                null,
431
                                null,
432
                                false,
433
                                0,
434
                                0,
435
                                0,
436
                                false
437
                            );
438
439
                            $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
440
                            $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
441
                            $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
442
                            $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
443
                            $groupInfo = $this->checkGroupId($toGroupId);
444
                            $insertUserId = $this->checkUserId($insertUserId);
445
                            $toUserId = $this->checkUserId($toUserId, true);
446
447
                            api_item_property_update(
448
                                $course_info,
449
                                TOOL_DOCUMENT,
450
                                $document_id,
451
                                'FolderCreated',
452
                                $insertUserId,
453
                                $groupInfo,
454
                                $toUserId,
455
                                null,
456
                                null,
457
                                $my_session_id
458
                            );
459
                        }
460
                    }
461
                }
462
463
                //error_log(print_r($originalFolderNameList, 1));
464
                if (file_exists($path.$document->path)) {
465
                    switch ($this->file_option) {
466
                        case FILE_OVERWRITE:
467
                            $origin_path = $this->course->backup_path.'/'.$document->path;
468
                            if (file_exists($origin_path)) {
469
                                copy($origin_path, $path.$document->path);
470
                                $this->fixEditorHtmlContent($path.$document->path, $webEditorCss);
471
                                $sql = "SELECT id FROM $table
472
                                        WHERE
473
                                            c_id = ".$this->destination_course_id." AND
474
                                            path = '/".self::DBUTF8escapestring(substr($document->path, 9))."'";
475
476
                                $res = Database::query($sql);
477
                                $count = Database::num_rows($res);
478
479
                                if ($count == 0) {
480
                                    $params = [
481
                                        'path' => "/".self::DBUTF8(substr($document->path, 9)),
482
                                        'c_id' => $this->destination_course_id,
483
                                        'comment' => self::DBUTF8($document->comment),
484
                                        'title' => self::DBUTF8($document->title),
485
                                        'filetype' => self::DBUTF8($document->file_type),
486
                                        'size' => self::DBUTF8($document->size),
487
                                        'session_id' => $my_session_id,
488
                                        'readonly' => 0,
489
                                    ];
490
491
                                    $document_id = Database::insert($table, $params);
492
493
                                    if ($document_id) {
494
                                        $sql = "UPDATE $table SET id = iid WHERE iid = $document_id";
495
                                        Database::query($sql);
496
                                    }
497
                                    $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id;
498
499
                                    $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
500
                                    $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
501
                                    $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
502
                                    $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
503
504
                                    $insertUserId = $this->checkUserId($insertUserId);
505
                                    $toUserId = $this->checkUserId($toUserId, true);
506
                                    $groupInfo = $this->checkGroupId($toGroupId);
507
508
                                    api_item_property_update(
509
                                        $course_info,
510
                                        TOOL_DOCUMENT,
511
                                        $document_id,
512
                                        'DocumentAdded',
513
                                        $insertUserId,
514
                                        $groupInfo,
515
                                        $toUserId,
516
                                        null,
517
                                        null,
518
                                        $my_session_id
519
                                    );
520
                                } else {
521
                                    $obj = Database::fetch_object($res);
522
                                    $document_id = $obj->id;
523
                                    $params = [
524
                                        'path' => "/".self::DBUTF8(substr($document->path, 9)),
525
                                        'c_id' => $this->destination_course_id,
526
                                        'comment' => self::DBUTF8($document->comment),
527
                                        'title' => self::DBUTF8($document->title),
528
                                        'filetype' => self::DBUTF8($document->file_type),
529
                                        'size' => self::DBUTF8($document->size),
530
                                        'session_id' => $my_session_id,
531
                                    ];
532
533
                                    Database::update(
534
                                        $table,
535
                                        $params,
536
                                        [
537
                                            'c_id = ? AND path = ?' => [
538
                                                $this->destination_course_id,
539
                                                "/".self::DBUTF8escapestring(substr($document->path, 9)),
540
                                            ],
541
                                        ]
542
                                    );
543
544
                                    $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $obj->id;
545
546
                                    $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
547
                                    $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
548
                                    $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
549
                                    $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
550
551
                                    $insertUserId = $this->checkUserId($insertUserId);
552
                                    $toUserId = $this->checkUserId($toUserId, true);
553
                                    $groupInfo = $this->checkGroupId($toGroupId);
554
555
                                    api_item_property_update(
556
                                        $course_info,
557
                                        TOOL_DOCUMENT,
558
                                        $obj->id,
559
                                        'default',
560
                                        $insertUserId,
561
                                        $groupInfo,
562
                                        $toUserId,
563
                                        null,
564
                                        null,
565
                                        $my_session_id
566
                                    );
567
                                }
568
569
                                // Replace old course code with the new destination code
570
                                $file_info = pathinfo($path.$document->path);
571
572
                                if (isset($file_info['extension']) && in_array($file_info['extension'], ['html', 'htm'])) {
573
                                    $content = file_get_contents($path.$document->path);
574
                                    if (UTF8_CONVERT) {
575
                                        $content = utf8_encode($content);
576
                                    }
577
                                    $content = DocumentManager::replaceUrlWithNewCourseCode(
578
                                        $content,
579
                                        $this->course->code,
580
                                        $this->course->destination_path,
581
                                        $this->course->backup_path,
582
                                        $this->course->info['path']
583
                                    );
584
                                    file_put_contents($path.$document->path, $content);
585
                                }
586
587
                                $params = [
588
                                    'comment' => self::DBUTF8($document->comment),
589
                                    'title' => self::DBUTF8($document->title),
590
                                    'size' => self::DBUTF8($document->size),
591
                                ];
592
                                Database::update(
593
                                    $table,
594
                                    $params,
595
                                    [
596
                                        'c_id = ? AND id = ?' => [
597
                                            $this->destination_course_id,
598
                                            $document_id,
599
                                        ],
600
                                    ]
601
                                );
602
                            }
603
                            break;
604
                        case FILE_SKIP:
605
                            $sql = "SELECT id FROM $table
606
                                    WHERE
607
                                        c_id = ".$this->destination_course_id." AND
608
                                        path='/".self::DBUTF8escapestring(substr($document->path, 9))."'";
609
                            $res = Database::query($sql);
610
                            $obj = Database::fetch_object($res);
611
                            $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $obj->id;
612
                            break;
613
                        case FILE_RENAME:
614
                            //error_log("Rename: ".$path.$document->path);
615
                            $i = 1;
616
                            $ext = explode('.', basename($document->path));
617
                            if (count($ext) > 1) {
618
                                $ext = array_pop($ext);
619
                                $file_name_no_ext = substr($document->path, 0, -(strlen($ext) + 1));
620
                                $ext = '.'.$ext;
621
                            } else {
622
                                $ext = '';
623
                                $file_name_no_ext = $document->path;
624
                            }
625
                            $new_file_name = $file_name_no_ext.'_'.$i.$ext;
626
                            $file_exists = file_exists($path.$new_file_name);
627
                            while ($file_exists) {
628
                                $i++;
629
                                $new_file_name = $file_name_no_ext.'_'.$i.$ext;
630
                                $file_exists = file_exists($path.$new_file_name);
631
                            }
632
633
                            if (!empty($session_id)) {
634
                                $originalPath = $document->path;
635
                                //error_log("document->path: ".$document->path);
636
                                $document_path = explode('/', $document->path, 3);
637
                                $course_path = $path;
638
                                $orig_base_folder = $document_path[1];
639
                                $orig_base_path = $course_path.$document_path[0].'/'.$document_path[1];
640
641
                                if (is_dir($orig_base_path)) {
642
                                    $new_base_foldername = $orig_base_folder;
643
                                    $new_base_path = $orig_base_path;
644
645
                                    if (isset($_SESSION['orig_base_foldername']) &&
646
                                        $_SESSION['orig_base_foldername'] != $new_base_foldername
647
                                    ) {
648
                                        unset($_SESSION['new_base_foldername']);
649
                                        unset($_SESSION['orig_base_foldername']);
650
                                        unset($_SESSION['new_base_path']);
651
                                    }
652
653
                                    $folder_exists = file_exists($new_base_path);
654
                                    if ($folder_exists) {
655
                                        // e.g: carpeta1 in session
656
                                        $_SESSION['orig_base_foldername'] = $new_base_foldername;
657
                                        $x = 0;
658
                                        while ($folder_exists) {
659
                                            $x = $x + 1;
660
                                            $new_base_foldername = $document_path[1].'_'.$x;
661
                                            $new_base_path = $orig_base_path.'_'.$x;
662
                                            if (isset($_SESSION['new_base_foldername']) &&
663
                                                $_SESSION['new_base_foldername'] == $new_base_foldername
664
                                            ) {
665
                                                break;
666
                                            }
667
                                            $folder_exists = file_exists($new_base_path);
668
                                        }
669
                                        $_SESSION['new_base_foldername'] = $new_base_foldername;
670
                                        $_SESSION['new_base_path'] = $new_base_path;
671
                                    }
672
673
                                    if (isset($_SESSION['new_base_foldername']) && isset($_SESSION['new_base_path'])) {
674
                                        $new_base_foldername = $_SESSION['new_base_foldername'];
675
                                        $new_base_path = $_SESSION['new_base_path'];
676
                                    }
677
678
                                    $dest_document_path = $new_base_path.'/'.$document_path[2]; // e.g: "/var/www/wiener/courses/CURSO4/document/carpeta1_1/subcarpeta1/collaborative.png"
679
                                    $basedir_dest_path = dirname($dest_document_path); // e.g: "/var/www/wiener/courses/CURSO4/document/carpeta1_1/subcarpeta1"
680
                                    $base_path_document = $course_path.$document_path[0]; // e.g: "/var/www/wiener/courses/CURSO4/document"
681
                                    $path_title = '/'.$new_base_foldername.'/'.$document_path[2];
682
683
                                    /*error_log("copy_folder_course_session");
684
                                    error_log("original: $orig_base_path");
685
                                    error_log($basedir_dest_path);
686
                                    error_log($document->title);*/
687
688
                                    copy_folder_course_session(
689
                                        $basedir_dest_path,
690
                                        $base_path_document,
691
                                        $session_id,
692
                                        $course_info,
693
                                        $document,
694
                                        $this->course_origin_id,
695
                                        $originalFolderNameList,
696
                                        $originalPath
697
                                    );
698
699
                                    if (file_exists($course_path.$document->path)) {
700
                                        copy($course_path.$document->path, $dest_document_path);
701
                                    }
702
703
                                    // Replace old course code with the new destination code see BT#1985
704
                                    if (file_exists($dest_document_path)) {
705
                                        $file_info = pathinfo($dest_document_path);
706
                                        if (in_array($file_info['extension'], ['html', 'htm'])) {
707
                                            $content = file_get_contents($dest_document_path);
708
                                            if (UTF8_CONVERT) {
709
                                                $content = utf8_encode($content);
710
                                            }
711
                                            $content = DocumentManager::replaceUrlWithNewCourseCode(
712
                                                $content,
713
                                                $this->course->code,
714
                                                $this->course->destination_path,
715
                                                $this->course->backup_path,
716
                                                $this->course->info['path']
717
                                            );
718
                                            file_put_contents($dest_document_path, $content);
719
                                            $this->fixEditorHtmlContent($dest_document_path, $webEditorCss);
720
                                        }
721
                                    }
722
723
                                    $title = basename($path_title);
724
                                    if (isset($originalFolderNameList[basename($path_title)])) {
725
                                        $title = $originalFolderNameList[basename($path_title)];
726
                                    }
727
728
                                    $params = [
729
                                        'path' => self::DBUTF8($path_title),
730
                                        'c_id' => $this->destination_course_id,
731
                                        'comment' => self::DBUTF8($document->comment),
732
                                        'title' => self::DBUTF8($title),
733
                                        'filetype' => self::DBUTF8($document->file_type),
734
                                        'size' => self::DBUTF8($document->size),
735
                                        'session_id' => $my_session_id,
736
                                    ];
737
738
                                    $document_id = Database::insert($table, $params);
739
740
                                    if ($document_id) {
741
                                        $sql = "UPDATE $table SET id = iid WHERE iid = $document_id";
742
                                        Database::query($sql);
743
744
                                        $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id;
745
746
                                        $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
747
                                        $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
748
                                        $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
749
                                        $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
750
751
                                        $insertUserId = $this->checkUserId($insertUserId);
752
                                        $toUserId = $this->checkUserId($toUserId, true);
753
                                        $groupInfo = $this->checkGroupId($toGroupId);
754
755
                                        api_item_property_update(
756
                                            $course_info,
757
                                            TOOL_DOCUMENT,
758
                                            $document_id,
759
                                            'DocumentAdded',
760
                                            $insertUserId,
761
                                            $groupInfo,
762
                                            $toUserId,
763
                                            null,
764
                                            null,
765
                                            $my_session_id
766
                                        );
767
                                    }
768
                                } else {
769
                                    if (file_exists($path.$document->path)) {
770
                                        copy($path.$document->path, $path.$new_file_name);
771
                                    }
772
                                    // Replace old course code with the new destination code see BT#1985
773
                                    if (file_exists($path.$new_file_name)) {
774
                                        $file_info = pathinfo($path.$new_file_name);
775
                                        if (in_array($file_info['extension'], ['html', 'htm'])) {
776
                                            $content = file_get_contents($path.$new_file_name);
777
                                            if (UTF8_CONVERT) {
778
                                                $content = utf8_encode($content);
779
                                            }
780
                                            $content = DocumentManager::replaceUrlWithNewCourseCode(
781
                                                $content,
782
                                                $this->course->code,
783
                                                $this->course->destination_path,
784
                                                $this->course->backup_path,
785
                                                $this->course->info['path']
786
                                            );
787
                                            file_put_contents($path.$new_file_name, $content);
788
                                            $this->fixEditorHtmlContent($path.$new_file_name, $webEditorCss);
789
                                        }
790
                                    }
791
792
                                    $params = [
793
                                        'path' => "/".self::DBUTF8escapestring(substr($new_file_name, 9)),
794
                                        'c_id' => $this->destination_course_id,
795
                                        'comment' => self::DBUTF8($document->comment),
796
                                        'title' => self::DBUTF8($document->title),
797
                                        'filetype' => self::DBUTF8($document->file_type),
798
                                        'size' => self::DBUTF8($document->size),
799
                                        'session_id' => $my_session_id,
800
                                    ];
801
802
                                    $document_id = Database::insert($table, $params);
803
804
                                    if ($document_id) {
805
                                        $sql = "UPDATE $table SET id = iid WHERE iid = $document_id";
806
                                        Database::query($sql);
807
808
                                        $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id;
809
810
                                        $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
811
                                        $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
812
                                        $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
813
                                        $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
814
815
                                        $insertUserId = $this->checkUserId($insertUserId);
816
                                        $toUserId = $this->checkUserId($toUserId, true);
817
                                        $groupInfo = $this->checkGroupId($toGroupId);
818
819
                                        api_item_property_update(
820
                                            $course_info,
821
                                            TOOL_DOCUMENT,
822
                                            $document_id,
823
                                            'DocumentAdded',
824
                                            $insertUserId,
825
                                            $groupInfo,
826
                                            $toUserId,
827
                                            null,
828
                                            null,
829
                                            $my_session_id
830
                                        );
831
                                    }
832
                                }
833
                            } else {
834
                                copy(
835
                                    $this->course->backup_path.'/'.$document->path,
836
                                    $path.$new_file_name
837
                                );
838
839
                                // Replace old course code with the new destination code see BT#1985
840
                                if (file_exists($path.$new_file_name)) {
841
                                    $file_info = pathinfo($path.$new_file_name);
842
                                    if (in_array($file_info['extension'], ['html', 'htm'])) {
843
                                        $content = file_get_contents($path.$new_file_name);
844
                                        if (UTF8_CONVERT) {
845
                                            $content = utf8_encode($content);
846
                                        }
847
                                        $content = DocumentManager::replaceUrlWithNewCourseCode(
848
                                            $content,
849
                                            $this->course->code,
850
                                            $this->course->destination_path,
851
                                            $this->course->backup_path,
852
                                            $this->course->info['path']
853
                                        );
854
                                        file_put_contents($path.$new_file_name, $content);
855
                                        $this->fixEditorHtmlContent($path.$new_file_name, $webEditorCss);
856
                                    }
857
                                }
858
859
                                $params = [
860
                                    'c_id' => $this->destination_course_id,
861
                                    'path' => "/".self::DBUTF8escapestring(substr($new_file_name, 9)),
862
                                    'comment' => self::DBUTF8($document->comment),
863
                                    'title' => self::DBUTF8($document->title),
864
                                    'filetype' => self::DBUTF8($document->file_type),
865
                                    'size' => self::DBUTF8($document->size),
866
                                    'session_id' => $my_session_id,
867
                                ];
868
869
                                $document_id = Database::insert($table, $params);
870
871
                                if ($document_id) {
872
                                    $sql = "UPDATE $table SET id = iid WHERE iid = $document_id";
873
                                    Database::query($sql);
874
                                    $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id;
875
876
                                    $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
877
                                    $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
878
                                    $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
879
                                    $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
880
881
                                    $insertUserId = $this->checkUserId($insertUserId);
882
                                    $toUserId = $this->checkUserId($toUserId, true);
883
                                    $groupInfo = $this->checkGroupId($toGroupId);
884
885
                                    api_item_property_update(
886
                                        $course_info,
887
                                        TOOL_DOCUMENT,
888
                                        $document_id,
889
                                        'DocumentAdded',
890
                                        $insertUserId,
891
                                        $groupInfo,
892
                                        $toUserId,
893
                                        null,
894
                                        null,
895
                                        $my_session_id
896
                                    );
897
                                }
898
                            }
899
                            break;
900
                    } // end switch
901
                } else {
902
                    // end if file exists
903
                    //make sure the source file actually exists
904
                    if (is_file($this->course->backup_path.'/'.$document->path) &&
905
                        is_readable($this->course->backup_path.'/'.$document->path) &&
906
                        is_dir(dirname($path.$document->path)) &&
907
                        is_writeable(dirname($path.$document->path))
908
                    ) {
909
                        copy(
910
                            $this->course->backup_path.'/'.$document->path,
911
                            $path.$document->path
912
                        );
913
914
                        // Replace old course code with the new destination code see BT#1985
915
                        if (file_exists($path.$document->path)) {
916
                            $file_info = pathinfo($path.$document->path);
917
                            if (isset($file_info['extension']) && in_array($file_info['extension'], ['html', 'htm'])) {
918
                                $content = file_get_contents($path.$document->path);
919
                                if (UTF8_CONVERT) {
920
                                    $content = utf8_encode($content);
921
                                }
922
                                $content = DocumentManager::replaceUrlWithNewCourseCode(
923
                                    $content,
924
                                    $this->course->code,
925
                                    $this->course->destination_path,
926
                                    $this->course->backup_path,
927
                                    $this->course->info['path']
928
                                );
929
                                file_put_contents($path.$document->path, $content);
930
                                $this->fixEditorHtmlContent($path.$document->path, $webEditorCss);
931
                            }
932
                        }
933
934
                        $params = [
935
                            'c_id' => $this->destination_course_id,
936
                            'path' => "/".self::DBUTF8(substr($document->path, 9)),
937
                            'comment' => self::DBUTF8($document->comment),
938
                            'title' => self::DBUTF8($document->title),
939
                            'filetype' => self::DBUTF8($document->file_type),
940
                            'size' => self::DBUTF8($document->size),
941
                            'session_id' => $my_session_id,
942
                            'readonly' => 0,
943
                        ];
944
945
                        $document_id = Database::insert($table, $params);
946
947
                        if ($document_id) {
948
                            $sql = "UPDATE $table SET id = iid WHERE iid = $document_id";
949
                            Database::query($sql);
950
951
                            $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id;
952
953
                            $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
954
                            $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
955
                            $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
956
                            $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
957
958
                            $insertUserId = $this->checkUserId($insertUserId);
959
                            $toUserId = $this->checkUserId($toUserId, true);
960
                            $groupInfo = $this->checkGroupId($toGroupId);
961
962
                            api_item_property_update(
963
                                $course_info,
964
                                TOOL_DOCUMENT,
965
                                $document_id,
966
                                'DocumentAdded',
967
                                $insertUserId,
968
                                $groupInfo,
969
                                $toUserId,
970
                                null,
971
                                null,
972
                                $my_session_id
973
                            );
974
                        }
975
                    } else {
976
                        // There was an error in checking existence and
977
                        // permissions for files to copy. Try to determine
978
                        // the exact issue
979
                        // Issue with origin document?
980
                        if (!is_file($this->course->backup_path.'/'.$document->path)) {
981
                            error_log(
982
                                'Course copy generated an ignorable error while trying to copy '.
983
                                $this->course->backup_path.'/'.$document->path.': origin file not found'
984
                            );
985
                        } elseif (!is_readable($this->course->backup_path.'/'.$document->path)) {
986
                            error_log(
987
                                'Course copy generated an ignorable error while trying to copy '.
988
                                $this->course->backup_path.'/'.$document->path.': origin file not readable'
989
                            );
990
                        }
991
                        // Issue with destination directories?
992
                        if (!is_dir(dirname($path.$document->path))) {
993
                            error_log(
994
                                'Course copy generated an ignorable error while trying to copy '.
995
                                $this->course->backup_path.'/'.$document->path.' to '.
996
                                dirname($path.$document->path).': destination directory not found'
997
                            );
998
                        }
999
                        if (!is_writeable(dirname($path.$document->path))) {
1000
                            error_log(
1001
                                'Course copy generated an ignorable error while trying to copy '.
1002
                                $this->course->backup_path.'/'.$document->path.' to '.
1003
                                dirname($path.$document->path).': destination directory not writable'
1004
                            );
1005
                        }
1006
                    }
1007
                } // end file doesn't exist
1008
            }
1009
1010
            // add image information for area questions
1011
            if (preg_match('/^quiz-.*$/', $document->title) &&
1012
                preg_match('/^document\/images\/.*$/', $document->path)
1013
            ) {
1014
                $this->course->resources[RESOURCE_DOCUMENT]['image_quiz'][$document->title] = [
1015
                    'path' => $document->path,
1016
                    'title' => $document->title,
1017
                    'source_id' => $document->source_id,
1018
                    'destination_id' => $document->destination_id,
1019
                ];
1020
            }
1021
        } // end for each
1022
1023
        // Delete sessions for the copy the new folder in session
1024
        unset($_SESSION['new_base_foldername']);
1025
        unset($_SESSION['orig_base_foldername']);
1026
        unset($_SESSION['new_base_path']);
1027
    }
1028
1029
    /**
1030
     * Restore scorm documents
1031
     * TODO @TODO check that the restore function with renaming doesn't break the scorm structure!
1032
     * see #7029.
1033
     */
1034
    public function restore_scorm_documents()
1035
    {
1036
        $perm = api_get_permissions_for_new_directories();
1037
        if ($this->course->has_resources(RESOURCE_SCORM)) {
1038
            $resources = $this->course->resources;
1039
            foreach ($resources[RESOURCE_SCORM] as $document) {
1040
                $path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/';
1041
                @mkdir(dirname($path.$document->path), $perm, true);
1042
                if (file_exists($path.$document->path)) {
1043
                    switch ($this->file_option) {
1044
                        case FILE_OVERWRITE:
1045
                            rmdirr($path.$document->path);
1046
                            copyDirTo(
1047
                                $this->course->backup_path.'/'.$document->path,
1048
                                $path.$document->path,
1049
                                false
1050
                            );
1051
                            break;
1052
                        case FILE_SKIP:
1053
                            break;
1054
                        case FILE_RENAME:
1055
                            $i = 1;
1056
                            $ext = explode('.', basename($document->path));
1057
                            if (count($ext) > 1) {
1058
                                $ext = array_pop($ext);
1059
                                $file_name_no_ext = substr($document->path, 0, -(strlen($ext) + 1));
1060
                                $ext = '.'.$ext;
1061
                            } else {
1062
                                $ext = '';
1063
                                $file_name_no_ext = $document->path;
1064
                            }
1065
1066
                            $new_file_name = $file_name_no_ext.'_'.$i.$ext;
1067
                            $file_exists = file_exists($path.$new_file_name);
1068
1069
                            while ($file_exists) {
1070
                                $i++;
1071
                                $new_file_name = $file_name_no_ext.'_'.$i.$ext;
1072
                                $file_exists = file_exists($path.$new_file_name);
1073
                            }
1074
1075
                            rename(
1076
                                $this->course->backup_path.'/'.$document->path,
1077
                                $this->course->backup_path.'/'.$new_file_name
1078
                            );
1079
                            copyDirTo(
1080
                                $this->course->backup_path.'/'.$new_file_name,
1081
                                $path.dirname($new_file_name),
1082
                                false
1083
                            );
1084
                            rename(
1085
                                $this->course->backup_path.'/'.$new_file_name,
1086
                                $this->course->backup_path.'/'.$document->path
1087
                            );
1088
                            break;
1089
                    } // end switch
1090
                } else {
1091
                    // end if file exists
1092
                    copyDirTo(
1093
                        $this->course->backup_path.'/'.$document->path,
1094
                        $path.$document->path,
1095
                        false
1096
                    );
1097
                }
1098
            } // end for each
1099
        }
1100
    }
1101
1102
    /**
1103
     * Restore forums.
1104
     *
1105
     * @param int $sessionId
1106
     */
1107
    public function restore_forums($sessionId = 0)
1108
    {
1109
        if ($this->course->has_resources(RESOURCE_FORUM)) {
1110
            $sessionId = (int) $sessionId;
1111
            $table_forum = Database::get_course_table(TABLE_FORUM);
1112
            $resources = $this->course->resources;
1113
            foreach ($resources[RESOURCE_FORUM] as $id => $forum) {
1114
                $params = (array) $forum->obj;
1115
                $cat_id = '';
1116
                if (isset($this->course->resources[RESOURCE_FORUMCATEGORY]) &&
1117
                    isset($this->course->resources[RESOURCE_FORUMCATEGORY][$params['forum_category']])) {
1118
                    if ($this->course->resources[RESOURCE_FORUMCATEGORY][$params['forum_category']]->destination_id == -1) {
1119
                        $cat_id = $this->restore_forum_category($params['forum_category'], $sessionId);
1120
                    } else {
1121
                        $cat_id = $this->course->resources[RESOURCE_FORUMCATEGORY][$params['forum_category']]->destination_id;
1122
                    }
1123
                }
1124
1125
                $params = self::DBUTF8_array($params);
1126
                $params['c_id'] = $this->destination_course_id;
1127
                $params['forum_category'] = $cat_id;
1128
                $params['session_id'] = $sessionId;
1129
                $params['start_time'] = isset($params['start_time']) && $params['start_time'] === '0000-00-00 00:00:00' ? null : $params['start_time'];
1130
                $params['end_time'] = isset($params['end_time']) && $params['end_time'] === '0000-00-00 00:00:00' ? null : $params['end_time'];
1131
                $params['forum_id'] = 0;
1132
                unset($params['iid']);
1133
1134
                $params['forum_comment'] = DocumentManager::replaceUrlWithNewCourseCode(
1135
                    $params['forum_comment'],
1136
                    $this->course->code,
1137
                    $this->course->destination_path,
1138
                    $this->course->backup_path,
1139
                    $this->course->info['path']
1140
                );
1141
1142
                if (!empty($params['forum_image'])) {
1143
                    $original_forum_image = $this->course->path.'upload/forum/images/'.$params['forum_image'];
1144
                    if (file_exists($original_forum_image)) {
1145
                        $new_forum_image = api_get_path(SYS_COURSE_PATH).
1146
                            $this->destination_course_info['path'].'/upload/forum/images/'.$params['forum_image'];
1147
                        @copy($original_forum_image, $new_forum_image);
1148
                    }
1149
                }
1150
1151
                $new_id = Database::insert($table_forum, $params);
1152
1153
                if ($new_id) {
1154
                    $sql = "UPDATE $table_forum SET forum_id = iid WHERE iid = $new_id";
1155
                    Database::query($sql);
1156
1157
                    api_item_property_update(
1158
                        $this->destination_course_info,
1159
                        TOOL_FORUM,
1160
                        $new_id,
1161
                        'ForumUpdated',
1162
                        api_get_user_id(),
1163
                        null,
1164
                        null,
1165
                        null,
1166
                        null,
1167
                        $sessionId
1168
                    );
1169
1170
                    $this->course->resources[RESOURCE_FORUM][$id]->destination_id = $new_id;
1171
                    $forum_topics = 0;
1172
                    if (isset($this->course->resources[RESOURCE_FORUMTOPIC]) &&
1173
                        is_array($this->course->resources[RESOURCE_FORUMTOPIC])
1174
                    ) {
1175
                        foreach ($this->course->resources[RESOURCE_FORUMTOPIC] as $topic_id => $topic) {
1176
                            if ($topic->obj->forum_id == $id) {
1177
                                $this->restore_topic($topic_id, $new_id, $sessionId);
1178
                                $forum_topics++;
1179
                            }
1180
                        }
1181
                    }
1182
                    if ($forum_topics > 0) {
1183
                        $sql = "UPDATE ".$table_forum." SET forum_threads = ".$forum_topics."
1184
                                WHERE c_id = {$this->destination_course_id} AND forum_id = ".(int) $new_id;
1185
                        Database::query($sql);
1186
                    }
1187
                }
1188
            }
1189
        }
1190
    }
1191
1192
    /**
1193
     * Restore forum-categories.
1194
     */
1195
    public function restore_forum_category($my_id = null, $sessionId = 0)
1196
    {
1197
        $forum_cat_table = Database::get_course_table(TABLE_FORUM_CATEGORY);
1198
        $resources = $this->course->resources;
1199
        $sessionId = (int) $sessionId;
1200
        if (!empty($resources[RESOURCE_FORUMCATEGORY])) {
1201
            foreach ($resources[RESOURCE_FORUMCATEGORY] as $id => $forum_cat) {
1202
                if (!empty($my_id)) {
1203
                    if ($my_id != $id) {
1204
                        continue;
1205
                    }
1206
                }
1207
                if ($forum_cat && !$forum_cat->is_restored()) {
1208
                    $params = (array) $forum_cat->obj;
1209
                    $params['c_id'] = $this->destination_course_id;
1210
                    $params['cat_comment'] = DocumentManager::replaceUrlWithNewCourseCode(
1211
                        $params['cat_comment'],
1212
                        $this->course->code,
1213
                        $this->course->destination_path,
1214
                        $this->course->backup_path,
1215
                        $this->course->info['path']
1216
                    );
1217
                    $params['session_id'] = $sessionId;
1218
                    $params['cat_id'] = 0;
1219
                    unset($params['iid']);
1220
1221
                    $params = self::DBUTF8_array($params);
1222
                    $new_id = Database::insert($forum_cat_table, $params);
1223
1224
                    if ($new_id) {
1225
                        $sql = "UPDATE $forum_cat_table SET cat_id = iid WHERE iid = $new_id";
1226
                        Database::query($sql);
1227
1228
                        api_item_property_update(
1229
                            $this->destination_course_info,
1230
                            TOOL_FORUM_CATEGORY,
1231
                            $new_id,
1232
                            'ForumCategoryUpdated',
1233
                            api_get_user_id(),
1234
                            null,
1235
                            null,
1236
                            null,
1237
                            null,
1238
                            $sessionId
1239
                        );
1240
                        $this->course->resources[RESOURCE_FORUMCATEGORY][$id]->destination_id = $new_id;
1241
                    }
1242
1243
                    if (!empty($my_id)) {
1244
                        return $new_id;
1245
                    }
1246
                }
1247
            }
1248
        }
1249
    }
1250
1251
    /**
1252
     * Restore a forum-topic.
1253
     *
1254
     * @param false|string $forum_id
1255
     *
1256
     * @return int
1257
     */
1258
    public function restore_topic($thread_id, $forum_id, $sessionId = 0)
1259
    {
1260
        $table = Database::get_course_table(TABLE_FORUM_THREAD);
1261
        $topic = $this->course->resources[RESOURCE_FORUMTOPIC][$thread_id];
1262
1263
        $sessionId = (int) $sessionId;
1264
        $params = (array) $topic->obj;
1265
1266
        $params = self::DBUTF8_array($params);
1267
        $params['c_id'] = $this->destination_course_id;
1268
        $params['forum_id'] = $forum_id;
1269
        $params['thread_poster_id'] = $this->first_teacher_id;
1270
        $params['thread_date'] = api_get_utc_datetime();
1271
        $params['thread_close_date'] = null;
1272
        $params['thread_last_post'] = 0;
1273
        $params['thread_replies'] = 0;
1274
        $params['thread_views'] = 0;
1275
        $params['session_id'] = $sessionId;
1276
        $params['thread_id'] = 0;
1277
1278
        unset($params['iid']);
1279
1280
        $new_id = Database::insert($table, $params);
1281
1282
        if ($new_id) {
1283
            $sql = "UPDATE $table SET thread_id = iid WHERE iid = $new_id";
1284
            Database::query($sql);
1285
1286
            api_item_property_update(
1287
                $this->destination_course_info,
1288
                TOOL_FORUM_THREAD,
1289
                $new_id,
1290
                'ThreadAdded',
1291
                api_get_user_id(),
1292
                0,
1293
                0,
1294
                null,
1295
                null,
1296
                $sessionId
1297
            );
1298
1299
            $this->course->resources[RESOURCE_FORUMTOPIC][$thread_id]->destination_id = $new_id;
1300
            $topic_replies = -1;
1301
1302
            foreach ($this->course->resources[RESOURCE_FORUMPOST] as $post_id => $post) {
1303
                if ($post->obj->thread_id == $thread_id) {
1304
                    $topic_replies++;
1305
                    $this->restore_post($post_id, $new_id, $forum_id, $sessionId);
1306
                }
1307
            }
1308
        }
1309
1310
        return $new_id;
1311
    }
1312
1313
    /**
1314
     * Restore a forum-post.
1315
     *
1316
     * @TODO Restore tree-structure of posts. For example: attachments to posts.
1317
     *
1318
     * @param false|string $topic_id
1319
     *
1320
     * @return int
1321
     */
1322
    public function restore_post($id, $topic_id, $forum_id, $sessionId = 0)
1323
    {
1324
        $table_post = Database::get_course_table(TABLE_FORUM_POST);
1325
        $post = $this->course->resources[RESOURCE_FORUMPOST][$id];
1326
        $params = (array) $post->obj;
1327
        $params['c_id'] = $this->destination_course_id;
1328
        $params['forum_id'] = $forum_id;
1329
        $params['thread_id'] = $topic_id;
1330
        $params['poster_id'] = $this->first_teacher_id;
1331
        $params['post_date'] = api_get_utc_datetime();
1332
        $params['post_id'] = 0;
1333
        unset($params['iid']);
1334
1335
        $params['post_text'] = DocumentManager::replaceUrlWithNewCourseCode(
1336
            $params['post_text'],
1337
            $this->course->code,
1338
            $this->course->destination_path,
1339
            $this->course->backup_path,
1340
            $this->course->info['path']
1341
        );
1342
        $new_id = Database::insert($table_post, $params);
1343
1344
        if ($new_id) {
1345
            $sql = "UPDATE $table_post SET post_id = iid WHERE iid = $new_id";
1346
            Database::query($sql);
1347
1348
            api_item_property_update(
1349
                $this->destination_course_info,
1350
                TOOL_FORUM_POST,
1351
                $new_id,
1352
                'PostAdded',
1353
                api_get_user_id(),
1354
                0,
1355
                0,
1356
                null,
1357
                null,
1358
                $sessionId
1359
            );
1360
            $this->course->resources[RESOURCE_FORUMPOST][$id]->destination_id = $new_id;
1361
        }
1362
1363
        return $new_id;
1364
    }
1365
1366
    /**
1367
     * Restore links.
1368
     */
1369
    public function restore_links($session_id = 0)
1370
    {
1371
        if ($this->course->has_resources(RESOURCE_LINK)) {
1372
            $link_table = Database::get_course_table(TABLE_LINK);
1373
            $resources = $this->course->resources;
1374
1375
            foreach ($resources[RESOURCE_LINK] as $oldLinkId => $link) {
1376
                $cat_id = (int) $this->restore_link_category($link->category_id, $session_id);
1377
                $sql = "SELECT MAX(display_order)
1378
                        FROM $link_table
1379
                        WHERE
1380
                            c_id = ".$this->destination_course_id." AND
1381
                            category_id='".$cat_id."'";
1382
                $result = Database::query($sql);
1383
                [$max_order] = Database::fetch_array($result);
1384
1385
                $params = [];
1386
                if (!empty($session_id)) {
1387
                    $params['session_id'] = $session_id;
1388
                }
1389
1390
                $params['c_id'] = $this->destination_course_id;
1391
                $params['url'] = self::DBUTF8($link->url);
1392
                $params['title'] = self::DBUTF8($link->title);
1393
                $params['description'] = self::DBUTF8($link->description);
1394
                $params['category_id'] = $cat_id;
1395
                $params['on_homepage'] = $link->on_homepage;
1396
                $params['display_order'] = $max_order + 1;
1397
                $params['target'] = $link->target;
1398
1399
                $id = Database::insert($link_table, $params);
1400
1401
                if ($id) {
1402
                    $sql = "UPDATE $link_table SET id = iid WHERE iid = $id";
1403
                    Database::query($sql);
1404
1405
                    api_item_property_update(
1406
                        $this->destination_course_info,
1407
                        TOOL_LINK,
1408
                        $id,
1409
                        'LinkAdded',
1410
                        api_get_user_id(),
1411
                        null,
1412
                        null,
1413
                        null,
1414
                        null,
1415
                        $session_id
1416
                    );
1417
1418
                    if (!isset($this->course->resources[RESOURCE_LINK][$oldLinkId])) {
1419
                        $this->course->resources[RESOURCE_LINK][$oldLinkId] = new stdClass();
1420
                    }
1421
                    $this->course->resources[RESOURCE_LINK][$oldLinkId]->destination_id = $id;
1422
                }
1423
            }
1424
        }
1425
    }
1426
1427
    /**
1428
     * Restore a link-category.
1429
     *
1430
     * @param int
1431
     * @param int
1432
     *
1433
     * @return bool
1434
     */
1435
    public function restore_link_category($id, $sessionId = 0)
1436
    {
1437
        $params = [];
1438
        $sessionId = (int) $sessionId;
1439
        if (!empty($sessionId)) {
1440
            $params['session_id'] = $sessionId;
1441
        }
1442
1443
        if ($id == 0) {
1444
            return 0;
1445
        }
1446
        $link_cat_table = Database::get_course_table(TABLE_LINK_CATEGORY);
1447
        $resources = $this->course->resources;
1448
        $link_cat = $resources[RESOURCE_LINKCATEGORY][$id];
1449
        if (is_object($link_cat) && !$link_cat->is_restored()) {
1450
            $sql = "SELECT MAX(display_order) FROM  $link_cat_table
1451
                    WHERE c_id = ".$this->destination_course_id;
1452
            $result = Database::query($sql);
1453
            [$orderMax] = Database::fetch_array($result, 'NUM');
1454
            $display_order = $orderMax + 1;
1455
1456
            $params['c_id'] = $this->destination_course_id;
1457
            $params['category_title'] = self::DBUTF8($link_cat->title);
1458
            $params['description'] = self::DBUTF8($link_cat->description);
1459
            $params['display_order'] = $display_order;
1460
            $new_id = Database::insert($link_cat_table, $params);
1461
1462
            if ($new_id) {
1463
                $sql = "UPDATE $link_cat_table
1464
                        SET id = iid
1465
                        WHERE iid = $new_id";
1466
                Database::query($sql);
1467
1468
                $courseInfo = api_get_course_info_by_id($this->destination_course_id);
1469
                api_item_property_update(
1470
                    $courseInfo,
1471
                    TOOL_LINK_CATEGORY,
1472
                    $new_id,
1473
                    'LinkCategoryAdded',
1474
                    api_get_user_id(),
1475
                    null,
1476
                    null,
1477
                    null,
1478
                    null,
1479
                    $sessionId
1480
                );
1481
                api_set_default_visibility(
1482
                    $new_id,
1483
                    TOOL_LINK_CATEGORY,
1484
                    0,
1485
                    $courseInfo,
1486
                    $sessionId
1487
                );
1488
            }
1489
1490
            $this->course->resources[RESOURCE_LINKCATEGORY][$id]->destination_id = $new_id;
1491
1492
            return $new_id;
1493
        }
1494
1495
        return $this->course->resources[RESOURCE_LINKCATEGORY][$id]->destination_id;
1496
    }
1497
1498
    /**
1499
     * Restore tool intro.
1500
     *
1501
     * @param int
1502
     */
1503
    public function restore_tool_intro($sessionId = 0)
1504
    {
1505
        if ($this->course->has_resources(RESOURCE_TOOL_INTRO)) {
1506
            $sessionId = (int) $sessionId;
1507
            $tool_intro_table = Database::get_course_table(TABLE_TOOL_INTRO);
1508
            $resources = $this->course->resources;
1509
            foreach ($resources[RESOURCE_TOOL_INTRO] as $id => $tool_intro) {
1510
                $sql = "DELETE FROM $tool_intro_table
1511
                        WHERE
1512
                            c_id = ".$this->destination_course_id." AND
1513
                            id='".self::DBUTF8escapestring($tool_intro->id)."'";
1514
                Database::query($sql);
1515
1516
                $tool_intro->intro_text = DocumentManager::replaceUrlWithNewCourseCode(
1517
                    $tool_intro->intro_text,
1518
                    $this->course->code,
1519
                    $this->course->destination_path,
1520
                    $this->course->backup_path,
1521
                    $this->course->info['path']
1522
                );
1523
1524
                $params = [
1525
                    'c_id' => $this->destination_course_id,
1526
                    'id' => ($tool_intro->id === false ? '' : self::DBUTF8($tool_intro->id)),
1527
                    'intro_text' => self::DBUTF8($tool_intro->intro_text),
1528
                    'session_id' => $sessionId,
1529
                ];
1530
1531
                $id = Database::insert($tool_intro_table, $params);
1532
                if ($id) {
1533
                    if (!isset($this->course->resources[RESOURCE_TOOL_INTRO][$id])) {
1534
                        $this->course->resources[RESOURCE_TOOL_INTRO][$id] = new stdClass();
1535
                    }
1536
1537
                    $this->course->resources[RESOURCE_TOOL_INTRO][$id]->destination_id = $id;
1538
                }
1539
            }
1540
        }
1541
    }
1542
1543
    /**
1544
     * Restore events.
1545
     *
1546
     * @param int
1547
     */
1548
    public function restore_events($sessionId = 0)
1549
    {
1550
        if ($this->course->has_resources(RESOURCE_EVENT)) {
1551
            $sessionId = (int) $sessionId;
1552
            $table = Database::get_course_table(TABLE_AGENDA);
1553
            $resources = $this->course->resources;
1554
            foreach ($resources[RESOURCE_EVENT] as $id => $event) {
1555
                // check resources inside html from ckeditor tool and copy correct urls into recipient course
1556
                $event->content = DocumentManager::replaceUrlWithNewCourseCode(
1557
                    $event->content,
1558
                    $this->course->code,
1559
                    $this->course->destination_path,
1560
                    $this->course->backup_path,
1561
                    $this->course->info['path']
1562
                );
1563
1564
                $params = [
1565
                    'c_id' => $this->destination_course_id,
1566
                    'title' => self::DBUTF8($event->title),
1567
                    'content' => ($event->content === false ? '' : self::DBUTF8($event->content)),
1568
                    'all_day' => $event->all_day,
1569
                    'start_date' => $event->start_date,
1570
                    'end_date' => $event->end_date,
1571
                    'session_id' => $sessionId,
1572
                ];
1573
                $new_event_id = Database::insert($table, $params);
1574
1575
                if ($new_event_id) {
1576
                    $sql = "UPDATE $table SET id = iid WHERE iid = $new_event_id";
1577
                    Database::query($sql);
1578
1579
                    if (!isset($this->course->resources[RESOURCE_EVENT][$id])) {
1580
                        $this->course->resources[RESOURCE_EVENT][$id] = new stdClass();
1581
                    }
1582
                    $this->course->resources[RESOURCE_EVENT][$id]->destination_id = $new_event_id;
1583
                }
1584
1585
                // Copy event attachment
1586
                $origin_path = $this->course->backup_path.'/upload/calendar/';
1587
                $destination_path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/upload/calendar/';
1588
1589
                if (!empty($this->course->orig)) {
1590
                    $table_attachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
1591
                    $sql = 'SELECT path, comment, size, filename
1592
                            FROM '.$table_attachment.'
1593
                            WHERE c_id = '.$this->destination_course_id.' AND agenda_id = '.$id;
1594
                    $attachment_event = Database::query($sql);
1595
                    $attachment_event = Database::fetch_object($attachment_event);
1596
1597
                    if (file_exists($origin_path.$attachment_event->path) &&
1598
                        !is_dir($origin_path.$attachment_event->path)
1599
                    ) {
1600
                        $new_filename = uniqid(''); //ass seen in the add_agenda_attachment_file() function in agenda.inc.php
1601
                        $copy_result = copy(
1602
                            $origin_path.$attachment_event->path,
1603
                            $destination_path.$new_filename
1604
                        );
1605
                        //$copy_result = true;
1606
                        if ($copy_result) {
1607
                            $table_attachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
1608
1609
                            $params = [
1610
                                'c_id' => $this->destination_course_id,
1611
                                'path' => self::DBUTF8($new_filename),
1612
                                'comment' => self::DBUTF8($attachment_event->comment),
1613
                                'size' => isset($attachment_event->size) ? $attachment_event->size : '',
1614
                                'filename' => isset($attachment_event->filename) ? $attachment_event->filename : '',
1615
                                'agenda_id' => $new_event_id,
1616
                            ];
1617
                            $id = Database::insert($table_attachment, $params);
1618
                            if ($id) {
1619
                                $sql = "UPDATE $table_attachment SET id = iid WHERE iid = $id";
1620
                                Database::query($sql);
1621
                            }
1622
                        }
1623
                    }
1624
                } else {
1625
                    // get the info of the file
1626
                    if (!empty($event->attachment_path) &&
1627
                        is_file($origin_path.$event->attachment_path) &&
1628
                        is_readable($origin_path.$event->attachment_path)
1629
                    ) {
1630
                        $new_filename = uniqid(''); //ass seen in the add_agenda_attachment_file() function in agenda.inc.php
1631
                        $copy_result = copy(
1632
                            $origin_path.$event->attachment_path,
1633
                            $destination_path.$new_filename
1634
                        );
1635
                        if ($copy_result) {
1636
                            $table_attachment = Database::get_course_table(TABLE_AGENDA_ATTACHMENT);
1637
1638
                            $params = [
1639
                                'c_id' => $this->destination_course_id,
1640
                                'path' => self::DBUTF8($new_filename),
1641
                                'comment' => self::DBUTF8($event->attachment_comment),
1642
                                'size' => isset($event->size) ? $event->size : '',
1643
                                'filename' => isset($event->filename) ? $event->filename : '',
1644
                                'agenda_id' => $new_event_id,
1645
                            ];
1646
                            $id = Database::insert($table_attachment, $params);
1647
1648
                            if ($id) {
1649
                                $sql = "UPDATE $table_attachment SET id = iid WHERE iid = $id";
1650
                                Database::query($sql);
1651
                            }
1652
                        }
1653
                    }
1654
                }
1655
            }
1656
        }
1657
    }
1658
1659
    /**
1660
     * Restore course-description.
1661
     *
1662
     * @param int
1663
     */
1664
    public function restore_course_descriptions($session_id = 0)
1665
    {
1666
        if ($this->course->has_resources(RESOURCE_COURSEDESCRIPTION)) {
1667
            $table = Database::get_course_table(TABLE_COURSE_DESCRIPTION);
1668
            $resources = $this->course->resources;
1669
            foreach ($resources[RESOURCE_COURSEDESCRIPTION] as $id => $cd) {
1670
                $courseDescription = (array) $cd;
1671
1672
                $content = isset($courseDescription['content']) ? $courseDescription['content'] : '';
1673
                $descriptionType = isset($courseDescription['description_type']) ? $courseDescription['description_type'] : '';
1674
                $title = isset($courseDescription['title']) ? $courseDescription['title'] : '';
1675
1676
                // check resources inside html from ckeditor tool and copy correct urls into recipient course
1677
                $description_content = DocumentManager::replaceUrlWithNewCourseCode(
1678
                    $content,
1679
                    $this->course->code,
1680
                    $this->course->destination_path,
1681
                    $this->course->backup_path,
1682
                    $this->course->info['path']
1683
                );
1684
1685
                $params = [];
1686
                $session_id = (int) $session_id;
1687
                $params['session_id'] = $session_id;
1688
                $params['c_id'] = $this->destination_course_id;
1689
                $params['description_type'] = self::DBUTF8($descriptionType);
1690
                $params['title'] = self::DBUTF8($title);
1691
                $params['content'] = ($description_content === false ? '' : self::DBUTF8($description_content));
1692
                $params['progress'] = 0;
1693
1694
                $id = Database::insert($table, $params);
1695
                if ($id) {
1696
                    $sql = "UPDATE $table SET id = iid WHERE iid = $id";
1697
                    Database::query($sql);
1698
1699
                    if (!isset($this->course->resources[RESOURCE_COURSEDESCRIPTION][$id])) {
1700
                        $this->course->resources[RESOURCE_COURSEDESCRIPTION][$id] = new stdClass();
1701
                    }
1702
                    $this->course->resources[RESOURCE_COURSEDESCRIPTION][$id]->destination_id = $id;
1703
                }
1704
            }
1705
        }
1706
    }
1707
1708
    /**
1709
     * Restore announcements.
1710
     *
1711
     * @param int
1712
     */
1713
    public function restore_announcements($sessionId = 0)
1714
    {
1715
        if ($this->course->has_resources(RESOURCE_ANNOUNCEMENT)) {
1716
            $sessionId = (int) $sessionId;
1717
            $table = Database::get_course_table(TABLE_ANNOUNCEMENT);
1718
            $resources = $this->course->resources;
1719
            foreach ($resources[RESOURCE_ANNOUNCEMENT] as $id => $announcement) {
1720
                // check resources inside html from ckeditor tool and copy correct urls into recipient course
1721
                $announcement->content = DocumentManager::replaceUrlWithNewCourseCode(
1722
                    $announcement->content,
1723
                    $this->course->code,
1724
                    $this->course->destination_path,
1725
                    $this->course->backup_path,
1726
                    $this->course->info['path']
1727
                );
1728
1729
                $params = [
1730
                    'c_id' => $this->destination_course_id,
1731
                    'title' => self::DBUTF8($announcement->title),
1732
                    'content' => ($announcement->content === false ? '' : self::DBUTF8($announcement->content)),
1733
                    'end_date' => $announcement->date,
1734
                    'display_order' => $announcement->display_order,
1735
                    'email_sent' => $announcement->email_sent,
1736
                    'session_id' => $sessionId,
1737
                ];
1738
1739
                $new_announcement_id = Database::insert($table, $params);
1740
1741
                if ($new_announcement_id) {
1742
                    $sql = "UPDATE $table SET id = iid WHERE iid = $new_announcement_id";
1743
                    Database::query($sql);
1744
1745
                    if (!isset($this->course->resources[RESOURCE_ANNOUNCEMENT][$id])) {
1746
                        $this->course->resources[RESOURCE_ANNOUNCEMENT][$id] = new stdClass();
1747
                    }
1748
                    $this->course->resources[RESOURCE_ANNOUNCEMENT][$id]->destination_id = $new_announcement_id;
1749
                }
1750
1751
                $origin_path = $this->course->backup_path.'/upload/announcements/';
1752
                $destination_path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/upload/announcements/';
1753
1754
                // Copy announcement attachment file
1755
                if (!empty($this->course->orig)) {
1756
                    $table_attachment = Database::get_course_table(TABLE_ANNOUNCEMENT_ATTACHMENT);
1757
                    $sql = 'SELECT path, comment, size, filename
1758
                            FROM '.$table_attachment.'
1759
                            WHERE
1760
                                c_id = '.$this->destination_course_id.' AND
1761
                                announcement_id = '.$id;
1762
                    $attachment_event = Database::query($sql);
1763
                    $attachment_event = Database::fetch_object($attachment_event);
1764
1765
                    if (file_exists($origin_path.$attachment_event->path) &&
1766
                        !is_dir($origin_path.$attachment_event->path)
1767
                    ) {
1768
                        $new_filename = uniqid(''); //ass seen in the add_agenda_attachment_file() function in agenda.inc.php
1769
                        $copy_result = copy(
1770
                            $origin_path.$attachment_event->path,
1771
                            $destination_path.$new_filename
1772
                        );
1773
1774
                        if ($copy_result) {
1775
                            $table_attachment = Database::get_course_table(TABLE_ANNOUNCEMENT_ATTACHMENT);
1776
1777
                            $params = [
1778
                                'c_id' => $this->destination_course_id,
1779
                                'path' => self::DBUTF8($new_filename),
1780
                                'comment' => self::DBUTF8($attachment_event->comment),
1781
                                'size' => $attachment_event->size,
1782
                                'filename' => $attachment_event->filename,
1783
                                'announcement_id' => $new_announcement_id,
1784
                            ];
1785
1786
                            $attachmentId = Database::insert($table_attachment, $params);
1787
1788
                            if ($attachmentId) {
1789
                                $sql = "UPDATE $table_attachment SET id = iid WHERE iid = $attachmentId";
1790
                                Database::query($sql);
1791
                            }
1792
                        }
1793
                    }
1794
                } else {
1795
                    // get the info of the file
1796
                    if (!empty($announcement->attachment_path) &&
1797
                        is_file($origin_path.$announcement->attachment_path) &&
1798
                        is_readable($origin_path.$announcement->attachment_path)
1799
                    ) {
1800
                        $new_filename = uniqid(''); //ass seen in the add_agenda_attachment_file() function in agenda.inc.php
1801
                        $copy_result = copy($origin_path.$announcement->attachment_path, $destination_path.$new_filename);
1802
1803
                        if ($copy_result) {
1804
                            $table_attachment = Database::get_course_table(TABLE_ANNOUNCEMENT_ATTACHMENT);
1805
1806
                            $params = [
1807
                                'c_id' => $this->destination_course_id,
1808
                                'path' => self::DBUTF8($new_filename),
1809
                                'comment' => self::DBUTF8($announcement->attachment_comment),
1810
                                'size' => $announcement->attachment_size,
1811
                                'filename' => $announcement->attachment_filename,
1812
                                'announcement_id' => $new_announcement_id,
1813
                            ];
1814
1815
                            $attachmentId = Database::insert($table_attachment, $params);
1816
1817
                            if ($attachmentId) {
1818
                                $sql = "UPDATE $table_attachment SET id = iid WHERE iid = $attachmentId";
1819
                                Database::query($sql);
1820
                            }
1821
                        }
1822
                    }
1823
                }
1824
            }
1825
        }
1826
    }
1827
1828
    /**
1829
     * Restore Quiz.
1830
     *
1831
     * @param int  $session_id
1832
     * @param bool $respect_base_content
1833
     */
1834
    public function restore_quizzes(
1835
        $session_id = 0,
1836
        $respect_base_content = false
1837
    ) {
1838
        if ($this->course->has_resources(RESOURCE_QUIZ)) {
1839
            $table_qui = Database::get_course_table(TABLE_QUIZ_TEST);
1840
            $table_rel = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
1841
            $table_doc = Database::get_course_table(TABLE_DOCUMENT);
1842
            $resources = $this->course->resources;
1843
1844
            foreach ($resources[RESOURCE_QUIZ] as $id => $quiz) {
1845
                if (isset($quiz->obj)) {
1846
                    // For new imports
1847
                    $quiz = $quiz->obj;
1848
                } else {
1849
                    // For backward compatibility
1850
                    $quiz->obj = $quiz;
1851
                }
1852
1853
                $doc = '';
1854
                if (!empty($quiz->sound)) {
1855
                    if (isset($this->course->resources[RESOURCE_DOCUMENT][$quiz->sound]) &&
1856
                        $this->course->resources[RESOURCE_DOCUMENT][$quiz->sound]->is_restored()) {
1857
                        $sql = "SELECT path FROM $table_doc
1858
                                WHERE
1859
                                    c_id = ".$this->destination_course_id." AND
1860
                                    id = ".$resources[RESOURCE_DOCUMENT][$quiz->sound]->destination_id;
1861
                        $doc = Database::query($sql);
1862
                        $doc = Database::fetch_object($doc);
1863
                        $doc = str_replace('/audio/', '', $doc->path);
1864
                    }
1865
                }
1866
1867
                if ($id != -1) {
1868
                    // check resources inside html from ckeditor tool and copy correct urls into recipient course
1869
                    $quiz->description = DocumentManager::replaceUrlWithNewCourseCode(
1870
                        $quiz->description,
1871
                        $this->course->code,
1872
                        $this->course->destination_path,
1873
                        $this->course->backup_path,
1874
                        $this->course->info['path']
1875
                    );
1876
1877
                    $quiz->start_time = $quiz->start_time == '0000-00-00 00:00:00' ? null : $quiz->start_time;
1878
                    $quiz->end_time = $quiz->end_time == '0000-00-00 00:00:00' ? null : $quiz->end_time;
1879
1880
                    global $_custom;
1881
                    if (isset($_custom['exercises_clean_dates_when_restoring']) &&
1882
                        $_custom['exercises_clean_dates_when_restoring']
1883
                    ) {
1884
                        $quiz->start_time = null;
1885
                        $quiz->end_time = null;
1886
                    }
1887
1888
                    $params = [
1889
                        'c_id' => $this->destination_course_id,
1890
                        'title' => self::DBUTF8($quiz->title),
1891
                        'description' => ($quiz->description === false ? '' : self::DBUTF8($quiz->description)),
1892
                        'type' => isset($quiz->quiz_type) ? (int) $quiz->quiz_type : $quiz->type,
1893
                        'random' => (int) $quiz->random,
1894
                        'active' => $quiz->active,
1895
                        'sound' => self::DBUTF8($doc),
1896
                        'max_attempt' => (int) $quiz->max_attempt,
1897
                        'results_disabled' => (int) $quiz->results_disabled,
1898
                        'access_condition' => $quiz->access_condition,
1899
                        'pass_percentage' => $quiz->pass_percentage,
1900
                        'feedback_type' => (int) $quiz->feedback_type,
1901
                        'random_answers' => (int) $quiz->random_answers,
1902
                        'random_by_category' => (int) $quiz->random_by_category,
1903
                        'review_answers' => (int) $quiz->review_answers,
1904
                        'propagate_neg' => (int) $quiz->propagate_neg,
1905
                        'text_when_finished' => (string) $quiz->text_when_finished,
1906
                        'expired_time' => (int) $quiz->expired_time,
1907
                        'start_time' => $quiz->start_time,
1908
                        'end_time' => $quiz->end_time,
1909
                        'display_category_name' => 0,
1910
                        'save_correct_answers' => isset($quiz->save_correct_answers) ? $quiz->save_correct_answers : 0,
1911
                        'hide_question_title' => isset($quiz->hide_question_title) ? $quiz->hide_question_title : 0,
1912
                    ];
1913
1914
                    $allow = api_get_configuration_value('allow_notification_setting_per_exercise');
1915
                    if ($allow) {
1916
                        $params['notifications'] = isset($quiz->notifications) ? $quiz->notifications : '';
1917
                    }
1918
1919
                    if ($respect_base_content) {
1920
                        $my_session_id = $quiz->session_id;
1921
                        if (!empty($quiz->session_id)) {
1922
                            $my_session_id = $session_id;
1923
                        }
1924
                        $params['session_id'] = $my_session_id;
1925
                    } else {
1926
                        if (!empty($session_id)) {
1927
                            $session_id = (int) $session_id;
1928
                            $params['session_id'] = $session_id;
1929
                        }
1930
                    }
1931
                    $new_id = Database::insert($table_qui, $params);
1932
1933
                    if ($new_id) {
1934
                        $sql = "UPDATE $table_qui SET id = iid WHERE iid = $new_id";
1935
                        Database::query($sql);
1936
                    }
1937
                } else {
1938
                    // $id = -1 identifies the fictionary test for collecting
1939
                    // orphan questions. We do not store it in the database.
1940
                    $new_id = -1;
1941
                }
1942
1943
                $this->course->resources[RESOURCE_QUIZ][$id]->destination_id = $new_id;
1944
                $order = 0;
1945
                if (!empty($quiz->question_ids)) {
1946
                    foreach ($quiz->question_ids as $index => $question_id) {
1947
                        $qid = $this->restore_quiz_question($question_id);
1948
                        $question_order = $quiz->question_orders[$index] ? $quiz->question_orders[$index] : ++$order;
1949
                        $sql = "INSERT IGNORE INTO $table_rel SET
1950
                                c_id = ".$this->destination_course_id.",
1951
                                question_id = $qid ,
1952
                                exercice_id = $new_id ,
1953
                                question_order = ".$question_order;
1954
                        Database::query($sql);
1955
                    }
1956
                }
1957
            }
1958
        }
1959
    }
1960
1961
    /**
1962
     * Restore quiz-questions.
1963
     *
1964
     * @params int $id question id
1965
     */
1966
    public function restore_quiz_question($id)
1967
    {
1968
        $em = Database::getManager();
1969
        $resources = $this->course->resources;
1970
        /** @var QuizQuestion $question */
1971
        $question = isset($resources[RESOURCE_QUIZQUESTION][$id]) ? $resources[RESOURCE_QUIZQUESTION][$id] : null;
1972
        $new_id = 0;
1973
1974
        if (is_object($question)) {
1975
            if ($question->is_restored()) {
1976
                return $question->destination_id;
1977
            }
1978
            $table_que = Database::get_course_table(TABLE_QUIZ_QUESTION);
1979
            $table_ans = Database::get_course_table(TABLE_QUIZ_ANSWER);
1980
            $table_options = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION);
1981
1982
            // check resources inside html from ckeditor tool and copy correct urls into recipient course
1983
            $question->description = DocumentManager::replaceUrlWithNewCourseCode(
1984
                $question->description,
1985
                $this->course->code,
1986
                $this->course->destination_path,
1987
                $this->course->backup_path,
1988
                $this->course->info['path']
1989
            );
1990
1991
            $imageNewId = '';
1992
            if (preg_match('/^quiz-.*$/', $question->picture) &&
1993
                isset($resources[RESOURCE_DOCUMENT]['image_quiz'][$question->picture])
1994
            ) {
1995
                $imageNewId = $resources[RESOURCE_DOCUMENT]['image_quiz'][$question->picture]['destination_id'];
1996
            } else {
1997
                if (isset($resources[RESOURCE_DOCUMENT][$question->picture])) {
1998
                    $documentsToRestore = $resources[RESOURCE_DOCUMENT][$question->picture];
1999
                    $imageNewId = $documentsToRestore->destination_id;
2000
                }
2001
            }
2002
            $question->question = DocumentManager::replaceUrlWithNewCourseCode(
2003
                $question->question,
2004
                $this->course->code,
2005
                $this->course->destination_path,
2006
                $this->course->backup_path,
2007
                $this->course->info['path']
2008
            );
2009
            $params = [
2010
                'c_id' => $this->destination_course_id,
2011
                'question' => self::DBUTF8($question->question),
2012
                'description' => ($question->description === false ? '' : self::DBUTF8($question->description)),
2013
                'ponderation' => self::DBUTF8($question->ponderation),
2014
                'position' => self::DBUTF8($question->position),
2015
                'type' => self::DBUTF8($question->quiz_type),
2016
                'picture' => self::DBUTF8($imageNewId),
2017
                'level' => self::DBUTF8($question->level),
2018
                'extra' => self::DBUTF8($question->extra),
2019
            ];
2020
2021
            $new_id = Database::insert($table_que, $params);
2022
2023
            if ($new_id) {
2024
                $sql = "UPDATE $table_que SET id = iid WHERE iid = $new_id";
2025
                Database::query($sql);
2026
            } else {
2027
                return 0;
2028
            }
2029
2030
            $correctAnswers = [];
2031
            $allAnswers = [];
2032
            $onlyAnswers = [];
2033
2034
            if (in_array($question->quiz_type, [DRAGGABLE, MATCHING, MATCHING_DRAGGABLE])) {
2035
                $tempAnswerList = $question->answers;
2036
                foreach ($tempAnswerList as &$value) {
2037
                    $value['answer'] = DocumentManager::replaceUrlWithNewCourseCode(
2038
                        $value['answer'],
2039
                        $this->course->code,
2040
                        $this->course->destination_path,
2041
                        $this->course->backup_path,
2042
                        $this->course->info['path']
2043
                    );
2044
                }
2045
                $allAnswers = array_column($tempAnswerList, 'answer', 'id');
2046
            }
2047
2048
            if (in_array($question->quiz_type, [MATCHING, MATCHING_DRAGGABLE])) {
2049
                $temp = [];
2050
                foreach ($question->answers as $index => $answer) {
2051
                    $temp[$answer['position']] = $answer;
2052
                }
2053
2054
                foreach ($temp as $index => $answer) {
2055
                    // check resources inside html from ckeditor tool and copy correct urls into recipient course
2056
                    $answer['answer'] = DocumentManager::replaceUrlWithNewCourseCode(
2057
                        $answer['answer'],
2058
                        $this->course->code,
2059
                        $this->course->destination_path,
2060
                        $this->course->backup_path,
2061
                        $this->course->info['path']
2062
                    );
2063
2064
                    $answer['comment'] = DocumentManager::replaceUrlWithNewCourseCode(
2065
                        $answer['comment'],
2066
                        $this->course->code,
2067
                        $this->course->destination_path,
2068
                        $this->course->backup_path,
2069
                        $this->course->info['path']
2070
                    );
2071
2072
                    $quizAnswer = new CQuizAnswer();
2073
                    $quizAnswer
2074
                        ->setCId($this->destination_course_id)
2075
                        ->setQuestionId($new_id)
2076
                        ->setAnswer(self::DBUTF8($answer['answer']))
2077
                        ->setCorrect($answer['correct'])
2078
                        ->setComment($answer['comment'] === false ? '' : self::DBUTF8($answer['comment']))
2079
                        ->setPonderation($answer['ponderation'])
2080
                        ->setPosition($answer['position'])
2081
                        ->setHotspotCoordinates($answer['hotspot_coordinates'])
2082
                        ->setHotspotType($answer['hotspot_type'])
2083
                        ->setIdAuto(0);
2084
2085
                    $em->persist($quizAnswer);
2086
                    $em->flush();
2087
2088
                    $answerId = $quizAnswer->getIid();
2089
2090
                    if ($answerId) {
2091
                        $quizAnswer
2092
                            ->setId($answerId)
2093
                            ->setIdAuto($answerId);
2094
                        $em->merge($quizAnswer);
2095
                        $em->flush();
2096
2097
                        $correctAnswers[$answerId] = $answer['correct'];
2098
                        $onlyAnswers[$answerId] = $answer['answer'];
2099
                    }
2100
                }
2101
            } else {
2102
                foreach ($question->answers as $index => $answer) {
2103
                    // check resources inside html from ckeditor tool and copy correct urls into recipient course
2104
                    $answer['answer'] = DocumentManager::replaceUrlWithNewCourseCode(
2105
                        $answer['answer'],
2106
                        $this->course->code,
2107
                        $this->course->destination_path,
2108
                        $this->course->backup_path,
2109
                        $this->course->info['path']
2110
                    );
2111
2112
                    $answer['comment'] = DocumentManager::replaceUrlWithNewCourseCode(
2113
                        $answer['comment'],
2114
                        $this->course->code,
2115
                        $this->course->destination_path,
2116
                        $this->course->backup_path,
2117
                        $this->course->info['path']
2118
                    );
2119
2120
                    $params = [
2121
                        'c_id' => $this->destination_course_id,
2122
                        'question_id' => $new_id,
2123
                        'answer' => self::DBUTF8($answer['answer']),
2124
                        'correct' => $answer['correct'],
2125
                        'comment' => ($answer['comment'] === false ? '' : self::DBUTF8($answer['comment'])),
2126
                        'ponderation' => $answer['ponderation'],
2127
                        'position' => $answer['position'],
2128
                        'hotspot_coordinates' => $answer['hotspot_coordinates'],
2129
                        'hotspot_type' => $answer['hotspot_type'],
2130
                        'id_auto' => 0,
2131
                        'destination' => '',
2132
                    ];
2133
2134
                    $answerId = Database::insert($table_ans, $params);
2135
2136
                    if ($answerId) {
2137
                        $sql = "UPDATE $table_ans SET id = iid, id_auto = iid WHERE iid = $answerId";
2138
                        Database::query($sql);
2139
                    }
2140
2141
                    $correctAnswers[$answerId] = $answer['correct'];
2142
                    $onlyAnswers[$answerId] = $answer['answer'];
2143
                }
2144
            }
2145
2146
            // Current course id
2147
            $course_id = api_get_course_int_id();
2148
2149
            // Moving quiz_question_options
2150
            if ($question->quiz_type == MULTIPLE_ANSWER_TRUE_FALSE) {
2151
                $question_option_list = Question::readQuestionOption($id, $course_id);
2152
2153
                // Question copied from the current platform
2154
                if ($question_option_list) {
2155
                    $old_option_ids = [];
2156
                    foreach ($question_option_list as $item) {
2157
                        $old_id = $item['id'];
2158
                        unset($item['id']);
2159
                        if (isset($item['iid'])) {
2160
                            unset($item['iid']);
2161
                        }
2162
                        $item['question_id'] = $new_id;
2163
                        $item['c_id'] = $this->destination_course_id;
2164
                        $question_option_id = Database::insert($table_options, $item);
2165
                        if ($question_option_id) {
2166
                            $old_option_ids[$old_id] = $question_option_id;
2167
                            $sql = "UPDATE $table_options SET id = iid WHERE iid = $question_option_id";
2168
                            Database::query($sql);
2169
                        }
2170
                    }
2171
                    if ($old_option_ids) {
2172
                        $new_answers = Database::select(
2173
                            'iid, correct',
2174
                            $table_ans,
2175
                            [
2176
                                'WHERE' => [
2177
                                    'question_id = ? AND c_id = ? ' => [
2178
                                        $new_id,
2179
                                        $this->destination_course_id,
2180
                                    ],
2181
                                ],
2182
                            ]
2183
                        );
2184
2185
                        foreach ($new_answers as $answer_item) {
2186
                            $params = [];
2187
                            $params['correct'] = $old_option_ids[$answer_item['correct']];
2188
                            Database::update(
2189
                                $table_ans,
2190
                                $params,
2191
                                [
2192
                                    'iid = ? AND c_id = ? AND question_id = ? ' => [
2193
                                        $answer_item['iid'],
2194
                                        $this->destination_course_id,
2195
                                        $new_id,
2196
                                    ],
2197
                                ],
2198
                                false
2199
                            );
2200
                        }
2201
                    }
2202
                } else {
2203
                    $new_options = [];
2204
                    if (isset($question->question_options)) {
2205
                        foreach ($question->question_options as $obj) {
2206
                            $item = [];
2207
                            $item['question_id'] = $new_id;
2208
                            $item['c_id'] = $this->destination_course_id;
2209
                            $item['name'] = $obj->obj->name;
2210
                            $item['position'] = $obj->obj->position;
2211
                            $question_option_id = Database::insert($table_options, $item);
2212
2213
                            if ($question_option_id) {
2214
                                $new_options[$obj->obj->id] = $question_option_id;
2215
                                $sql = "UPDATE $table_options SET id = iid WHERE iid = $question_option_id";
2216
                                Database::query($sql);
2217
                            }
2218
                        }
2219
2220
                        foreach ($correctAnswers as $answer_id => $correct_answer) {
2221
                            $params = [];
2222
                            $params['correct'] = isset($new_options[$correct_answer]) ? $new_options[$correct_answer] : '';
2223
                            Database::update(
2224
                                $table_ans,
2225
                                $params,
2226
                                [
2227
                                    'id = ? AND c_id = ? AND question_id = ? ' => [
2228
                                        $answer_id,
2229
                                        $this->destination_course_id,
2230
                                        $new_id,
2231
                                    ],
2232
                                ],
2233
                                false
2234
                            );
2235
                        }
2236
                    }
2237
                }
2238
            }
2239
2240
            // Fix correct answers
2241
            if (in_array($question->quiz_type, [DRAGGABLE, MATCHING, MATCHING_DRAGGABLE])) {
2242
                foreach ($correctAnswers as $answer_id => $correct_answer) {
2243
                    $params = [];
2244
2245
                    if (isset($allAnswers[$correct_answer])) {
2246
                        $correct = '';
2247
                        foreach ($onlyAnswers as $key => $value) {
2248
                            if ($value == $allAnswers[$correct_answer]) {
2249
                                $correct = $key;
2250
                                break;
2251
                            }
2252
                        }
2253
2254
                        $params['correct'] = $correct;
2255
                        Database::update(
2256
                            $table_ans,
2257
                            $params,
2258
                            [
2259
                                'id = ? AND c_id = ? AND question_id = ? ' => [
2260
                                    $answer_id,
2261
                                    $this->destination_course_id,
2262
                                    $new_id,
2263
                                ],
2264
                            ]
2265
                        );
2266
                    }
2267
                }
2268
            }
2269
2270
            $this->course->resources[RESOURCE_QUIZQUESTION][$id]->destination_id = $new_id;
2271
        }
2272
2273
        return $new_id;
2274
    }
2275
2276
    /**
2277
     * @todo : add session id when used for session
2278
     */
2279
    public function restore_test_category($session_id, $respect_base_content, $destination_course_code)
2280
    {
2281
        // Cannot restore a test category to a session.
2282
        if (!empty($session_id)) {
2283
            return false;
2284
        }
2285
2286
        $destinationCourseId = $this->destination_course_info['real_id'];
2287
        // Let's restore the categories
2288
        $categoryOldVsNewList = []; // used to build the quiz_question_rel_category table
2289
        if ($this->course->has_resources(RESOURCE_TEST_CATEGORY)) {
2290
            $resources = $this->course->resources;
2291
            foreach ($resources[RESOURCE_TEST_CATEGORY] as $id => $courseCopyTestCategory) {
2292
                $categoryOldVsNewList[$courseCopyTestCategory->source_id] = $id;
2293
                // check if this test_category already exist in the destination BDD
2294
                // do not Database::escape_string $title and $description, it will be done later
2295
                $title = $courseCopyTestCategory->title;
2296
                $description = $courseCopyTestCategory->description;
2297
                if (TestCategory::categoryTitleExists($title, $destinationCourseId)) {
2298
                    switch ($this->file_option) {
2299
                        case FILE_SKIP:
2300
                            //Do nothing
2301
                            break;
2302
                        case FILE_RENAME:
2303
                            $new_title = $title.'_';
2304
                            while (TestCategory::categoryTitleExists($new_title, $destinationCourseId)) {
2305
                                $new_title .= '_';
2306
                            }
2307
                            $test_category = new TestCategory();
2308
                            $test_category->name = $new_title;
2309
                            $test_category->description = $description;
2310
                            $new_id = $test_category->save($destinationCourseId);
2311
                            $categoryOldVsNewList[$courseCopyTestCategory->source_id] = $new_id;
2312
                            break;
2313
                        case FILE_OVERWRITE:
2314
                            // get category from source
2315
                            $destinationCategoryId = TestCategory::get_category_id_for_title(
2316
                                $title,
2317
                                $destinationCourseId
2318
                            );
2319
                            if ($destinationCategoryId) {
2320
                                $my_cat = new TestCategory();
2321
                                $my_cat = $my_cat->getCategory($destinationCategoryId, $destinationCourseId);
2322
                                $my_cat->name = $title;
2323
                                $my_cat->description = $description;
2324
                                $my_cat->modifyCategory($destinationCourseId);
2325
                                $categoryOldVsNewList[$courseCopyTestCategory->source_id] = $destinationCategoryId;
2326
                            }
2327
                            break;
2328
                    }
2329
                } else {
2330
                    // create a new test_category
2331
                    $test_category = new TestCategory();
2332
                    $test_category->name = $title;
2333
                    $test_category->description = $description;
2334
                    $new_id = $test_category->save($destinationCourseId);
2335
                    $categoryOldVsNewList[$courseCopyTestCategory->source_id] = $new_id;
2336
                }
2337
                $this->course->resources[RESOURCE_TEST_CATEGORY][$id]->destination_id = $categoryOldVsNewList[$courseCopyTestCategory->source_id];
2338
            }
2339
        }
2340
2341
        // lets check if quizzes-question are restored too,
2342
        // to redo the link between test_category and quizzes question for questions restored
2343
        // we can use the source_id field
2344
        // question source_id => category source_id
2345
        if ($this->course->has_resources(RESOURCE_QUIZQUESTION)) {
2346
            // check the category number of each question restored
2347
            if (!empty($resources[RESOURCE_QUIZQUESTION])) {
2348
                foreach ($resources[RESOURCE_QUIZQUESTION] as $id => $courseCopyQuestion) {
2349
                    $newQuestionId = $resources[RESOURCE_QUIZQUESTION][$id]->destination_id;
2350
                    $questionCategoryId = $courseCopyQuestion->question_category;
2351
                    if ($newQuestionId > 0 &&
2352
                        $questionCategoryId > 0 &&
2353
                        isset($categoryOldVsNewList[$questionCategoryId])
2354
                    ) {
2355
                        TestCategory::addCategoryToQuestion(
2356
                            $categoryOldVsNewList[$questionCategoryId],
2357
                            $newQuestionId,
2358
                            $destinationCourseId
2359
                        );
2360
                    }
2361
                }
2362
            }
2363
        }
2364
    }
2365
2366
    /**
2367
     * Restore surveys.
2368
     *
2369
     * @param int $sessionId Optional. The session id
2370
     */
2371
    public function restore_surveys($sessionId = 0)
2372
    {
2373
        $sessionId = (int) $sessionId;
2374
        if ($this->course->has_resources(RESOURCE_SURVEY)) {
2375
            $table_sur = Database::get_course_table(TABLE_SURVEY);
2376
            $table_que = Database::get_course_table(TABLE_SURVEY_QUESTION);
2377
            $table_ans = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
2378
            $resources = $this->course->resources;
2379
            foreach ($resources[RESOURCE_SURVEY] as $id => $survey) {
2380
                $sql = 'SELECT survey_id FROM '.$table_sur.'
2381
                        WHERE
2382
                            c_id = '.$this->destination_course_id.' AND
2383
                            code = "'.self::DBUTF8escapestring($survey->code).'" AND
2384
                            lang = "'.self::DBUTF8escapestring($survey->lang).'" ';
2385
2386
                $result_check = Database::query($sql);
2387
2388
                // check resources inside html from ckeditor tool and copy correct urls into recipient course
2389
                $survey->title = DocumentManager::replaceUrlWithNewCourseCode(
2390
                    $survey->title,
2391
                    $this->course->code,
2392
                    $this->course->destination_path,
2393
                    $this->course->backup_path,
2394
                    $this->course->info['path']
2395
                );
2396
2397
                $survey->subtitle = DocumentManager::replaceUrlWithNewCourseCode(
2398
                    $survey->subtitle,
2399
                    $this->course->code,
2400
                    $this->course->destination_path,
2401
                    $this->course->backup_path,
2402
                    $this->course->info['path']
2403
                );
2404
2405
                $survey->intro = DocumentManager::replaceUrlWithNewCourseCode(
2406
                    $survey->intro,
2407
                    $this->course->code,
2408
                    $this->course->destination_path,
2409
                    $this->course->backup_path,
2410
                    $this->course->info['path']
2411
                );
2412
2413
                $survey->surveythanks = DocumentManager::replaceUrlWithNewCourseCode(
2414
                    $survey->surveythanks,
2415
                    $this->course->code,
2416
                    $this->course->destination_path,
2417
                    $this->course->backup_path,
2418
                    $this->course->info['path']
2419
                );
2420
2421
                $params = [
2422
                    'c_id' => $this->destination_course_id,
2423
                    'code' => self::DBUTF8($survey->code),
2424
                    'title' => ($survey->title === false ? '' : self::DBUTF8($survey->title)),
2425
                    'subtitle' => ($survey->subtitle === false ? '' : self::DBUTF8($survey->subtitle)),
2426
                    'author' => self::DBUTF8($survey->author),
2427
                    'lang' => self::DBUTF8($survey->lang),
2428
                    'avail_from' => self::DBUTF8($survey->avail_from),
2429
                    'avail_till' => self::DBUTF8($survey->avail_till),
2430
                    'is_shared' => self::DBUTF8($survey->is_shared),
2431
                    'template' => self::DBUTF8($survey->template),
2432
                    'intro' => $survey->intro === false ? '' : self::DBUTF8($survey->intro),
2433
                    'surveythanks' => $survey->surveythanks === false ? '' : self::DBUTF8($survey->surveythanks),
2434
                    'creation_date' => self::DBUTF8($survey->creation_date),
2435
                    'invited' => '0',
2436
                    'answered' => '0',
2437
                    'invite_mail' => self::DBUTF8($survey->invite_mail),
2438
                    'reminder_mail' => self::DBUTF8($survey->reminder_mail),
2439
                    'session_id' => $sessionId,
2440
                    'one_question_per_page' => isset($survey->one_question_per_page) ? $survey->one_question_per_page : 0,
2441
                    'shuffle' => isset($survey->suffle) ? $survey->suffle : 0,
2442
                ];
2443
2444
                // An existing survey exists with the same code and the same language
2445
                if (Database::num_rows($result_check) == 1) {
2446
                    switch ($this->file_option) {
2447
                        case FILE_SKIP:
2448
                            //Do nothing
2449
                            break;
2450
                        case FILE_RENAME:
2451
                            $survey_code = $survey->code.'_';
2452
                            $i = 1;
2453
                            $temp_survey_code = $survey_code.$i;
2454
                            while (!$this->is_survey_code_available($temp_survey_code)) {
2455
                                $temp_survey_code = $survey_code.++$i;
2456
                            }
2457
                            $survey_code = $temp_survey_code;
2458
2459
                            $params['code'] = $survey_code;
2460
                            $new_id = Database::insert($table_sur, $params);
2461
                            if ($new_id) {
2462
                                $sql = "UPDATE $table_sur SET survey_id = iid WHERE iid = $new_id";
2463
                                Database::query($sql);
2464
2465
                                $this->course->resources[RESOURCE_SURVEY][$id]->destination_id = $new_id;
2466
                                foreach ($survey->question_ids as $index => $question_id) {
2467
                                    $qid = $this->restore_survey_question($question_id, $new_id);
2468
                                    $sql = "UPDATE $table_que SET survey_id = $new_id
2469
                                            WHERE c_id = ".$this->destination_course_id." AND question_id = $qid";
2470
                                    Database::query($sql);
2471
                                    $sql = "UPDATE $table_ans SET survey_id = $new_id
2472
                                            WHERE  c_id = ".$this->destination_course_id." AND  question_id = $qid";
2473
                                    Database::query($sql);
2474
                                }
2475
                            }
2476
                            break;
2477
                        case FILE_OVERWRITE:
2478
                            // Delete the existing survey with the same code and language and
2479
                            // import the one of the source course
2480
                            // getting the information of the survey (used for when the survey is shared)
2481
                            $sql = "SELECT * FROM $table_sur
2482
                                    WHERE
2483
                                        c_id = ".$this->destination_course_id." AND
2484
                                        survey_id='".self::DBUTF8escapestring(Database::result($result_check, 0, 0))."'";
2485
                            $result = Database::query($sql);
2486
                            $survey_data = Database::fetch_array($result, 'ASSOC');
2487
2488
                            // if the survey is shared => also delete the shared content
2489
                            if (isset($survey_data['survey_share']) && is_numeric($survey_data['survey_share'])) {
2490
                                SurveyManager::delete_survey(
2491
                                    $survey_data['survey_share'],
2492
                                    true,
2493
                                    $this->destination_course_id
2494
                                );
2495
                            }
2496
                            SurveyManager::delete_survey(
2497
                                $survey_data['survey_id'],
2498
                                false,
2499
                                $this->destination_course_id
2500
                            );
2501
2502
                            // Insert the new source survey
2503
                            $new_id = Database::insert($table_sur, $params);
2504
2505
                            if ($new_id) {
2506
                                $sql = "UPDATE $table_sur SET survey_id = iid WHERE iid = $new_id";
2507
                                Database::query($sql);
2508
2509
                                $this->course->resources[RESOURCE_SURVEY][$id]->destination_id = $new_id;
2510
                                foreach ($survey->question_ids as $index => $question_id) {
2511
                                    $qid = $this->restore_survey_question(
2512
                                        $question_id,
2513
                                        $new_id
2514
                                    );
2515
                                    $sql = "UPDATE $table_que SET survey_id = $new_id
2516
                                            WHERE c_id = ".$this->destination_course_id." AND question_id = $qid";
2517
                                    Database::query($sql);
2518
                                    $sql = "UPDATE $table_ans SET survey_id = $new_id
2519
                                            WHERE c_id = ".$this->destination_course_id." AND question_id = $qid";
2520
                                    Database::query($sql);
2521
                                }
2522
                            }
2523
                            break;
2524
                        default:
2525
                            break;
2526
                    }
2527
                } else {
2528
                    // No existing survey with the same language and the same code, we just copy the survey
2529
                    $new_id = Database::insert($table_sur, $params);
2530
2531
                    if ($new_id) {
2532
                        $sql = "UPDATE $table_sur SET survey_id = iid WHERE iid = $new_id";
2533
                        Database::query($sql);
2534
2535
                        $this->course->resources[RESOURCE_SURVEY][$id]->destination_id = $new_id;
2536
                        foreach ($survey->question_ids as $index => $question_id) {
2537
                            $qid = $this->restore_survey_question(
2538
                                $question_id,
2539
                                $new_id
2540
                            );
2541
                            $sql = "UPDATE $table_que SET survey_id = $new_id
2542
                                    WHERE c_id = ".$this->destination_course_id." AND question_id = $qid";
2543
                            Database::query($sql);
2544
                            $sql = "UPDATE $table_ans SET survey_id = $new_id
2545
                                    WHERE c_id = ".$this->destination_course_id." AND question_id = $qid";
2546
                            Database::query($sql);
2547
                        }
2548
                    }
2549
                }
2550
            }
2551
        }
2552
    }
2553
2554
    /**
2555
     * Check availability of a survey code.
2556
     *
2557
     * @param string $survey_code
2558
     *
2559
     * @return bool
2560
     */
2561
    public function is_survey_code_available($survey_code)
2562
    {
2563
        $table_sur = Database::get_course_table(TABLE_SURVEY);
2564
        $sql = "SELECT * FROM $table_sur
2565
                WHERE
2566
                    c_id = ".$this->destination_course_id." AND
2567
                    code = '".self::DBUTF8escapestring($survey_code)."'";
2568
        $result = Database::query($sql);
2569
        if (Database::num_rows($result) > 0) {
2570
            return false;
2571
        } else {
2572
            return true;
2573
        }
2574
    }
2575
2576
    /**
2577
     * Restore survey-questions.
2578
     *
2579
     * @param int    $id
2580
     * @param string $survey_id
2581
     */
2582
    public function restore_survey_question($id, $survey_id)
2583
    {
2584
        $resources = $this->course->resources;
2585
        $question = $resources[RESOURCE_SURVEYQUESTION][$id];
2586
        $new_id = 0;
2587
2588
        if (is_object($question)) {
2589
            if ($question->is_restored()) {
2590
                return $question->destination_id;
2591
            }
2592
            $table_que = Database::get_course_table(TABLE_SURVEY_QUESTION);
2593
            $table_ans = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
2594
2595
            // check resources inside html from ckeditor tool and copy correct urls into recipient course
2596
            $question->survey_question = DocumentManager::replaceUrlWithNewCourseCode(
2597
                $question->survey_question,
2598
                $this->course->code,
2599
                $this->course->destination_path,
2600
                $this->course->backup_path,
2601
                $this->course->info['path']
2602
            );
2603
2604
            $params = [
2605
                'c_id' => $this->destination_course_id,
2606
                'survey_id' => self::DBUTF8($survey_id),
2607
                'survey_question' => ($question->survey_question === false ? '' : self::DBUTF8($question->survey_question)),
2608
                'survey_question_comment' => self::DBUTF8($question->survey_question_comment),
2609
                'type' => self::DBUTF8($question->survey_question_type),
2610
                'display' => self::DBUTF8($question->display),
2611
                'sort' => self::DBUTF8($question->sort),
2612
                'shared_question_id' => self::DBUTF8($question->shared_question_id),
2613
                'max_value' => self::DBUTF8($question->max_value),
2614
            ];
2615
            if (api_get_configuration_value('allow_required_survey_questions')) {
2616
                if (isset($question->is_required)) {
2617
                    $params['is_required'] = $question->is_required;
2618
                }
2619
            }
2620
2621
            $new_id = Database::insert($table_que, $params);
2622
            if ($new_id) {
2623
                $sql = "UPDATE $table_que SET question_id = iid WHERE iid = $new_id";
2624
                Database::query($sql);
2625
2626
                foreach ($question->answers as $index => $answer) {
2627
                    // check resources inside html from ckeditor tool and copy correct urls into recipient course
2628
                    $answer['option_text'] = DocumentManager::replaceUrlWithNewCourseCode(
2629
                        $answer['option_text'],
2630
                        $this->course->code,
2631
                        $this->course->destination_path,
2632
                        $this->course->backup_path,
2633
                        $this->course->info['path']
2634
                    );
2635
2636
                    $params = [
2637
                        'c_id' => $this->destination_course_id,
2638
                        'question_id' => $new_id,
2639
                        'option_text' => ($answer['option_text'] === false ? '' : self::DBUTF8($answer['option_text'])),
2640
                        'sort' => $answer['sort'],
2641
                        'survey_id' => self::DBUTF8($survey_id),
2642
                    ];
2643
                    $answerId = Database::insert($table_ans, $params);
2644
                    if ($answerId) {
2645
                        $sql = "UPDATE $table_ans SET question_option_id = iid
2646
                                WHERE iid = $answerId";
2647
                        Database::query($sql);
2648
                    }
2649
                }
2650
                $this->course->resources[RESOURCE_SURVEYQUESTION][$id]->destination_id = $new_id;
2651
            }
2652
        }
2653
2654
        return $new_id;
2655
    }
2656
2657
    /**
2658
     * @param int  $sessionId
2659
     * @param bool $baseContent
2660
     */
2661
    public function restore_learnpath_category($sessionId = 0, $baseContent = false)
2662
    {
2663
        $reuseExisting = false;
2664
2665
        if (isset($this->tool_copy_settings['learnpath_category']) &&
2666
            isset($this->tool_copy_settings['learnpath_category']['reuse_existing']) &&
2667
            true === $this->tool_copy_settings['learnpath_category']['reuse_existing']
2668
        ) {
2669
            $reuseExisting = true;
2670
        }
2671
2672
        $tblLpCategory = Database::get_course_table(TABLE_LP_CATEGORY);
2673
2674
        if ($this->course->has_resources(RESOURCE_LEARNPATH_CATEGORY)) {
2675
            $resources = $this->course->resources;
2676
            /** @var LearnPathCategory $item */
2677
            foreach ($resources[RESOURCE_LEARNPATH_CATEGORY] as $id => $item) {
2678
                /** @var CLpCategory $lpCategory */
2679
                $lpCategory = $item->object;
2680
2681
                if ($lpCategory) {
2682
                    $existingLpCategory = Database::select(
2683
                        'iid',
2684
                        $tblLpCategory,
2685
                        [
2686
                            'WHERE' => [
2687
                                'c_id = ? AND name = ?' => [$this->destination_course_id, $lpCategory->getName()],
2688
                            ],
2689
                        ],
2690
                        'first'
2691
                    );
2692
2693
                    if ($reuseExisting && !empty($existingLpCategory)) {
2694
                        $categoryId = $existingLpCategory['iid'];
2695
                    } else {
2696
                        $values = [
2697
                            'c_id' => $this->destination_course_id,
2698
                            'name' => $lpCategory->getName(),
2699
                        ];
2700
                        $categoryId = \learnpath::createCategory($values);
2701
                    }
2702
2703
                    if ($categoryId) {
2704
                        $this->course->resources[RESOURCE_LEARNPATH_CATEGORY][$id]->destination_id = $categoryId;
2705
                    }
2706
                }
2707
            }
2708
        }
2709
    }
2710
2711
    /**
2712
     * Restoring learning paths.
2713
     *
2714
     * @param int        $session_id
2715
     * @param bool|false $respect_base_content
2716
     */
2717
    public function restore_learnpaths($session_id = 0, $respect_base_content = false)
2718
    {
2719
        $session_id = (int) $session_id;
2720
        if ($this->course->has_resources(RESOURCE_LEARNPATH)) {
2721
            $table_main = Database::get_course_table(TABLE_LP_MAIN);
2722
            $table_item = Database::get_course_table(TABLE_LP_ITEM);
2723
            $table_tool = Database::get_course_table(TABLE_TOOL_LIST);
2724
2725
            $resources = $this->course->resources;
2726
            $origin_path = $this->course->backup_path.'/upload/learning_path/images/';
2727
            $destination_path = api_get_path(SYS_COURSE_PATH).
2728
                $this->course->destination_path.'/upload/learning_path/images/';
2729
2730
            // Choose default visibility
2731
            $toolVisibility = api_get_setting('tool_visible_by_default_at_creation');
2732
            $defaultLpVisibility = 'invisible';
2733
            if (isset($toolVisibility['learning_path']) && $toolVisibility['learning_path'] == 'true') {
2734
                $defaultLpVisibility = 'visible';
2735
            }
2736
2737
            foreach ($resources[RESOURCE_LEARNPATH] as $id => $lp) {
2738
                $condition_session = '';
2739
                if (!empty($session_id)) {
2740
                    if ($respect_base_content) {
2741
                        $my_session_id = $lp->session_id;
2742
                        if (!empty($lp->session_id)) {
2743
                            $my_session_id = $session_id;
2744
                        }
2745
                        $condition_session = $my_session_id;
2746
                    } else {
2747
                        $session_id = (int) $session_id;
2748
                        $condition_session = $session_id;
2749
                    }
2750
                }
2751
2752
                // Adding the LP image
2753
                if (!empty($lp->preview_image)) {
2754
                    $new_filename = uniqid('').substr(
2755
                        $lp->preview_image,
2756
                        strlen($lp->preview_image) - 7,
2757
                        strlen($lp->preview_image)
2758
                    );
2759
2760
                    if (file_exists($origin_path.$lp->preview_image) &&
2761
                        !is_dir($origin_path.$lp->preview_image)
2762
                    ) {
2763
                        $copy_result = copy(
2764
                            $origin_path.$lp->preview_image,
2765
                            $destination_path.$new_filename
2766
                        );
2767
                        if ($copy_result) {
2768
                            $lp->preview_image = $new_filename;
2769
                            // Create 64 version from original
2770
                            $temp = new \Image($destination_path.$new_filename);
2771
                            $temp->resize(64);
2772
                            $pathInfo = pathinfo($new_filename);
2773
                            if ($pathInfo) {
2774
                                $filename = $pathInfo['filename'];
2775
                                $extension = $pathInfo['extension'];
2776
                                $temp->send_image($destination_path.'/'.$filename.'.64.'.$extension);
2777
                            }
2778
                        } else {
2779
                            $lp->preview_image = '';
2780
                        }
2781
                    }
2782
                }
2783
2784
                if ($this->add_text_in_items) {
2785
                    $lp->name = $lp->name.' '.get_lang('CopyLabelSuffix');
2786
                }
2787
2788
                if (isset($this->tool_copy_settings['learnpaths'])) {
2789
                    if (isset($this->tool_copy_settings['learnpaths']['reset_dates']) &&
2790
                        $this->tool_copy_settings['learnpaths']['reset_dates']
2791
                    ) {
2792
                        $lp->created_on = api_get_utc_datetime();
2793
                        $lp->modified_on = api_get_utc_datetime();
2794
                        $lp->publicated_on = null;
2795
                    }
2796
                }
2797
2798
                $lp->expired_on = isset($lp->expired_on) && $lp->expired_on === '0000-00-00 00:00:00' ? null : $lp->expired_on;
2799
                $lp->publicated_on = isset($lp->publicated_on) && $lp->publicated_on === '0000-00-00 00:00:00' ? null : $lp->publicated_on;
2800
2801
                if (isset($lp->categoryId)) {
2802
                    $lp->categoryId = (int) $lp->categoryId;
2803
                }
2804
2805
                $categoryId = 0;
2806
                if (!empty($lp->categoryId)) {
2807
                    if (isset($resources[RESOURCE_LEARNPATH_CATEGORY][$lp->categoryId])) {
2808
                        $categoryId = $resources[RESOURCE_LEARNPATH_CATEGORY][$lp->categoryId]->destination_id;
2809
                    }
2810
                }
2811
                $params = [
2812
                    'c_id' => $this->destination_course_id,
2813
                    'lp_type' => $lp->lp_type,
2814
                    'name' => self::DBUTF8($lp->name),
2815
                    'path' => self::DBUTF8($lp->path),
2816
                    'ref' => $lp->ref,
2817
                    'description' => self::DBUTF8($lp->description),
2818
                    'content_local' => self::DBUTF8($lp->content_local),
2819
                    'default_encoding' => self::DBUTF8($lp->default_encoding),
2820
                    'default_view_mod' => self::DBUTF8($lp->default_view_mod),
2821
                    'prevent_reinit' => self::DBUTF8($lp->prevent_reinit),
2822
                    'force_commit' => self::DBUTF8($lp->force_commit),
2823
                    'content_maker' => self::DBUTF8($lp->content_maker),
2824
                    'display_order' => self::DBUTF8($lp->display_order),
2825
                    'js_lib' => self::DBUTF8($lp->js_lib),
2826
                    'content_license' => self::DBUTF8($lp->content_license),
2827
                    'author' => self::DBUTF8($lp->author),
2828
                    'preview_image' => self::DBUTF8($lp->preview_image),
2829
                    'use_max_score' => self::DBUTF8($lp->use_max_score),
2830
                    'autolaunch' => self::DBUTF8(isset($lp->autolaunch) ? $lp->autolaunch : ''),
2831
                    'created_on' => empty($lp->created_on) ? api_get_utc_datetime() : self::DBUTF8($lp->created_on),
2832
                    'modified_on' => empty($lp->modified_on) ? api_get_utc_datetime() : self::DBUTF8($lp->modified_on),
2833
                    'publicated_on' => empty($lp->publicated_on) ? api_get_utc_datetime() : self::DBUTF8($lp->publicated_on),
2834
                    'expired_on' => self::DBUTF8($lp->expired_on),
2835
                    'debug' => self::DBUTF8($lp->debug),
2836
                    'theme' => '',
2837
                    'session_id' => $session_id,
2838
                    'prerequisite' => 0,
2839
                    'hide_toc_frame' => 0,
2840
                    'seriousgame_mode' => 0,
2841
                    'category_id' => $categoryId,
2842
                    'max_attempts' => 0,
2843
                    'subscribe_users' => 0,
2844
                ];
2845
2846
                if (!empty($condition_session)) {
2847
                    $params['session_id'] = $condition_session;
2848
                }
2849
2850
                $new_lp_id = Database::insert($table_main, $params);
2851
2852
                if ($new_lp_id) {
2853
                    // The following only makes sense if a new LP was
2854
                    // created in the destination course
2855
                    $sql = "UPDATE $table_main SET id = iid WHERE iid = $new_lp_id";
2856
                    Database::query($sql);
2857
2858
                    if ($lp->visibility) {
2859
                        $params = [
2860
                            'c_id' => $this->destination_course_id,
2861
                            'name' => self::DBUTF8($lp->name),
2862
                            'link' => "lp/lp_controller.php?action=view&lp_id=$new_lp_id&id_session=$session_id",
2863
                            'image' => 'scormbuilder.gif',
2864
                            'visibility' => '0',
2865
                            'admin' => '0',
2866
                            'address' => 'squaregrey.gif',
2867
                            'session_id' => $session_id,
2868
                        ];
2869
                        $insertId = Database::insert($table_tool, $params);
2870
                        if ($insertId) {
2871
                            $sql = "UPDATE $table_tool SET id = iid WHERE iid = $insertId";
2872
                            Database::query($sql);
2873
                        }
2874
                    }
2875
2876
                    if (isset($lp->extraFields) && !empty($lp->extraFields)) {
2877
                        $extraFieldValue = new \ExtraFieldValue('lp');
2878
                        foreach ($lp->extraFields as $extraField) {
2879
                            $params = [
2880
                                'item_id' => $new_lp_id,
2881
                                'value' => $extraField['value'],
2882
                                'variable' => $extraField['variable']
2883
                            ];
2884
                            $extraFieldValue->save($params);
2885
                        }
2886
                    }
2887
2888
                    api_item_property_update(
2889
                        $this->destination_course_info,
2890
                        TOOL_LEARNPATH,
2891
                        $new_lp_id,
2892
                        'LearnpathAdded',
2893
                        api_get_user_id(),
2894
                        0,
2895
                        0,
2896
                        0,
2897
                        0,
2898
                        $session_id
2899
                    );
2900
2901
                    // Set the new LP to visible
2902
                    api_item_property_update(
2903
                        $this->destination_course_info,
2904
                        TOOL_LEARNPATH,
2905
                        $new_lp_id,
2906
                        $defaultLpVisibility,
2907
                        api_get_user_id(),
2908
                        0,
2909
                        0,
2910
                        0,
2911
                        0,
2912
                        $session_id
2913
                    );
2914
2915
                    $new_item_ids = [];
2916
                    $parent_item_ids = [];
2917
                    $previous_item_ids = [];
2918
                    $next_item_ids = [];
2919
                    $old_prerequisite = [];
2920
                    $old_refs = [];
2921
                    $prerequisite_ids = [];
2922
2923
                    foreach ($lp->get_items() as $index => $item) {
2924
                        // we set the ref code here and then we update in a for loop
2925
                        $ref = $item['ref'];
2926
2927
                        // Dealing with path the same way as ref as some data has
2928
                        // been put into path when it's a local resource
2929
                        // Only fix the path for no scos
2930
                        if ($item['item_type'] === 'sco') {
2931
                            $path = $item['path'];
2932
                        } else {
2933
                            $path = $this->get_new_id($item['item_type'], $item['path']);
2934
                        }
2935
2936
                        $item['item_type'] = $item['item_type'] === 'dokeos_chapter' ? 'dir' : $item['item_type'];
2937
2938
                        $masteryScore = $item['mastery_score'];
2939
                        // If item is a chamilo quiz, then use the max score as mastery_score.
2940
                        if ($item['item_type'] === 'quiz') {
2941
                            if (empty($masteryScore)) {
2942
                                $masteryScore = $item['max_score'];
2943
                            }
2944
                        }
2945
2946
                        $params = [
2947
                            'c_id' => $this->destination_course_id,
2948
                            'lp_id' => self::DBUTF8($new_lp_id),
2949
                            'item_type' => self::DBUTF8($item['item_type']),
2950
                            'ref' => self::DBUTF8($ref),
2951
                            'path' => self::DBUTF8($path),
2952
                            'title' => self::DBUTF8($item['title']),
2953
                            'description' => self::DBUTF8($item['description']),
2954
                            'min_score' => self::DBUTF8($item['min_score']),
2955
                            'max_score' => self::DBUTF8($item['max_score']),
2956
                            'mastery_score' => self::DBUTF8($masteryScore),
2957
                            'parent_item_id' => self::DBUTF8($item['parent_item_id']),
2958
                            'previous_item_id' => self::DBUTF8($item['previous_item_id']),
2959
                            'next_item_id' => self::DBUTF8($item['next_item_id']),
2960
                            'display_order' => self::DBUTF8($item['display_order']),
2961
                            'prerequisite' => self::DBUTF8($item['prerequisite']),
2962
                            'parameters' => self::DBUTF8($item['parameters']),
2963
                            'audio' => self::DBUTF8($item['audio']),
2964
                            'launch_data' => self::DBUTF8($item['launch_data']),
2965
                        ];
2966
2967
                        $new_item_id = Database::insert($table_item, $params);
2968
                        if ($new_item_id) {
2969
                            $sql = "UPDATE $table_item SET id = iid WHERE iid = $new_item_id";
2970
                            Database::query($sql);
2971
2972
                            //save a link between old and new item IDs
2973
                            $new_item_ids[$item['id']] = $new_item_id;
2974
                            //save a reference of items that need a parent_item_id refresh
2975
                            $parent_item_ids[$new_item_id] = $item['parent_item_id'];
2976
                            //save a reference of items that need a previous_item_id refresh
2977
                            $previous_item_ids[$new_item_id] = $item['previous_item_id'];
2978
                            //save a reference of items that need a next_item_id refresh
2979
                            $next_item_ids[$new_item_id] = $item['next_item_id'];
2980
2981
                            if (!empty($item['prerequisite'])) {
2982
                                if ($lp->lp_type == '2') {
2983
                                    // if is an sco
2984
                                    $old_prerequisite[$new_item_id] = $item['prerequisite'];
2985
                                } else {
2986
                                    $old_prerequisite[$new_item_id] = isset($new_item_ids[$item['prerequisite']]) ? $new_item_ids[$item['prerequisite']] : '';
2987
                                }
2988
                            }
2989
2990
                            if (!empty($ref)) {
2991
                                if ($lp->lp_type == '2') {
2992
                                    // if is an sco
2993
                                    $old_refs[$new_item_id] = $ref;
2994
                                } elseif (isset($new_item_ids[$ref])) {
2995
                                    $old_refs[$new_item_id] = $new_item_ids[$ref];
2996
                                }
2997
                            }
2998
                            $prerequisite_ids[$new_item_id] = $item['prerequisite'];
2999
                        }
3000
                    }
3001
3002
                    // Updating prerequisites
3003
                    foreach ($old_prerequisite as $key => $my_old_prerequisite) {
3004
                        if ($my_old_prerequisite != '') {
3005
                            $my_old_prerequisite = Database::escape_string($my_old_prerequisite);
3006
                            $sql = "UPDATE $table_item SET prerequisite = '$my_old_prerequisite'
3007
                                    WHERE c_id = ".$this->destination_course_id." AND id = '".$key."'  ";
3008
                            Database::query($sql);
3009
                        }
3010
                    }
3011
3012
                    // Updating refs
3013
                    foreach ($old_refs as $key => $my_old_ref) {
3014
                        if ($my_old_ref != '') {
3015
                            $my_old_ref = Database::escape_string($my_old_ref);
3016
                            $sql = "UPDATE $table_item SET ref = '$my_old_ref'
3017
                                    WHERE c_id = ".$this->destination_course_id." AND id = $key";
3018
                            Database::query($sql);
3019
                        }
3020
                    }
3021
3022
                    foreach ($parent_item_ids as $new_item_id => $parent_item_old_id) {
3023
                        $new_item_id = (int) $new_item_id;
3024
                        $parent_new_id = 0;
3025
                        if ($parent_item_old_id != 0) {
3026
                            $parent_new_id = isset($new_item_ids[$parent_item_old_id]) ? $new_item_ids[$parent_item_old_id] : 0;
3027
                        }
3028
3029
                        $parent_new_id = Database::escape_string($parent_new_id);
3030
                        $sql = "UPDATE $table_item SET parent_item_id = '$parent_new_id'
3031
                                WHERE c_id = ".$this->destination_course_id." AND id = $new_item_id";
3032
                        Database::query($sql);
3033
                    }
3034
3035
                    foreach ($previous_item_ids as $new_item_id => $previous_item_old_id) {
3036
                        $new_item_id = (int) $new_item_id;
3037
                        $previous_new_id = 0;
3038
                        if ($previous_item_old_id != 0) {
3039
                            $previous_new_id = isset($new_item_ids[$previous_item_old_id]) ? $new_item_ids[$previous_item_old_id] : 0;
3040
                        }
3041
                        $previous_new_id = Database::escape_string($previous_new_id);
3042
                        $sql = "UPDATE $table_item SET previous_item_id = '$previous_new_id'
3043
                                WHERE c_id = ".$this->destination_course_id." AND id = '".$new_item_id."'";
3044
                        Database::query($sql);
3045
                    }
3046
3047
                    foreach ($next_item_ids as $new_item_id => $next_item_old_id) {
3048
                        $new_item_id = (int) $new_item_id;
3049
                        $next_new_id = 0;
3050
                        if ($next_item_old_id != 0) {
3051
                            $next_new_id = isset($new_item_ids[$next_item_old_id]) ? $new_item_ids[$next_item_old_id] : 0;
3052
                        }
3053
                        $next_new_id = Database::escape_string($next_new_id);
3054
                        $sql = "UPDATE $table_item SET next_item_id = '$next_new_id'
3055
                                WHERE c_id = ".$this->destination_course_id." AND id = '".$new_item_id."'";
3056
                        Database::query($sql);
3057
                    }
3058
3059
                    foreach ($prerequisite_ids as $new_item_id => $prerequisite_old_id) {
3060
                        $new_item_id = (int) $new_item_id;
3061
                        $prerequisite_new_id = 0;
3062
                        if ($prerequisite_old_id != 0) {
3063
                            $prerequisite_new_id = $new_item_ids[$prerequisite_old_id];
3064
                        }
3065
                        $prerequisite_new_id = Database::escape_string($prerequisite_new_id);
3066
                        $sql = "UPDATE $table_item SET prerequisite = '$prerequisite_new_id'
3067
                                WHERE c_id = ".$this->destination_course_id." AND id = $new_item_id";
3068
                        Database::query($sql);
3069
                    }
3070
                    $this->course->resources[RESOURCE_LEARNPATH][$id]->destination_id = $new_lp_id;
3071
                }
3072
            }
3073
        }
3074
    }
3075
3076
    /**
3077
     * Copy all directory and sub directory.
3078
     *
3079
     * @param string $source The path origin
3080
     * @param string $dest   The path destination
3081
     * @param bool Option Overwrite
3082
     *
3083
     * @deprecated
3084
     */
3085
    public function allow_create_all_directory($source, $dest, $overwrite = false)
3086
    {
3087
        if (!is_dir($dest)) {
3088
            mkdir($dest, api_get_permissions_for_new_directories());
3089
        }
3090
        if ($handle = opendir($source)) {
3091
            // if the folder exploration is sucsessful, continue
3092
            while (false !== ($file = readdir($handle))) {
3093
                // as long as storing the next file to $file is successful, continue
3094
                if ($file != '.' && $file != '..') {
3095
                    $path = $source.'/'.$file;
3096
                    if (is_file($path)) {
3097
                        /* if (!is_file($dest . '/' . $file) || $overwrite)
3098
                         if (!@copy($path, $dest . '/' . $file)) {
3099
                             echo '<font color="red">File ('.$path.') '.get_lang('NotHavePermission').'</font>';
3100
                         }*/
3101
                    } elseif (is_dir($path)) {
3102
                        if (!is_dir($dest.'/'.$file)) {
3103
                            mkdir($dest.'/'.$file);
3104
                        }
3105
                        self:: allow_create_all_directory($path, $dest.'/'.$file, $overwrite);
3106
                    }
3107
                }
3108
            }
3109
            closedir($handle);
3110
        }
3111
    }
3112
3113
    /**
3114
     * Gets the new ID of one specific tool item from the tool name and the old ID.
3115
     *
3116
     * @param	string	Tool name
3117
     * @param	int	Old ID
3118
     *
3119
     * @return int New ID
3120
     */
3121
    public function get_new_id($tool, $ref)
3122
    {
3123
        // Check if the value exist in the current array.
3124
        if ($tool === 'hotpotatoes') {
3125
            $tool = 'document';
3126
        }
3127
3128
        if ($tool === 'student_publication') {
3129
            $tool = RESOURCE_WORK;
3130
        }
3131
3132
        if (isset($this->course->resources[$tool][$ref]) &&
3133
            isset($this->course->resources[$tool][$ref]->destination_id) &&
3134
            !empty($this->course->resources[$tool][$ref]->destination_id)
3135
        ) {
3136
            return $this->course->resources[$tool][$ref]->destination_id;
3137
        }
3138
3139
        // Check if the course is the same (last hope).
3140
        if ($this->course_origin_id == $this->destination_course_id) {
3141
            return $ref;
3142
        }
3143
3144
        return '';
3145
    }
3146
3147
    /**
3148
     * Restore glossary.
3149
     */
3150
    public function restore_glossary($sessionId = 0)
3151
    {
3152
        $sessionId = (int) $sessionId;
3153
        if ($this->course->has_resources(RESOURCE_GLOSSARY)) {
3154
            $table_glossary = Database::get_course_table(TABLE_GLOSSARY);
3155
            $resources = $this->course->resources;
3156
            foreach ($resources[RESOURCE_GLOSSARY] as $id => $glossary) {
3157
                $params = [];
3158
                if (!empty($sessionId)) {
3159
                    $params['session_id'] = $sessionId;
3160
                }
3161
3162
                // check resources inside html from ckeditor tool and copy correct urls into recipient course
3163
                $glossary->description = DocumentManager::replaceUrlWithNewCourseCode(
3164
                    $glossary->description,
3165
                    $this->course->code,
3166
                    $this->course->destination_path,
3167
                    $this->course->backup_path,
3168
                    $this->course->info['path']
3169
                );
3170
3171
                $params['c_id'] = $this->destination_course_id;
3172
                $params['description'] = ($glossary->description === false ? '' : self::DBUTF8($glossary->description));
3173
                $params['display_order'] = $glossary->display_order;
3174
                $params['name'] = self::DBUTF8($glossary->name);
3175
                $params['glossary_id'] = 0;
3176
                $my_id = Database::insert($table_glossary, $params);
3177
                if ($my_id) {
3178
                    $sql = "UPDATE $table_glossary SET glossary_id = iid WHERE iid = $my_id";
3179
                    Database::query($sql);
3180
3181
                    api_item_property_update(
3182
                        $this->destination_course_info,
3183
                        TOOL_GLOSSARY,
3184
                        $my_id,
3185
                        'GlossaryAdded',
3186
                        api_get_user_id(),
3187
                        null,
3188
                        null,
3189
                        null,
3190
                        null,
3191
                        $sessionId
3192
                    );
3193
3194
                    if (!isset($this->course->resources[RESOURCE_GLOSSARY][$id])) {
3195
                        $this->course->resources[RESOURCE_GLOSSARY][$id] = new stdClass();
3196
                    }
3197
3198
                    $this->course->resources[RESOURCE_GLOSSARY][$id]->destination_id = $my_id;
3199
                }
3200
            }
3201
        }
3202
    }
3203
3204
    /**
3205
     * @param int $sessionId
3206
     */
3207
    public function restore_wiki($sessionId = 0)
3208
    {
3209
        if ($this->course->has_resources(RESOURCE_WIKI)) {
3210
            // wiki table of the target course
3211
            $table_wiki = Database::get_course_table(TABLE_WIKI);
3212
            $table_wiki_conf = Database::get_course_table(TABLE_WIKI_CONF);
3213
3214
            // storing all the resources that have to be copied in an array
3215
            $resources = $this->course->resources;
3216
3217
            foreach ($resources[RESOURCE_WIKI] as $id => $wiki) {
3218
                // the sql statement to insert the groups from the old course to the new course
3219
                // check resources inside html from ckeditor tool and copy correct urls into recipient course
3220
                $wiki->content = DocumentManager::replaceUrlWithNewCourseCode(
3221
                    $wiki->content,
3222
                    $this->course->code,
3223
                    $this->course->destination_path,
3224
                    $this->course->backup_path,
3225
                    $this->course->info['path']
3226
                );
3227
3228
                $params = [
3229
                    'c_id' => $this->destination_course_id,
3230
                    'page_id' => self::DBUTF8($wiki->page_id),
3231
                    'reflink' => self::DBUTF8($wiki->reflink),
3232
                    'title' => self::DBUTF8($wiki->title),
3233
                    'content' => ($wiki->content === false ? '' : self::DBUTF8($wiki->content)),
3234
                    'user_id' => intval($wiki->user_id),
3235
                    'group_id' => intval($wiki->group_id),
3236
                    'dtime' => self::DBUTF8($wiki->dtime),
3237
                    'progress' => self::DBUTF8($wiki->progress),
3238
                    'version' => intval($wiki->version),
3239
                    'session_id' => !empty($sessionId) ? intval($sessionId) : 0,
3240
                    'addlock' => 0,
3241
                    'editlock' => 0,
3242
                    'visibility' => 0,
3243
                    'addlock_disc' => 0,
3244
                    'visibility_disc' => 0,
3245
                    'ratinglock_disc' => 0,
3246
                    'assignment' => 0,
3247
                    'comment' => '',
3248
                    'is_editing' => 0,
3249
                    'linksto' => 0,
3250
                    'tag' => '',
3251
                    'user_ip' => '',
3252
                ];
3253
3254
                $new_id = Database::insert($table_wiki, $params);
3255
3256
                if ($new_id) {
3257
                    $sql = "UPDATE $table_wiki SET page_id = '$new_id', id = iid
3258
                            WHERE c_id = ".$this->destination_course_id." AND iid = '$new_id'";
3259
                    Database::query($sql);
3260
3261
                    $this->course->resources[RESOURCE_WIKI][$id]->destination_id = $new_id;
3262
3263
                    // we also add an entry in wiki_conf
3264
                    $params = [
3265
                        'c_id' => $this->destination_course_id,
3266
                        'page_id' => $new_id,
3267
                        'task' => '',
3268
                        'feedback1' => '',
3269
                        'feedback2' => '',
3270
                        'feedback3' => '',
3271
                        'fprogress1' => '',
3272
                        'fprogress2' => '',
3273
                        'fprogress3' => '',
3274
                        'max_size' => 0,
3275
                        'max_text' => 0,
3276
                        'max_version' => 0,
3277
                        'startdate_assig' => null,
3278
                        'enddate_assig' => null,
3279
                        'delayedsubmit' => 0,
3280
                    ];
3281
3282
                    Database::insert($table_wiki_conf, $params);
3283
                }
3284
            }
3285
        }
3286
    }
3287
3288
    /**
3289
     * Restore Thematics.
3290
     *
3291
     * @param int $sessionId
3292
     */
3293
    public function restore_thematic($sessionId = 0)
3294
    {
3295
        if ($this->course->has_resources(RESOURCE_THEMATIC)) {
3296
            $table_thematic = Database::get_course_table(TABLE_THEMATIC);
3297
            $table_thematic_advance = Database::get_course_table(TABLE_THEMATIC_ADVANCE);
3298
            $table_thematic_plan = Database::get_course_table(TABLE_THEMATIC_PLAN);
3299
3300
            $resources = $this->course->resources;
3301
            foreach ($resources[RESOURCE_THEMATIC] as $id => $thematic) {
3302
                // check resources inside html from ckeditor tool and copy correct urls into recipient course
3303
                $thematic->params['content'] = DocumentManager::replaceUrlWithNewCourseCode(
3304
                    $thematic->params['content'],
3305
                    $this->course->code,
3306
                    $this->course->destination_path,
3307
                    $this->course->backup_path,
3308
                    $this->course->info['path']
3309
                );
3310
                $thematic->params['c_id'] = $this->destination_course_id;
3311
                unset($thematic->params['id']);
3312
                unset($thematic->params['iid']);
3313
3314
                $last_id = Database::insert($table_thematic, $thematic->params, false);
3315
3316
                if ($last_id) {
3317
                    $sql = "UPDATE $table_thematic SET id = iid WHERE iid = $last_id";
3318
                    Database::query($sql);
3319
3320
                    api_item_property_update(
3321
                        $this->destination_course_info,
3322
                        'thematic',
3323
                        $last_id,
3324
                        'ThematicAdded',
3325
                        api_get_user_id(),
3326
                        null,
3327
                        null,
3328
                        null,
3329
                        null,
3330
                        $sessionId
3331
                    );
3332
3333
                    foreach ($thematic->thematic_advance_list as $thematic_advance) {
3334
                        unset($thematic_advance['id']);
3335
                        unset($thematic_advance['iid']);
3336
                        $thematic_advance['attendance_id'] = 0;
3337
                        $thematic_advance['thematic_id'] = $last_id;
3338
                        $thematic_advance['c_id'] = $this->destination_course_id;
3339
3340
                        $my_id = Database::insert(
3341
                            $table_thematic_advance,
3342
                            $thematic_advance,
3343
                            false
3344
                        );
3345
3346
                        if ($my_id) {
3347
                            $sql = "UPDATE $table_thematic_advance SET id = iid WHERE iid = $my_id";
3348
                            Database::query($sql);
3349
3350
                            api_item_property_update(
3351
                                $this->destination_course_info,
3352
                                'thematic_advance',
3353
                                $my_id,
3354
                                'ThematicAdvanceAdded',
3355
                                api_get_user_id(),
3356
                                null,
3357
                                null,
3358
                                null,
3359
                                null,
3360
                                $sessionId
3361
                            );
3362
                        }
3363
                    }
3364
3365
                    foreach ($thematic->thematic_plan_list as $thematic_plan) {
3366
                        unset($thematic_plan['id']);
3367
                        unset($thematic_plan['iid']);
3368
                        $thematic_plan['thematic_id'] = $last_id;
3369
                        $thematic_plan['c_id'] = $this->destination_course_id;
3370
                        $my_id = Database::insert($table_thematic_plan, $thematic_plan, false);
3371
3372
                        if ($my_id) {
3373
                            $sql = "UPDATE $table_thematic_plan SET id = iid WHERE iid = $my_id";
3374
                            Database::query($sql);
3375
3376
                            api_item_property_update(
3377
                                $this->destination_course_info,
3378
                                'thematic_plan',
3379
                                $my_id,
3380
                                'ThematicPlanAdded',
3381
                                api_get_user_id(),
3382
                                null,
3383
                                null,
3384
                                null,
3385
                                null,
3386
                                $sessionId
3387
                            );
3388
                        }
3389
                    }
3390
                }
3391
            }
3392
        }
3393
    }
3394
3395
    /**
3396
     * Restore Attendance.
3397
     *
3398
     * @param int $sessionId
3399
     */
3400
    public function restore_attendance($sessionId = 0)
3401
    {
3402
        if ($this->course->has_resources(RESOURCE_ATTENDANCE)) {
3403
            $table_attendance = Database::get_course_table(TABLE_ATTENDANCE);
3404
            $table_attendance_calendar = Database::get_course_table(TABLE_ATTENDANCE_CALENDAR);
3405
3406
            $resources = $this->course->resources;
3407
            foreach ($resources[RESOURCE_ATTENDANCE] as $id => $obj) {
3408
                // check resources inside html from ckeditor tool and copy correct urls into recipient course
3409
                $obj->params['description'] = DocumentManager::replaceUrlWithNewCourseCode(
3410
                    $obj->params['description'],
3411
                    $this->course->code,
3412
                    $this->course->destination_path,
3413
                    $this->course->backup_path,
3414
                    $this->course->info['path']
3415
                );
3416
3417
                unset($obj->params['id']);
3418
                unset($obj->params['iid']);
3419
                $obj->params['c_id'] = $this->destination_course_id;
3420
                $last_id = Database::insert($table_attendance, $obj->params);
3421
3422
                if (is_numeric($last_id)) {
3423
                    $sql = "UPDATE $table_attendance SET id = iid WHERE iid = $last_id";
3424
                    Database::query($sql);
3425
3426
                    $this->course->resources[RESOURCE_ATTENDANCE][$id]->destination_id = $last_id;
3427
3428
                    api_item_property_update(
3429
                        $this->destination_course_info,
3430
                        TOOL_ATTENDANCE,
3431
                        $last_id,
3432
                        'AttendanceAdded',
3433
                        api_get_user_id(),
3434
                        null,
3435
                        null,
3436
                        null,
3437
                        null,
3438
                        $sessionId
3439
                    );
3440
3441
                    foreach ($obj->attendance_calendar as $attendance_calendar) {
3442
                        unset($attendance_calendar['id']);
3443
                        unset($attendance_calendar['iid']);
3444
3445
                        $attendance_calendar['attendance_id'] = $last_id;
3446
                        $attendance_calendar['c_id'] = $this->destination_course_id;
3447
                        $attendanceCalendarId = Database::insert(
3448
                            $table_attendance_calendar,
3449
                            $attendance_calendar
3450
                        );
3451
3452
                        $sql = "UPDATE $table_attendance_calendar SET id = iid WHERE iid = $attendanceCalendarId";
3453
                        Database::query($sql);
3454
                    }
3455
                }
3456
            }
3457
        }
3458
    }
3459
3460
    /**
3461
     * Restore Works.
3462
     *
3463
     * @param int $sessionId
3464
     */
3465
    public function restore_works($sessionId = 0)
3466
    {
3467
        require_once api_get_path(SYS_CODE_PATH).'work/work.lib.php';
3468
        if ($this->course->has_resources(RESOURCE_WORK)) {
3469
            $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
3470
3471
            $resources = $this->course->resources;
3472
            foreach ($resources[RESOURCE_WORK] as $obj) {
3473
                // check resources inside html from ckeditor tool and copy correct urls into recipient course
3474
                $obj->params['description'] = DocumentManager::replaceUrlWithNewCourseCode(
3475
                    $obj->params['description'],
3476
                    $this->course->code,
3477
                    $this->course->destination_path,
3478
                    $this->course->backup_path,
3479
                    $this->course->info['path']
3480
                );
3481
3482
                $id_work = $obj->params['id'];
3483
                $obj->params['id'] = null;
3484
                $obj->params['c_id'] = $this->destination_course_info['real_id'];
3485
3486
                // re-create dir
3487
                // @todo check security against injection of dir in crafted course backup here!
3488
                $path = $obj->params['url'];
3489
                $path = '/'.str_replace('/', '', substr($path, 1));
3490
3491
                $workData = [];
3492
3493
                switch ($this->file_option) {
3494
                    case FILE_SKIP:
3495
                        $workData = get_work_data_by_path(
3496
                            $path,
3497
                            $this->destination_course_info['real_id']
3498
                        );
3499
                        if (!empty($workData)) {
3500
                            break;
3501
                        }
3502
                        break;
3503
                    case FILE_OVERWRITE:
3504
                        if (!empty($this->course_origin_id)) {
3505
                            $sql = 'SELECT * FROM '.$table.'
3506
                                    WHERE
3507
                                        c_id = '.$this->course_origin_id.' AND
3508
                                        publication_id = '.$id_work;
3509
                            $result = Database::query($sql);
3510
                            $cant = Database::num_rows($result);
3511
                            if ($cant > 0) {
3512
                                $row = Database::fetch_assoc($result);
3513
                            }
3514
3515
                            $obj->params['enableExpiryDate'] = empty($row['expires_on']) ? false : true;
3516
                            $obj->params['enableEndDate'] = empty($row['ends_on']) ? false : true;
3517
                            $obj->params['expires_on'] = $row['expires_on'];
3518
                            $obj->params['ends_on'] = $row['ends_on'];
3519
                            $obj->params['enable_qualification'] = $row['enable_qualification'];
3520
                            $obj->params['add_to_calendar'] = !empty($row['add_to_calendar']) ? 1 : 0;
3521
                        }
3522
                        //no break
3523
                    case FILE_RENAME:
3524
                        $workData = get_work_data_by_path(
3525
                            $path,
3526
                            $this->destination_course_info['real_id']
3527
                        );
3528
                        break;
3529
                }
3530
3531
                $obj->params['work_title'] = $obj->params['title'];
3532
                $obj->params['new_dir'] = $obj->params['title'];
3533
3534
                if (empty($workData)) {
3535
                    $workId = addDir(
3536
                        $obj->params,
3537
                        api_get_user_id(),
3538
                        $this->destination_course_info,
3539
                        0,
3540
                        $sessionId
3541
                    );
3542
                    $this->course->resources[RESOURCE_WORK][$id_work]->destination_id = $workId;
3543
                } else {
3544
                    $workId = $workData['iid'];
3545
                    updateWork(
3546
                        $workId,
3547
                        $obj->params,
3548
                        $this->destination_course_info,
3549
                        $sessionId
3550
                    );
3551
                    updatePublicationAssignment(
3552
                        $workId,
3553
                        $obj->params,
3554
                        $this->destination_course_info,
3555
                        0
3556
                    );
3557
                    $this->course->resources[RESOURCE_WORK][$id_work]->destination_id = $workId;
3558
                }
3559
            }
3560
        }
3561
    }
3562
3563
    /**
3564
     * Restore gradebook.
3565
     *
3566
     * @param int $sessionId
3567
     *
3568
     * @return bool
3569
     */
3570
    public function restore_gradebook($sessionId = 0)
3571
    {
3572
        if (in_array($this->file_option, [FILE_SKIP, FILE_RENAME])) {
3573
            return false;
3574
        }
3575
        // if overwrite
3576
        if ($this->course->has_resources(RESOURCE_GRADEBOOK)) {
3577
            $resources = $this->course->resources;
3578
            $destinationCourseCode = $this->destination_course_info['code'];
3579
            // Delete destination gradebook
3580
            $cats = \Category:: load(
3581
                null,
3582
                null,
3583
                $destinationCourseCode,
3584
                null,
3585
                null,
3586
                $sessionId
3587
            );
3588
3589
            if (!empty($cats)) {
3590
                /** @var \Category $cat */
3591
                foreach ($cats as $cat) {
3592
                    $cat->delete_all();
3593
                }
3594
            }
3595
3596
            /** @var GradeBookBackup $obj */
3597
            foreach ($resources[RESOURCE_GRADEBOOK] as $id => $obj) {
3598
                if (!empty($obj->categories)) {
3599
                    $categoryIdList = [];
3600
                    /** @var \Category $cat */
3601
                    foreach ($obj->categories as $cat) {
3602
                        $cat->set_course_code($destinationCourseCode);
3603
                        $cat->set_session_id($sessionId);
3604
3605
                        $parentId = $cat->get_parent_id();
3606
                        if (!empty($parentId)) {
3607
                            if (isset($categoryIdList[$parentId])) {
3608
                                $cat->set_parent_id($categoryIdList[$parentId]);
3609
                            }
3610
                        }
3611
                        $oldId = $cat->get_id();
3612
                        $categoryId = $cat->add();
3613
                        $categoryIdList[$oldId] = $categoryId;
3614
                        if (!empty($cat->evaluations)) {
3615
                            /** @var \Evaluation $evaluation */
3616
                            foreach ($cat->evaluations as $evaluation) {
3617
                                $evaluation->set_category_id($categoryId);
3618
                                $evaluation->set_course_code($destinationCourseCode);
3619
                                $evaluation->setSessionId($sessionId);
3620
                                $evaluation->add();
3621
                            }
3622
                        }
3623
3624
                        if (!empty($cat->links)) {
3625
                            /** @var \AbstractLink $link */
3626
                            foreach ($cat->links as $link) {
3627
                                $link->set_category_id($categoryId);
3628
                                $link->set_course_code($destinationCourseCode);
3629
                                $link->set_session_id($sessionId);
3630
                                $import = false;
3631
                                $itemId = $link->get_ref_id();
3632
                                switch ($link->get_type()) {
3633
                                    case LINK_EXERCISE:
3634
                                        $type = RESOURCE_QUIZ;
3635
                                        break;
3636
                                    /*case LINK_DROPBOX:
3637
                                        break;*/
3638
                                    case LINK_STUDENTPUBLICATION:
3639
                                        $type = RESOURCE_WORK;
3640
                                        break;
3641
                                    case LINK_LEARNPATH:
3642
                                        $type = RESOURCE_LEARNPATH;
3643
                                        break;
3644
                                    case LINK_FORUM_THREAD:
3645
                                        $type = RESOURCE_FORUMTOPIC;
3646
                                        break;
3647
                                    case LINK_ATTENDANCE:
3648
                                        $type = RESOURCE_ATTENDANCE;
3649
                                        break;
3650
                                    case LINK_SURVEY:
3651
                                        $type = RESOURCE_ATTENDANCE;
3652
                                        break;
3653
                                    case LINK_HOTPOTATOES:
3654
                                        $type = RESOURCE_QUIZ;
3655
                                        break;
3656
                                }
3657
3658
                                if ($this->course->has_resources($type) &&
3659
                                    isset($this->course->resources[$type][$itemId])
3660
                                ) {
3661
                                    $item = $this->course->resources[$type][$itemId];
3662
                                    if ($item && $item->is_restored()) {
3663
                                        $link->set_ref_id($item->destination_id);
3664
                                        $import = true;
3665
                                    }
3666
                                }
3667
3668
                                if ($import) {
3669
                                    $link->add();
3670
                                }
3671
                            }
3672
                        }
3673
                    }
3674
                }
3675
            }
3676
        }
3677
    }
3678
3679
    /**
3680
     * Restore course assets (not included in documents).
3681
     */
3682
    public function restore_assets()
3683
    {
3684
        if ($this->course->has_resources(RESOURCE_ASSET)) {
3685
            $resources = $this->course->resources;
3686
            $path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/';
3687
3688
            foreach ($resources[RESOURCE_ASSET] as $asset) {
3689
                if (is_file($this->course->backup_path.'/'.$asset->path) &&
3690
                    is_readable($this->course->backup_path.'/'.$asset->path) &&
3691
                    is_dir(dirname($path.$asset->path)) &&
3692
                    is_writeable(dirname($path.$asset->path))
3693
                ) {
3694
                    switch ($this->file_option) {
3695
                        case FILE_SKIP:
3696
                            break;
3697
                        case FILE_OVERWRITE:
3698
                            copy(
3699
                                $this->course->backup_path.'/'.$asset->path,
3700
                                $path.$asset->path
3701
                            );
3702
                            break;
3703
                    }
3704
                }
3705
            }
3706
        }
3707
    }
3708
3709
    /**
3710
     * @param string $str
3711
     *
3712
     * @return string
3713
     */
3714
    public function DBUTF8($str)
3715
    {
3716
        if (UTF8_CONVERT) {
3717
            $str = utf8_encode($str);
3718
        }
3719
3720
        return $str;
3721
    }
3722
3723
    /**
3724
     * @param string $str
3725
     *
3726
     * @return string
3727
     */
3728
    public function DBUTF8escapestring($str)
3729
    {
3730
        if (UTF8_CONVERT) {
3731
            $str = utf8_encode($str);
3732
        }
3733
3734
        return Database::escape_string($str);
3735
    }
3736
3737
    /**
3738
     * @param array $array
3739
     *
3740
     * @return mixed
3741
     */
3742
    public function DBUTF8_array($array)
3743
    {
3744
        if (UTF8_CONVERT) {
3745
            foreach ($array as &$item) {
3746
                $item = utf8_encode($item);
3747
            }
3748
3749
            return $array;
3750
        } else {
3751
            return $array;
3752
        }
3753
    }
3754
3755
    /**
3756
     * @param int $groupId
3757
     *
3758
     * @return array
3759
     */
3760
    public function checkGroupId($groupId)
3761
    {
3762
        return \GroupManager::get_group_properties($groupId);
3763
    }
3764
3765
    /**
3766
     * @param string $documentPath
3767
     * @param string $webEditorCss
3768
     */
3769
    public function fixEditorHtmlContent($documentPath, $webEditorCss = '')
3770
    {
3771
        $extension = pathinfo(basename($documentPath), PATHINFO_EXTENSION);
3772
3773
        switch ($extension) {
3774
            case 'html':
3775
            case 'htm':
3776
                $contents = file_get_contents($documentPath);
3777
                $contents = str_replace(
3778
                    '{{css_editor}}',
3779
                    $webEditorCss,
3780
                    $contents
3781
                );
3782
                file_put_contents($documentPath, $contents);
3783
                break;
3784
        }
3785
    }
3786
3787
    /**
3788
     * Check if user exist otherwise use current user.
3789
     *
3790
     * @param int  $userId
3791
     * @param bool $returnNull
3792
     *
3793
     * @return int
3794
     */
3795
    private function checkUserId($userId, $returnNull = false)
3796
    {
3797
        if (!empty($userId)) {
3798
            $userInfo = api_get_user_info($userId);
3799
            if (empty($userInfo)) {
3800
                return api_get_user_id();
3801
            }
3802
        }
3803
3804
        if ($returnNull) {
3805
            return null;
3806
        }
3807
3808
        if (empty($userId)) {
3809
            return api_get_user_id();
3810
        }
3811
3812
        return $userId;
3813
    }
3814
}
3815