Completed
Push — 1.10.x ( 484d85...fbe198 )
by Julito
35:25
created

CourseRestorer::restore_quiz_question()   F

Complexity

Conditions 30
Paths 404

Size

Total Lines 298
Code Lines 205

Duplication

Lines 33
Ratio 11.07 %

Importance

Changes 0
Metric Value
cc 30
eloc 205
nc 404
nop 1
dl 33
loc 298
rs 3.4496
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
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CourseBundle\Entity\CQuizAnswer;
5
6
require_once 'Resource.class.php';
7
require_once 'GradeBookBackup.php';
8
require_once 'Course.class.php';
9
require_once 'Event.class.php';
10
require_once 'Link.class.php';
11
require_once 'ToolIntro.class.php';
12
require_once 'LinkCategory.class.php';
13
require_once 'ForumCategory.class.php';
14
require_once 'Forum.class.php';
15
require_once 'ForumTopic.class.php';
16
require_once 'ForumPost.class.php';
17
require_once 'CourseDescription.class.php';
18
require_once 'CourseCopyLearnpath.class.php';
19
require_once 'Survey.class.php';
20
require_once 'SurveyQuestion.class.php';
21
require_once 'Glossary.class.php';
22
require_once 'wiki.class.php';
23
require_once 'Thematic.class.php';
24
require_once 'Work.class.php';
25
26
define('FILE_SKIP', 1);
27
define('FILE_RENAME', 2);
28
define('FILE_OVERWRITE', 3);
29
define('UTF8_CONVERT', false); //false by default
30
31
/**
32
 * Class CourseRestorer
33
 *
34
 * Class to restore items from a course object to a Chamilo-course
35
 * @author Bart Mollet <[email protected]>
36
 * @author Julio Montoya <[email protected]> Several fixes/improvements
37
 * @package chamilo.backup
38
 */
39
class CourseRestorer
40
{
41
	/**
42
	 * The course-object
43
	 */
44
    public $course;
45
    public $destination_course_info;
46
47
	/**
48
	 * What to do with files with same name (FILE_SKIP, FILE_RENAME or
49
	 * FILE_OVERWRITE)
50
	 */
51
    public $file_option;
52
    public $set_tools_invisible_by_default;
53
    public $skip_content;
54
    public $tools_to_restore = array(
55
        'announcements',
56
        'attendance',
57
        'course_descriptions',
58
        'documents',
59
        'events',
60
        'forum_category',
61
        'forums',
62
       // 'forum_topics',
63
        'glossary',
64
        'quizzes',
65
        'test_category',
66
        'links',
67
        'learnpaths',
68
        'surveys',
69
        //'scorm_documents', ??
70
        'tool_intro',
71
        'thematic',
72
        'wiki',
73
        'works',
74
        'gradebook',
75
    );
76
77
    /** Setting per tool */
78
    public $tool_copy_settings = array();
79
80
    /**
81
     * If true adds the text "copy" in the title of an item (only for LPs right now)
82
     *
83
     **/
84
    public $add_text_in_items = false;
85
    public $destination_course_id;
86
87
    /**
88
     * CourseRestorer constructor.
89
     * @param Course $course
90
     */
91
    public function __construct($course)
92
    {
93
        $this->course = $course;
94
        $course_info = api_get_course_info($this->course->code);
95
        if (!empty($course_info)) {
96
            $this->course_origin_id = $course_info['real_id'];
97
        } else {
98
            $this->course_origin_id = null;
99
        }
100
        $this->file_option = FILE_RENAME;
101
        $this->set_tools_invisible_by_default = false;
102
        $this->skip_content = array();
103
    }
104
105
    /**
106
     * Set the file-option
107
     * @param int $option (optional) What to do with files with same name
108
     * FILE_SKIP, FILE_RENAME or FILE_OVERWRITE
109
     */
110
    public function set_file_option($option = FILE_OVERWRITE)
111
    {
112
        $this->file_option = $option;
113
    }
114
115
    /**
116
     * @param string $status
117
     */
118
    public function set_add_text_in_items($status)
119
    {
120
        $this->add_text_in_items = $status;
0 ignored issues
show
Documentation Bug introduced by
The property $add_text_in_items was declared of type boolean, but $status is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
121
    }
122
123
    /**
124
     * @param array $array
125
     */
126
    public function set_tool_copy_settings($array)
127
    {
128
        $this->tool_copy_settings = $array;
129
    }
130
131
	/**
132
	 * Restore a course.
133
     *
134
	 * @param string    $destination_course_code code of the Chamilo-course in
135
	 * @param int	    $session_id
136
	 * @param bool	    $update_course_settings Course settings are going to be restore?
137
     * @param bool      $respect_base_content
138
     * @return false|null
139
	 */
140
    public function restore(
141
        $destination_course_code = '',
142
        $session_id = 0,
143
        $update_course_settings = false,
144
        $respect_base_content = false
145
    ) {
146
        if ($destination_course_code == '') {
147
            $course_info = api_get_course_info();
148
            $this->destination_course_info = $course_info;
149
            $this->course->destination_path = $course_info['path'];
150
        } else {
151
            $course_info = api_get_course_info($destination_course_code);
152
            $this->destination_course_info = $course_info;
153
            $this->course->destination_path = $course_info['path'];
154
        }
155
        $this->destination_course_id = $course_info['real_id'];
156
157
        //Getting first teacher (for the forums)
158
        $teacher_list = CourseManager::get_teacher_list_from_course_code(
159
            $course_info['code']
160
        );
161
        $this->first_teacher_id = api_get_user_id();
162
163
        if (!empty($teacher_list)) {
164
            foreach ($teacher_list as $teacher) {
165
                $this->first_teacher_id = $teacher['user_id'];
166
                break;
167
            }
168
        }
169
170
        if (empty($this->course)) {
171
            return false;
172
        }
173
174
        // Source platform encoding - reading/detection
175
        // The correspondent data field has been added as of version 1.8.6.1
176
177
        if (empty($this->course->encoding)) {
178
            // The archive has been created by a system which is prior to 1.8.6.1 version.
179
            // In this case we have to detect the encoding.
180
            $sample_text = $this->course->get_sample_text()."\n";
181
            // Let us exclude ASCII lines, probably they are English texts.
182
            $sample_text = explode("\n", $sample_text);
183
            foreach ($sample_text as $key => &$line) {
184
                if (api_is_valid_ascii($line)) {
185
                    unset($sample_text[$key]);
186
                }
187
            }
188
            $sample_text = join("\n", $sample_text);
189
            $this->course->encoding = api_detect_encoding($sample_text, $course_info['language']);
190
        }
191
192
        // Encoding conversion of the course, if it is needed.
193
        $this->course->to_system_encoding();
194
195
        foreach ($this->tools_to_restore as $tool) {
196
            $function_build = 'restore_'.$tool;
197
            $this->$function_build($session_id, $respect_base_content, $destination_course_code);
198
        }
199
200
        if ($update_course_settings) {
201
            $this->restore_course_settings($destination_course_code);
202
        }
203
204
        // Restore the item properties
205
        $table = Database::get_course_table(TABLE_ITEM_PROPERTY);
206
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'] = intval($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(
232
                                    $property['tool']
233
                                );
234
                                $property['insert_user_id'] = $this->checkUserId($property['insert_user_id']);
235
236
                                $params['insert_user_id'] = self::DBUTF8(
237
                                    $property['insert_user_id']
238
                                );
239
                                $params['insert_date'] = self::DBUTF8(
240
                                    $property['insert_date']
241
                                );
242
                                $params['lastedit_date'] = self::DBUTF8(
243
                                    $property['lastedit_date']
244
                                );
245
                                $params['ref'] = $resource->destination_id;
246
                                $params['lastedit_type'] = self::DBUTF8(
247
                                    $property['lastedit_type']
248
                                );
249
                                $params['lastedit_user_id'] = self::DBUTF8(
250
                                    $property['lastedit_user_id']
251
                                );
252
                                $params['visibility'] = self::DBUTF8(
253
                                    $property['visibility']
254
                                );
255
                                $params['start_visible'] = self::DBUTF8(
256
                                    $property['start_visible']
257
                                );
258
                                $params['end_visible'] = self::DBUTF8(
259
                                    $property['end_visible']
260
                                );
261
262
                                $property['to_user_id'] = $this->checkUserId($property['to_user_id'], true);
263
264
                                $params['to_user_id'] = self::DBUTF8(
265
                                    $property['to_user_id']
266
                                );
267
                                //$params['to_group_id'] = 'NULL';
268
269
                                $id = Database::insert($table, $params);
270
                                if ($id) {
271
                                    $sql = "UPDATE $table SET id = iid WHERE iid = $id";
272
                                    Database::query($sql);
273
                                }
274
                            }
275
                        }
276
                    }
277
                }
278
            }
279
        }
280
    }
281
282
	/**
283
	 * Restore only harmless course settings:
284
     * course_language, visibility, department_name,department_url,
285
     * subscribe, unsubscribe ,category_code
286
	 *
287
	 * @param string $destination_course_code
288
	 */
289
    public function restore_course_settings($destination_course_code)
290
    {
291
	    $origin_course_info = api_get_course_info($destination_course_code);
292
	    $course_info = $this->course->info;
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Course.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
293
        $params['course_language'] = $course_info['language'];
294
        $params['visibility'] = $course_info['visibility'];
295
        $params['department_name'] = $course_info['department_name'];
296
        $params['department_url'] = $course_info['department_url'];
297
298
        $params['category_code'] = $course_info['categoryCode'];
299
        $params['subscribe'] = $course_info['subscribe_allowed'];
300
        $params['unsubscribe'] = $course_info['unsubscribe'];
301
	    CourseManager::update_attributes($origin_course_info['real_id'], $params);
302
	}
303
304
    /**
305
     * Restore documents
306
     *
307
     * @param int $session_id
308
     * @param bool $respect_base_content
309
     * @param string $destination_course_code
310
     */
311
    public function restore_documents($session_id = 0, $respect_base_content = false, $destination_course_code = '')
312
    {
313
        $course_info = api_get_course_info($destination_course_code);
314
315
        if ($this->course->has_resources(RESOURCE_DOCUMENT)) {
316
			$table = Database :: get_course_table(TABLE_DOCUMENT);
317
			$resources = $this->course->resources;
318
            $path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/';
319
320
			foreach ($resources[RESOURCE_DOCUMENT] as $id => $document) {
321
322
                if (empty($document->item_properties[0]['id_session'])) {
323
                    $my_session_id = 0;
324
                } else {
325
                    $my_session_id = $session_id;
326
                }
327
328
                if ($document->file_type == FOLDER) {
329
                    $visibility = $document->item_properties[0]['visibility'];
330
                    $new = substr($document->path, 8);
331
332
                    $folderList = explode('/', $new);
333
                    $tempFolder = '';
334
335
                    // Check if the parent path exists.
336
                    foreach ($folderList as $folder) {
337
                        $folderToCreate = $tempFolder.$folder;
338
                        $sysFolderPath = $path.'document'.$folderToCreate;
339
                        $tempFolder .= $folder.'/';
340
341
                        if (empty($folderToCreate)) {
342
                            continue;
343
                        }
344
345
                        $title = $document->title;
346
                        if (empty($title)) {
347
                            $title = basename($sysFolderPath);
348
                        }
349
350
                        // File doesn't exist in file system.
351
                        if (!is_dir($sysFolderPath)) {
352
                            // Creating directory
353
                            create_unexisting_directory(
354
                                $course_info,
355
                                api_get_user_id(),
356
                                $my_session_id,
357
                                0,
358
                                0,
359
                                $path.'document',
360
                                $folderToCreate,
361
                                $title,
362
                                $visibility
363
                            );
364
                        } else {
365
                            // File exist in file system.
366
                            $documentData = DocumentManager::get_document_id(
367
                                $course_info,
368
                                $folderToCreate,
369
                                $my_session_id
370
                            );
371
372
                            if (empty($documentData)) {
373
                                /* This means the folder exists in the
374
                                filesystem but not in the DB, trying to fix it */
375
                                add_document(
376
                                    $course_info,
377
                                    $folderToCreate,
378
                                    'folder',
379
                                    0,
380
                                    $title,
381
                                    null,
382
                                    null,
383
                                    false,
384
                                    null,
385
                                    $my_session_id
386
                                );
387
                            }
388
                        }
389
                    }
390
		    	} elseif ($document->file_type == DOCUMENT) {
391
                    //Checking if folder exists in the database otherwise we created it
392
                    $dir_to_create = dirname($document->path);
393
394
                    if (!empty($dir_to_create) && $dir_to_create != 'document' && $dir_to_create != '/') {
395
                        if (is_dir($path.dirname($document->path))) {
396
                            $sql = "SELECT id FROM $table
397
                                    WHERE
398
                                        c_id = ".$this->destination_course_id." AND
399
                                        path = '/".self::DBUTF8escapestring(substr(dirname($document->path), 9))."'";
400
                            $res = Database::query($sql);
401
                            if (Database::num_rows($res) == 0) {
402
                                //continue;
403
                                $visibility = $document->item_properties[0]['visibility'];
404
                                $new = '/'.substr(dirname($document->path), 9);
405
                                $title = $document->title;
406
                                if (empty($title)) {
407
                                    $title = str_replace('/', '', $new);
408
                                }
409
410
                                // This code fixes the possibility for a file without a directory entry to be
411
                                $document_id = add_document(
412
                                    $course_info,
413
                                    $new,
414
                                    'folder',
415
                                    0,
416
                                    $title,
417
                                    null,
418
                                    null,
419
                                    false
420
                                );
421
422
                                $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
423
                                $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
424
                                $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
425
                                $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
426
427
                                $insertUserId = $this->checkUserId($insertUserId);
428
                                $toUserId = $this->checkUserId($toUserId, true);
429
430
                                api_item_property_update(
431
                                    $course_info,
432
                                    TOOL_DOCUMENT,
433
                                    $document_id,
434
                                    'FolderCreated',
435
                                    $insertUserId,
436
                                    $toGroupId,
437
                                    $toUserId,
438
                                    null,
439
                                    null,
440
                                    $my_session_id
441
                                );
442
                            }
443
                        }
444
                    }
445
446
					if (file_exists($path.$document->path)) {
447
						switch ($this->file_option) {
448
							case FILE_OVERWRITE:
449
                                $origin_path = $this->course->backup_path.'/'.$document->path;
450
451
								if (file_exists($origin_path)) {
452
        						    copy($origin_path, $path.$document->path);
453
                                    $sql = "SELECT id FROM $table
454
                                            WHERE
455
                                                c_id = ".$this->destination_course_id." AND
456
                                                path = '/".self::DBUTF8escapestring(substr($document->path, 9))."'";
457
458
        						    $res = Database::query($sql);
459
                                    $count = Database::num_rows($res);
460
461
                                    if ($count == 0) {
462
                                        $params = [
463
                                            'path' => "/".self::DBUTF8(substr($document->path, 9)),
464
                                            'c_id' => $this->destination_course_id,
465
                                            'comment'=> self::DBUTF8($document->comment),
466
                                            'title' => self::DBUTF8($document->title),
467
                                            'filetype' => self::DBUTF8($document->file_type),
468
                                            'size' => self::DBUTF8($document->size),
469
                                            'session_id' => $my_session_id,
470
                                        ];
471
472
    									$document_id = Database::insert($table, $params);
473
474
                                        if ($document_id) {
475
                                            $sql = "UPDATE $table SET id = iid WHERE iid = $document_id";
476
                                            Database::query($sql);
477
                                        }
478
                                        $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id;
479
480
                                        $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
481
                                        $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
482
                                        $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
483
                                        $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
484
485
                                        $insertUserId = $this->checkUserId($insertUserId);
486
                                        $toUserId = $this->checkUserId($toUserId, true);
487
488
                                        api_item_property_update(
489
                                            $course_info,
490
                                            TOOL_DOCUMENT,
491
                                            $document_id,
492
                                            'DocumentAdded',
493
                                            $insertUserId,
494
                                            $toGroupId,
495
                                            $toUserId,
496
                                            null,
497
                                            null,
498
                                            $my_session_id
499
                                        );
500
                                    } else {
501
                                        $obj = Database::fetch_object($res);
502
                                        $document_id = $obj->id;
503
                                        $params = [
504
                                            'path' => "/".self::DBUTF8(substr($document->path, 9)),
505
                                            'c_id' => $this->destination_course_id,
506
                                            'comment'=> self::DBUTF8($document->comment),
507
                                            'title' => self::DBUTF8($document->title),
508
                                            'filetype' => self::DBUTF8($document->file_type),
509
                                            'size' => self::DBUTF8($document->size),
510
                                            'session_id' => $my_session_id,
511
                                        ];
512
513
                                        Database::update(
514
                                            $table,
515
                                            $params,
516
                                            [
517
                                                'c_id = ? AND path = ?' => [
518
                                                    $this->destination_course_id,
519
                                                    "/".self::DBUTF8escapestring(substr($document->path, 9)),
520
                                                ],
521
                                            ]
522
                                        );
523
524
                                        $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $obj->id;
525
526
                                        $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
527
                                        $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
528
                                        $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
529
                                        $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
530
531
                                        $insertUserId = $this->checkUserId($insertUserId);
532
                                        $toUserId = $this->checkUserId($toUserId, true);
533
534
                                        api_item_property_update(
535
                                            $course_info,
536
                                            TOOL_DOCUMENT,
537
                                            $obj->id,
538
                                            'default',
539
                                            $insertUserId,
540
                                            $toGroupId,
541
                                            $toUserId,
542
                                            null,
543
                                            null,
544
                                            $my_session_id
545
                                        );
546
                                    }
547
548
                                    // Replace old course code with the new destination code
549
550
                                    $file_info = pathinfo($path.$document->path);
551
552
                                    if (in_array($file_info['extension'], array('html', 'htm'))) {
553
                                        $content = file_get_contents($path.$document->path);
554
                                        if (UTF8_CONVERT) $content = utf8_encode($content);
555
                                        $content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
556
                                            $content,
557
                                            $this->course->code,
558
                                            $this->course->destination_path,
559
                                            $this->course->backup_path,
560
                                            $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Course.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
561
                                        );
562
                                        file_put_contents($path.$document->path,$content);
563
                                    }
564
565
                                    $params = [
566
                                        'comment'=> self::DBUTF8($document->comment),
567
                                        'title' => self::DBUTF8($document->title),
568
                                        'size' => self::DBUTF8($document->size),
569
                                    ];
570
                                    Database::update(
571
                                        $table,
572
                                        $params,
573
                                        [
574
                                            'c_id = ? AND id = ?' => [
575
                                                $this->destination_course_id,
576
                                                $document_id,
577
                                            ],
578
                                        ]
579
                                    );
580
								}
581
582
								break;
583
							case FILE_SKIP:
584
								$sql = "SELECT id FROM $table
585
								        WHERE
586
								            c_id = ".$this->destination_course_id." AND
587
								            path='/".self::DBUTF8escapestring(substr($document->path, 9))."'";
588
								$res = Database::query($sql);
589
								$obj = Database::fetch_object($res);
590
								$this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $obj->id;
591
								break;
592
							case FILE_RENAME:
593
								$i = 1;
594
								$ext = explode('.', basename($document->path));
595 View Code Duplication
								if (count($ext) > 1) {
596
									$ext = array_pop($ext);
597
									$file_name_no_ext = substr($document->path, 0, - (strlen($ext) + 1));
598
									$ext = '.'.$ext;
599
								} else {
600
									$ext = '';
601
									$file_name_no_ext = $document->path;
602
								}
603
								$new_file_name = $file_name_no_ext.'_'.$i.$ext;
604
								$file_exists = file_exists($path.$new_file_name);
605 View Code Duplication
								while ($file_exists) {
606
									$i ++;
607
									$new_file_name = $file_name_no_ext.'_'.$i.$ext;
608
									$file_exists = file_exists($path.$new_file_name);
609
								}
610
611
								if (!empty($session_id)) {
612
613
									$document_path = explode('/',$document->path,3);
614
									$course_path = $path;
615
									$orig_base_folder = $document_path[1];
616
									$orig_base_path   = $course_path.$document_path[0].'/'.$document_path[1];
617
618
									if (is_dir($orig_base_path)) {
619
620
										$new_base_foldername = $orig_base_folder;
621
										$new_base_path = $orig_base_path;
622
623
										if ($_SESSION['orig_base_foldername'] != $new_base_foldername) {
624
											unset($_SESSION['new_base_foldername']);
625
											unset($_SESSION['orig_base_foldername']);
626
											unset($_SESSION['new_base_path']);
627
										}
628
629
										$folder_exists = file_exists($new_base_path);
630
										if ($folder_exists) {
631
											$_SESSION['orig_base_foldername'] = $new_base_foldername; 		// e.g: carpeta1 in session
632
											$x = '';
633
											while ($folder_exists) {
634
												$x = $x + 1;
635
												$new_base_foldername = $document_path[1].'_'.$x;
636
												$new_base_path = $orig_base_path.'_'.$x;
637
                                                if ($_SESSION['new_base_foldername'] == $new_base_foldername) {
638
                                                    break;
639
                                                }
640
												$folder_exists = file_exists($new_base_path);
641
											}
642
											$_SESSION['new_base_foldername'] = $new_base_foldername;
643
											$_SESSION['new_base_path'] = $new_base_path;
644
										}
645
646
										if (isset($_SESSION['new_base_foldername']) && isset($_SESSION['new_base_path'])) {
647
											$new_base_foldername = $_SESSION['new_base_foldername'];
648
											$new_base_path = $_SESSION['new_base_path'];
649
										}
650
651
										$dest_document_path = $new_base_path.'/'.$document_path[2];		// e.g: "/var/www/wiener/courses/CURSO4/document/carpeta1_1/subcarpeta1/collaborative.png"
652
										$basedir_dest_path 	= dirname($dest_document_path);				// e.g: "/var/www/wiener/courses/CURSO4/document/carpeta1_1/subcarpeta1"
653
										$base_path_document = $course_path.$document_path[0];			// e.g: "/var/www/wiener/courses/CURSO4/document"
654
										$path_title = '/'.$new_base_foldername.'/'.$document_path[2];
655
656
										copy_folder_course_session(
657
                                            $basedir_dest_path,
658
                                            $base_path_document,
659
                                            $session_id,
660
                                            $course_info,
661
                                            $document,
662
                                            $this->course_origin_id
663
                                        );
664
665
                                        if (file_exists($course_path.$document->path)) {
666
                                            copy($course_path.$document->path, $dest_document_path);
667
                                        }
668
669
                                        //Replace old course code with the new destination code see BT#1985
670
                                        if (file_exists($dest_document_path)) {
671
                                            $file_info = pathinfo($dest_document_path);
672
                                            if (in_array($file_info['extension'], array('html','htm'))) {
673
                                                $content = file_get_contents($dest_document_path);
674
                                                if (UTF8_CONVERT) {
675
                                                    $content = utf8_encode($content);
676
                                                }
677
                                                $content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
678
                                                    $content,
679
                                                    $this->course->code,
680
                                                    $this->course->destination_path,
681
                                                    $this->course->backup_path,
682
                                                    $this->course->info['path']
683
                                                );
684
                                                file_put_contents($dest_document_path, $content);
685
                                            }
686
                                        }
687
688
                                        $params = [
689
                                            'path' => self::DBUTF8($path_title),
690
                                            'c_id' => $this->destination_course_id,
691
                                            'comment'=> self::DBUTF8($document->comment),
692
                                            'title' => self::DBUTF8(basename($path_title)),
693
                                            'filetype' => self::DBUTF8($document->file_type),
694
                                            'size' => self::DBUTF8($document->size),
695
                                            'session_id' => $my_session_id,
696
                                        ];
697
698
										$document_id = Database::insert($table, $params);
699
700
                                        if ($document_id) {
701
                                            $sql = "UPDATE $table SET id = iid WHERE iid = $document_id";
702
                                            Database::query($sql);
703
                                        }
704
705
                                        $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id;
706
707
                                        $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
708
                                        $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
709
                                        $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
710
                                        $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
711
712
                                        $insertUserId = $this->checkUserId($insertUserId);
713
                                        $toUserId = $this->checkUserId($toUserId, true);
714
715
                                        api_item_property_update(
716
                                            $course_info,
717
                                            TOOL_DOCUMENT,
718
                                            $document_id,
719
                                            'DocumentAdded',
720
                                            $insertUserId,
721
                                            $toGroupId,
722
                                            $toUserId,
723
                                            null,
724
                                            null,
725
                                            $my_session_id
726
                                        );
727
									} else {
728
									    if (file_exists($path.$document->path)) {
729
                                            copy($path.$document->path, $path.$new_file_name);
730
									    }
731
                                        //Replace old course code with the new destination code see BT#1985
732 View Code Duplication
                                        if (file_exists($path.$new_file_name)) {
733
                                            $file_info = pathinfo($path.$new_file_name);
734
                                            if (in_array($file_info['extension'], array('html','htm'))) {
735
                                                $content    = file_get_contents($path.$new_file_name);
736
                                                if (UTF8_CONVERT) {
737
                                                    $content = utf8_encode($content);
738
                                                }
739
                                                $content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
740
                                                    $content,
741
                                                    $this->course->code,
742
                                                    $this->course->destination_path,
743
                                                    $this->course->backup_path,
744
                                                    $this->course->info['path']
745
                                                );
746
                                                file_put_contents($path.$new_file_name, $content);
747
                                            }
748
                                        }
749
750
                                        $params = [
751
                                            'path' => "/".self::DBUTF8escapestring(substr($new_file_name, 9)),
752
                                            'c_id' => $this->destination_course_id,
753
                                            'comment'=> self::DBUTF8($document->comment),
754
                                            'title' => self::DBUTF8($document->title),
755
                                            'filetype' => self::DBUTF8($document->file_type),
756
                                            'size' => self::DBUTF8($document->size),
757
                                            'session_id' => $my_session_id,
758
                                        ];
759
760
                                        $document_id = Database::insert($table, $params);
761
762
                                        if ($document_id) {
763
                                            $sql = "UPDATE $table SET id = iid WHERE iid = $document_id";
764
                                            Database::query($sql);
765
766
                                            $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id;
767
768
                                            $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
769
                                            $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
770
                                            $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
771
                                            $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
772
773
                                            $insertUserId = $this->checkUserId($insertUserId);
774
                                            $toUserId = $this->checkUserId($toUserId, true);
775
776
                                            api_item_property_update(
777
                                                $course_info,
778
                                                TOOL_DOCUMENT,
779
                                                $document_id,
780
                                                'DocumentAdded',
781
                                                $insertUserId,
782
                                                $toGroupId,
783
                                                $toUserId,
784
                                                null,
785
                                                null,
786
                                                $my_session_id
787
                                            );
788
                                        }
789
									}
790
								} else {
791
792
									copy($this->course->backup_path.'/'.$document->path, $path.$new_file_name);
793
794
                                    //Replace old course code with the new destination code see BT#1985
795 View Code Duplication
                                    if (file_exists($path.$new_file_name)) {
796
                                        $file_info = pathinfo($path.$new_file_name);
797
                                        if (in_array($file_info['extension'], array('html','htm'))) {
798
                                            $content    = file_get_contents($path.$new_file_name);
799
                                            if (UTF8_CONVERT) {
800
                                                $content = utf8_encode($content);
801
                                            }
802
                                            $content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
803
                                                $content,
804
                                                $this->course->code,
805
                                                $this->course->destination_path,
806
                                                $this->course->backup_path,
807
                                                $this->course->info['path']
808
                                            );
809
                                            file_put_contents($path.$new_file_name, $content);
810
                                        }
811
                                    }
812
813
                                    $params = [
814
                                        'c_id' => $this->destination_course_id,
815
                                        'path' => "/".self::DBUTF8escapestring(substr($new_file_name, 9)),
816
                                        'comment'=> self::DBUTF8($document->comment),
817
                                        'title' => self::DBUTF8($document->title),
818
                                        'filetype' => self::DBUTF8($document->file_type),
819
                                        'size' => self::DBUTF8($document->size),
820
                                        'session_id' => $my_session_id,
821
                                    ];
822
823
                                    $document_id = Database::insert($table, $params);
824
825
                                    if ($document_id) {
826
                                        $sql = "UPDATE $table SET id = iid WHERE iid = $document_id";
827
                                        Database::query($sql);
828
                                    }
829
830
                                    $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id;
831
832
                                    $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
833
                                    $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
834
                                    $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
835
                                    $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
836
837
                                    $insertUserId = $this->checkUserId($insertUserId);
838
                                    $toUserId = $this->checkUserId($toUserId, true);
839
840
                                    api_item_property_update(
841
                                        $course_info,
842
                                        TOOL_DOCUMENT,
843
                                        $document_id,
844
                                        'DocumentAdded',
845
                                        $insertUserId,
846
                                        $toGroupId,
847
                                        $toUserId,
848
                                        null,
849
                                        null,
850
                                        $my_session_id
851
                                    );
852
								}
853
								break;
854
855
						} // end switch
856
					} else {
857
					    // end if file exists
858
						//make sure the source file actually exists
859
						if (is_file($this->course->backup_path.'/'.$document->path) &&
860
                            is_readable($this->course->backup_path.'/'.$document->path) &&
861
                            is_dir(dirname($path.$document->path)) &&
862
                            is_writeable(dirname($path.$document->path))
863
                        ) {
864
						    //echo 'Copying';
865
							copy($this->course->backup_path.'/'.$document->path, $path.$document->path);
866
867
                            //Replace old course code with the new destination code see BT#1985
868
                            if (file_exists($path.$document->path)) {
869
                                $file_info = pathinfo($path.$document->path);
870
                                if (in_array($file_info['extension'], array('html','htm'))) {
871
                                    $content    = file_get_contents($path.$document->path);
872
                                    if (UTF8_CONVERT) {
873
                                        $content = utf8_encode($content);
874
                                    }
875
                                    $content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
876
                                        $content,
877
                                        $this->course->code,
878
                                        $this->course->destination_path,
879
                                        $this->course->backup_path,
880
                                        $this->course->info['path']
881
                                    );
882
                                    file_put_contents($path.$document->path, $content);
883
                                }
884
                            }
885
886
                            $params = [
887
                                'c_id' => $this->destination_course_id,
888
                                'path' => "/".self::DBUTF8(substr($document->path, 9)),
889
                                'comment'=> self::DBUTF8($document->comment),
890
                                'title' => self::DBUTF8($document->title),
891
                                'filetype' => self::DBUTF8($document->file_type),
892
                                'size' => self::DBUTF8($document->size),
893
                                'session_id' => $my_session_id,
894
                            ];
895
896
                            $document_id = Database::insert($table, $params);
897
898
                            if ($document_id) {
899
                                $sql = "UPDATE $table SET id = iid WHERE iid = $document_id";
900
                                Database::query($sql);
901
                            }
902
903
							$this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id;
904
905
                            $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
906
                            $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
907
                            $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
908
                            $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
909
910
                            $insertUserId = $this->checkUserId($insertUserId);
911
                            $toUserId = $this->checkUserId($toUserId, true);
912
913
                            api_item_property_update(
914
                                $course_info,
915
                                TOOL_DOCUMENT,
916
                                $document_id,
917
                                'DocumentAdded',
918
                                $insertUserId,
919
                                $toGroupId,
920
                                $toUserId,
921
                                null,
922
                                null,
923
                                $my_session_id
924
                            );
925
						} else {
926
							if (is_file($this->course->backup_path.'/'.$document->path) &&
927
                                is_readable($this->course->backup_path.'/'.$document->path)
928
                            ) {
929
								error_log('Course copy generated an ignoreable error while trying to copy '.$this->course->backup_path.'/'.$document->path.': file not found');
930
							}
931 View Code Duplication
							if (!is_dir(dirname($path.$document->path))) {
932
								error_log('Course copy generated an ignoreable error while trying to copy to '.dirname($path.$document->path).': directory not found');
933
							}
934 View Code Duplication
							if (!is_writeable(dirname($path.$document->path))) {
935
								error_log('Course copy generated an ignoreable error while trying to copy to '.dirname($path.$document->path).': directory not writeable');
936
							}
937
						}
938
					} // end file doesn't exist
939
				}
940
			} // end for each
941
942
    		// Delete sessions for the copy the new folder in session
943
    		unset($_SESSION['new_base_foldername']);
944
    		unset($_SESSION['orig_base_foldername']);
945
    		unset($_SESSION['new_base_path']);
946
		}
947
	}
948
949
	/**
950
	 * Restore scorm documents
951
	 * TODO @TODO check that the restore function with renaming doesn't break the scorm structure!
952
     * see #7029
953
	 */
954
	public function restore_scorm_documents()
955
    {
956
		$perm = api_get_permissions_for_new_directories();
957
958
		if ($this->course->has_resources(RESOURCE_SCORM)) {
959
			$resources = $this->course->resources;
960
961
			foreach ($resources[RESOURCE_SCORM] as $document) {
962
				$path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/';
963
964
				@mkdir(dirname($path.$document->path), $perm, true);
965
966
				if (file_exists($path.$document->path)) {
967
					switch ($this->file_option) {
968
						case FILE_OVERWRITE:
969
							rmdirr($path.$document->path);
970
                            copyDirTo(
971
                                $this->course->backup_path . '/' . $document->path,
972
                                $path . dirname($document->path),
973
                                false
974
                            );
975
							break;
976
						case FILE_SKIP:
977
							break;
978
                        case FILE_RENAME:
979
							$i = 1;
980
							$ext = explode('.', basename($document->path));
981 View Code Duplication
							if (count($ext) > 1) {
982
								$ext = array_pop($ext);
983
								$file_name_no_ext = substr($document->path, 0, - (strlen($ext) + 1));
984
								$ext = '.'.$ext;
985
							} else {
986
								$ext = '';
987
								$file_name_no_ext = $document->path;
988
							}
989
990
							$new_file_name = $file_name_no_ext.'_'.$i.$ext;
991
							$file_exists = file_exists($path.$new_file_name);
992
993 View Code Duplication
							while ($file_exists) {
994
								$i ++;
995
								$new_file_name = $file_name_no_ext.'_'.$i.$ext;
996
								$file_exists = file_exists($path.$new_file_name);
997
							}
998
999
                            rename(
1000
                                $this->course->backup_path . '/' . $document->path,
1001
                                $this->course->backup_path . '/' . $new_file_name
1002
                            );
1003
                            copyDirTo(
1004
                                $this->course->backup_path . '/' . $new_file_name,
1005
                                $path . dirname($new_file_name),
1006
                                false
1007
                            );
1008
                            rename(
1009
                                $this->course->backup_path . '/' . $new_file_name,
1010
                                $this->course->backup_path . '/' . $document->path
1011
                            );
1012
1013
							break;
1014
					} // end switch
1015
				} else {
1016
                    // end if file exists
1017
                    copyDirTo(
1018
                        $this->course->backup_path . '/' . $document->path,
1019
                        $path . dirname($document->path),
1020
                        false
1021
                    );
1022
				}
1023
			} // end for each
1024
		}
1025
	}
1026
1027
	/**
1028
	 * Restore forums
1029
	 */
1030
	public function restore_forums($sessionId = 0)
1031
    {
1032
		if ($this->course->has_resources(RESOURCE_FORUM)) {
1033
            $sessionId = intval($sessionId);
1034
			$table_forum = Database::get_course_table(TABLE_FORUM);
1035
			$resources = $this->course->resources;
1036
			foreach ($resources[RESOURCE_FORUM] as $id => $forum) {
1037
                $params = (array)$forum->obj;
1038
                $cat_id = '';
1039
                if (isset($this->course->resources[RESOURCE_FORUMCATEGORY]) &&
1040
                    isset($this->course->resources[RESOURCE_FORUMCATEGORY][$params['forum_category']])) {
1041
                    if ($this->course->resources[RESOURCE_FORUMCATEGORY][$params['forum_category']]->destination_id == -1) {
1042
                        $cat_id = $this->restore_forum_category(
1043
                            $params['forum_category'],
1044
                            $sessionId
1045
                        );
1046
                    } else {
1047
                        $cat_id = $this->course->resources[RESOURCE_FORUMCATEGORY][$params['forum_category']]->destination_id;
1048
                    }
1049
                }
1050
1051
                $params = self::DBUTF8_array($params);
1052
                $params['c_id'] = $this->destination_course_id;
1053
                $params['forum_category'] = $cat_id;
1054
                $params['session_id'] = $sessionId;
1055
1056
                unset($params['forum_id']);
1057
                unset($params['iid']);
1058
1059
                $params['forum_comment'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1060
                    $params['forum_comment'],
1061
                    $this->course->code,
1062
                    $this->course->destination_path,
1063
                    $this->course->backup_path,
1064
                    $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Course.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1065
                );
1066
1067
                if (!empty($params['forum_image'])) {
1068
                    $original_forum_image = $this->course->path.'upload/forum/images/'.$params['forum_image'];
1069
                    if (file_exists($original_forum_image)) {
1070
                        $new_forum_image = api_get_path(SYS_COURSE_PATH).$this->destination_course_info['path'].'/upload/forum/images/'.$params['forum_image'];
1071
                        @copy($original_forum_image, $new_forum_image);
1072
                    }
1073
                }
1074
1075
                $new_id = Database::insert($table_forum, $params);
1076
1077
                if ($new_id) {
1078
                    $sql = "UPDATE $table_forum SET forum_id = iid WHERE iid = $new_id";
1079
                    Database::query($sql);
1080
                }
1081
1082
				$this->course->resources[RESOURCE_FORUM][$id]->destination_id = $new_id;
1083
1084
				$forum_topics = 0;
1085
				if (is_array($this->course->resources[RESOURCE_FORUMTOPIC])) {
1086
					foreach ($this->course->resources[RESOURCE_FORUMTOPIC] as $topic_id => $topic) {
1087
						if ($topic->obj->forum_id == $id) {
1088
							$this->restore_topic($topic_id, $new_id, $sessionId);
1089
							$forum_topics ++;
1090
						}
1091
					}
1092
				}
1093
				if ($forum_topics > 0) {
1094
					$sql = "UPDATE ".$table_forum." SET forum_threads = ".$forum_topics."
1095
                            WHERE c_id = {$this->destination_course_id} AND forum_id = ".(int)$new_id;
1096
					Database::query($sql);
1097
				}
1098
			}
1099
		}
1100
	}
1101
1102
	/**
1103
	 * Restore forum-categories
1104
	 */
1105
    public function restore_forum_category($my_id = null, $sessionId = 0)
1106
    {
1107
		$forum_cat_table = Database :: get_course_table(TABLE_FORUM_CATEGORY);
1108
		$resources = $this->course->resources;
1109
        if (!empty($resources[RESOURCE_FORUMCATEGORY])) {
1110
            foreach ($resources[RESOURCE_FORUMCATEGORY] as $id => $forum_cat) {
1111
                if (!empty($my_id)) {
1112
                    if ($my_id != $id) {
1113
                        continue;
1114
                    }
1115
                }
1116
                if ($forum_cat && !$forum_cat->is_restored()) {
1117
                    /*$title = $forum_cat->obj->cat_title;
1118
                    if (!empty($title)) {
1119
                        if (!preg_match('/.*\((.+)\)$/', $title, $matches)) {
1120
                            // This is for avoiding repetitive adding of training code after several backup/restore cycles.
1121
                            if ($matches[1] != $this->course->code) {
1122
                                $title = $title.' ('.$this->course->code.')';
1123
                            }
1124
                        }
1125
                    }*/
1126
                    $params = (array) $forum_cat->obj;
1127
                    $params['c_id'] = $this->destination_course_id;
1128
                    $params['cat_comment'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1129
                        $params['cat_comment'],
1130
                        $this->course->code,
1131
                        $this->course->destination_path,
1132
                        $this->course->backup_path,
1133
                        $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Course.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1134
                    );
1135
                    $params['session_id'] = intval($sessionId);
1136
1137
                    unset($params['cat_id']);
1138
                    unset($params['iid']);
1139
1140
                    $params = self::DBUTF8_array($params);
1141
                    $new_id = Database::insert($forum_cat_table, $params);
1142
1143
                    if ($new_id) {
1144
                        $sql = "UPDATE $forum_cat_table SET cat_id = iid WHERE iid = $new_id";
1145
                        Database::query($sql);
1146
                    }
1147
1148
                    $this->course->resources[RESOURCE_FORUMCATEGORY][$id]->destination_id = $new_id;
1149
                    if (!empty($my_id)) {
1150
                        return $new_id;
1151
                    }
1152
                }
1153
            }
1154
        }
1155
	}
1156
1157
	/**
1158
	 * Restore a forum-topic
1159
	 * @param false|string $forum_id
1160
	 */
1161
    public function restore_topic($thread_id, $forum_id, $sessionId = 0)
1162
    {
1163
		$table = Database :: get_course_table(TABLE_FORUM_THREAD);
1164
		$topic = $this->course->resources[RESOURCE_FORUMTOPIC][$thread_id];
1165
1166
        $params = (array)$topic->obj;
1167
        $params = self::DBUTF8_array($params);
1168
        $params['c_id'] = $this->destination_course_id;
1169
        $params['forum_id'] = $forum_id;
1170
        $params['thread_poster_id'] = $this->first_teacher_id;
1171
        $params['thread_date'] = api_get_utc_datetime();
1172
        $params['thread_close_date']  = '0000-00-00 00:00:00';
1173
        $params['thread_last_post'] = 0;
1174
        $params['thread_replies'] = 0;
1175
        $params['thread_views'] = 0;
1176
        $params['session_id'] = intval($sessionId);
1177
        unset($params['thread_id']);
1178
        unset($params['iid']);
1179
1180
        $new_id = Database::insert($table, $params);
1181
1182
        if ($new_id) {
1183
            $sql = "UPDATE $table SET thread_id = iid WHERE iid = $new_id";
1184
            Database::query($sql);
1185
        }
1186
1187
        api_item_property_update(
1188
            $this->destination_course_info,
1189
            TOOL_FORUM_THREAD,
1190
            $new_id,
1191
            'ThreadAdded',
1192
            api_get_user_id(),
1193
            0,
1194
            0,
1195
            null,
1196
            null,
1197
            $sessionId
1198
        );
1199
1200
		$this->course->resources[RESOURCE_FORUMTOPIC][$thread_id]->destination_id = $new_id;
1201
1202
		$topic_replies = -1;
1203
1204
		foreach ($this->course->resources[RESOURCE_FORUMPOST] as $post_id => $post) {
1205
			if ($post->obj->thread_id == $thread_id) {
1206
				$topic_replies++;
1207
				$this->restore_post($post_id, $new_id, $forum_id, $sessionId);
1208
			}
1209
		}
1210
		return $new_id;
1211
	}
1212
1213
	/**
1214
	 * Restore a forum-post
1215
	 * @TODO Restore tree-structure of posts. For example: attachments to posts.
1216
	 * @param false|string $topic_id
1217
	 */
1218
    public function restore_post($id, $topic_id, $forum_id, $sessionId = 0)
1219
    {
1220
		$table_post = Database :: get_course_table(TABLE_FORUM_POST);
1221
		$post = $this->course->resources[RESOURCE_FORUMPOST][$id];
1222
        $params = (array) $post->obj;
1223
        $params['c_id'] = $this->destination_course_id;
1224
        $params['forum_id'] = $forum_id;
1225
        $params['thread_id'] = $topic_id;
1226
        $params['poster_id'] = $this->first_teacher_id;
1227
        $params['post_date'] = api_get_utc_datetime();
1228
        unset($params['post_id']);
1229
        unset($params['iid']);
1230
        $params['post_text'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1231
            $params['post_text'],
1232
            $this->course->code,
1233
            $this->course->destination_path,
1234
            $this->course->backup_path,
1235
            $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Course.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1236
        );
1237
        $new_id = Database::insert($table_post, $params);
1238
1239
        if ($new_id) {
1240
            $sql = "UPDATE $table_post SET post_id = iid WHERE iid = $new_id";
1241
            Database::query($sql);
1242
        }
1243
1244
        api_item_property_update(
1245
            $this->destination_course_info,
1246
            TOOL_FORUM_POST,
1247
            $new_id,
1248
            'PostAdded',
1249
            api_get_user_id(),
1250
            0,
1251
            0,
1252
            null,
1253
            null,
1254
            $sessionId
1255
        );
1256
		$this->course->resources[RESOURCE_FORUMPOST][$id]->destination_id = $new_id;
1257
1258
		return $new_id;
1259
	}
1260
1261
	/**
1262
	 * Restore links
1263
	 */
1264
    public function restore_links($session_id = 0)
1265
    {
1266
		if ($this->course->has_resources(RESOURCE_LINK)) {
1267
			$link_table = Database :: get_course_table(TABLE_LINK);
1268
			$resources = $this->course->resources;
1269
1270
			foreach ($resources[RESOURCE_LINK] as $id => $link) {
1271
                $cat_id = $this->restore_link_category(
1272
                    $link->category_id,
1273
                    $session_id
1274
                );
1275
				$sql = "SELECT MAX(display_order)
1276
				        FROM $link_table
1277
				        WHERE
1278
				            c_id = ".$this->destination_course_id." AND
1279
				            category_id='" . intval($cat_id). "'";
1280
				$result = Database::query($sql);
1281
    			list($max_order) = Database::fetch_array($result);
0 ignored issues
show
Bug introduced by
It seems like $result can be null; however, fetch_array() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
1282
1283
                $params = [];
1284
    			if (!empty($session_id)) {
1285
                    $params['session_id'] = $session_id;
1286
    			}
1287
1288
                $params['c_id'] = $this->destination_course_id;
1289
                $params['url'] = self::DBUTF8($link->url);
1290
                $params['title'] = self::DBUTF8($link->title);
1291
                $params['description'] = self::DBUTF8($link->description);
1292
                $params['category_id'] = $cat_id;
1293
                $params['on_homepage'] = $link->on_homepage;
1294
                $params['display_order'] = $max_order+1;
1295
1296
                $id = Database::insert($link_table, $params);
1297
1298 View Code Duplication
                if ($id) {
1299
                    $sql = "UPDATE $link_table SET id = iid WHERE iid = $id";
1300
                    Database::query($sql);
1301
1302
                    api_item_property_update(
1303
                        $this->destination_course_info,
1304
                        TOOL_LINK,
1305
                        $id,
1306
                        'LinkAdded',
1307
                        api_get_user_id()
1308
                    );
1309
1310
                    if (!isset($this->course->resources[RESOURCE_LINK][$id])) {
1311
                        $this->course->resources[RESOURCE_LINK][$id] = new stdClass();
1312
                    }
1313
                    $this->course->resources[RESOURCE_LINK][$id]->destination_id = $id;
1314
                }
1315
			}
1316
		}
1317
	}
1318
1319
    /**
1320
     * Restore a link-category
1321
     */
1322
    public function restore_link_category($id, $session_id = 0)
1323
    {
1324
        $params = [];
1325
        if (!empty($session_id)) {
1326
            $params['session_id'] = $session_id;
1327
        }
1328
1329
        if ($id == 0) {
1330
            return 0;
1331
        }
1332
        $link_cat_table = Database :: get_course_table(TABLE_LINK_CATEGORY);
1333
        $resources = $this->course->resources;
1334
        $link_cat = $resources[RESOURCE_LINKCATEGORY][$id];
1335
        if (is_object($link_cat) && !$link_cat->is_restored()) {
1336
            $sql = "SELECT MAX(display_order) FROM  $link_cat_table
1337
			        WHERE c_id = ".$this->destination_course_id." ";
1338
            $result=Database::query($sql);
1339
            list($orderMax)=Database::fetch_array($result,'NUM');
0 ignored issues
show
Bug introduced by
It seems like $result can be null; however, fetch_array() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
1340
            $display_order=$orderMax+1;
1341
1342
            $params['c_id'] = $this->destination_course_id;
1343
            $params['category_title'] = self::DBUTF8($link_cat->title);
1344
            $params['description'] = self::DBUTF8($link_cat->description);
1345
            $params['display_order'] = $display_order;
1346
1347
            $new_id = Database::insert($link_cat_table, $params);
1348
1349
            if ($new_id) {
1350
                $sql = "UPDATE $link_cat_table SET id = iid WHERE iid = $new_id";
1351
                Database::query($sql);
1352
                api_set_default_visibility($new_id, TOOL_LINK_CATEGORY);
1353
            }
1354
1355
            $this->course->resources[RESOURCE_LINKCATEGORY][$id]->destination_id = $new_id;
1356
            return $new_id;
1357
        }
1358
        return $this->course->resources[RESOURCE_LINKCATEGORY][$id]->destination_id;
1359
    }
1360
1361
	/**
1362
	 * Restore tool intro
1363
	 */
1364
    public function restore_tool_intro($sessionId = 0)
1365
    {
1366
		if ($this->course->has_resources(RESOURCE_TOOL_INTRO)) {
1367
            $sessionId = intval($sessionId);
1368
			$tool_intro_table = Database :: get_course_table(TABLE_TOOL_INTRO);
1369
			$resources = $this->course->resources;
1370
			foreach ($resources[RESOURCE_TOOL_INTRO] as $id => $tool_intro) {
1371
				$sql = "DELETE FROM ".$tool_intro_table."
1372
				        WHERE
1373
				            c_id = ".$this->destination_course_id." AND
1374
				            id = '".self::DBUTF8escapestring($tool_intro->id)."'";
1375
				Database::query($sql);
1376
1377
                $tool_intro->intro_text = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1378
                    $tool_intro->intro_text,
1379
                    $this->course->code,
1380
                    $this->course->destination_path,
1381
                    $this->course->backup_path,
1382
                    $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Course.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1383
                );
1384
1385
                $params = [
1386
                    'c_id' => $this->destination_course_id,
1387
                    'id' => self::DBUTF8($tool_intro->id),
1388
                    'intro_text' => self::DBUTF8($tool_intro->intro_text),
0 ignored issues
show
Security Bug introduced by
It seems like $tool_intro->intro_text can also be of type false; however, CourseRestorer::DBUTF8() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
1389
                    'session_id' => $sessionId,
1390
                ];
1391
1392
                $id = Database::insert($tool_intro_table, $params);
1393
                if ($id) {
1394
                    // id is a varchar not an int
1395
                    /*$sql = "UPDATE $tool_intro_table SET id = iid WHERE iid = $id";
1396
                    Database::query($sql);*/
1397
1398
                    if (!isset($this->course->resources[RESOURCE_TOOL_INTRO][$id])) {
1399
                        $this->course->resources[RESOURCE_TOOL_INTRO][$id] = new stdClass();
1400
                    }
1401
1402
                    $this->course->resources[RESOURCE_TOOL_INTRO][$id]->destination_id = $id;
1403
                }
1404
			}
1405
		}
1406
	}
1407
1408
	/**
1409
	 * Restore events
1410
	 */
1411 View Code Duplication
    public function restore_events($sessionId = 0)
1412
    {
1413
		if ($this->course->has_resources(RESOURCE_EVENT)) {
1414
            $sessionId = intval($sessionId);
1415
			$table = Database :: get_course_table(TABLE_AGENDA);
1416
			$resources = $this->course->resources;
1417
			foreach ($resources[RESOURCE_EVENT] as $id => $event) {
1418
				// check resources inside html from ckeditor tool and copy correct urls into recipient course
1419
                $event->content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1420
                    $event->content,
1421
                    $this->course->code,
1422
                    $this->course->destination_path,
1423
                    $this->course->backup_path,
1424
                    $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Course.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1425
                );
1426
1427
                $params = [
1428
                    'c_id' => $this->destination_course_id,
1429
                    'title' => self::DBUTF8($event->title),
1430
                    'content' => self::DBUTF8($event->content),
0 ignored issues
show
Security Bug introduced by
It seems like $event->content can also be of type false; however, CourseRestorer::DBUTF8() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
1431
                    'all_day' => $event->all_day,
1432
                    'start_date' => $event->start_date,
1433
                    'end_date' => $event->end_date,
1434
                    'session_id' => $sessionId,
1435
                ];
1436
				$new_event_id = Database::insert($table, $params);
1437
1438
                if ($new_event_id) {
1439
                    $sql = "UPDATE $table SET id = iid WHERE iid = $new_event_id";
1440
                    Database::query($sql);
1441
1442
                    if (!isset($this->course->resources[RESOURCE_EVENT][$id])) {
1443
                        $this->course->resources[RESOURCE_EVENT][$id] = new stdClass();
1444
                    }
1445
1446
                    $this->course->resources[RESOURCE_EVENT][$id]->destination_id = $new_event_id;
1447
                }
1448
1449
				// Copy event attachment
1450
1451
				$origin_path = $this->course->backup_path.'/upload/calendar/';
1452
				$destination_path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/upload/calendar/';
1453
1454
				if (!empty($this->course->orig)) {
0 ignored issues
show
Bug introduced by
The property orig does not seem to exist in Course.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1455
1456
					$table_attachment = Database :: get_course_table(TABLE_AGENDA_ATTACHMENT);
1457
					$sql = 'SELECT path, comment, size, filename
1458
					        FROM '.$table_attachment.'
1459
					        WHERE c_id = '.$this->destination_course_id.' AND agenda_id = '.$id;
1460
					$attachment_event = Database::query($sql);
1461
					$attachment_event = Database::fetch_object($attachment_event);
0 ignored issues
show
Bug introduced by
It seems like $attachment_event can be null; however, fetch_object() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
1462
1463
					if (file_exists($origin_path.$attachment_event->path) &&
1464
                        !is_dir($origin_path.$attachment_event->path)
1465
                    ) {
1466
						$new_filename = uniqid(''); //ass seen in the add_agenda_attachment_file() function in agenda.inc.php
1467
						$copy_result = copy($origin_path.$attachment_event->path, $destination_path.$new_filename);
1468
						//$copy_result = true;
1469
						if ($copy_result) {
1470
							$table_attachment = Database :: get_course_table(TABLE_AGENDA_ATTACHMENT);
1471
1472
							$params = [
1473
                                'c_id' => $this->destination_course_id,
1474
                                'path' => self::DBUTF8($new_filename),
1475
                                'comment' => self::DBUTF8($attachment_event->comment),
1476
                                'size' => $attachment_event->size,
1477
                                'filename' => $attachment_event->filename,
1478
                                'agenda_id' => $new_event_id,
1479
                            ];
1480
                            $id = Database::insert($table_attachment, $params);
1481
                            if ($id) {
1482
                                $sql = "UPDATE $table_attachment SET id = iid WHERE iid = $id";
1483
                                Database::query($sql);
1484
                            }
1485
                        }
1486
					}
1487
				} else {
1488
					// get the info of the file
1489
					if (!empty($event->attachment_path) &&
1490
                        is_file($origin_path.$event->attachment_path) &&
1491
                        is_readable($origin_path.$event->attachment_path)
1492
                    ) {
1493
						$new_filename = uniqid(''); //ass seen in the add_agenda_attachment_file() function in agenda.inc.php
1494
						$copy_result = copy($origin_path.$event->attachment_path, $destination_path.$new_filename);
1495
						if ($copy_result) {
1496
							$table_attachment = Database :: get_course_table(TABLE_AGENDA_ATTACHMENT);
1497
1498
                            $params = [
1499
                                'c_id' => $this->destination_course_id,
1500
                                'path' => self::DBUTF8($new_filename),
1501
                                'comment' => self::DBUTF8($event->attachment_comment),
1502
                                'size' => $event->size,
1503
                                'filename' => $event->filename,
1504
                                'agenda_id' => $new_event_id,
1505
                            ];
1506
                            $id = Database::insert($table_attachment, $params);
1507
1508
                            if ($id) {
1509
                                $sql = "UPDATE $table_attachment SET id = iid WHERE iid = $id";
1510
                                Database::query($sql);
1511
                            }
1512
						}
1513
					}
1514
				}
1515
			}
1516
		}
1517
	}
1518
1519
	/**
1520
	 * Restore course-description
1521
	 */
1522
    public function restore_course_descriptions($session_id = 0)
1523
    {
1524
		if ($this->course->has_resources(RESOURCE_COURSEDESCRIPTION)) {
1525
			$table = Database :: get_course_table(TABLE_COURSE_DESCRIPTION);
1526
			$resources = $this->course->resources;
1527
			foreach ($resources[RESOURCE_COURSEDESCRIPTION] as $id => $cd) {
1528
                $courseDescription = (array) $cd;
1529
1530
                $content = isset($courseDescription['content']) ? $courseDescription['content'] : '';
1531
                $descriptionType = isset($courseDescription['description_type']) ? $courseDescription['description_type'] : '';
1532
                $title = isset($courseDescription['title']) ? $courseDescription['title'] : '';
1533
1534
				// check resources inside html from ckeditor tool and copy correct urls into recipient course
1535
                $description_content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1536
                    $content,
1537
                    $this->course->code,
1538
                    $this->course->destination_path,
1539
                    $this->course->backup_path,
1540
                    $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Course.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1541
                );
1542
1543
                $params = [];
1544
1545
                $session_id = intval($session_id);
1546
                $params['session_id'] = $session_id;
1547
                $params['c_id'] = $this->destination_course_id;
1548
                $params['description_type'] = self::DBUTF8($descriptionType);
1549
                $params['title'] = self::DBUTF8($title);
1550
                $params['content'] = self::DBUTF8($description_content);
0 ignored issues
show
Security Bug introduced by
It seems like $description_content defined by \DocumentManager::replac...->course->info['path']) on line 1535 can also be of type false; however, CourseRestorer::DBUTF8() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
1551
1552
                $id = Database::insert($table, $params);
1553
                if ($id) {
1554
                    $sql = "UPDATE $table SET id = iid WHERE iid = $id";
1555
                    Database::query($sql);
1556
1557
                    if (!isset($this->course->resources[RESOURCE_COURSEDESCRIPTION][$id])) {
1558
                        $this->course->resources[RESOURCE_COURSEDESCRIPTION][$id] = new stdClass();
1559
                    }
1560
                    $this->course->resources[RESOURCE_COURSEDESCRIPTION][$id]->destination_id = $id;
1561
                }
1562
			}
1563
		}
1564
	}
1565
1566
	/**
1567
	 * Restore announcements
1568
	 */
1569 View Code Duplication
    public function restore_announcements($sessionId = 0)
1570
    {
1571
		if ($this->course->has_resources(RESOURCE_ANNOUNCEMENT)) {
1572
            $sessionId = intval($sessionId);
1573
			$table = Database :: get_course_table(TABLE_ANNOUNCEMENT);
1574
			$resources = $this->course->resources;
1575
			foreach ($resources[RESOURCE_ANNOUNCEMENT] as $id => $announcement) {
1576
1577
				// check resources inside html from ckeditor tool and copy correct urls into recipient course
1578
                $announcement->content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1579
                    $announcement->content,
1580
                    $this->course->code,
1581
                    $this->course->destination_path,
1582
                    $this->course->backup_path,
1583
                    $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Course.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1584
                );
1585
1586
                $params = [
1587
                    'c_id' => $this->destination_course_id,
1588
                    'title' =>  self::DBUTF8($announcement->title),
1589
                    'content' => self::DBUTF8($announcement->content),
0 ignored issues
show
Security Bug introduced by
It seems like $announcement->content can also be of type false; however, CourseRestorer::DBUTF8() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
1590
                    'end_date' => $announcement->date,
1591
                    'display_order' => $announcement->display_order,
1592
                    'email_sent' => $announcement->email_sent,
1593
                    'session_id' => $sessionId,
1594
                ];
1595
1596
				$new_announcement_id = Database::insert($table, $params);
1597
1598
                if ($new_announcement_id) {
1599
                    $sql = "UPDATE $table SET id = iid WHERE iid = $new_announcement_id";
1600
                    Database::query($sql);
1601
1602
                    if (!isset($this->course->resources[RESOURCE_ANNOUNCEMENT][$id])) {
1603
                        $this->course->resources[RESOURCE_ANNOUNCEMENT][$id] = new stdClass();
1604
                    }
1605
                    $this->course->resources[RESOURCE_ANNOUNCEMENT][$id]->destination_id = $new_announcement_id;
1606
                }
1607
1608
				$origin_path = $this->course->backup_path.'/upload/announcements/';
1609
				$destination_path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/upload/announcements/';
1610
1611
				// Copy announcement attachment file
1612
				if (!empty($this->course->orig)) {
0 ignored issues
show
Bug introduced by
The property orig does not seem to exist in Course.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1613
1614
					$table_attachment = Database::get_course_table(TABLE_ANNOUNCEMENT_ATTACHMENT);
1615
					$sql = 'SELECT path, comment, size, filename
1616
					        FROM '.$table_attachment.'
1617
					        WHERE
1618
					            c_id = '.$this->destination_course_id.' AND
1619
					            announcement_id = '.$id;
1620
					$attachment_event = Database::query($sql);
1621
					$attachment_event = Database::fetch_object($attachment_event);
0 ignored issues
show
Bug introduced by
It seems like $attachment_event can be null; however, fetch_object() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
1622
1623
					if (file_exists($origin_path.$attachment_event->path) &&
1624
                        !is_dir($origin_path.$attachment_event->path)
1625
                    ) {
1626
						$new_filename = uniqid(''); //ass seen in the add_agenda_attachment_file() function in agenda.inc.php
1627
                        $copy_result = copy(
1628
                            $origin_path.$attachment_event->path,
1629
                            $destination_path.$new_filename
1630
                        );
1631
1632
						if ($copy_result) {
1633
							$table_attachment = Database :: get_course_table(TABLE_ANNOUNCEMENT_ATTACHMENT);
1634
1635
                            $params = [
1636
                                'c_id' => $this->destination_course_id,
1637
                                'path' => self::DBUTF8($new_filename),
1638
                                'comment' => self::DBUTF8($attachment_event->comment),
1639
                                'size' => $attachment_event->size,
1640
                                'filename' => $attachment_event->filename,
1641
                                'announcement_id' => $new_announcement_id,
1642
                            ];
1643
1644
                            $attachmentId = Database::insert($table_attachment, $params);
1645
1646
                            if ($attachmentId) {
1647
                                $sql = "UPDATE $table_attachment SET id = iid WHERE iid = $attachmentId";
1648
                                Database::query($sql);
1649
                            }
1650
						}
1651
					}
1652
				} else {
1653
					// get the info of the file
1654
					if (!empty($announcement->attachment_path) &&
1655
                        is_file($origin_path.$announcement->attachment_path) &&
1656
                        is_readable($origin_path.$announcement->attachment_path)
1657
                    ) {
1658
						$new_filename = uniqid(''); //ass seen in the add_agenda_attachment_file() function in agenda.inc.php
1659
						$copy_result = copy($origin_path.$announcement->attachment_path, $destination_path.$new_filename);
1660
1661
						if ($copy_result) {
1662
							$table_attachment = Database :: get_course_table(TABLE_ANNOUNCEMENT_ATTACHMENT);
1663
							/*$sql = "INSERT INTO ".$table_attachment." SET
1664
							        c_id = ".$this->destination_course_id." ,
1665
							        path = '".self::DBUTF8escapestring($new_filename)."',
1666
							        comment = '".self::DBUTF8escapestring($announcement->attachment_comment)."',
1667
							        size = '".$announcement->attachment_size."', filename = '".$announcement->attachment_filename."',
1668
							        announcement_id = '".$new_announcement_id."' ";
1669
							Database::query($sql);*/
1670
1671
                            $params = [
1672
                                'c_id' => $this->destination_course_id,
1673
                                'path' => self::DBUTF8($new_filename),
1674
                                'comment' => self::DBUTF8($announcement->attachment_comment),
1675
                                'size' => $announcement->attachment_size,
1676
                                'filename' => $announcement->attachment_filename,
1677
                                'announcement_id' => $new_announcement_id,
1678
                            ];
1679
1680
                            $attachmentId = Database::insert($table_attachment, $params);
1681
1682
                            if ($attachmentId) {
1683
                                $sql = "UPDATE $table_attachment SET id = iid WHERE iid = $attachmentId";
1684
                                Database::query($sql);
1685
                            }
1686
						}
1687
					}
1688
				}
1689
			}
1690
		}
1691
	}
1692
1693
    /**
1694
     * Restore Quiz
1695
     * @param int $session_id
1696
     * @param bool $respect_base_content
1697
     */
1698
    public function restore_quizzes(
1699
        $session_id = 0,
1700
        $respect_base_content = false
1701
    ) {
1702
		if ($this->course->has_resources(RESOURCE_QUIZ)) {
1703
			$table_qui = Database :: get_course_table(TABLE_QUIZ_TEST);
1704
			$table_rel = Database :: get_course_table(TABLE_QUIZ_TEST_QUESTION);
1705
			$table_doc = Database :: get_course_table(TABLE_DOCUMENT);
1706
			$resources = $this->course->resources;
1707
1708
			foreach ($resources[RESOURCE_QUIZ] as $id => $quiz) {
1709
1710
                if (isset($quiz->obj)) {
1711
                    //For new imports
1712
                    $quiz = $quiz->obj;
1713
                } else {
1714
                    //For backward compatibility
1715
                    $quiz->obj = $quiz;
1716
                }
1717
1718
				$doc = '';
1719
                if (!empty($quiz->sound)) {
1720
                    if (isset($this->course->resources[RESOURCE_DOCUMENT][$quiz->sound]) &&
1721
                        $this->course->resources[RESOURCE_DOCUMENT][$quiz->sound]->is_restored()) {
1722
                        $sql = "SELECT path FROM " . $table_doc . "
1723
                                WHERE
1724
                                    c_id = " . $this->destination_course_id . "  AND
1725
                                    id = " . $resources[RESOURCE_DOCUMENT][$quiz->sound]->destination_id;
1726
						$doc = Database::query($sql);
1727
						$doc = Database::fetch_object($doc);
0 ignored issues
show
Bug introduced by
It seems like $doc can be null; however, fetch_object() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
1728
						$doc = str_replace('/audio/', '', $doc->path);
1729
					}
1730
				}
1731
1732
				if ($id != -1) {
1733
					// check resources inside html from ckeditor tool and copy correct urls into recipient course
1734
                    $quiz->description = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1735
                        $quiz->description,
1736
                        $this->course->code,
1737
                        $this->course->destination_path,
1738
                        $this->course->backup_path,
1739
                        $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Course.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1740
                    );
1741
1742
					global $_custom;
1743
					if (isset($_custom['exercises_clean_dates_when_restoring']) &&
1744
                        $_custom['exercises_clean_dates_when_restoring']
1745
                    ) {
1746
						$quiz->start_time = null;
1747
						$quiz->end_time   = null;
1748
					}
1749
1750
                    $params = array(
1751
                        'c_id' => $this->destination_course_id,
1752
                        'title' => self::DBUTF8($quiz->title),
1753
                        'description' => self::DBUTF8($quiz->description),
0 ignored issues
show
Security Bug introduced by
It seems like $quiz->description can also be of type false; however, CourseRestorer::DBUTF8() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
1754
                        'type' => isset($quiz->quiz_type) ? $quiz->quiz_type : $quiz->type,
1755
                        'random' => $quiz->random,
1756
                        'active' => $quiz->active,
1757
                        'sound' => self::DBUTF8($doc),
1758
                        'max_attempt' => (int)$quiz->max_attempt,
1759
                        'results_disabled' => (int)$quiz->results_disabled,
1760
                        'access_condition' => $quiz->access_condition,
1761
                        'start_time' => $quiz->start_time,
1762
                        'pass_percentage' => $quiz->pass_percentage,
1763
                        'end_time' => $quiz->end_time,
1764
                        'feedback_type' => (int)$quiz->feedback_type,
1765
                        'random_answers' => (int)$quiz->random_answers,
1766
                        'random_by_category' => $quiz->random_by_category,
1767
                        'review_answers' => $quiz->review_answers,
1768
                        'propagate_neg' => $quiz->propagate_neg,
1769
                        'text_when_finished' => $quiz->text_when_finished,
1770
                        'expired_time' => (int)$quiz->expired_time,
1771
                    );
1772
1773 View Code Duplication
                    if ($respect_base_content) {
1774
                        $my_session_id = $quiz->session_id;
1775
                        if (!empty($quiz->session_id)) {
1776
                            $my_session_id = $session_id;
1777
                        }
1778
                        $params['session_id'] = $my_session_id;
1779
                    } else {
1780
        				if (!empty($session_id)) {
1781
        					$session_id = intval($session_id);
1782
                            $params['session_id'] = $session_id;
1783
    				    }
1784
                    }
1785
                    $new_id = Database::insert($table_qui, $params);
1786
1787
                    if ($new_id) {
1788
                        $sql = "UPDATE $table_qui SET id = iid WHERE iid = $new_id";
1789
                        Database::query($sql);
1790
                    }
1791
1792
				} else {
1793
					// $id = -1 identifies the fictionary test for collecting
1794
					// orphan questions. We do not store it in the database.
1795
					$new_id = -1;
1796
				}
1797
1798
				$this->course->resources[RESOURCE_QUIZ][$id]->destination_id = $new_id;
1799
1800
				$order = 0;
1801
                if (!empty($quiz->question_ids)) {
1802
                    foreach ($quiz->question_ids as $index => $question_id) {
1803
                        $qid = $this->restore_quiz_question($question_id);
1804
                        $question_order = $quiz->question_orders[$index] ? $quiz->question_orders[$index] : ++$order;
1805
                        $sql = "INSERT IGNORE INTO $table_rel SET
1806
                                c_id = " . $this->destination_course_id . ",
1807
                                question_id = " . $qid . ",
1808
                                exercice_id = " . $new_id . ",
1809
                                question_order = " . $question_order;
1810
                        Database::query($sql);
1811
                    }
1812
                }
1813
			}
1814
		}
1815
	}
1816
1817
	/**
1818
	 * Restore quiz-questions
1819
     * @params int question id
1820
	 */
1821
    public function restore_quiz_question($id)
1822
    {
1823
		$em = Database::getManager();
1824
		$resources = $this->course->resources;
1825
        $question = isset($resources[RESOURCE_QUIZQUESTION][$id]) ? $resources[RESOURCE_QUIZQUESTION][$id] : null;
1826
1827
		$new_id = 0;
1828
1829
		if (is_object($question)) {
1830
			if ($question->is_restored()) {
1831
				return $question->destination_id;
1832
			}
1833
			$table_que = Database::get_course_table(TABLE_QUIZ_QUESTION);
1834
			$table_ans = Database::get_course_table(TABLE_QUIZ_ANSWER);
1835
            $table_options = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION);
1836
1837
			// check resources inside html from ckeditor tool and copy correct urls into recipient course
1838
            $question->description = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1839
                $question->description,
1840
                $this->course->code,
1841
                $this->course->destination_path,
1842
                $this->course->backup_path,
1843
                $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Course.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1844
            );
1845
1846
            $params = [
1847
                'c_id' => $this->destination_course_id,
1848
                'question' => self::DBUTF8($question->question),
1849
                'description' => self::DBUTF8($question->description),
0 ignored issues
show
Security Bug introduced by
It seems like $question->description can also be of type false; however, CourseRestorer::DBUTF8() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
1850
                'ponderation' => self::DBUTF8($question->ponderation),
1851
                'position' => self::DBUTF8($question->position),
1852
                'type' => self::DBUTF8($question->quiz_type),
1853
                'picture' => self::DBUTF8($question->picture),
1854
                'level' => self::DBUTF8($question->level),
1855
                'extra' => self::DBUTF8($question->extra),
1856
            ];
1857
1858
			$new_id = Database::insert($table_que, $params);
1859
1860
            if ($new_id) {
1861
                $sql = "UPDATE $table_que SET id = iid WHERE iid = $new_id";
1862
                Database::query($sql);
1863
1864
                if (!empty($question->picture)) {
1865
                    $question_temp = Question::read(
1866
                        $new_id,
1867
                        $this->destination_course_info['real_id']
1868
                    );
1869
1870
                    $documentPath = api_get_path(SYS_COURSE_PATH).$this->destination_course_info['path'].'/document';
1871
                    // picture path
1872
                    $picturePath = $documentPath.'/images';
1873
                    $old_picture = api_get_path(SYS_COURSE_PATH).$this->course->info['path'].'/document/images/'.$question->picture;
1874
                    if (file_exists($old_picture)) {
1875
                        $picture_name = 'quiz-'.$new_id.'.jpg';
1876
                        $result = $question_temp->uploadPicture($old_picture, $picture_name, $picturePath);
1877
                        if ($result) {
1878
                            $sql = "UPDATE $table_que SET
1879
                                        picture = '$picture_name'
1880
                                    WHERE
1881
                                        c_id = " . $this->destination_course_id . " AND
1882
                                        id = $new_id ";
1883
                            Database::query($sql);
1884
                        }
1885
                    }
1886
                }
1887
            }
1888
1889
            $correctAnswers = array();
1890
            $allAnswers = [];
1891
            $onlyAnswers = [];
1892
1893
            if (in_array($question->quiz_type, [DRAGGABLE, MATCHING, MATCHING_DRAGGABLE])) {
1894
                $allAnswers = array_column($question->answers, 'answer', 'id');
1895
            }
1896
1897
            if (in_array($question->quiz_type, [MATCHING, MATCHING_DRAGGABLE])) {
1898
                $temp = array();
1899
                foreach ($question->answers as $index => $answer) {
1900
                    $temp[$answer['position']] = $answer;
1901
                }
1902
1903
                foreach ($temp as $index => $answer) {
1904
                    // check resources inside html from ckeditor tool and copy correct urls into recipient course
1905
                    $answer['answer'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1906
                        $answer['answer'],
1907
                        $this->course->code,
1908
                        $this->course->destination_path,
1909
                        $this->course->backup_path,
1910
                        $this->course->info['path']
1911
                    );
1912
1913
                    $answer['comment'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1914
                        $answer['comment'],
1915
                        $this->course->code,
1916
                        $this->course->destination_path,
1917
                        $this->course->backup_path,
1918
                        $this->course->info['path']
1919
                    );
1920
1921
                    $quizAnswer = new CQuizAnswer();
1922
                    $quizAnswer
1923
                        ->setCId($this->destination_course_id)
1924
                        ->setQuestionId($new_id)
1925
                        ->setAnswer(self::DBUTF8($answer['answer']))
1926
                        ->setCorrect($answer['correct'])
1927
                        ->setComment(self::DBUTF8($answer['comment']))
0 ignored issues
show
Security Bug introduced by
It seems like $answer['comment'] can also be of type false; however, CourseRestorer::DBUTF8() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
1928
                        ->setPonderation($answer['ponderation'])
1929
                        ->setPosition($answer['position'])
1930
                        ->setHotspotCoordinates($answer['hotspot_coordinates'])
1931
                        ->setHotspotType($answer['hotspot_type'])
1932
                        ->setIdAuto(0);
1933
1934
                    $em->persist($quizAnswer);
1935
                    $em->flush();
1936
1937
                    $answerId = $quizAnswer->getIid();
1938
1939 View Code Duplication
                    if ($answerId) {
1940
                        $quizAnswer
1941
                            ->setId($answerId)
1942
                            ->setIdAuto($answerId);
1943
1944
                        $em->merge($quizAnswer);
1945
                        $em->flush();
1946
1947
                        $correctAnswers[$answerId] = $answer['correct'];
1948
                        $onlyAnswers[$answerId] = $answer['answer'];
1949
                    }
1950
				}
1951
			} else {
1952
				foreach ($question->answers as $index => $answer) {
1953
					// check resources inside html from ckeditor tool and copy correct urls into recipient course
1954
                    $answer['answer'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1955
                        $answer['answer'],
1956
                        $this->course->code,
1957
                        $this->course->destination_path,
1958
                        $this->course->backup_path,
1959
                        $this->course->info['path']
1960
                    );
1961
1962
                    $answer['comment'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1963
                        $answer['comment'],
1964
                        $this->course->code,
1965
                        $this->course->destination_path,
1966
                        $this->course->backup_path,
1967
                        $this->course->info['path']
1968
                    );
1969
1970
                    $params = [
1971
                        'c_id' => $this->destination_course_id,
1972
                        'question_id' => $new_id,
1973
                        'answer' => self::DBUTF8($answer['answer']),
1974
                        'correct' => $answer['correct'],
1975
                        'comment' => self::DBUTF8($answer['comment']),
0 ignored issues
show
Security Bug introduced by
It seems like $answer['comment'] can also be of type false; however, CourseRestorer::DBUTF8() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
1976
                        'ponderation' => $answer['ponderation'],
1977
                        'position' => $answer['position'],
1978
                        'hotspot_coordinates' => $answer['hotspot_coordinates'],
1979
                        'hotspot_type' => $answer['hotspot_type'],
1980
                        'id_auto' => 0,
1981
                        'destination' => '',
1982
                    ];
1983
1984
                    $answerId = Database::insert($table_ans, $params);
1985
1986
                    if ($answerId) {
1987
                        $sql = "UPDATE $table_ans SET id = iid, id_auto = iid WHERE iid = $answerId";
1988
                        Database::query($sql);
1989
                    }
1990
1991
                    $correctAnswers[$answerId] = $answer['correct'];
1992
                    $onlyAnswers[$answerId] = $answer['answer'];
1993
				}
1994
			}
1995
1996
            // Current course id
1997
            $course_id = api_get_course_int_id();
1998
1999
            // Moving quiz_question_options
2000
            if ($question->quiz_type == MULTIPLE_ANSWER_TRUE_FALSE) {
2001
                $question_option_list = Question::readQuestionOption($id, $course_id);
2002
2003
                // Question copied from the current platform
2004
                if ($question_option_list) {
2005
                    $old_option_ids = array();
2006
                    foreach ($question_option_list as $item) {
2007
                        $old_id = $item['id'];
2008
                        unset($item['id']);
2009
                        if (isset($item['iid'])) {
2010
                            unset($item['iid']);
2011
                        }
2012
                        $item['question_id'] = $new_id;
2013
                        $item['c_id'] = $this->destination_course_id;
2014
                        $question_option_id = Database::insert($table_options, $item);
2015
                        if ($question_option_id) {
2016
                            $old_option_ids[$old_id] = $question_option_id;
2017
                            $sql = "UPDATE $table_options SET id = iid WHERE iid = $question_option_id";
2018
                            Database::query($sql);
2019
                        }
2020
                    }
2021
                    if ($old_option_ids) {
2022
                        $new_answers = Database::select(
2023
                            'iid, correct',
2024
                            $table_ans,
2025
                            array(
2026
                                'WHERE' => array(
2027
                                    'question_id = ? AND c_id = ? ' => array(
2028
                                        $new_id,
2029
                                        $this->destination_course_id,
2030
                                    ),
2031
                                ),
2032
                            )
2033
                        );
2034
2035
                        foreach ($new_answers as $answer_item) {
2036
                            $params = array();
2037
                            $params['correct'] = $old_option_ids[$answer_item['correct']];
2038
                            Database::update(
2039
                                $table_ans,
2040
                                $params,
2041
                                array(
2042
                                    'iid = ? AND c_id = ? AND question_id = ? ' => array(
2043
                                        $answer_item['iid'],
2044
                                        $this->destination_course_id,
2045
                                        $new_id,
2046
                                    ),
2047
                                ),
2048
                                false
2049
                            );
2050
                        }
2051
                    }
2052
                } else {
2053
                    $new_options = array();
2054
                    if (isset($question->question_options)) {
2055
                        foreach ($question->question_options as $obj) {
2056
                            $item = array();
2057
                            $item['question_id'] = $new_id;
2058
                            $item['c_id'] = $this->destination_course_id;
2059
                            $item['name'] = $obj->obj->name;
2060
                            $item['position'] = $obj->obj->position;
2061
                            $question_option_id = Database::insert($table_options, $item);
2062
2063
                            if ($question_option_id) {
2064
                                $new_options[$obj->obj->id] = $question_option_id;
2065
                                $sql = "UPDATE $table_options SET id = iid WHERE iid = $question_option_id";
2066
                                Database::query($sql);
2067
                            }
2068
                        }
2069
2070
                        foreach ($correctAnswers as $answer_id => $correct_answer) {
2071
                            $params = array();
2072
                            $params['correct'] = $new_options[$correct_answer];
2073
                            Database::update(
2074
                                $table_ans,
2075
                                $params,
2076
                                array(
2077
                                    'id = ? AND c_id = ? AND question_id = ? ' => array(
2078
                                        $answer_id,
2079
                                        $this->destination_course_id,
2080
                                        $new_id,
2081
                                    ),
2082
                                ),
2083
                                false
2084
                            );
2085
                        }
2086
                    }
2087
                }
2088
            }
2089
2090
            // Fix correct answers
2091 View Code Duplication
            if (in_array($question->quiz_type, [DRAGGABLE, MATCHING, MATCHING_DRAGGABLE])) {
2092
                $onlyAnswersFlip = array_flip($onlyAnswers);
2093
                foreach ($correctAnswers as $answer_id => $correct_answer) {
2094
                    $params = array();
2095
                    if (isset($allAnswers[$correct_answer]) &&
2096
                        isset($onlyAnswersFlip[$allAnswers[$correct_answer]])
2097
                    ) {
2098
                        $params['correct'] = $onlyAnswersFlip[$allAnswers[$correct_answer]];
2099
                        Database::update(
2100
                            $table_ans,
2101
                            $params,
2102
                            array(
2103
                                'id = ? AND c_id = ? AND question_id = ? ' => array(
2104
                                    $answer_id,
2105
                                    $this->destination_course_id,
2106
                                    $new_id,
2107
                                ),
2108
                            )
2109
                        );
2110
                    }
2111
                }
2112
            }
2113
2114
			$this->course->resources[RESOURCE_QUIZQUESTION][$id]->destination_id = $new_id;
2115
		}
2116
2117
		return $new_id;
2118
	}
2119
2120
	/**
2121
     * @todo : add session id when used for session
2122
     */
2123
    public function restore_test_category($session_id, $respect_base_content, $destination_course_code)
2124
    {
2125
        $course_id = api_get_course_int_id();
2126
        // Let's restore the categories
2127
        $tab_test_category_id_old_new = array(); // used to build the quiz_question_rel_category table
2128
        if ($this->course->has_resources(RESOURCE_TEST_CATEGORY)) {
2129
            $resources = $this->course->resources;
2130
            foreach ($resources[RESOURCE_TEST_CATEGORY] as $id => $CourseCopyTestcategory ) {
2131
                $tab_test_category_id_old_new[$CourseCopyTestcategory->source_id] = $id;
2132
                // check if this test_category already exist in the destination BDD
2133
                // do not Database::escape_string $title and $description, it will be done later
2134
                $title = $CourseCopyTestcategory->title;
2135
                $description = $CourseCopyTestcategory->description;
2136
2137
                if (TestCategory::category_exists_with_title($title)) {
2138
                    switch ($this->file_option) {
2139
                        case FILE_SKIP:
2140
                            //Do nothing
2141
                            break;
2142
                        case FILE_RENAME:
2143
                            $new_title = $title."_";
2144
                            while (TestCategory::category_exists_with_title(
2145
                                $new_title
2146
                            )) {
2147
                                $new_title .= "_";
2148
                            }
2149
                            $test_category = new TestCategory(0, $new_title, $description);
2150
                            $new_id = $test_category->addCategoryInBDD();
2151
                            $tab_test_category_id_old_new[$CourseCopyTestcategory->source_id] = $new_id;
2152
                            break;
2153
                        case FILE_OVERWRITE:
2154
                            $id = TestCategory::get_category_id_for_title($title);
2155
                            $my_cat = new TestCategory($id);
2156
                            $my_cat->name = $title;
2157
                            $my_cat->modifyCategory();
2158
                            $tab_test_category_id_old_new[$CourseCopyTestcategory->source_id] = $id;
2159
                            break;
2160
                    }
2161
                } else {
2162
                    // create a new test_category
2163
                    $test_category = new TestCategory(0, $title, $description);
2164
                    $new_id = $test_category->addCategoryInBDD();
2165
                    $tab_test_category_id_old_new[$CourseCopyTestcategory->source_id] = $new_id;
2166
                }
2167
                $this->course->resources[RESOURCE_TEST_CATEGORY][$id]->destination_id = $tab_test_category_id_old_new[$CourseCopyTestcategory->source_id];
2168
            }
2169
        }
2170
        // lets check if quizzes-question are restored too, to redo the link between test_category and quizzes question for questions restored
2171
        // we can use the source_id field
2172
        // question source_id => category source_id
2173
        if ($this->course->has_resources(RESOURCE_QUIZQUESTION)) {
2174
            // check the category number of each question restored
2175
            if (!empty($resources[RESOURCE_QUIZQUESTION])) {
2176
                foreach ($resources[RESOURCE_QUIZQUESTION] as $id => $CourseCopyQuestion) {
2177
                    $new_quiz_question_id = $resources[RESOURCE_QUIZQUESTION][$id]->destination_id;
2178
                    $question_category = $CourseCopyQuestion->question_category;
2179
                    if ($question_category > 0) {
2180
                        TestCategory::add_category_for_question_id(
2181
                            $tab_test_category_id_old_new[$question_category],
2182
                            $new_quiz_question_id,
2183
                            $course_id
2184
                        );
2185
                    }
2186
                }
2187
            }
2188
        }
2189
    }
2190
2191
    /**
2192
     * Restore surveys
2193
     * @param int $sessionId Optional. The session id
2194
     */
2195
    public function restore_surveys($sessionId = 0)
2196
    {
2197
        $sessionId = intval($sessionId);
2198
2199
        if ($this->course->has_resources(RESOURCE_SURVEY)) {
2200
			$table_sur = Database :: get_course_table(TABLE_SURVEY);
2201
			$table_que = Database :: get_course_table(TABLE_SURVEY_QUESTION);
2202
			$table_ans = Database :: get_course_table(TABLE_SURVEY_QUESTION_OPTION);
2203
			$resources = $this->course->resources;
2204
			foreach ($resources[RESOURCE_SURVEY] as $id => $survey) {
2205
2206
				$sql = 'SELECT survey_id FROM '.$table_sur.'
2207
                        WHERE
2208
                            c_id = '.$this->destination_course_id.' AND
2209
                            code = "'.self::DBUTF8escapestring($survey->code).'" AND
2210
                            lang = "'.self::DBUTF8escapestring($survey->lang).'" ';
2211
2212
				$result_check = Database::query($sql);
2213
2214
				// check resources inside html from ckeditor tool and copy correct urls into recipient course
2215
                $survey->title = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2216
                    $survey->title,
2217
                    $this->course->code,
2218
                    $this->course->destination_path,
2219
                    $this->course->backup_path,
2220
                    $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Course.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
2221
                );
2222
2223
                $survey->subtitle = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2224
                    $survey->subtitle,
2225
                    $this->course->code,
2226
                    $this->course->destination_path,
2227
                    $this->course->backup_path,
2228
                    $this->course->info['path']
2229
                );
2230
2231
                $survey->intro = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2232
                    $survey->intro,
2233
                    $this->course->code,
2234
                    $this->course->destination_path,
2235
                    $this->course->backup_path,
2236
                    $this->course->info['path']
2237
                );
2238
2239
                $survey->surveythanks = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2240
                    $survey->surveythanks,
2241
                    $this->course->code,
2242
                    $this->course->destination_path,
2243
                    $this->course->backup_path,
2244
                    $this->course->info['path']
2245
                );
2246
2247
                $params = [
2248
                    'c_id' => $this->destination_course_id,
2249
                    'code' => self::DBUTF8($survey->code),
2250
                    'title' => self::DBUTF8($survey->title),
0 ignored issues
show
Security Bug introduced by
It seems like $survey->title can also be of type false; however, CourseRestorer::DBUTF8() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
2251
                    'subtitle' => self::DBUTF8($survey->subtitle),
0 ignored issues
show
Security Bug introduced by
It seems like $survey->subtitle can also be of type false; however, CourseRestorer::DBUTF8() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
2252
                    'author' => self::DBUTF8($survey->author),
2253
                    'lang' => self::DBUTF8($survey->lang),
2254
                    'avail_from' => self::DBUTF8($survey->avail_from),
2255
                    'avail_till' => self::DBUTF8($survey->avail_till),
2256
                    'is_shared' => self::DBUTF8($survey->is_shared),
2257
                    'template' => self::DBUTF8($survey->template),
2258
                    'intro' => self::DBUTF8($survey->intro),
0 ignored issues
show
Security Bug introduced by
It seems like $survey->intro can also be of type false; however, CourseRestorer::DBUTF8() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
2259
                    'surveythanks' => self::DBUTF8($survey->surveythanks),
0 ignored issues
show
Security Bug introduced by
It seems like $survey->surveythanks can also be of type false; however, CourseRestorer::DBUTF8() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
2260
                    'creation_date' => self::DBUTF8($survey->creation_date),
2261
                    'invited' => '0',
2262
                    'answered' => '0',
2263
                    'invite_mail' => self::DBUTF8($survey->invite_mail),
2264
                    'reminder_mail' => self::DBUTF8($survey->reminder_mail),
2265
                    'session_id' => $sessionId,
2266
                ];
2267
2268
				//An existing survey exists with the same code and the same language
2269
				if (Database::num_rows($result_check) == 1) {
2270
					switch ($this->file_option) {
2271
						case FILE_SKIP:
2272
							//Do nothing
2273
							break;
2274
						case FILE_RENAME:
2275
							$survey_code = $survey->code.'_';
2276
							$i=1;
2277
							$temp_survey_code = $survey_code.$i;
2278
							while (!$this->is_survey_code_available($temp_survey_code)) {
2279
								$temp_survey_code = $survey_code.++$i;
2280
							}
2281
							$survey_code = $temp_survey_code;
2282
2283
                            $params['code'] = $survey_code;
2284
                            $new_id = Database::insert($table_sur, $params);
2285
                            if ($new_id) {
2286
                                $sql = "UPDATE $table_sur SET survey_id = iid WHERE iid = $new_id";
2287
                                Database::query($sql);
2288
2289
                                $this->course->resources[RESOURCE_SURVEY][$id]->destination_id = $new_id;
2290
                                foreach ($survey->question_ids as $index => $question_id) {
2291
                                    $qid = $this->restore_survey_question($question_id, $new_id);
2292
                                    $sql = "UPDATE ".$table_que." SET survey_id = ".$new_id."
2293
								            WHERE c_id = ".$this->destination_course_id." AND question_id = $qid";
2294
                                    Database::query($sql);
2295
                                    $sql = "UPDATE ".$table_ans." SET survey_id = ".$new_id."
2296
								            WHERE  c_id = ".$this->destination_course_id." AND  question_id = $qid";
2297
                                    Database::query($sql);
2298
                                }
2299
                            }
2300
							break;
2301
						case FILE_OVERWRITE:
2302
							// Delete the existing survey with the same code and language and import the one of the source course
2303
							// getting the information of the survey (used for when the survey is shared)
2304
2305
							$sql = "SELECT * FROM $table_sur
2306
							        WHERE
2307
							            c_id = ".$this->destination_course_id." AND
2308
							            survey_id='".self::DBUTF8escapestring(Database::result($result_check,0,0))."'";
2309
							$result = Database::query($sql);
2310
							$survey_data = Database::fetch_array($result,'ASSOC');
2311
2312
							// if the survey is shared => also delete the shared content
2313 View Code Duplication
							if (isset($survey_data['survey_share']) && is_numeric($survey_data['survey_share'])) {
2314
                                SurveyManager::delete_survey($survey_data['survey_share'], true,$this->destination_course_id);
2315
							}
2316
							SurveyManager :: delete_survey($survey_data['survey_id'],false,$this->destination_course_id);
2317
2318
							// Insert the new source survey
2319
                            $new_id = Database::insert($table_sur, $params);
2320
2321 View Code Duplication
                            if ($new_id) {
2322
                                $sql = "UPDATE $table_sur SET survey_id = iid WHERE iid = $new_id";
2323
                                Database::query($sql);
2324
2325
                                $this->course->resources[RESOURCE_SURVEY][$id]->destination_id = $new_id;
2326
                                foreach ($survey->question_ids as $index => $question_id) {
2327
                                    $qid = $this->restore_survey_question(
2328
                                        $question_id,
2329
                                        $new_id
2330
                                    );
2331
                                    $sql = "UPDATE $table_que SET survey_id = $new_id
2332
                                            WHERE c_id = ".$this->destination_course_id." AND question_id = $qid";
2333
                                    Database::query($sql);
2334
                                    $sql = "UPDATE $table_ans SET survey_id = $new_id
2335
                                            WHERE c_id = ".$this->destination_course_id." AND question_id = $qid";
2336
                                    Database::query($sql);
2337
                                }
2338
                            }
2339
							break;
2340
						default:
2341
							break;
2342
					}
2343
				} else {
2344
                    // No existing survey with the same language and the same code, we just copy the survey
2345
                    $new_id = Database::insert($table_sur, $params);
2346
2347 View Code Duplication
                    if ($new_id) {
2348
                        $sql = "UPDATE $table_sur SET survey_id = iid WHERE iid = $new_id";
2349
                        Database::query($sql);
2350
2351
                        $this->course->resources[RESOURCE_SURVEY][$id]->destination_id = $new_id;
2352
                        foreach ($survey->question_ids as $index => $question_id) {
2353
                            $qid = $this->restore_survey_question(
2354
                                $question_id,
2355
                                $new_id
2356
                            );
2357
                            $sql = "UPDATE $table_que SET survey_id = $new_id
2358
                                    WHERE c_id = ".$this->destination_course_id." AND question_id = $qid";
2359
                            Database::query($sql);
2360
                            $sql = "UPDATE $table_ans SET survey_id = $new_id
2361
                                    WHERE c_id = ".$this->destination_course_id." AND question_id = $qid";
2362
                            Database::query($sql);
2363
                        }
2364
                    }
2365
				}
2366
			}
2367
		}
2368
	}
2369
2370
	/**
2371
	 * Check availability of a survey code
2372
	 * @param string $survey_code
2373
	 */
2374 View Code Duplication
    public function is_survey_code_available($survey_code)
2375
    {
2376
		$table_sur = Database :: get_course_table(TABLE_SURVEY);
2377
		$sql = "SELECT * FROM $table_sur
2378
		        WHERE
2379
		            c_id = ".$this->destination_course_id." AND
2380
		            code='".self::DBUTF8escapestring($survey_code)."'";
2381
		$result = Database::query($sql);
2382
		if (Database::num_rows($result) > 0) return false; else return true;
2383
	}
2384
2385
	/**
2386
	 * Restore survey-questions
2387
	 * @param string $survey_id
2388
	 */
2389
    public function restore_survey_question($id, $survey_id)
2390
    {
2391
		$resources = $this->course->resources;
2392
		$question = $resources[RESOURCE_SURVEYQUESTION][$id];
2393
2394
		$new_id=0;
2395
2396
		if (is_object($question)) {
2397
			if ($question->is_restored()) {
2398
				return $question->destination_id;
2399
			}
2400
			$table_que = Database :: get_course_table(TABLE_SURVEY_QUESTION);
2401
			$table_ans = Database :: get_course_table(TABLE_SURVEY_QUESTION_OPTION);
2402
2403
			// check resources inside html from ckeditor tool and copy correct urls into recipient course
2404
            $question->survey_question = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2405
                $question->survey_question,
2406
                $this->course->code,
2407
                $this->course->destination_path,
2408
                $this->course->backup_path,
2409
                $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Course.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
2410
            );
2411
2412
            $params = [
2413
                'c_id' => $this->destination_course_id,
2414
                'survey_id' => self::DBUTF8($survey_id),
2415
                'survey_question' => self::DBUTF8($question->survey_question),
0 ignored issues
show
Security Bug introduced by
It seems like $question->survey_question can also be of type false; however, CourseRestorer::DBUTF8() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
2416
                'survey_question_comment' => self::DBUTF8($question->survey_question_comment),
2417
                'type' => self::DBUTF8($question->survey_question_type),
2418
                'display' => self::DBUTF8($question->display),
2419
                'sort' => self::DBUTF8($question->sort),
2420
                'shared_question_id' => self::DBUTF8($question->shared_question_id),
2421
                'max_value' => self::DBUTF8($question->max_value),
2422
            ];
2423
2424
            $new_id = Database::insert($table_que, $params);
2425
            if ($new_id) {
2426
2427
                $sql = "UPDATE $table_que SET question_id = iid WHERE iid = $new_id";
2428
                Database::query($sql);
2429
2430
                foreach ($question->answers as $index => $answer) {
2431
2432
                    // check resources inside html from ckeditor tool and copy correct urls into recipient course
2433
                    $answer['option_text'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2434
                        $answer['option_text'],
2435
                        $this->course->code,
2436
                        $this->course->destination_path,
2437
                        $this->course->backup_path,
2438
                        $this->course->info['path']
2439
                    );
2440
2441
                    $params = [
2442
                        'c_id' => $this->destination_course_id,
2443
                        'question_id' => $new_id,
2444
                        'option_text' => self::DBUTF8($answer['option_text']),
0 ignored issues
show
Security Bug introduced by
It seems like $answer['option_text'] can also be of type false; however, CourseRestorer::DBUTF8() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
2445
                        'sort' => $answer['sort'],
2446
                        'survey_id' => self::DBUTF8($survey_id),
2447
                    ];
2448
                    $answerId = Database::insert($table_ans, $params);
2449
                    if ($answerId) {
2450
                        $sql = "UPDATE $table_ans SET question_option_id = iid
2451
                                WHERE iid = $answerId";
2452
                        Database::query($sql);
2453
                    }
2454
                }
2455
                $this->course->resources[RESOURCE_SURVEYQUESTION][$id]->destination_id = $new_id;
2456
            }
2457
		}
2458
2459
		return $new_id;
2460
	}
2461
2462
    /**
2463
     * Restoring learning paths
2464
     * @param int $session_id
2465
     * @param bool|false $respect_base_content
2466
     */
2467
    public function restore_learnpaths($session_id = 0, $respect_base_content = false)
2468
    {
2469
        $session_id = intval($session_id);
2470
2471
		if ($this->course->has_resources(RESOURCE_LEARNPATH)) {
2472
            $table_main = Database::get_course_table(TABLE_LP_MAIN);
2473
            $table_item = Database::get_course_table(TABLE_LP_ITEM);
2474
            $table_tool = Database::get_course_table(TABLE_TOOL_LIST);
2475
2476
			$resources = $this->course->resources;
2477
2478
			$origin_path = $this->course->backup_path.'/upload/learning_path/images/';
2479
			$destination_path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/upload/learning_path/images/';
2480
2481
			foreach ($resources[RESOURCE_LEARNPATH] as $id => $lp) {
2482
2483
				$condition_session = "";
2484 View Code Duplication
				if (!empty($session_id)) {
2485
                    if ($respect_base_content) {
2486
                        $my_session_id = $lp->session_id;
2487
                        if (!empty($lp->session_id)) {
2488
                            $my_session_id = $session_id;
2489
                        }
2490
                        $condition_session = $my_session_id;
2491
                    } else {
2492
                        $session_id = intval($session_id);
2493
                        $condition_session = $session_id;
2494
                    }
2495
				}
2496
2497
				// Adding the author's image
2498
				if (!empty($lp->preview_image)) {
2499
					$new_filename = uniqid('').substr($lp->preview_image,strlen($lp->preview_image)-7, strlen($lp->preview_image));
2500
					if (file_exists($origin_path.$lp->preview_image) && !is_dir($origin_path.$lp->preview_image)) {
2501
						$copy_result = copy($origin_path.$lp->preview_image, $destination_path.$new_filename);
2502
						//$copy_result = true;
2503
						if ($copy_result) {
2504
							$lp->preview_image = $new_filename;
2505
						} else {
2506
							$lp->preview_image ='';
2507
						}
2508
					}
2509
				}
2510
2511
                if ($this->add_text_in_items) {
2512
                    $lp->name = $lp->name.' '.get_lang('CopyLabelSuffix');
2513
                }
2514
2515
                if (isset($this->tool_copy_settings['learnpaths'])) {
2516
                    if (isset($this->tool_copy_settings['learnpaths']['reset_dates']) &&
2517
                        $this->tool_copy_settings['learnpaths']['reset_dates']
2518
                    ) {
2519
                        $lp->created_on     = api_get_utc_datetime();
2520
                        $lp->modified_on    = api_get_utc_datetime();
2521
                        $lp->publicated_on  = null;
2522
                    }
2523
                }
2524
2525
                $params = [
2526
                    'c_id' => $this->destination_course_id,
2527
                    'lp_type' => $lp->lp_type,
2528
                    'name' => self::DBUTF8($lp->name),
2529
                    'path' => self::DBUTF8($lp->path),
2530
                    'ref' => $lp->ref,
2531
                    'description' => self::DBUTF8($lp->description),
2532
                    'content_local' => self::DBUTF8($lp->content_local),
2533
                    'default_encoding' => self::DBUTF8($lp->default_encoding),
2534
                    'default_view_mod' => self::DBUTF8($lp->default_view_mod),
2535
                    'prevent_reinit' => self::DBUTF8($lp->prevent_reinit),
2536
                    'force_commit' => self::DBUTF8($lp->force_commit),
2537
                    'content_maker' => self::DBUTF8($lp->content_maker),
2538
                    'display_order' => self::DBUTF8($lp->display_order),
2539
                    'js_lib' => self::DBUTF8($lp->js_lib),
2540
                    'content_license' => self::DBUTF8($lp->content_license),
2541
                    'author' => self::DBUTF8($lp->author),
2542
                    'preview_image' => self::DBUTF8($lp->preview_image),
2543
                    'use_max_score' => self::DBUTF8($lp->use_max_score),
2544
                    'autolaunch' => self::DBUTF8(isset($lp->autolaunch) ? $lp->autolaunch : ''),
2545
                    'created_on' => self::DBUTF8($lp->created_on),
2546
                    'modified_on' => self::DBUTF8($lp->modified_on),
2547
                    'publicated_on' => empty($lp->publicated_on) ? api_get_utc_datetime() : self::DBUTF8($lp->publicated_on),
2548
                    'expired_on' => self::DBUTF8($lp->expired_on),
2549
                    'debug' => self::DBUTF8($lp->debug),
2550
                ];
2551
2552
                if (!empty($condition_session)) {
2553
                    $params['session_id'] = $condition_session;
2554
                }
2555
2556
				$new_lp_id = Database::insert($table_main, $params);
2557
2558
                if ($new_lp_id) {
2559
2560
                    $sql = "UPDATE $table_main SET id = iid WHERE iid = $new_lp_id";
2561
                    Database::query($sql);
2562
2563
                    if ($lp->visibility) {
2564
                        $params = [
2565
                            'c_id' => $this->destination_course_id,
2566
                            'name' => self::DBUTF8($lp->name),
2567
                            'link' => 'newscorm/lp_controller.php?action=view&lp_id=$new_lp_id&id_session='.$session_id,
2568
                            'image' => 'scormbuilder.gif',
2569
                            'visibility' => '0',
2570
                            'admin' => '0',
2571
                            'address' => 'squaregrey.gif',
2572
                            'session_id' => $session_id,
2573
                        ];
2574
                        $insertId = Database::insert($table_tool, $params);
2575
                        if ($insertId) {
2576
                            $sql = "UPDATE $table_tool SET id = iid WHERE iid = $insertId";
2577
                            Database::query($sql);
2578
                        }
2579
                    }
2580
2581
                    api_item_property_update(
2582
                        $this->destination_course_info,
2583
                        TOOL_LEARNPATH,
2584
                        $new_lp_id,
2585
                        'LearnpathAdded',
2586
                        api_get_user_id(),
2587
                        0,
2588
                        0,
2589
                        0,
2590
                        0,
2591
                        $session_id
2592
                    );
2593
2594
                    // Set the new LP to visible
2595
                    api_item_property_update(
2596
                        $this->destination_course_info,
2597
                        TOOL_LEARNPATH,
2598
                        $new_lp_id,
2599
                        'invisible',
2600
                        api_get_user_id(),
2601
                        0,
2602
                        0,
2603
                        0,
2604
                        0,
2605
                        $session_id
2606
                    );
2607
                }
2608
2609
                $new_item_ids = array();
2610
                $parent_item_ids = array();
2611
                $previous_item_ids = array();
2612
                $next_item_ids = array();
2613
                $old_prerequisite = array();
2614
                $old_refs = array();
2615
                $prerequisite_ids = array();
2616
2617
				foreach ($lp->get_items() as $index => $item) {
2618
					// we set the ref code here and then we update in a for loop
2619
					$ref = $item['ref'];
2620
2621
					// Dealing with path the same way as ref as some data has
2622
                    // been put into path when it's a local resource
2623
					// Only fix the path for no scos
2624
                    if ($item['item_type'] == 'sco') {
2625
                        $path = $item['path'];
2626
                    } else {
2627
                        $path = $item['path'];
2628
                        $path = $this->get_new_id($item['item_type'], $path);
2629
                    }
2630
2631
                    $params = [
2632
                        'c_id' => $this->destination_course_id,
2633
                        'lp_id' => self::DBUTF8($new_lp_id),
0 ignored issues
show
Security Bug introduced by
It seems like $new_lp_id defined by \Database::insert($table_main, $params) on line 2556 can also be of type false; however, CourseRestorer::DBUTF8() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
2634
                        'item_type' => self::DBUTF8($item['item_type']),
2635
                        'ref' => self::DBUTF8($ref),
2636
                        'title' => self::DBUTF8($item['title']),
2637
                        'description' => self::DBUTF8($item['description']),
2638
                        'path' => self::DBUTF8($path),
2639
                        'min_score' => self::DBUTF8($item['min_score']),
2640
                        'max_score' => self::DBUTF8($item['max_score']),
2641
                        'mastery_score' => self::DBUTF8($item['mastery_score']),
2642
                        'parent_item_id' => self::DBUTF8($item['parent_item_id']),
2643
                        'previous_item_id' => self::DBUTF8($item['previous_item_id']),
2644
                        'next_item_id' => self::DBUTF8($item['next_item_id']),
2645
                        'display_order' => self::DBUTF8($item['display_order']),
2646
                        'prerequisite' => self::DBUTF8($item['prerequisite']),
2647
                        'parameters' => self::DBUTF8($item['parameters']),
2648
                        'audio' => self::DBUTF8($item['audio']),
2649
                        'launch_data' => self::DBUTF8($item['launch_data']),
2650
                    ];
2651
2652
					$new_item_id = Database::insert($table_item, $params);
2653
2654
                    $sql = "UPDATE $table_item SET id = iid WHERE iid = $new_item_id";
2655
                    Database::query($sql);
2656
2657
					//save a link between old and new item IDs
2658
					$new_item_ids[$item['id']] = $new_item_id;
2659
					//save a reference of items that need a parent_item_id refresh
2660
					$parent_item_ids[$new_item_id] = $item['parent_item_id'];
2661
					//save a reference of items that need a previous_item_id refresh
2662
					$previous_item_ids[$new_item_id] = $item['previous_item_id'];
2663
					//save a reference of items that need a next_item_id refresh
2664
					$next_item_ids[$new_item_id] = $item['next_item_id'];
2665
2666
					if (!empty($item['prerequisite'])) {
2667
						if ($lp->lp_type =='2') {
2668
							// if is an sco
2669
							$old_prerequisite[$new_item_id]= $item['prerequisite'];
2670
						} else {
2671
							$old_prerequisite[$new_item_id]= $new_item_ids[$item['prerequisite']];
2672
						}
2673
					}
2674
2675
					if (!empty($ref)) {
2676
						if ($lp->lp_type =='2') {
2677
							// if is an sco
2678
							$old_refs[$new_item_id]= $ref;
2679
						} else {
2680
                            $old_refs[$new_item_id]= $new_item_ids[$ref];
2681
						}
2682
					}
2683
2684
					$prerequisite_ids[$new_item_id] = $item['prerequisite'];
2685
				}
2686
2687
				// Updating prerequisites
2688 View Code Duplication
				foreach ($old_prerequisite  as $key=>$my_old_prerequisite) {
2689
					if($my_old_prerequisite != ''){
2690
						$sql = "UPDATE ".$table_item." SET prerequisite = '".$my_old_prerequisite."'
2691
						        WHERE c_id = ".$this->destination_course_id." AND id = '".$key."'  ";
2692
						Database::query($sql);
2693
					}
2694
				}
2695
2696
				// Updating refs
2697 View Code Duplication
				foreach ($old_refs  as $key=>$my_old_ref) {
2698
					if ($my_old_ref != '') {
2699
						$sql = "UPDATE ".$table_item." SET ref = '".$my_old_ref."'
2700
						        WHERE c_id = ".$this->destination_course_id." AND id = '".$key."'  ";
2701
						Database::query($sql);
2702
					}
2703
				}
2704
2705 View Code Duplication
				foreach ($parent_item_ids as $new_item_id => $parent_item_old_id) {
2706
					$parent_new_id = 0;
2707
					if($parent_item_old_id != 0){
2708
						$parent_new_id = $new_item_ids[$parent_item_old_id];
2709
					}
2710
					$sql = "UPDATE ".$table_item." SET parent_item_id = '".$parent_new_id."'
2711
					        WHERE c_id = ".$this->destination_course_id." AND id = '".$new_item_id."'";
2712
					Database::query($sql);
2713
				}
2714 View Code Duplication
				foreach ($previous_item_ids as $new_item_id => $previous_item_old_id) {
2715
					$previous_new_id = 0;
2716
					if($previous_item_old_id != 0){
2717
						$previous_new_id = $new_item_ids[$previous_item_old_id];
2718
					}
2719
					$sql = "UPDATE ".$table_item." SET previous_item_id = '".$previous_new_id."'
2720
					        WHERE  c_id = ".$this->destination_course_id." AND id = '".$new_item_id."'";
2721
					Database::query($sql);
2722
				}
2723
2724 View Code Duplication
				foreach ($next_item_ids as $new_item_id => $next_item_old_id) {
2725
					$next_new_id = 0;
2726
					if($next_item_old_id != 0){
2727
						$next_new_id = $new_item_ids[$next_item_old_id];
2728
					}
2729
					$sql = "UPDATE ".$table_item." SET next_item_id = '".$next_new_id."'
2730
					        WHERE c_id = ".$this->destination_course_id." AND id = '".$new_item_id."'";
2731
					Database::query($sql);
2732
				}
2733
2734 View Code Duplication
				foreach ($prerequisite_ids as $new_item_id => $prerequisite_old_id) {
2735
					$prerequisite_new_id = 0;
2736
					if($prerequisite_old_id != 0){
2737
						$prerequisite_new_id = $new_item_ids[$prerequisite_old_id];
2738
					}
2739
					$sql = "UPDATE ".$table_item." SET prerequisite = '".$prerequisite_new_id."'
2740
					        WHERE c_id = ".$this->destination_course_id." AND id = '".$new_item_id."'";
2741
					Database::query($sql);
2742
				}
2743
				$this->course->resources[RESOURCE_LEARNPATH][$id]->destination_id = $new_lp_id;
2744
			}
2745
		}
2746
	}
2747
2748
	/**
2749
	 * Restore works
2750
     * @deprecated use restore_works
2751
     *
2752
	 */
2753
	public function restore_student_publication($sessionId = 0)
2754
    {
2755
        $sessionId = intval($sessionId);
2756
		$work_assignment_table  = Database :: get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
2757
		$work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
2758
		$item_property_table  	= Database :: get_course_table(TABLE_ITEM_PROPERTY);
2759
2760
		// Query in student publication
2761
		$sql = 'SELECT * FROM '.$work_table.'
2762
		        WHERE c_id = '.$this->course_origin_id.' AND filetype = "folder" AND active IN (0, 1) ';
2763
2764
		$result = Database::query($sql);
2765
		$folders = Database::store_result($result, 'ASSOC');
2766
2767
		foreach ($folders  as $folder) {
2768
		    $old_id = $folder['id'];
2769
            unset($folder['id']);
2770
			$folder['c_id'] = $this->destination_course_id;
2771
            $folder['parent_id'] = 0;
2772
            $folder['session_id'] = $sessionId;
2773
			$new_id = Database::insert($work_table, $folder);
2774
2775
            if ($new_id) {
2776
                //query in item property
2777
                $sql = 'SELECT
2778
                        tool,
2779
                        insert_user_id,
2780
                        insert_date,
2781
                        lastedit_date,
2782
                        ref,
2783
                        lastedit_type,
2784
                        lastedit_user_id,
2785
                        to_group_id,
2786
                        to_user_id,
2787
                        visibility,
2788
                        start_visible,
2789
                        end_visible
2790
                        FROM '.$item_property_table.' ip
2791
                        INNER JOIN '.$work_table.' sp
2792
                        ON ip.ref=sp.id
2793
                        WHERE
2794
                            sp.c_id = '.$this->course_origin_id.' AND
2795
                            ip.c_id = '.$this->course_origin_id.' AND
2796
                            tool="work" AND sp.id = '.$old_id.'';
2797
2798
                $result = Database::query($sql);
2799
                $sub_folders = Database::store_result($result, 'ASSOC');
2800
                foreach ($sub_folders  as $sub_folder) {
2801
                    $sub_folder['c_id'] = $this->destination_course_id;
2802
                    $sub_folder['ref'] = $new_id;
2803
                    $sub_folder['session_id'] = $sessionId;
2804
                    $new_item_id = Database::insert($item_property_table, $sub_folder);
2805
                    if ($new_item_id) {
2806
                        $sql = "UPDATE $item_property_table SET id = iid WHERE iid = $new_item_id";
2807
                        Database::query($sql);
2808
                    }
2809
                }
2810
2811
                $sql = 'SELECT sa.id, sa.expires_on,sa.ends_on,sa.add_to_calendar, sa.enable_qualification, sa.publication_id
2812
                        FROM '.$work_assignment_table.' sa
2813
                        INNER JOIN '.$work_table.' sp ON sa.publication_id=sp.id
2814
                        WHERE
2815
                            sp.c_id = '.$this->course_origin_id.' AND
2816
                            sa.c_id = '.$this->course_origin_id.' AND
2817
                            filetype="folder" AND sp.id = '.$old_id.'';
2818
2819
                $result = Database::query($sql);
2820
                $assing_list = Database::store_result($result, 'ASSOC');
2821
                foreach ($assing_list  as $assign) {
2822
                    $assign['c_id'] = $this->destination_course_id;
2823
                    $assign['id'] = $new_id;
2824
                    $assignmentId = Database::insert($work_assignment_table, $assign);
2825
2826
                    if ($assignmentId) {
2827
                        $sql = "UPDATE $work_assignment_table SET id = iid WHERE iid = $assignmentId";
2828
                        Database::query($sql);
2829
                    }
2830
                }
2831
            }
2832
		}
2833
2834
		$destination = '../../courses/'.$this->course->destination_path.'/work/';
2835
		$origin = '../../courses/'.$this->course->info['path'].'/work/';
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Course.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
2836
		self::allow_create_all_directory($origin,$destination,false);
0 ignored issues
show
Deprecated Code introduced by
The method CourseRestorer::allow_create_all_directory() has been deprecated.

This method has been deprecated.

Loading history...
2837
	}
2838
2839
    /**
2840
    * copy all directory and sub directory
2841
    * @param string The path origin
2842
    * @param string The path destination
2843
    * @param boolean Option Overwrite
2844
    * @param string $source
2845
    * @param string $dest
2846
    * @return void()
0 ignored issues
show
Documentation introduced by
The doc-type void() could not be parsed: Expected "|" or "end of type", but got "(" at position 4. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
2847
    * @deprecated
2848
    */
2849
    public function allow_create_all_directory($source, $dest, $overwrite = false)
2850
    {
2851
        if (!is_dir($dest)) {
2852
            mkdir($dest, api_get_permissions_for_new_directories());
2853
        }
2854
        if ($handle = opendir($source)) {        // if the folder exploration is sucsessful, continue
2855
            while (false !== ($file = readdir($handle))) { // as long as storing the next file to $file is successful, continue
2856
                if ($file != '.' && $file != '..') {
2857
                    $path = $source . '/' . $file;
2858
                    if (is_file($path)) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
2859
                       /* if (!is_file($dest . '/' . $file) || $overwrite)
2860
                        if (!@copy($path, $dest . '/' . $file)) {
2861
                            echo '<font color="red">File ('.$path.') '.get_lang('NotHavePermission').'</font>';
2862
                        }*/
2863
                    } elseif(is_dir($path)) {
2864
                        if (!is_dir($dest . '/' . $file))
2865
                        mkdir($dest . '/' . $file);
2866
                       self:: allow_create_all_directory($path, $dest . '/' . $file, $overwrite);
0 ignored issues
show
Deprecated Code introduced by
The method CourseRestorer::allow_create_all_directory() has been deprecated.

This method has been deprecated.

Loading history...
2867
                    }
2868
                }
2869
            }
2870
            closedir($handle);
2871
        }
2872
    }
2873
2874
	/**
2875
	 * Gets the new ID of one specific tool item from the tool name and the old ID
2876
	 * @param	string	Tool name
2877
	 * @param	integer	Old ID
2878
	 * @return	integer	New ID
2879
	 */
2880
    public function get_new_id($tool, $ref)
2881
    {
2882
        // Check if the value exist in the current array.
2883
2884
        if ($tool == 'hotpotatoes') {
2885
            $tool = 'document';
2886
        }
2887
2888
        if (isset($this->course->resources[$tool][$ref]) &&
2889
            isset($this->course->resources[$tool][$ref]->destination_id) &&
2890
            !empty($this->course->resources[$tool][$ref]->destination_id)
2891
        ) {
2892
            return $this->course->resources[$tool][$ref]->destination_id;
2893
        }
2894
2895
        // Check if the course is the same (last hope).
2896
        if ($this->course_origin_id == $this->destination_course_id) {
2897
            return $ref;
2898
        }
2899
2900
        return '';
2901
	}
2902
2903
	/**
2904
	 * Restore glossary
2905
	 */
2906
    public function restore_glossary($session_id = 0)
2907
    {
2908
		if ($this->course->has_resources(RESOURCE_GLOSSARY)) {
2909
			$table_glossary = Database :: get_course_table(TABLE_GLOSSARY);
2910
			$resources = $this->course->resources;
2911
			foreach ($resources[RESOURCE_GLOSSARY] as $id => $glossary) {
2912
2913
                $params = [];
2914
    			if (!empty($session_id)) {
2915
    				$session_id = intval($session_id);
2916
                    $params['session_id'] = $session_id;
2917
    			}
2918
2919
				// check resources inside html from ckeditor tool and copy correct urls into recipient course
2920
                $glossary->description = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2921
                    $glossary->description,
2922
                    $this->course->code,
2923
                    $this->course->destination_path,
2924
                    $this->course->backup_path,
2925
                    $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Course.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
2926
                );
2927
2928
                $params['c_id'] = $this->destination_course_id;
2929
                $params['description'] = self::DBUTF8($glossary->description);
0 ignored issues
show
Security Bug introduced by
It seems like $glossary->description can also be of type false; however, CourseRestorer::DBUTF8() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
2930
                $params['display_order'] = $glossary->display_order;
2931
                $params['name'] = self::DBUTF8($glossary->name);
2932
2933
                $my_id = Database::insert($table_glossary, $params);
2934 View Code Duplication
                if ($my_id) {
2935
2936
                    $sql = "UPDATE $table_glossary SET glossary_id = iid WHERE iid = $my_id";
2937
                    Database::query($sql);
2938
2939
                    api_item_property_update(
2940
                        $this->destination_course_info,
2941
                        TOOL_GLOSSARY,
2942
                        $my_id,
2943
                        "GlossaryAdded",
2944
                        api_get_user_id()
2945
                    );
2946
2947
                    if (!isset($this->course->resources[RESOURCE_GLOSSARY][$id])) {
2948
                        $this->course->resources[RESOURCE_GLOSSARY][$id] = new stdClass();
2949
                    }
2950
2951
                    $this->course->resources[RESOURCE_GLOSSARY][$id]->destination_id = $my_id;
2952
                }
2953
			}
2954
		}
2955
	}
2956
2957
    /**
2958
     * @param int $session_id
2959
     */
2960
    public function restore_wiki($session_id = 0)
2961
    {
2962
		if ($this->course->has_resources(RESOURCE_WIKI)) {
2963
			// wiki table of the target course
2964
			$table_wiki = Database :: get_course_table(TABLE_WIKI);
2965
			$table_wiki_conf = Database :: get_course_table(TABLE_WIKI_CONF);
2966
2967
			// storing all the resources that have to be copied in an array
2968
			$resources = $this->course->resources;
2969
2970
			foreach ($resources[RESOURCE_WIKI] as $id => $wiki) {
2971
				// the sql statement to insert the groups from the old course to the new course
2972
2973
				// check resources inside html from ckeditor tool and copy correct urls into recipient course
2974
                $wiki->content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2975
                    $wiki->content,
2976
                    $this->course->code,
2977
                    $this->course->destination_path,
2978
                    $this->course->backup_path,
2979
                    $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Course.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
2980
                );
2981
2982
                $params = [
2983
                    'c_id' => $this->destination_course_id,
2984
                    'page_id' => self::DBUTF8($wiki->page_id),
2985
                    'reflink' => self::DBUTF8($wiki->reflink),
2986
                    'title' => self::DBUTF8($wiki->title),
2987
                    'content' => self::DBUTF8($wiki->content),
0 ignored issues
show
Security Bug introduced by
It seems like $wiki->content can also be of type false; however, CourseRestorer::DBUTF8() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
2988
                    'user_id' => intval($wiki->user_id),
2989
                    'group_id' => intval($wiki->group_id),
2990
                    'dtime' => self::DBUTF8($wiki->dtime),
2991
                    'progress' => self::DBUTF8($wiki->progress),
2992
                    'version' => intval($wiki->version),
2993
                    'session_id' => !empty($session_id) ? intval($session_id) : 0,
2994
                ];
2995
2996
				$new_id = Database::insert($table_wiki, $params);
2997
2998
                if ($new_id) {
2999
3000
                    $sql = "UPDATE $table_wiki SET page_id = '$new_id', id = iid
3001
                            WHERE c_id = ".$this->destination_course_id." AND iid = '$new_id'";
3002
                    Database::query($sql);
3003
3004
                    $this->course->resources[RESOURCE_WIKI][$id]->destination_id = $new_id;
3005
3006
                    // we also add an entry in wiki_conf
3007
                    $params = [
3008
                        'c_id' => $this->destination_course_id,
3009
                        'page_id' => $new_id,
3010
                        'task' => '',
3011
                        'feedback1' => '',
3012
                        'feedback2' => '',
3013
                        'feedback3' => '',
3014
                        'fprogress1' => '',
3015
                        'fprogress2' => '',
3016
                        'fprogress3' => '',
3017
                        'max_size' => '',
3018
                        'max_text' => 0,
3019
                        'max_version' => 0,
3020
                        'startdate_assig' => '',
3021
                        'enddate_assig' => '',
3022
                        'delayedsubmit' => 0,
3023
                    ];
3024
3025
                    Database::insert($table_wiki_conf, $params);
3026
                }
3027
			}
3028
		}
3029
	}
3030
3031
    /**
3032
     * Restore Thematics
3033
     * @param int $session_id
3034
     */
3035
    public function restore_thematic($session_id = 0)
3036
    {
3037
		if ($this->course->has_resources(RESOURCE_THEMATIC)) {
3038
            $table_thematic = Database:: get_course_table(TABLE_THEMATIC);
3039
            $table_thematic_advance = Database:: get_course_table(TABLE_THEMATIC_ADVANCE);
3040
            $table_thematic_plan = Database:: get_course_table(TABLE_THEMATIC_PLAN);
3041
3042
			$resources = $this->course->resources;
3043
			foreach ($resources[RESOURCE_THEMATIC] as $id => $thematic) {
3044
3045
				// check resources inside html from ckeditor tool and copy correct urls into recipient course
3046
                $thematic->params['content'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
3047
                    $thematic->params['content'],
3048
                    $this->course->code,
3049
                    $this->course->destination_path,
3050
                    $this->course->backup_path,
3051
                    $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Course.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
3052
                );
3053
				$thematic->params['c_id']  = $this->destination_course_id;
3054
				unset($thematic->params['id']);
3055
                unset($thematic->params['iid']);
3056
3057
				$last_id = Database::insert($table_thematic, $thematic->params, false);
3058
3059
				if ($last_id) {
3060
3061
                    $sql = "UPDATE $table_thematic SET id = iid WHERE iid = $last_id";
3062
                    Database::query($sql);
3063
3064
                    api_item_property_update(
3065
                        $this->destination_course_info,
3066
                        'thematic',
3067
                        $last_id,
3068
                        "ThematicAdded",
3069
                        api_get_user_id()
3070
                    );
3071
3072 View Code Duplication
					foreach ($thematic->thematic_advance_list as $thematic_advance) {
3073
						unset($thematic_advance['id']);
3074
                        unset($thematic_advance['iid']);
3075
						$thematic_advance['attendance_id'] = 0;
3076
						$thematic_advance['thematic_id'] = $last_id;
3077
						$thematic_advance['c_id']  = $this->destination_course_id;
3078
                        $my_id = Database::insert(
3079
                            $table_thematic_advance,
3080
                            $thematic_advance,
3081
                            false
3082
                        );
3083
3084
						if ($my_id) {
3085
3086
                            $sql = "UPDATE $table_thematic_advance SET id = iid WHERE iid = $my_id";
3087
                            Database::query($sql);
3088
3089
                            api_item_property_update(
3090
                                $this->destination_course_info,
3091
                                'thematic_advance',
3092
                                $my_id,
3093
                                "ThematicAdvanceAdded",
3094
                                api_get_user_id()
3095
                            );
3096
						}
3097
					}
3098
3099 View Code Duplication
					foreach($thematic->thematic_plan_list as $thematic_plan) {
3100
						unset($thematic_plan['id']);
3101
                        unset($thematic_plan['iid']);
3102
						$thematic_plan['thematic_id'] = $last_id;
3103
						$thematic_plan['c_id'] = $this->destination_course_id;
3104
						$my_id = Database::insert($table_thematic_plan, $thematic_plan, false);
3105
3106
						if ($my_id) {
3107
3108
                            $sql = "UPDATE $table_thematic_plan SET id = iid WHERE iid = $my_id";
3109
                            Database::query($sql);
3110
3111
                            api_item_property_update(
3112
                                $this->destination_course_info,
3113
                                'thematic_plan',
3114
                                $my_id,
3115
                                "ThematicPlanAdded",
3116
                                api_get_user_id()
3117
                            );
3118
						}
3119
					}
3120
				}
3121
			}
3122
		}
3123
	}
3124
3125
    /**
3126
     * Restore Attendance
3127
     * @param int $session_id
3128
     */
3129
    public function restore_attendance($session_id = 0)
3130
    {
3131
		if ($this->course->has_resources(RESOURCE_ATTENDANCE)) {
3132
			$table_attendance = Database :: get_course_table(TABLE_ATTENDANCE);
3133
			$table_attendance_calendar = Database :: get_course_table(TABLE_ATTENDANCE_CALENDAR);
3134
3135
			$resources = $this->course->resources;
3136
			foreach ($resources[RESOURCE_ATTENDANCE] as $id => $obj) {
3137
3138
				// check resources inside html from ckeditor tool and copy correct urls into recipient course
3139
                $obj->params['description'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
3140
                    $obj->params['description'],
3141
                    $this->course->code,
3142
                    $this->course->destination_path,
3143
                    $this->course->backup_path,
3144
                    $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Course.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
3145
                );
3146
3147
                unset($obj->params['id']);
3148
                unset($obj->params['iid']);
3149
3150
				$obj->params['c_id'] = $this->destination_course_id;
3151
3152
				$last_id = Database::insert($table_attendance, $obj->params);
3153
3154
				if (is_numeric($last_id)) {
3155
3156
                    $sql = "UPDATE $table_attendance SET id = iid WHERE iid = $last_id";
3157
                    Database::query($sql);
3158
3159
                    api_item_property_update(
3160
                        $this->destination_course_info,
3161
                        TOOL_ATTENDANCE,
3162
                        $last_id,
3163
                        "AttendanceAdded",
3164
                        api_get_user_id()
3165
                    );
3166
3167
                    foreach ($obj->attendance_calendar as $attendance_calendar) {
3168
						unset($attendance_calendar['id']);
3169
                        unset($attendance_calendar['iid']);
3170
3171
						$attendance_calendar['attendance_id'] = $last_id;
3172
						$attendance_calendar['c_id'] = $this->destination_course_id;
3173
                        $attendanceCalendarId = Database::insert(
3174
                            $table_attendance_calendar,
3175
                            $attendance_calendar
3176
                        );
3177
3178
                        $sql = "UPDATE $table_attendance_calendar SET id = iid WHERE iid = $attendanceCalendarId";
3179
                        Database::query($sql);
3180
					}
3181
				}
3182
			}
3183
		}
3184
	}
3185
3186
    /**
3187
     * Restore Works
3188
     * @param int $sessionId
3189
     */
3190
    public function restore_works($sessionId = 0)
3191
    {
3192
        require_once api_get_path(SYS_CODE_PATH).'work/work.lib.php';
3193
        if ($this->course->has_resources(RESOURCE_WORK)) {
3194
            $table_work_assignment = Database :: get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
3195
3196
            $resources = $this->course->resources;
3197
            foreach ($resources[RESOURCE_WORK] as $obj) {
3198
3199
                // check resources inside html from ckeditor tool and copy correct urls into recipient course
3200
                $obj->params['description'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
3201
                    $obj->params['description'],
3202
                    $this->course->code,
3203
                    $this->course->destination_path,
3204
                    $this->course->backup_path,
3205
                    $this->course->info['path']
0 ignored issues
show
Bug introduced by
The property info does not seem to exist in Course.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
3206
                );
3207
3208
                $id_work = $obj->params['id'];
3209
                $obj->params['id'] = null;
3210
                $obj->params['c_id'] = $this->destination_course_info['real_id'];
3211
3212
                // re-create dir
3213
                // @todo check security against injection of dir in crafted course backup here!
3214
                $path = $obj->params['url'];
3215
                $path = '/'.str_replace('/','',substr($path,1));
3216
3217
                $workData = array();
3218
                switch ($this->file_option) {
3219
                    case FILE_SKIP:
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
3220
                        $workData = get_work_data_by_path(
3221
                            $path,
3222
                            $this->destination_course_info['real_id']
3223
                        );
3224
                        if (!empty($workData)) {
3225
                            continue;
3226
                        }
3227
                    case FILE_OVERWRITE:
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
3228
                        // Creating folder.
3229
                        $workData = get_work_data_by_path(
3230
                            $path,
3231
                            $this->destination_course_info['real_id']
3232
                        );
3233
                    case FILE_RENAME:
3234
                        $obj->params['new_dir'] = $obj->params['title'];
3235
3236
                        if (!empty($this->course_origin_id)) {
3237
                            $sql = 'SELECT * FROM ' . $table_work_assignment . '
3238
                                    WHERE
3239
                                        c_id = ' . $this->course_origin_id . ' AND
3240
                                        publication_id = ' . $id_work;
3241
3242
                            $result = Database::query($sql);
3243
                            $cant = Database::num_rows($result);
3244
                            if ($cant > 0) {
3245
                                $row = Database::fetch_assoc($result);
3246
                            }
3247
3248
                            //$obj->params['qualification'] = empty($row['enable_qualification']) ? true : false;
3249
                            $obj->params['enableExpiryDate'] = $row['expires_on'] == '0000-00-00 00:00:00' ? false : true;
3250
                            $obj->params['enableEndDate'] = $row['ends_on'] == '0000-00-00 00:00:00' ? false : true;
3251
                            $obj->params['expires_on'] = $row['expires_on'];
3252
                            $obj->params['ends_on'] = $row['ends_on'];
3253
                            $obj->params['enable_qualification'] = $row['enable_qualification'];
3254
                            $obj->params['add_to_calendar'] = !empty($row['add_to_calendar']) ? 1 : 0;
3255
3256
                            if (empty($workData)) {
3257
                                addDir(
3258
                                    $obj->params,
3259
                                    api_get_user_id(),
3260
                                    $this->destination_course_info,
3261
                                    0,
3262
                                    $sessionId
3263
                                );
3264
                            } else {
3265
                                $workId = $workData['id'];
3266
                                updateWork(
3267
                                    $workId,
3268
                                    $obj->params,
3269
                                    $this->destination_course_info,
3270
                                    $sessionId
3271
                                );
3272
                                updatePublicationAssignment(
3273
                                    $workId,
3274
                                    $obj->params,
3275
                                    $this->destination_course_info,
3276
                                    0
3277
                                );
3278
                            }
3279
                        }
3280
                        break;
3281
                }
3282
            }
3283
        }
3284
    }
3285
3286
    /**
3287
     * Restore Works
3288
     * @param int $sessionId
3289
     */
3290
    public function restore_gradebook($sessionId = 0)
3291
    {
3292
        if ($this->course->has_resources(RESOURCE_GRADEBOOK)) {
3293
            $resources = $this->course->resources;
3294
            /**
3295
             * @var GradeBookBackup $obj
3296
             */
3297
            foreach ($resources[RESOURCE_GRADEBOOK] as $id => $obj) {
3298
                if (!empty($obj->categories)) {
3299
                    $categoryIdList = [];
3300
                    /** @var Category $cat */
3301
                    foreach ($obj->categories as $cat) {
3302
                        $cat->set_course_code($this->destination_course_info['code']);
3303
                        $cat->set_session_id($sessionId);
3304
3305
                        $parentId = $cat->get_parent_id();
3306
                        if (!empty($parentId)) {
3307
                            if (isset($categoryIdList[$parentId])) {
3308
                                $cat->set_parent_id($categoryIdList[$parentId]);
3309
                            }
3310
                        }
3311
                        $oldId = $cat->get_id();
3312
                        $categoryId = $cat->add();
3313
                        $categoryIdList[$oldId] = $categoryId;
3314
                    }
3315
                }
3316
            }
3317
        }
3318
    }
3319
3320
    /**
3321
     * @param string $str
3322
     * @return string
3323
     */
3324
    public function DBUTF8($str)
3325
    {
3326
		if (UTF8_CONVERT) {
3327
            $str = utf8_encode($str);
3328
        }
3329
		return $str;
3330
	}
3331
3332
    /**
3333
     * @param string $str
3334
     * @return string
3335
     */
3336
    public function DBUTF8escapestring($str)
3337
    {
3338
        if (UTF8_CONVERT) {
3339
            $str = utf8_encode($str);
3340
        }
3341
		return Database::escape_string($str);
3342
	}
3343
3344
    /**
3345
     * @param array $array
3346
     * @return mixed
3347
     */
3348
    public function DBUTF8_array($array)
3349
    {
3350
        if (UTF8_CONVERT) {
3351
            foreach ($array as &$item)  {
3352
                $item = utf8_encode($item);
3353
            }
3354
            return $array;
3355
        } else {
3356
            return $array;
3357
        }
3358
    }
3359
3360
    /**
3361
     * Check if user exist otherwise use current user
3362
     * @param int $userId
3363
     * @param bool $returnNull
3364
     *
3365
     * @return int
3366
     */
3367
    private function checkUserId($userId, $returnNull = false) {
3368
3369
        if (!empty($userId)) {
3370
            $userInfo = api_get_user_info($userId);
3371
            if (empty($userInfo)) {
3372
                return api_get_user_id();
3373
            }
3374
        }
3375
3376
        if ($returnNull) {
3377
            return null;
3378
        }
3379
3380
        return $userId;
3381
    }
3382
}
3383