Passed
Push — 1.10.x ( b77fe8...f38c8d )
by
unknown
133:09 queued 81:28
created

CourseRestorer::restore_topic()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 51
Code Lines 38

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 51
rs 8.8981
cc 4
eloc 38
nc 6
nop 3

How to fix   Long Method   

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
require_once 'Resource.class.php';
5
require_once 'GradeBookBackup.php';
6
require_once 'Course.class.php';
7
require_once 'Event.class.php';
8
require_once 'Link.class.php';
9
require_once 'ToolIntro.class.php';
10
require_once 'LinkCategory.class.php';
11
require_once 'ForumCategory.class.php';
12
require_once 'Forum.class.php';
13
require_once 'ForumTopic.class.php';
14
require_once 'ForumPost.class.php';
15
require_once 'CourseDescription.class.php';
16
require_once 'CourseCopyLearnpath.class.php';
17
require_once 'Survey.class.php';
18
require_once 'SurveyQuestion.class.php';
19
require_once 'Glossary.class.php';
20
require_once 'wiki.class.php';
21
require_once 'Thematic.class.php';
22
require_once 'Work.class.php';
23
24
define('FILE_SKIP', 1);
25
define('FILE_RENAME', 2);
26
define('FILE_OVERWRITE', 3);
27
define('UTF8_CONVERT', false); //false by default
28
29
/**
30
 * Class CourseRestorer
31
 *
32
 * Class to restore items from a course object to a Chamilo-course
33
 * @author Bart Mollet <[email protected]>
34
 * @author Julio Montoya <[email protected]> Several fixes/improvements
35
 * @package chamilo.backup
36
 */
37
class CourseRestorer
38
{
39
	/**
40
	 * The course-object
41
	 */
42
    public $course;
43
    public $destination_course_info;
44
45
	/**
46
	 * What to do with files with same name (FILE_SKIP, FILE_RENAME or
47
	 * FILE_OVERWRITE)
48
	 */
49
    public $file_option;
50
    public $set_tools_invisible_by_default;
51
    public $skip_content;
52
    public $tools_to_restore = array(
53
        'announcements',
54
        'attendance',
55
        'course_descriptions',
56
        'documents',
57
        'events',
58
        'forum_category',
59
        'forums',
60
       // 'forum_topics',
61
        'glossary',
62
        'quizzes',
63
        'test_category',
64
        'links',
65
        'learnpaths',
66
        'surveys',
67
        //'scorm_documents', ??
68
        'tool_intro',
69
        'thematic',
70
        'wiki',
71
        'works',
72
        'gradebook',
73
    );
74
75
    /** Setting per tool */
76
    public $tool_copy_settings = array();
77
78
    /**
79
     * If true adds the text "copy" in the title of an item (only for LPs right now)
80
     *
81
     **/
82
    public $add_text_in_items = false;
83
    public $destination_course_id;
84
85
    /**
86
     * CourseRestorer constructor.
87
     * @param array $course
88
     */
89
    public function __construct($course)
90
    {
91
        $this->course = $course;
92
        $course_info = api_get_course_info($this->course->code);
93
        if (!empty($course_info)) {
94
            $this->course_origin_id = $course_info['real_id'];
95
        } else {
96
            $this->course_origin_id = null;
97
        }
98
        $this->file_option = FILE_RENAME;
99
        $this->set_tools_invisible_by_default = false;
100
        $this->skip_content = array();
101
    }
102
103
    /**
104
     * Set the file-option
105
     * @param int $option (optional) What to do with files with same name
106
     * FILE_SKIP, FILE_RENAME or FILE_OVERWRITE
107
     */
108
    public function set_file_option($option = FILE_OVERWRITE)
109
    {
110
        $this->file_option = $option;
111
    }
112
113
    /**
114
     * @param string $status
115
     */
116
    public function set_add_text_in_items($status)
117
    {
118
        $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...
119
    }
120
121
    /**
122
     * @param array $array
123
     */
124
    public function set_tool_copy_settings($array)
125
    {
126
        $this->tool_copy_settings = $array;
127
    }
128
129
	/**
130
	 * Restore a course.
131
     *
132
	 * @param string    $destination_course_code code of the Chamilo-course in
133
	 * @param int	    $session_id
134
	 * @param bool	    $update_course_settings Course settings are going to be restore?
135
     * @param bool      $respect_base_content
136
     * @return bool
137
	 */
138
    public function restore(
139
        $destination_course_code = '',
140
        $session_id = 0,
141
        $update_course_settings = false,
142
        $respect_base_content = false
143
    ) {
144
        if ($destination_course_code == '') {
145
            $course_info = api_get_course_info();
146
            $this->destination_course_info = $course_info;
147
            $this->course->destination_path = $course_info['path'];
148
        } else {
149
            $course_info = api_get_course_info($destination_course_code);
150
            $this->destination_course_info = $course_info;
151
            $this->course->destination_path = $course_info['path'];
152
        }
153
        $this->destination_course_id = $course_info['real_id'];
154
155
        //Getting first teacher (for the forums)
156
        $teacher_list = CourseManager::get_teacher_list_from_course_code(
157
            $course_info['code']
158
        );
159
        $this->first_teacher_id = api_get_user_id();
160
161
        if (!empty($teacher_list)) {
162
            foreach ($teacher_list as $teacher) {
163
                $this->first_teacher_id = $teacher['user_id'];
164
                break;
165
            }
166
        }
167
168
        if (empty($this->course)) {
169
            return false;
170
        }
171
172
        // Source platform encoding - reading/detection
173
        // The correspondent data field has been added as of version 1.8.6.1
174
175
        if (empty($this->course->encoding)) {
176
            // The archive has been created by a system which is prior to 1.8.6.1 version.
177
            // In this case we have to detect the encoding.
178
            $sample_text = $this->course->get_sample_text()."\n";
0 ignored issues
show
Bug introduced by
The method get_sample_text cannot be called on $this->course (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
179
            // Let us exclude ASCII lines, probably they are English texts.
180
            $sample_text = explode("\n", $sample_text);
181
            foreach ($sample_text as $key => &$line) {
182
                if (api_is_valid_ascii($line)) {
183
                    unset($sample_text[$key]);
184
                }
185
            }
186
            $sample_text = join("\n", $sample_text);
187
            $this->course->encoding = api_detect_encoding($sample_text, $course_info['language']);
188
        }
189
190
        // Encoding conversion of the course, if it is needed.
191
        $this->course->to_system_encoding();
0 ignored issues
show
Bug introduced by
The method to_system_encoding cannot be called on $this->course (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
192
193
        foreach ($this->tools_to_restore as $tool) {
194
            $function_build = 'restore_'.$tool;
195
            $this->$function_build($session_id, $respect_base_content, $destination_course_code);
196
        }
197
198
        if ($update_course_settings) {
199
            $this->restore_course_settings($destination_course_code);
200
        }
201
202
        // Restore the item properties
203
        $table = Database::get_course_table(TABLE_ITEM_PROPERTY);
204
205
        foreach ($this->course->resources as $type => $resources) {
206
            if (is_array($resources)) {
207
                foreach ($resources as $id => $resource) {
208
                    if (isset($resource->item_properties)) {
209
                        foreach ($resource->item_properties as $property) {
210
                            // First check if there isn't already a record for this resource
211
                            $sql = "SELECT * FROM $table
212
                                    WHERE
213
                                        c_id = ".$this->destination_course_id." AND
214
                                        tool = '".$property['tool']."' AND
215
                                        ref = '".$resource->destination_id."'";
216
217
                            $params = [];
218
                            if (!empty($session_id)) {
219
                                $params['session_id'] = intval($session_id);
220
                            }
221
222
                            $res = Database::query($sql);
223
                            if (Database::num_rows($res) == 0) {
224
                                /* The to_group_id and to_user_id are set to default
225
                                values as users/groups possibly not exist in
226
                                the target course*/
227
228
                                $params['c_id'] = $this->destination_course_id;
229
                                $params['tool'] = self::DBUTF8(
230
                                    $property['tool']
231
                                );
232
                                $property['insert_user_id'] = $this->checkUserId($property['insert_user_id']);
233
234
                                $params['insert_user_id'] = self::DBUTF8(
235
                                    $property['insert_user_id']
236
                                );
237
                                $params['insert_date'] = self::DBUTF8(
238
                                    $property['insert_date']
239
                                );
240
                                $params['lastedit_date'] = self::DBUTF8(
241
                                    $property['lastedit_date']
242
                                );
243
                                $params['ref'] = $resource->destination_id;
244
                                $params['lastedit_type'] = self::DBUTF8(
245
                                    $property['lastedit_type']
246
                                );
247
                                $params['lastedit_user_id'] = self::DBUTF8(
248
                                    $property['lastedit_user_id']
249
                                );
250
                                $params['visibility'] = self::DBUTF8(
251
                                    $property['visibility']
252
                                );
253
                                $params['start_visible'] = self::DBUTF8(
254
                                    $property['start_visible']
255
                                );
256
                                $params['end_visible'] = self::DBUTF8(
257
                                    $property['end_visible']
258
                                );
259
260
                                $property['to_user_id'] = $this->checkUserId($property['to_user_id'], true);
261
262
                                $params['to_user_id'] = self::DBUTF8(
263
                                    $property['to_user_id']
264
                                );
265
                                //$params['to_group_id'] = 'NULL';
266
267
                                $id = Database::insert($table, $params);
268
                                if ($id) {
269
                                    $sql = "UPDATE $table SET id = iid WHERE iid = $id";
270
                                    Database::query($sql);
271
                                }
272
                            }
273
                        }
274
                    }
275
                }
276
            }
277
        }
278
    }
279
280
	/**
281
	 * Restore only harmless course settings:
282
     * course_language, visibility, department_name,department_url,
283
     * subscribe, unsubscribe ,category_code
284
	 *
285
	 * @param string $destination_course_code
286
	 */
287
    public function restore_course_settings($destination_course_code)
288
    {
289
	    $origin_course_info = api_get_course_info($destination_course_code);
290
	    $course_info = $this->course->info;
291
        $params['course_language'] = $course_info['language'];
292
        $params['visibility'] = $course_info['visibility'];
293
        $params['department_name'] = $course_info['department_name'];
294
        $params['department_url'] = $course_info['department_url'];
295
296
        $params['category_code'] = $course_info['categoryCode'];
297
        $params['subscribe'] = $course_info['subscribe_allowed'];
298
        $params['unsubscribe'] = $course_info['unsubscribe'];
299
	    CourseManager::update_attributes($origin_course_info['real_id'], $params);
300
	}
301
302
    /**
303
     * Restore documents
304
     *
305
     * @param int $session_id
306
     * @param bool $respect_base_content
307
     * @param string $destination_course_code
308
     */
309
    public function restore_documents($session_id = 0, $respect_base_content = false, $destination_course_code = '')
310
    {
311
        $course_info = api_get_course_info($destination_course_code);
312
313
        if ($this->course->has_resources(RESOURCE_DOCUMENT)) {
0 ignored issues
show
Bug introduced by
The method has_resources cannot be called on $this->course (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
314
			$table = Database :: get_course_table(TABLE_DOCUMENT);
315
			$resources = $this->course->resources;
316
            $path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/';
317
318
			foreach ($resources[RESOURCE_DOCUMENT] as $id => $document) {
319
320
                if (empty($document->item_properties[0]['id_session'])) {
321
                    $my_session_id = 0;
322
                } else {
323
                    $my_session_id = $session_id;
324
                }
325
326
                if ($document->file_type == FOLDER) {
327
                    $visibility = $document->item_properties[0]['visibility'];
328
                    $new = substr($document->path, 8);
329
330
                    $folderList = explode('/', $new);
331
                    $tempFolder = '';
332
333
                    // Check if the parent path exists.
334
                    foreach ($folderList as $folder) {
335
                        $folderToCreate = $tempFolder.$folder;
336
                        $sysFolderPath = $path.'document'.$folderToCreate;
337
                        $tempFolder .= $folder.'/';
338
339
                        if (empty($folderToCreate)) {
340
                            continue;
341
                        }
342
343
                        $title = $document->title;
344
                        if (empty($title)) {
345
                            $title = basename($sysFolderPath);
346
                        }
347
348
                        // File doesn't exist in file system.
349
                        if (!is_dir($sysFolderPath)) {
350
                            // Creating directory
351
                            create_unexisting_directory(
352
                                $course_info,
353
                                api_get_user_id(),
354
                                $my_session_id,
355
                                0,
356
                                0,
357
                                $path.'document',
358
                                $folderToCreate,
359
                                $title,
360
                                $visibility
361
                            );
362
                        } else {
363
                            // File exist in file system.
364
                            $documentData = DocumentManager::get_document_id(
365
                                $course_info,
366
                                $folderToCreate,
367
                                $my_session_id
368
                            );
369
370
                            if (empty($documentData)) {
371
                                /* This means the folder exists in the
372
                                filesystem but not in the DB, trying to fix it */
373
                                add_document(
374
                                    $course_info,
375
                                    $folderToCreate,
376
                                    'folder',
377
                                    0,
378
                                    $title,
379
                                    null,
380
                                    null,
381
                                    false,
382
                                    null,
383
                                    $my_session_id
384
                                );
385
                            }
386
                        }
387
                    }
388
		    	} elseif ($document->file_type == DOCUMENT) {
389
                    //Checking if folder exists in the database otherwise we created it
390
                    $dir_to_create = dirname($document->path);
391
392
                    if (!empty($dir_to_create) && $dir_to_create != 'document' && $dir_to_create != '/') {
393
                        if (is_dir($path.dirname($document->path))) {
394
                            $sql = "SELECT id FROM $table
395
                                    WHERE
396
                                        c_id = ".$this->destination_course_id." AND
397
                                        path = '/".self::DBUTF8escapestring(substr(dirname($document->path), 9))."'";
398
                            $res = Database::query($sql);
399
                            if (Database::num_rows($res) == 0) {
400
                                //continue;
401
                                $visibility = $document->item_properties[0]['visibility'];
402
                                $new = '/'.substr(dirname($document->path), 9);
403
                                $title = $document->title;
404
                                if (empty($title)) {
405
                                    $title = str_replace('/', '', $new);
406
                                }
407
408
                                // This code fixes the possibility for a file without a directory entry to be
409
                                $document_id = add_document(
410
                                    $course_info,
411
                                    $new,
412
                                    'folder',
413
                                    0,
414
                                    $title,
415
                                    null,
416
                                    null,
417
                                    false
418
                                );
419
420
                                $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
421
                                $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
422
                                $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
423
                                $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
424
425
                                $insertUserId = $this->checkUserId($insertUserId);
426
                                $toUserId = $this->checkUserId($toUserId, true);
427
428
                                api_item_property_update(
429
                                    $course_info,
430
                                    TOOL_DOCUMENT,
431
                                    $document_id,
432
                                    'FolderCreated',
433
                                    $insertUserId,
434
                                    $toGroupId,
435
                                    $toUserId,
436
                                    null,
437
                                    null,
438
                                    $my_session_id
439
                                );
440
                            }
441
                        }
442
                    }
443
444
					if (file_exists($path.$document->path)) {
445
						switch ($this->file_option) {
446
							case FILE_OVERWRITE:
447
                                $origin_path = $this->course->backup_path.'/'.$document->path;
448
449
								if (file_exists($origin_path)) {
450
        						    copy($origin_path, $path.$document->path);
451
                                    $sql = "SELECT id FROM $table
452
                                            WHERE
453
                                                c_id = ".$this->destination_course_id." AND
454
                                                path = '/".self::DBUTF8escapestring(substr($document->path, 9))."'";
455
456
        						    $res = Database::query($sql);
457
                                    $count = Database::num_rows($res);
458
459
                                    if ($count == 0) {
460
                                        $params = [
461
                                            'path' => "/".self::DBUTF8(substr($document->path, 9)),
462
                                            'c_id' => $this->destination_course_id,
463
                                            'comment'=> self::DBUTF8($document->comment),
464
                                            'title' => self::DBUTF8($document->title),
465
                                            'filetype' => self::DBUTF8($document->file_type),
466
                                            'size' => self::DBUTF8($document->size),
467
                                            'session_id' => $my_session_id,
468
                                        ];
469
470
    									$document_id = Database::insert($table, $params);
471
472
                                        if ($document_id) {
473
                                            $sql = "UPDATE $table SET id = iid WHERE iid = $document_id";
474
                                            Database::query($sql);
475
                                        }
476
                                        $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id;
477
478
                                        $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
479
                                        $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
480
                                        $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
481
                                        $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
482
483
                                        $insertUserId = $this->checkUserId($insertUserId);
484
                                        $toUserId = $this->checkUserId($toUserId, true);
485
486
                                        api_item_property_update(
487
                                            $course_info,
488
                                            TOOL_DOCUMENT,
489
                                            $document_id,
490
                                            'DocumentAdded',
491
                                            $insertUserId,
492
                                            $toGroupId,
493
                                            $toUserId,
494
                                            null,
495
                                            null,
496
                                            $my_session_id
497
                                        );
498
                                    } else {
499
                                        $obj = Database::fetch_object($res);
500
                                        $document_id = $obj->id;
501
                                        $params = [
502
                                            'path' => "/".self::DBUTF8(substr($document->path, 9)),
503
                                            'c_id' => $this->destination_course_id,
504
                                            'comment'=> self::DBUTF8($document->comment),
505
                                            'title' => self::DBUTF8($document->title),
506
                                            'filetype' => self::DBUTF8($document->file_type),
507
                                            'size' => self::DBUTF8($document->size),
508
                                            'session_id' => $my_session_id,
509
                                        ];
510
511
                                        Database::update(
512
                                            $table,
513
                                            $params,
514
                                            [
515
                                                'c_id = ? AND path = ?' => [
516
                                                    $this->destination_course_id,
517
                                                    "/".self::DBUTF8escapestring(substr($document->path, 9)),
518
                                                ],
519
                                            ]
520
                                        );
521
522
                                        $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $obj->id;
523
524
                                        $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
525
                                        $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
526
                                        $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
527
                                        $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
528
529
                                        $insertUserId = $this->checkUserId($insertUserId);
530
                                        $toUserId = $this->checkUserId($toUserId, true);
531
532
                                        api_item_property_update(
533
                                            $course_info,
534
                                            TOOL_DOCUMENT,
535
                                            $obj->id,
536
                                            'default',
537
                                            $insertUserId,
538
                                            $toGroupId,
539
                                            $toUserId,
540
                                            null,
541
                                            null,
542
                                            $my_session_id
543
                                        );
544
                                    }
545
546
                                    // Replace old course code with the new destination code
547
548
                                    $file_info = pathinfo($path.$document->path);
549
550
                                    if (in_array($file_info['extension'], array('html', 'htm'))) {
551
                                        $content = file_get_contents($path.$document->path);
552
                                        if (UTF8_CONVERT) $content = utf8_encode($content);
553
                                        $content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
554
                                            $content,
555
                                            $this->course->code,
556
                                            $this->course->destination_path,
557
                                            $this->course->backup_path,
558
                                            $this->course->info['path']
559
                                        );
560
                                        file_put_contents($path.$document->path,$content);
561
                                    }
562
563
                                    $params = [
564
                                        'comment'=> self::DBUTF8($document->comment),
565
                                        'title' => self::DBUTF8($document->title),
566
                                        'size' => self::DBUTF8($document->size),
567
                                    ];
568
                                    Database::update(
569
                                        $table,
570
                                        $params,
571
                                        [
572
                                            'c_id = ? AND id = ?' => [
573
                                                $this->destination_course_id,
574
                                                $document_id,
575
                                            ],
576
                                        ]
577
                                    );
578
								}
579
580
								break;
581
							case FILE_SKIP:
582
								$sql = "SELECT id FROM $table
583
								        WHERE
584
								            c_id = ".$this->destination_course_id." AND
585
								            path='/".self::DBUTF8escapestring(substr($document->path, 9))."'";
586
								$res = Database::query($sql);
587
								$obj = Database::fetch_object($res);
588
								$this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $obj->id;
589
								break;
590
							case FILE_RENAME:
591
								$i = 1;
592
								$ext = explode('.', basename($document->path));
593 View Code Duplication
								if (count($ext) > 1) {
594
									$ext = array_pop($ext);
595
									$file_name_no_ext = substr($document->path, 0, - (strlen($ext) + 1));
596
									$ext = '.'.$ext;
597
								} else {
598
									$ext = '';
599
									$file_name_no_ext = $document->path;
600
								}
601
								$new_file_name = $file_name_no_ext.'_'.$i.$ext;
602
								$file_exists = file_exists($path.$new_file_name);
603 View Code Duplication
								while ($file_exists) {
604
									$i ++;
605
									$new_file_name = $file_name_no_ext.'_'.$i.$ext;
606
									$file_exists = file_exists($path.$new_file_name);
607
								}
608
609
								if (!empty($session_id)) {
610
611
									$document_path = explode('/',$document->path,3);
612
									$course_path = $path;
613
									$orig_base_folder = $document_path[1];
614
									$orig_base_path   = $course_path.$document_path[0].'/'.$document_path[1];
615
616
									if (is_dir($orig_base_path)) {
617
618
										$new_base_foldername = $orig_base_folder;
619
										$new_base_path = $orig_base_path;
620
621
										if ($_SESSION['orig_base_foldername'] != $new_base_foldername) {
622
											unset($_SESSION['new_base_foldername']);
623
											unset($_SESSION['orig_base_foldername']);
624
											unset($_SESSION['new_base_path']);
625
										}
626
627
										$folder_exists = file_exists($new_base_path);
628
										if ($folder_exists) {
629
											$_SESSION['orig_base_foldername'] = $new_base_foldername; 		// e.g: carpeta1 in session
630
											$x = '';
631
											while ($folder_exists) {
632
												$x = $x + 1;
633
												$new_base_foldername = $document_path[1].'_'.$x;
634
												$new_base_path = $orig_base_path.'_'.$x;
635
                                                if ($_SESSION['new_base_foldername'] == $new_base_foldername) {
636
                                                    break;
637
                                                }
638
												$folder_exists = file_exists($new_base_path);
639
											}
640
											$_SESSION['new_base_foldername'] = $new_base_foldername;
641
											$_SESSION['new_base_path'] = $new_base_path;
642
										}
643
644
										if (isset($_SESSION['new_base_foldername']) && isset($_SESSION['new_base_path'])) {
645
											$new_base_foldername = $_SESSION['new_base_foldername'];
646
											$new_base_path = $_SESSION['new_base_path'];
647
										}
648
649
										$dest_document_path = $new_base_path.'/'.$document_path[2];		// e.g: "/var/www/wiener/courses/CURSO4/document/carpeta1_1/subcarpeta1/collaborative.png"
650
										$basedir_dest_path 	= dirname($dest_document_path);				// e.g: "/var/www/wiener/courses/CURSO4/document/carpeta1_1/subcarpeta1"
651
										$base_path_document = $course_path.$document_path[0];			// e.g: "/var/www/wiener/courses/CURSO4/document"
652
										$path_title = '/'.$new_base_foldername.'/'.$document_path[2];
653
654
										copy_folder_course_session(
655
                                            $basedir_dest_path,
656
                                            $base_path_document,
657
                                            $session_id,
658
                                            $course_info,
659
                                            $document,
660
                                            $this->course_origin_id
661
                                        );
662
663
                                        if (file_exists($course_path.$document->path)) {
664
                                            copy($course_path.$document->path, $dest_document_path);
665
                                        }
666
667
                                        //Replace old course code with the new destination code see BT#1985
668
                                        if (file_exists($dest_document_path)) {
669
                                            $file_info = pathinfo($dest_document_path);
670
                                            if (in_array($file_info['extension'], array('html','htm'))) {
671
                                                $content = file_get_contents($dest_document_path);
672
                                                if (UTF8_CONVERT) {
673
                                                    $content = utf8_encode($content);
674
                                                }
675
                                                $content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
676
                                                    $content,
677
                                                    $this->course->code,
678
                                                    $this->course->destination_path,
679
                                                    $this->course->backup_path,
680
                                                    $this->course->info['path']
681
                                                );
682
                                                file_put_contents($dest_document_path, $content);
683
                                            }
684
                                        }
685
686
                                        $params = [
687
                                            'path' => self::DBUTF8($path_title),
688
                                            'c_id' => $this->destination_course_id,
689
                                            'comment'=> self::DBUTF8($document->comment),
690
                                            'title' => self::DBUTF8(basename($path_title)),
691
                                            'filetype' => self::DBUTF8($document->file_type),
692
                                            'size' => self::DBUTF8($document->size),
693
                                            'session_id' => $my_session_id,
694
                                        ];
695
696
										$document_id = Database::insert($table, $params);
697
698
                                        if ($document_id) {
699
                                            $sql = "UPDATE $table SET id = iid WHERE iid = $document_id";
700
                                            Database::query($sql);
701
                                        }
702
703
                                        $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id;
704
705
                                        $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
706
                                        $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
707
                                        $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
708
                                        $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
709
710
                                        $insertUserId = $this->checkUserId($insertUserId);
711
                                        $toUserId = $this->checkUserId($toUserId, true);
712
713
                                        api_item_property_update(
714
                                            $course_info,
715
                                            TOOL_DOCUMENT,
716
                                            $document_id,
717
                                            'DocumentAdded',
718
                                            $insertUserId,
719
                                            $toGroupId,
720
                                            $toUserId,
721
                                            null,
722
                                            null,
723
                                            $my_session_id
724
                                        );
725
									} else {
726
									    if (file_exists($path.$document->path)) {
727
                                            copy($path.$document->path, $path.$new_file_name);
728
									    }
729
                                        //Replace old course code with the new destination code see BT#1985
730 View Code Duplication
                                        if (file_exists($path.$new_file_name)) {
731
                                            $file_info = pathinfo($path.$new_file_name);
732
                                            if (in_array($file_info['extension'], array('html','htm'))) {
733
                                                $content    = file_get_contents($path.$new_file_name);
734
                                                if (UTF8_CONVERT) {
735
                                                    $content = utf8_encode($content);
736
                                                }
737
                                                $content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
738
                                                    $content,
739
                                                    $this->course->code,
740
                                                    $this->course->destination_path,
741
                                                    $this->course->backup_path,
742
                                                    $this->course->info['path']
743
                                                );
744
                                                file_put_contents($path.$new_file_name, $content);
745
                                            }
746
                                        }
747
748
                                        $params = [
749
                                            'path' => "/".self::DBUTF8escapestring(substr($new_file_name, 9)),
750
                                            'c_id' => $this->destination_course_id,
751
                                            'comment'=> self::DBUTF8($document->comment),
752
                                            'title' => self::DBUTF8($document->title),
753
                                            'filetype' => self::DBUTF8($document->file_type),
754
                                            'size' => self::DBUTF8($document->size),
755
                                            'session_id' => $my_session_id,
756
                                        ];
757
758
                                        $document_id = Database::insert($table, $params);
759
760
                                        if ($document_id) {
761
                                            $sql = "UPDATE $table SET id = iid WHERE iid = $document_id";
762
                                            Database::query($sql);
763
764
                                            $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id;
765
766
                                            $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
767
                                            $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
768
                                            $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
769
                                            $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
770
771
                                            $insertUserId = $this->checkUserId($insertUserId);
772
                                            $toUserId = $this->checkUserId($toUserId, true);
773
774
                                            api_item_property_update(
775
                                                $course_info,
776
                                                TOOL_DOCUMENT,
777
                                                $document_id,
778
                                                'DocumentAdded',
779
                                                $insertUserId,
780
                                                $toGroupId,
781
                                                $toUserId,
782
                                                null,
783
                                                null,
784
                                                $my_session_id
785
                                            );
786
                                        }
787
									}
788
								} else {
789
790
									copy($this->course->backup_path.'/'.$document->path, $path.$new_file_name);
791
792
                                    //Replace old course code with the new destination code see BT#1985
793 View Code Duplication
                                    if (file_exists($path.$new_file_name)) {
794
                                        $file_info = pathinfo($path.$new_file_name);
795
                                        if (in_array($file_info['extension'], array('html','htm'))) {
796
                                            $content    = file_get_contents($path.$new_file_name);
797
                                            if (UTF8_CONVERT) {
798
                                                $content = utf8_encode($content);
799
                                            }
800
                                            $content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
801
                                                $content,
802
                                                $this->course->code,
803
                                                $this->course->destination_path,
804
                                                $this->course->backup_path,
805
                                                $this->course->info['path']
806
                                            );
807
                                            file_put_contents($path.$new_file_name, $content);
808
                                        }
809
                                    }
810
811
                                    $params = [
812
                                        'c_id' => $this->destination_course_id,
813
                                        'path' => "/".self::DBUTF8escapestring(substr($new_file_name, 9)),
814
                                        'comment'=> self::DBUTF8($document->comment),
815
                                        'title' => self::DBUTF8($document->title),
816
                                        'filetype' => self::DBUTF8($document->file_type),
817
                                        'size' => self::DBUTF8($document->size),
818
                                        'session_id' => $my_session_id,
819
                                    ];
820
821
                                    $document_id = Database::insert($table, $params);
822
823
                                    if ($document_id) {
824
                                        $sql = "UPDATE $table SET id = iid WHERE iid = $document_id";
825
                                        Database::query($sql);
826
                                    }
827
828
                                    $this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id;
829
830
                                    $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
831
                                    $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
832
                                    $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
833
                                    $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
834
835
                                    $insertUserId = $this->checkUserId($insertUserId);
836
                                    $toUserId = $this->checkUserId($toUserId, true);
837
838
                                    api_item_property_update(
839
                                        $course_info,
840
                                        TOOL_DOCUMENT,
841
                                        $document_id,
842
                                        'DocumentAdded',
843
                                        $insertUserId,
844
                                        $toGroupId,
845
                                        $toUserId,
846
                                        null,
847
                                        null,
848
                                        $my_session_id
849
                                    );
850
								}
851
								break;
852
853
						} // end switch
854
					} else {
855
					    // end if file exists
856
						//make sure the source file actually exists
857
						if (is_file($this->course->backup_path.'/'.$document->path) &&
858
                            is_readable($this->course->backup_path.'/'.$document->path) &&
859
                            is_dir(dirname($path.$document->path)) &&
860
                            is_writeable(dirname($path.$document->path))
861
                        ) {
862
						    //echo 'Copying';
863
							copy($this->course->backup_path.'/'.$document->path, $path.$document->path);
864
865
                            //Replace old course code with the new destination code see BT#1985
866
                            if (file_exists($path.$document->path)) {
867
                                $file_info = pathinfo($path.$document->path);
868
                                if (in_array($file_info['extension'], array('html','htm'))) {
869
                                    $content    = file_get_contents($path.$document->path);
870
                                    if (UTF8_CONVERT) {
871
                                        $content = utf8_encode($content);
872
                                    }
873
                                    $content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
874
                                        $content,
875
                                        $this->course->code,
876
                                        $this->course->destination_path,
877
                                        $this->course->backup_path,
878
                                        $this->course->info['path']
879
                                    );
880
                                    file_put_contents($path.$document->path, $content);
881
                                }
882
                            }
883
884
                            $params = [
885
                                'c_id' => $this->destination_course_id,
886
                                'path' => "/".self::DBUTF8(substr($document->path, 9)),
887
                                'comment'=> self::DBUTF8($document->comment),
888
                                'title' => self::DBUTF8($document->title),
889
                                'filetype' => self::DBUTF8($document->file_type),
890
                                'size' => self::DBUTF8($document->size),
891
                                'session_id' => $my_session_id,
892
                            ];
893
894
                            $document_id = Database::insert($table, $params);
895
896
                            if ($document_id) {
897
                                $sql = "UPDATE $table SET id = iid WHERE iid = $document_id";
898
                                Database::query($sql);
899
                            }
900
901
							$this->course->resources[RESOURCE_DOCUMENT][$id]->destination_id = $document_id;
902
903
                            $itemProperty = isset($document->item_properties[0]) ? $document->item_properties[0] : '';
904
                            $insertUserId = isset($itemProperty['insert_user_id']) ? $itemProperty['insert_user_id'] : api_get_user_id();
905
                            $toGroupId = isset($itemProperty['to_group_id']) ? $itemProperty['to_group_id'] : 0;
906
                            $toUserId = isset($itemProperty['to_user_id']) ? $itemProperty['to_user_id'] : null;
907
908
                            $insertUserId = $this->checkUserId($insertUserId);
909
                            $toUserId = $this->checkUserId($toUserId, true);
910
911
                            api_item_property_update(
912
                                $course_info,
913
                                TOOL_DOCUMENT,
914
                                $document_id,
915
                                'DocumentAdded',
916
                                $insertUserId,
917
                                $toGroupId,
918
                                $toUserId,
919
                                null,
920
                                null,
921
                                $my_session_id
922
                            );
923
						} else {
924
							if (is_file($this->course->backup_path.'/'.$document->path) &&
925
                                is_readable($this->course->backup_path.'/'.$document->path)
926
                            ) {
927
								error_log('Course copy generated an ignoreable error while trying to copy '.$this->course->backup_path.'/'.$document->path.': file not found');
928
							}
929 View Code Duplication
							if (!is_dir(dirname($path.$document->path))) {
930
								error_log('Course copy generated an ignoreable error while trying to copy to '.dirname($path.$document->path).': directory not found');
931
							}
932 View Code Duplication
							if (!is_writeable(dirname($path.$document->path))) {
933
								error_log('Course copy generated an ignoreable error while trying to copy to '.dirname($path.$document->path).': directory not writeable');
934
							}
935
						}
936
					} // end file doesn't exist
937
				}
938
			} // end for each
939
940
    		// Delete sessions for the copy the new folder in session
941
    		unset($_SESSION['new_base_foldername']);
942
    		unset($_SESSION['orig_base_foldername']);
943
    		unset($_SESSION['new_base_path']);
944
		}
945
	}
946
947
	/**
948
	 * Restore scorm documents
949
	 * TODO @TODO check that the restore function with renaming doesn't break the scorm structure!
950
     * see #7029
951
	 */
952
	public function restore_scorm_documents()
953
    {
954
		$perm = api_get_permissions_for_new_directories();
955
956
		if ($this->course->has_resources(RESOURCE_SCORM)) {
0 ignored issues
show
Bug introduced by
The method has_resources cannot be called on $this->course (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
957
			$resources = $this->course->resources;
958
959
			foreach ($resources[RESOURCE_SCORM] as $document) {
960
				$path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/';
961
962
				@mkdir(dirname($path.$document->path), $perm, true);
963
964
				if (file_exists($path.$document->path)) {
965
					switch ($this->file_option) {
966
						case FILE_OVERWRITE:
967
							rmdirr($path.$document->path);
968
                            copyDirTo(
969
                                $this->course->backup_path . '/' . $document->path,
970
                                $path . dirname($document->path),
971
                                false
972
                            );
973
							break;
974
						case FILE_SKIP:
975
							break;
976
                        case FILE_RENAME:
977
							$i = 1;
978
							$ext = explode('.', basename($document->path));
979 View Code Duplication
							if (count($ext) > 1) {
980
								$ext = array_pop($ext);
981
								$file_name_no_ext = substr($document->path, 0, - (strlen($ext) + 1));
982
								$ext = '.'.$ext;
983
							} else {
984
								$ext = '';
985
								$file_name_no_ext = $document->path;
986
							}
987
988
							$new_file_name = $file_name_no_ext.'_'.$i.$ext;
989
							$file_exists = file_exists($path.$new_file_name);
990
991 View Code Duplication
							while ($file_exists) {
992
								$i ++;
993
								$new_file_name = $file_name_no_ext.'_'.$i.$ext;
994
								$file_exists = file_exists($path.$new_file_name);
995
							}
996
997
                            rename(
998
                                $this->course->backup_path . '/' . $document->path,
999
                                $this->course->backup_path . '/' . $new_file_name
1000
                            );
1001
                            copyDirTo(
1002
                                $this->course->backup_path . '/' . $new_file_name,
1003
                                $path . dirname($new_file_name),
1004
                                false
1005
                            );
1006
                            rename(
1007
                                $this->course->backup_path . '/' . $new_file_name,
1008
                                $this->course->backup_path . '/' . $document->path
1009
                            );
1010
1011
							break;
1012
					} // end switch
1013
				} else {
1014
                    // end if file exists
1015
                    copyDirTo(
1016
                        $this->course->backup_path . '/' . $document->path,
1017
                        $path . dirname($document->path),
1018
                        false
1019
                    );
1020
				}
1021
			} // end for each
1022
		}
1023
	}
1024
1025
	/**
1026
	 * Restore forums
1027
	 */
1028
	public function restore_forums($sessionId = 0)
1029
    {
1030
		if ($this->course->has_resources(RESOURCE_FORUM)) {
0 ignored issues
show
Bug introduced by
The method has_resources cannot be called on $this->course (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1031
            $sessionId = intval($sessionId);
1032
			$table_forum = Database::get_course_table(TABLE_FORUM);
1033
			$resources = $this->course->resources;
1034
			foreach ($resources[RESOURCE_FORUM] as $id => $forum) {
1035
                $params = (array)$forum->obj;
1036
                $cat_id = '';
1037
                if (isset($this->course->resources[RESOURCE_FORUMCATEGORY]) &&
1038
                    isset($this->course->resources[RESOURCE_FORUMCATEGORY][$params['forum_category']])) {
1039
                    if ($this->course->resources[RESOURCE_FORUMCATEGORY][$params['forum_category']]->destination_id == -1) {
1040
                        $cat_id = $this->restore_forum_category(
1041
                            $params['forum_category'],
1042
                            $sessionId
1043
                        );
1044
                    } else {
1045
                        $cat_id = $this->course->resources[RESOURCE_FORUMCATEGORY][$params['forum_category']]->destination_id;
1046
                    }
1047
                }
1048
1049
                $params = self::DBUTF8_array($params);
1050
                $params['c_id'] = $this->destination_course_id;
1051
                $params['forum_category'] = $cat_id;
1052
                $params['session_id'] = $sessionId;
1053
1054
                unset($params['forum_id']);
1055
                unset($params['iid']);
1056
1057
                $params['forum_comment'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1058
                    $params['forum_comment'],
1059
                    $this->course->code,
1060
                    $this->course->destination_path,
1061
                    $this->course->backup_path,
1062
                    $this->course->info['path']
1063
                );
1064
1065
                if (!empty($params['forum_image'])) {
1066
                    $original_forum_image = $this->course->path.'upload/forum/images/'.$params['forum_image'];
1067
                    if (file_exists($original_forum_image)) {
1068
                        $new_forum_image = api_get_path(SYS_COURSE_PATH).$this->destination_course_info['path'].'/upload/forum/images/'.$params['forum_image'];
1069
                        @copy($original_forum_image, $new_forum_image);
1070
                    }
1071
                }
1072
1073
                $new_id = Database::insert($table_forum, $params);
1074
1075
                if ($new_id) {
1076
                    $sql = "UPDATE $table_forum SET forum_id = iid WHERE iid = $new_id";
1077
                    Database::query($sql);
1078
                }
1079
1080
				$this->course->resources[RESOURCE_FORUM][$id]->destination_id = $new_id;
1081
1082
				$forum_topics = 0;
1083
				if (is_array($this->course->resources[RESOURCE_FORUMTOPIC])) {
1084
					foreach ($this->course->resources[RESOURCE_FORUMTOPIC] as $topic_id => $topic) {
1085
						if ($topic->obj->forum_id == $id) {
1086
							$this->restore_topic($topic_id, $new_id, $sessionId);
1087
							$forum_topics ++;
1088
						}
1089
					}
1090
				}
1091
				if ($forum_topics > 0) {
1092
					$sql = "UPDATE ".$table_forum." SET forum_threads = ".$forum_topics."
1093
                            WHERE c_id = {$this->destination_course_id} AND forum_id = ".(int)$new_id;
1094
					Database::query($sql);
1095
				}
1096
			}
1097
		}
1098
	}
1099
1100
	/**
1101
	 * Restore forum-categories
1102
	 */
1103
    public function restore_forum_category($my_id = null, $sessionId = 0)
1104
    {
1105
		$forum_cat_table = Database :: get_course_table(TABLE_FORUM_CATEGORY);
1106
		$resources = $this->course->resources;
1107
        if (!empty($resources[RESOURCE_FORUMCATEGORY])) {
1108
            foreach ($resources[RESOURCE_FORUMCATEGORY] as $id => $forum_cat) {
1109
                if (!empty($my_id)) {
1110
                    if ($my_id != $id) {
1111
                        continue;
1112
                    }
1113
                }
1114
                if ($forum_cat && !$forum_cat->is_restored()) {
1115
                    /*$title = $forum_cat->obj->cat_title;
1116
                    if (!empty($title)) {
1117
                        if (!preg_match('/.*\((.+)\)$/', $title, $matches)) {
1118
                            // This is for avoiding repetitive adding of training code after several backup/restore cycles.
1119
                            if ($matches[1] != $this->course->code) {
1120
                                $title = $title.' ('.$this->course->code.')';
1121
                            }
1122
                        }
1123
                    }*/
1124
                    $params = (array) $forum_cat->obj;
1125
                    $params['c_id'] = $this->destination_course_id;
1126
                    $params['cat_comment'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1127
                        $params['cat_comment'],
1128
                        $this->course->code,
1129
                        $this->course->destination_path,
1130
                        $this->course->backup_path,
1131
                        $this->course->info['path']
1132
                    );
1133
                    $params['session_id'] = intval($sessionId);
1134
1135
                    unset($params['cat_id']);
1136
                    unset($params['iid']);
1137
1138
                    $params = self::DBUTF8_array($params);
1139
                    $new_id = Database::insert($forum_cat_table, $params);
1140
1141
                    if ($new_id) {
1142
                        $sql = "UPDATE $forum_cat_table SET cat_id = iid WHERE iid = $new_id";
1143
                        Database::query($sql);
1144
                    }
1145
1146
                    $this->course->resources[RESOURCE_FORUMCATEGORY][$id]->destination_id = $new_id;
1147
                    if (!empty($my_id)) {
1148
                        return $new_id;
1149
                    }
1150
                }
1151
            }
1152
        }
1153
	}
1154
1155
	/**
1156
	 * Restore a forum-topic
1157
	 */
1158
    public function restore_topic($thread_id, $forum_id, $sessionId = 0)
1159
    {
1160
		$table = Database :: get_course_table(TABLE_FORUM_THREAD);
1161
		$topic = $this->course->resources[RESOURCE_FORUMTOPIC][$thread_id];
1162
1163
        $params = (array)$topic->obj;
1164
        $params = self::DBUTF8_array($params);
1165
        $params['c_id'] = $this->destination_course_id;
1166
        $params['forum_id'] = $forum_id;
1167
        $params['thread_poster_id'] = $this->first_teacher_id;
1168
        $params['thread_date'] = api_get_utc_datetime();
1169
        $params['thread_close_date']  = '0000-00-00 00:00:00';
1170
        $params['thread_last_post'] = 0;
1171
        $params['thread_replies'] = 0;
1172
        $params['thread_views'] = 0;
1173
        $params['session_id'] = intval($sessionId);
1174
        unset($params['thread_id']);
1175
        unset($params['iid']);
1176
1177
        $new_id = Database::insert($table, $params);
1178
1179
        if ($new_id) {
1180
            $sql = "UPDATE $table SET thread_id = iid WHERE iid = $new_id";
1181
            Database::query($sql);
1182
        }
1183
1184
        api_item_property_update(
1185
            $this->destination_course_info,
1186
            TOOL_FORUM_THREAD,
1187
            $new_id,
1188
            'ThreadAdded',
1189
            api_get_user_id(),
1190
            0,
1191
            0,
1192
            null,
1193
            null,
1194
            $sessionId
1195
        );
1196
1197
		$this->course->resources[RESOURCE_FORUMTOPIC][$thread_id]->destination_id = $new_id;
1198
1199
		$topic_replies = -1;
1200
1201
		foreach ($this->course->resources[RESOURCE_FORUMPOST] as $post_id => $post) {
1202
			if ($post->obj->thread_id == $thread_id) {
1203
				$topic_replies++;
1204
				$this->restore_post($post_id, $new_id, $forum_id, $sessionId);
1205
			}
1206
		}
1207
		return $new_id;
1208
	}
1209
1210
	/**
1211
	 * Restore a forum-post
1212
	 * @TODO Restore tree-structure of posts. For example: attachments to posts.
1213
	 */
1214
    public function restore_post($id, $topic_id, $forum_id, $sessionId = 0)
1215
    {
1216
		$table_post = Database :: get_course_table(TABLE_FORUM_POST);
1217
		$post = $this->course->resources[RESOURCE_FORUMPOST][$id];
1218
        $params = (array) $post->obj;
1219
        $params['c_id'] = $this->destination_course_id;
1220
        $params['forum_id'] = $forum_id;
1221
        $params['thread_id'] = $topic_id;
1222
        $params['poster_id'] = $this->first_teacher_id;
1223
        $params['post_date'] = api_get_utc_datetime();
1224
        unset($params['post_id']);
1225
        unset($params['iid']);
1226
        $params['post_text'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1227
            $params['post_text'],
1228
            $this->course->code,
1229
            $this->course->destination_path,
1230
            $this->course->backup_path,
1231
            $this->course->info['path']
1232
        );
1233
        $new_id = Database::insert($table_post, $params);
1234
1235
        if ($new_id) {
1236
            $sql = "UPDATE $table_post SET post_id = iid WHERE iid = $new_id";
1237
            Database::query($sql);
1238
        }
1239
1240
        api_item_property_update(
1241
            $this->destination_course_info,
1242
            TOOL_FORUM_POST,
1243
            $new_id,
1244
            'PostAdded',
1245
            api_get_user_id(),
1246
            0,
1247
            0,
1248
            null,
1249
            null,
1250
            $sessionId
1251
        );
1252
		$this->course->resources[RESOURCE_FORUMPOST][$id]->destination_id = $new_id;
1253
1254
		return $new_id;
1255
	}
1256
1257
	/**
1258
	 * Restore links
1259
	 */
1260
    public function restore_links($session_id = 0)
1261
    {
1262
		if ($this->course->has_resources(RESOURCE_LINK)) {
0 ignored issues
show
Bug introduced by
The method has_resources cannot be called on $this->course (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1263
			$link_table = Database :: get_course_table(TABLE_LINK);
1264
			$resources = $this->course->resources;
1265
1266
			foreach ($resources[RESOURCE_LINK] as $id => $link) {
1267
                $cat_id = $this->restore_link_category(
1268
                    $link->category_id,
1269
                    $session_id
1270
                );
1271
				$sql = "SELECT MAX(display_order)
1272
				        FROM $link_table
1273
				        WHERE
1274
				            c_id = ".$this->destination_course_id." AND
1275
				            category_id='" . intval($cat_id). "'";
1276
				$result = Database::query($sql);
1277
    			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...
1278
1279
                $params = [];
1280
    			if (!empty($session_id)) {
1281
                    $params['session_id'] = $session_id;
1282
    			}
1283
1284
                $params['c_id'] = $this->destination_course_id;
1285
                $params['url'] = self::DBUTF8($link->url);
1286
                $params['title'] = self::DBUTF8($link->title);
1287
                $params['description'] = self::DBUTF8($link->description);
1288
                $params['category_id'] = $cat_id;
1289
                $params['on_homepage'] = $link->on_homepage;
1290
                $params['display_order'] = $max_order+1;
1291
1292
                $id = Database::insert($link_table, $params);
1293
1294 View Code Duplication
                if ($id) {
1295
                    $sql = "UPDATE $link_table SET id = iid WHERE iid = $id";
1296
                    Database::query($sql);
1297
1298
                    api_item_property_update(
1299
                        $this->destination_course_info,
1300
                        TOOL_LINK,
1301
                        $id,
1302
                        'LinkAdded',
1303
                        api_get_user_id()
1304
                    );
1305
1306
                    if (!isset($this->course->resources[RESOURCE_LINK][$id])) {
1307
                        $this->course->resources[RESOURCE_LINK][$id] = new stdClass();
1308
                    }
1309
                    $this->course->resources[RESOURCE_LINK][$id]->destination_id = $id;
1310
                }
1311
			}
1312
		}
1313
	}
1314
1315
    /**
1316
     * Restore a link-category
1317
     */
1318
    public function restore_link_category($id, $session_id = 0)
1319
    {
1320
        $params = [];
1321
        if (!empty($session_id)) {
1322
            $params['session_id'] = $session_id;
1323
        }
1324
1325
        if ($id == 0) {
1326
            return 0;
1327
        }
1328
        $link_cat_table = Database :: get_course_table(TABLE_LINK_CATEGORY);
1329
        $resources = $this->course->resources;
1330
        $link_cat = $resources[RESOURCE_LINKCATEGORY][$id];
1331
        if (is_object($link_cat) && !$link_cat->is_restored()) {
1332
            $sql = "SELECT MAX(display_order) FROM  $link_cat_table
1333
			        WHERE c_id = ".$this->destination_course_id." ";
1334
            $result=Database::query($sql);
1335
            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...
1336
            $display_order=$orderMax+1;
1337
1338
            $params['c_id'] = $this->destination_course_id;
1339
            $params['category_title'] = self::DBUTF8($link_cat->title);
1340
            $params['description'] = self::DBUTF8($link_cat->description);
1341
            $params['display_order'] = $display_order;
1342
1343
            $new_id = Database::insert($link_cat_table, $params);
1344
1345
            if ($new_id) {
1346
                $sql = "UPDATE $link_cat_table SET id = iid WHERE iid = $new_id";
1347
                Database::query($sql);
1348
                api_set_default_visibility($new_id, TOOL_LINK_CATEGORY);
1349
            }
1350
1351
            $this->course->resources[RESOURCE_LINKCATEGORY][$id]->destination_id = $new_id;
1352
            return $new_id;
1353
        }
1354
        return $this->course->resources[RESOURCE_LINKCATEGORY][$id]->destination_id;
1355
    }
1356
1357
	/**
1358
	 * Restore tool intro
1359
	 */
1360
    public function restore_tool_intro($sessionId = 0)
1361
    {
1362
		if ($this->course->has_resources(RESOURCE_TOOL_INTRO)) {
0 ignored issues
show
Bug introduced by
The method has_resources cannot be called on $this->course (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1363
            $sessionId = intval($sessionId);
1364
			$tool_intro_table = Database :: get_course_table(TABLE_TOOL_INTRO);
1365
			$resources = $this->course->resources;
1366
			foreach ($resources[RESOURCE_TOOL_INTRO] as $id => $tool_intro) {
1367
				$sql = "DELETE FROM ".$tool_intro_table."
1368
				        WHERE
1369
				            c_id = ".$this->destination_course_id." AND
1370
				            id='".self::DBUTF8escapestring($tool_intro->id)."'";
1371
				Database::query($sql);
1372
1373
                $tool_intro->intro_text = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1374
                    $tool_intro->intro_text,
1375
                    $this->course->code,
1376
                    $this->course->destination_path,
1377
                    $this->course->backup_path,
1378
                    $this->course->info['path']
1379
                );
1380
1381
                $params = [
1382
                    'c_id' => $this->destination_course_id,
1383
                    'id' => self::DBUTF8($tool_intro->id),
1384
                    '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...
1385
                    'session_id' => $sessionId,
1386
                ];
1387
1388
                $id = Database::insert($tool_intro_table, $params);
1389
                if ($id) {
1390
                    $sql = "UPDATE $tool_intro_table SET id = iid WHERE iid = $id";
1391
                    Database::query($sql);
1392
1393
                    if (!isset($this->course->resources[RESOURCE_TOOL_INTRO][$id])) {
1394
                        $this->course->resources[RESOURCE_TOOL_INTRO][$id] = new stdClass();
1395
                    }
1396
1397
                    $this->course->resources[RESOURCE_TOOL_INTRO][$id]->destination_id = $id;
1398
                }
1399
			}
1400
		}
1401
	}
1402
1403
	/**
1404
	 * Restore events
1405
	 */
1406 View Code Duplication
    public function restore_events($sessionId = 0)
1407
    {
1408
		if ($this->course->has_resources(RESOURCE_EVENT)) {
0 ignored issues
show
Bug introduced by
The method has_resources cannot be called on $this->course (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1409
            $sessionId = intval($sessionId);
1410
			$table = Database :: get_course_table(TABLE_AGENDA);
1411
			$resources = $this->course->resources;
1412
			foreach ($resources[RESOURCE_EVENT] as $id => $event) {
1413
				// check resources inside html from ckeditor tool and copy correct urls into recipient course
1414
                $event->content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1415
                    $event->content,
1416
                    $this->course->code,
1417
                    $this->course->destination_path,
1418
                    $this->course->backup_path,
1419
                    $this->course->info['path']
1420
                );
1421
1422
                $params = [
1423
                    'c_id' => $this->destination_course_id,
1424
                    'title' => self::DBUTF8($event->title),
1425
                    '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...
1426
                    'all_day' => $event->all_day,
1427
                    'start_date' => $event->start_date,
1428
                    'end_date' => $event->end_date,
1429
                    'session_id' => $sessionId,
1430
                ];
1431
				$new_event_id = Database::insert($table, $params);
1432
1433
                if ($new_event_id) {
1434
                    $sql = "UPDATE $table SET id = iid WHERE iid = $new_event_id";
1435
                    Database::query($sql);
1436
1437
                    if (!isset($this->course->resources[RESOURCE_EVENT][$id])) {
1438
                        $this->course->resources[RESOURCE_EVENT][$id] = new stdClass();
1439
                    }
1440
1441
                    $this->course->resources[RESOURCE_EVENT][$id]->destination_id = $new_event_id;
1442
                }
1443
1444
				// Copy event attachment
1445
1446
				$origin_path = $this->course->backup_path.'/upload/calendar/';
1447
				$destination_path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/upload/calendar/';
1448
1449
				if (!empty($this->course->orig)) {
1450
1451
					$table_attachment = Database :: get_course_table(TABLE_AGENDA_ATTACHMENT);
1452
					$sql = 'SELECT path, comment, size, filename
1453
					        FROM '.$table_attachment.'
1454
					        WHERE c_id = '.$this->destination_course_id.' AND agenda_id = '.$id;
1455
					$attachment_event = Database::query($sql);
1456
					$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...
1457
1458
					if (file_exists($origin_path.$attachment_event->path) &&
1459
                        !is_dir($origin_path.$attachment_event->path)
1460
                    ) {
1461
						$new_filename = uniqid(''); //ass seen in the add_agenda_attachment_file() function in agenda.inc.php
1462
						$copy_result = copy($origin_path.$attachment_event->path, $destination_path.$new_filename);
1463
						//$copy_result = true;
1464
						if ($copy_result) {
1465
							$table_attachment = Database :: get_course_table(TABLE_AGENDA_ATTACHMENT);
1466
1467
							$params = [
1468
                                'c_id' => $this->destination_course_id,
1469
                                'path' => self::DBUTF8($new_filename),
1470
                                'comment' => self::DBUTF8($attachment_event->comment),
1471
                                'size' => $attachment_event->size,
1472
                                'filename' => $attachment_event->filename,
1473
                                'agenda_id' => $new_event_id,
1474
                            ];
1475
                            $id = Database::insert($table_attachment, $params);
1476
                            if ($id) {
1477
                                $sql = "UPDATE $table_attachment SET id = iid WHERE iid = $id";
1478
                                Database::query($sql);
1479
                            }
1480
                        }
1481
					}
1482
				} else {
1483
					// get the info of the file
1484
					if (!empty($event->attachment_path) &&
1485
                        is_file($origin_path.$event->attachment_path) &&
1486
                        is_readable($origin_path.$event->attachment_path)
1487
                    ) {
1488
						$new_filename = uniqid(''); //ass seen in the add_agenda_attachment_file() function in agenda.inc.php
1489
						$copy_result = copy($origin_path.$event->attachment_path, $destination_path.$new_filename);
1490
						if ($copy_result) {
1491
							$table_attachment = Database :: get_course_table(TABLE_AGENDA_ATTACHMENT);
1492
1493
                            $params = [
1494
                                'c_id' => $this->destination_course_id,
1495
                                'path' => self::DBUTF8($new_filename),
1496
                                'comment' => self::DBUTF8($event->attachment_comment),
1497
                                'size' => $event->size,
1498
                                'filename' => $event->filename,
1499
                                'agenda_id' => $new_event_id,
1500
                            ];
1501
                            $id = Database::insert($table_attachment, $params);
1502
1503
                            if ($id) {
1504
                                $sql = "UPDATE $table_attachment SET id = iid WHERE iid = $id";
1505
                                Database::query($sql);
1506
                            }
1507
						}
1508
					}
1509
				}
1510
			}
1511
		}
1512
	}
1513
1514
	/**
1515
	 * Restore course-description
1516
	 */
1517
    public function restore_course_descriptions($session_id = 0)
1518
    {
1519
		if ($this->course->has_resources(RESOURCE_COURSEDESCRIPTION)) {
0 ignored issues
show
Bug introduced by
The method has_resources cannot be called on $this->course (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1520
			$table = Database :: get_course_table(TABLE_COURSE_DESCRIPTION);
1521
			$resources = $this->course->resources;
1522
			foreach ($resources[RESOURCE_COURSEDESCRIPTION] as $id => $cd) {
1523
                $courseDescription = (array) $cd;
1524
1525
                $content = isset($courseDescription['content']) ? $courseDescription['content'] : '';
1526
                $descriptionType = isset($courseDescription['description_type']) ? $courseDescription['description_type'] : '';
1527
                $title = isset($courseDescription['title']) ? $courseDescription['title'] : '';
1528
1529
				// check resources inside html from ckeditor tool and copy correct urls into recipient course
1530
                $description_content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1531
                    $content,
1532
                    $this->course->code,
1533
                    $this->course->destination_path,
1534
                    $this->course->backup_path,
1535
                    $this->course->info['path']
1536
                );
1537
1538
                $params = [];
1539
				if (!empty($session_id)) {
1540
					$session_id = intval($session_id);
1541
                    $params['session_id'] = $session_id;
1542
				}
1543
                $params['c_id'] = $this->destination_course_id;
1544
                $params['description_type'] = self::DBUTF8($descriptionType);
1545
                $params['title'] = self::DBUTF8($title);
1546
                $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 1530 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...
1547
1548
                $id = Database::insert($table, $params);
1549
                if ($id) {
1550
                    $sql = "UPDATE $table SET id = iid WHERE iid = $id";
1551
                    Database::query($sql);
1552
1553
                    if (!isset($this->course->resources[RESOURCE_COURSEDESCRIPTION][$id])) {
1554
                        $this->course->resources[RESOURCE_COURSEDESCRIPTION][$id] = new stdClass();
1555
                    }
1556
                    $this->course->resources[RESOURCE_COURSEDESCRIPTION][$id]->destination_id = $id;
1557
                }
1558
			}
1559
		}
1560
	}
1561
1562
	/**
1563
	 * Restore announcements
1564
	 */
1565 View Code Duplication
    public function restore_announcements($sessionId = 0)
1566
    {
1567
		if ($this->course->has_resources(RESOURCE_ANNOUNCEMENT)) {
0 ignored issues
show
Bug introduced by
The method has_resources cannot be called on $this->course (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1568
            $sessionId = intval($sessionId);
1569
			$table = Database :: get_course_table(TABLE_ANNOUNCEMENT);
1570
			$resources = $this->course->resources;
1571
			foreach ($resources[RESOURCE_ANNOUNCEMENT] as $id => $announcement) {
1572
1573
				// check resources inside html from ckeditor tool and copy correct urls into recipient course
1574
                $announcement->content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1575
                    $announcement->content,
1576
                    $this->course->code,
1577
                    $this->course->destination_path,
1578
                    $this->course->backup_path,
1579
                    $this->course->info['path']
1580
                );
1581
1582
                $params = [
1583
                    'c_id' => $this->destination_course_id,
1584
                    'title' =>  self::DBUTF8($announcement->title),
1585
                    '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...
1586
                    'end_date' => $announcement->date,
1587
                    'display_order' => $announcement->display_order,
1588
                    'email_sent' => $announcement->email_sent,
1589
                    'session_id' => $sessionId,
1590
                ];
1591
1592
				$new_announcement_id = Database::insert($table, $params);
1593
1594
                if ($new_announcement_id) {
1595
                    $sql = "UPDATE $table SET id = iid WHERE iid = $new_announcement_id";
1596
                    Database::query($sql);
1597
1598
                    if (!isset($this->course->resources[RESOURCE_ANNOUNCEMENT][$id])) {
1599
                        $this->course->resources[RESOURCE_ANNOUNCEMENT][$id] = new stdClass();
1600
                    }
1601
                    $this->course->resources[RESOURCE_ANNOUNCEMENT][$id]->destination_id = $new_announcement_id;
1602
                }
1603
1604
				$origin_path = $this->course->backup_path.'/upload/announcements/';
1605
				$destination_path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/upload/announcements/';
1606
1607
				// Copy announcement attachment file
1608
				if (!empty($this->course->orig)) {
1609
1610
					$table_attachment = Database::get_course_table(TABLE_ANNOUNCEMENT_ATTACHMENT);
1611
					$sql = 'SELECT path, comment, size, filename
1612
					        FROM '.$table_attachment.'
1613
					        WHERE
1614
					            c_id = '.$this->destination_course_id.' AND
1615
					            announcement_id = '.$id;
1616
					$attachment_event = Database::query($sql);
1617
					$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...
1618
1619
					if (file_exists($origin_path.$attachment_event->path) &&
1620
                        !is_dir($origin_path.$attachment_event->path)
1621
                    ) {
1622
						$new_filename = uniqid(''); //ass seen in the add_agenda_attachment_file() function in agenda.inc.php
1623
                        $copy_result = copy(
1624
                            $origin_path.$attachment_event->path,
1625
                            $destination_path.$new_filename
1626
                        );
1627
1628
						if ($copy_result) {
1629
							$table_attachment = Database :: get_course_table(TABLE_ANNOUNCEMENT_ATTACHMENT);
1630
1631
                            $params = [
1632
                                'c_id' => $this->destination_course_id,
1633
                                'path' => self::DBUTF8($new_filename),
1634
                                'comment' => self::DBUTF8($attachment_event->comment),
1635
                                'size' => $attachment_event->size,
1636
                                'filename' => $attachment_event->filename,
1637
                                'announcement_id' => $new_announcement_id,
1638
                            ];
1639
1640
                            $attachmentId = Database::insert($table_attachment, $params);
1641
1642
                            if ($attachmentId) {
1643
                                $sql = "UPDATE $table_attachment SET id = iid WHERE iid = $attachmentId";
1644
                                Database::query($sql);
1645
                            }
1646
						}
1647
					}
1648
				} else {
1649
					// get the info of the file
1650
					if (!empty($announcement->attachment_path) &&
1651
                        is_file($origin_path.$announcement->attachment_path) &&
1652
                        is_readable($origin_path.$announcement->attachment_path)
1653
                    ) {
1654
						$new_filename = uniqid(''); //ass seen in the add_agenda_attachment_file() function in agenda.inc.php
1655
						$copy_result = copy($origin_path.$announcement->attachment_path, $destination_path.$new_filename);
1656
1657
						if ($copy_result) {
1658
							$table_attachment = Database :: get_course_table(TABLE_ANNOUNCEMENT_ATTACHMENT);
1659
							/*$sql = "INSERT INTO ".$table_attachment." SET
1660
							        c_id = ".$this->destination_course_id." ,
1661
							        path = '".self::DBUTF8escapestring($new_filename)."',
1662
							        comment = '".self::DBUTF8escapestring($announcement->attachment_comment)."',
1663
							        size = '".$announcement->attachment_size."', filename = '".$announcement->attachment_filename."',
1664
							        announcement_id = '".$new_announcement_id."' ";
1665
							Database::query($sql);*/
1666
1667
                            $params = [
1668
                                'c_id' => $this->destination_course_id,
1669
                                'path' => self::DBUTF8($new_filename),
1670
                                'comment' => self::DBUTF8($announcement->attachment_comment),
1671
                                'size' => $announcement->attachment_size,
1672
                                'filename' => $announcement->attachment_filename,
1673
                                'announcement_id' => $new_announcement_id,
1674
                            ];
1675
1676
                            $attachmentId = Database::insert($table_attachment, $params);
1677
1678
                            if ($attachmentId) {
1679
                                $sql = "UPDATE $table_attachment SET id = iid WHERE iid = $attachmentId";
1680
                                Database::query($sql);
1681
                            }
1682
						}
1683
					}
1684
				}
1685
			}
1686
		}
1687
	}
1688
1689
    /**
1690
     * Restore Quiz
1691
     * @param int $session_id
1692
     * @param bool $respect_base_content
1693
     */
1694
    public function restore_quizzes(
1695
        $session_id = 0,
1696
        $respect_base_content = false
1697
    ) {
1698
		if ($this->course->has_resources(RESOURCE_QUIZ)) {
0 ignored issues
show
Bug introduced by
The method has_resources cannot be called on $this->course (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1699
			$table_qui = Database :: get_course_table(TABLE_QUIZ_TEST);
1700
			$table_rel = Database :: get_course_table(TABLE_QUIZ_TEST_QUESTION);
1701
			$table_doc = Database :: get_course_table(TABLE_DOCUMENT);
1702
			$resources = $this->course->resources;
1703
1704
			foreach ($resources[RESOURCE_QUIZ] as $id => $quiz) {
1705
1706
                if (isset($quiz->obj)) {
1707
                    //For new imports
1708
                    $quiz = $quiz->obj;
1709
                } else {
1710
                    //For backward compatibility
1711
                    $quiz->obj = $quiz;
1712
                }
1713
1714
				$doc = '';
1715
                if (!empty($quiz->sound)) {
1716
                    if (isset($this->course->resources[RESOURCE_DOCUMENT][$quiz->sound]) &&
1717
                        $this->course->resources[RESOURCE_DOCUMENT][$quiz->sound]->is_restored()) {
1718
                        $sql = "SELECT path FROM " . $table_doc . "
1719
                                WHERE
1720
                                    c_id = " . $this->destination_course_id . "  AND
1721
                                    id = " . $resources[RESOURCE_DOCUMENT][$quiz->sound]->destination_id;
1722
						$doc = Database::query($sql);
1723
						$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...
1724
						$doc = str_replace('/audio/', '', $doc->path);
1725
					}
1726
				}
1727
1728
				if ($id != -1) {
1729
					// check resources inside html from ckeditor tool and copy correct urls into recipient course
1730
                    $quiz->description = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1731
                        $quiz->description,
1732
                        $this->course->code,
1733
                        $this->course->destination_path,
1734
                        $this->course->backup_path,
1735
                        $this->course->info['path']
1736
                    );
1737
1738
					global $_custom;
1739
					if (isset($_custom['exercises_clean_dates_when_restoring']) &&
1740
                        $_custom['exercises_clean_dates_when_restoring']
1741
                    ) {
1742
						$quiz->start_time = null;
1743
						$quiz->end_time   = null;
1744
					}
1745
1746
                    $params = array(
1747
                        'c_id' => $this->destination_course_id,
1748
                        'title' => self::DBUTF8($quiz->title),
1749
                        '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...
1750
                        'type' => isset($quiz->quiz_type) ? $quiz->quiz_type : $quiz->type,
1751
                        'random' => $quiz->random,
1752
                        'active' => $quiz->active,
1753
                        'sound' => self::DBUTF8($doc),
1754
                        'max_attempt' => (int)$quiz->max_attempt,
1755
                        'results_disabled' => (int)$quiz->results_disabled,
1756
                        'access_condition' => $quiz->access_condition,
1757
                        'start_time' => $quiz->start_time,
1758
                        'pass_percentage' => $quiz->pass_percentage,
1759
                        'end_time' => $quiz->end_time,
1760
                        'feedback_type' => (int)$quiz->feedback_type,
1761
                        'random_answers' => (int)$quiz->random_answers,
1762
                        'random_by_category' => $quiz->random_by_category,
1763
                        'review_answers' => $quiz->review_answers,
1764
                        'propagate_neg' => $quiz->propagate_neg,
1765
                        'text_when_finished' => $quiz->text_when_finished,
1766
                        'expired_time' => (int)$quiz->expired_time,
1767
                    );
1768
1769 View Code Duplication
                    if ($respect_base_content) {
1770
                        $my_session_id = $quiz->session_id;
1771
                        if (!empty($quiz->session_id)) {
1772
                            $my_session_id = $session_id;
1773
                        }
1774
                        $params['session_id'] = $my_session_id;
1775
                    } else {
1776
        				if (!empty($session_id)) {
1777
        					$session_id = intval($session_id);
1778
                            $params['session_id'] = $session_id;
1779
    				    }
1780
                    }
1781
                    $new_id = Database::insert($table_qui, $params);
1782
1783
                    if ($new_id) {
1784
                        $sql = "UPDATE $table_qui SET id = iid WHERE iid = $new_id";
1785
                        Database::query($sql);
1786
                    }
1787
1788
				} else {
1789
					// $id = -1 identifies the fictionary test for collecting
1790
					// orphan questions. We do not store it in the database.
1791
					$new_id = -1;
1792
				}
1793
1794
				$this->course->resources[RESOURCE_QUIZ][$id]->destination_id = $new_id;
1795
1796
				$order = 0;
1797
                if (!empty($quiz->question_ids)) {
1798
                    foreach ($quiz->question_ids as $index => $question_id) {
1799
                        $qid = $this->restore_quiz_question($question_id);
1800
                        $question_order = $quiz->question_orders[$index] ? $quiz->question_orders[$index] : ++$order;
1801
                        $sql = "INSERT IGNORE INTO $table_rel SET
1802
                                c_id = " . $this->destination_course_id . ",
1803
                                question_id = " . $qid . ",
1804
                                exercice_id = " . $new_id . ",
1805
                                question_order = " . $question_order;
1806
                        Database::query($sql);
1807
                    }
1808
                }
1809
			}
1810
		}
1811
	}
1812
1813
	/**
1814
	 * Restore quiz-questions
1815
     * @params int question id
1816
	 */
1817
    public function restore_quiz_question($id)
1818
    {
1819
		$resources = $this->course->resources;
1820
        $question = isset($resources[RESOURCE_QUIZQUESTION][$id]) ? $resources[RESOURCE_QUIZQUESTION][$id] : null;
1821
1822
		$new_id = 0;
1823
1824
		if (is_object($question)) {
1825
			if ($question->is_restored()) {
1826
				return $question->destination_id;
1827
			}
1828
			$table_que = Database::get_course_table(TABLE_QUIZ_QUESTION);
1829
			$table_ans = Database::get_course_table(TABLE_QUIZ_ANSWER);
1830
            $table_options = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION);
1831
1832
			// check resources inside html from ckeditor tool and copy correct urls into recipient course
1833
            $question->description = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1834
                $question->description,
1835
                $this->course->code,
1836
                $this->course->destination_path,
1837
                $this->course->backup_path,
1838
                $this->course->info['path']
1839
            );
1840
1841
            $params = [
1842
                'c_id' => $this->destination_course_id,
1843
                'question' => self::DBUTF8($question->question),
1844
                '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...
1845
                'ponderation' => self::DBUTF8($question->ponderation),
1846
                'position' => self::DBUTF8($question->position),
1847
                'type' => self::DBUTF8($question->quiz_type),
1848
                'picture' => self::DBUTF8($question->picture),
1849
                'level' => self::DBUTF8($question->level),
1850
                'extra' => self::DBUTF8($question->extra),
1851
            ];
1852
1853
			$new_id = Database::insert($table_que, $params);
1854
1855
            if ($new_id) {
1856
1857
                $sql = "UPDATE $table_que SET id = iid WHERE iid = $new_id";
1858
                Database::query($sql);
1859
1860
                if (!empty($question->picture)) {
1861
                    $question_temp = Question::read(
1862
                        $new_id,
1863
                        $this->destination_course_info['real_id']
1864
                    );
1865
1866
                    $documentPath = api_get_path(SYS_COURSE_PATH).$this->destination_course_info['path'].'/document';
1867
                    // picture path
1868
                    $picturePath = $documentPath.'/images';
1869
1870
                    $old_picture = api_get_path(SYS_COURSE_PATH).$this->course->info['path'].'/document/images/'.$question->picture;
1871
                    if (file_exists($old_picture)) {
1872
                        $picture_name = 'quiz-'.$new_id.'.jpg';
1873
1874
                        $result = $question_temp->uploadPicture($old_picture, $picture_name, $picturePath);
1875
                        if ($result) {
1876
                            $sql = "UPDATE $table_que SET
1877
                                        picture = '$picture_name'
1878
                                    WHERE
1879
                                        c_id = " . $this->destination_course_id . " AND
1880
                                        id = $new_id ";
1881
                            Database::query($sql);
1882
                        }
1883
                    }
1884
                }
1885
            }
1886
            if (in_array($question->quiz_type, [MATCHING, MATCHING_DRAGGABLE])) {
1887
                $temp = array();
1888
                foreach ($question->answers as $index => $answer) {
1889
                    $temp[$answer['position']] = $answer;
1890
                }
1891
1892
                foreach ($temp as $index => $answer) {
1893
                    //id = '".$index."',
1894
					$params = [
1895
                        'c_id' => $this->destination_course_id,
1896
                        'question_id' => $new_id,
1897
                        'answer' => self::DBUTF8($answer['answer']),
1898
                        'correct' => $answer['correct'],
1899
                        'comment' => self::DBUTF8($answer['comment']),
1900
                        'ponderation' => $answer['ponderation'],
1901
                        'position' => $answer['position'],
1902
                        'hotspot_coordinates' => $answer['hotspot_coordinates'],
1903
                        'hotspot_type' => $answer['hotspot_type'],
1904
                    ];
1905
                    $answerId = Database::insert($table_ans, $params);
1906
1907
                    if ($answerId) {
1908
                        $sql = "UPDATE $table_ans SET id = iid, id_auto = iid WHERE iid = $answerId";
1909
                        Database::query($sql);
1910
                    }
1911
				}
1912
			} else {
1913
                $correct_answers = array();
1914
				foreach ($question->answers as $index => $answer) {
1915
1916
					// check resources inside html from ckeditor tool and copy correct urls into recipient course
1917
                    $answer['answer'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1918
                        $answer['answer'],
1919
                        $this->course->code,
1920
                        $this->course->destination_path,
1921
                        $this->course->backup_path,
1922
                        $this->course->info['path']
1923
                    );
1924
1925
                    $answer['comment'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1926
                        $answer['comment'],
1927
                        $this->course->code,
1928
                        $this->course->destination_path,
1929
                        $this->course->backup_path,
1930
                        $this->course->info['path']
1931
                    );
1932
1933
                    //                     id = '". ($index + 1)."',
1934
1935
                    $params = [
1936
                        'c_id' => $this->destination_course_id,
1937
                        'question_id' => $new_id,
1938
                        'answer' => self::DBUTF8($answer['answer']),
1939
                        'correct' => $answer['correct'],
1940
                        '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...
1941
                        'ponderation' => $answer['ponderation'],
1942
                        'position' => $answer['position'],
1943
                        'hotspot_coordinates' => $answer['hotspot_coordinates'],
1944
                        'hotspot_type' => $answer['hotspot_type'],
1945
                    ];
1946
1947
                    $answerId = Database::insert($table_ans, $params);
1948
1949
                    if ($answerId) {
1950
                        $sql = "UPDATE $table_ans SET id = iid, id_auto = iid WHERE iid = $answerId";
1951
                        Database::query($sql);
1952
                    }
1953
1954
                    $correct_answers[$answerId] = $answer['correct'];
1955
				}
1956
			}
1957
1958
            //Current course id
1959
            $course_id = api_get_course_int_id();
1960
1961
            //Moving quiz_question_options
1962
            if ($question->quiz_type == MULTIPLE_ANSWER_TRUE_FALSE) {
1963
                $question_option_list = Question::readQuestionOption($id, $course_id);
1964
1965
                //Question copied from the current platform
1966
                if ($question_option_list) {
1967
                    $old_option_ids = array();
1968
                    foreach ($question_option_list as $item) {
1969
                        $old_id = $item['id'];
1970
                        unset($item['id']);
1971
                        if (isset($item['iid'])) {
1972
                            unset($item['iid']);
1973
                        }
1974
                        $item['question_id'] = $new_id;
1975
                        $item['c_id'] = $this->destination_course_id;
1976
                        $question_option_id = Database::insert($table_options, $item);
1977
                        if ($question_option_id) {
1978
                            $old_option_ids[$old_id] = $question_option_id;
1979
                            $sql = "UPDATE $table_options SET id = iid WHERE iid = $question_option_id";
1980
                            Database::query($sql);
1981
                        }
1982
1983
                    }
1984
                    if ($old_option_ids) {
1985
                        $new_answers = Database::select(
1986
                            'iid, correct',
1987
                            $table_ans,
1988
                            array(
1989
                                'WHERE' => array(
1990
                                    'question_id = ? AND c_id = ? ' => array(
1991
                                        $new_id,
1992
                                        $this->destination_course_id,
1993
                                    ),
1994
                                ),
1995
                            )
1996
                        );
1997
1998 View Code Duplication
                        foreach ($new_answers as $answer_item) {
1999
                            $params = array();
2000
                            $params['correct'] = $old_option_ids[$answer_item['correct']];
2001
                            Database::update(
2002
                                $table_ans,
2003
                                $params,
2004
                                array(
2005
                                    'iid = ? AND c_id = ? AND question_id = ? ' => array(
2006
                                        $answer_item['iid'],
2007
                                        $this->destination_course_id,
2008
                                        $new_id,
2009
                                    ),
2010
                                ),
2011
                                false
2012
                            );
2013
                        }
2014
                    }
2015
                } else {
2016
                    $new_options = array();
2017
                    if (isset($question->question_options)) {
2018
                        foreach ($question->question_options as $obj) {
2019
                            $item = array();
2020
                            $item['question_id'] = $new_id;
2021
                            $item['c_id'] = $this->destination_course_id;
2022
                            $item['name'] = $obj->obj->name;
2023
                            $item['position'] = $obj->obj->position;
2024
2025
                            $question_option_id = Database::insert($table_options, $item);
2026
2027
                            if ($question_option_id) {
2028
                                $new_options[$obj->obj->id] = $question_option_id;
2029
                                $sql = "UPDATE $table_options SET id = iid WHERE iid = $question_option_id";
2030
                                Database::query($sql);
2031
                            }
2032
                        }
2033
2034 View Code Duplication
                        foreach($correct_answers as $answer_id => $correct_answer) {
2035
                            $params = array();
2036
                            $params['correct'] = $new_options[$correct_answer];
2037
                            Database::update(
2038
                                $table_ans,
2039
                                $params,
2040
                                array(
2041
                                    'id = ? AND c_id = ? AND question_id = ? ' => array(
2042
                                        $answer_id,
2043
                                        $this->destination_course_id,
2044
                                        $new_id,
2045
                                    ),
2046
                                ),
2047
                                false
2048
                            );
2049
                        }
2050
                    }
2051
                }
2052
            }
2053
			$this->course->resources[RESOURCE_QUIZQUESTION][$id]->destination_id = $new_id;
2054
		}
2055
		return $new_id;
2056
	}
2057
2058
	/**
2059
     * @todo : add session id when used for session
2060
     */
2061
    public function restore_test_category($session_id, $respect_base_content, $destination_course_code)
2062
    {
2063
        $course_id = api_get_course_int_id();
2064
        // Let's restore the categories
2065
        $tab_test_category_id_old_new = array(); // used to build the quiz_question_rel_category table
2066
        if ($this->course->has_resources(RESOURCE_TEST_CATEGORY)) {
0 ignored issues
show
Bug introduced by
The method has_resources cannot be called on $this->course (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
2067
            $resources = $this->course->resources;
2068
            foreach ($resources[RESOURCE_TEST_CATEGORY] as $id => $CourseCopyTestcategory ) {
2069
                $tab_test_category_id_old_new[$CourseCopyTestcategory->source_id] = $id;
2070
                // check if this test_category already exist in the destination BDD
2071
                // do not Database::escape_string $title and $description, it will be done later
2072
                $title = $CourseCopyTestcategory->title;
2073
                $description = $CourseCopyTestcategory->description;
2074
2075
                if (TestCategory::category_exists_with_title($title)) {
2076
                    switch ($this->file_option) {
2077
                        case FILE_SKIP:
2078
                            //Do nothing
2079
                            break;
2080
                        case FILE_RENAME:
2081
                            $new_title = $title."_";
2082
                            while (TestCategory::category_exists_with_title(
2083
                                $new_title
2084
                            )) {
2085
                                $new_title .= "_";
2086
                            }
2087
                            $test_category = new TestCategory(0, $new_title, $description);
2088
                            $new_id = $test_category->addCategoryInBDD();
2089
                            $tab_test_category_id_old_new[$CourseCopyTestcategory->source_id] = $new_id;
2090
                            break;
2091
                        case FILE_OVERWRITE:
2092
                            $id = TestCategory::get_category_id_for_title($title);
2093
                            $my_cat = new TestCategory($id);
2094
                            $my_cat->name = $title;
2095
                            $my_cat->modifyCategory();
2096
                            $tab_test_category_id_old_new[$CourseCopyTestcategory->source_id] = $id;
2097
                            break;
2098
                    }
2099
                } else {
2100
                    // create a new test_category
2101
                    $test_category = new TestCategory(0, $title, $description);
2102
                    $new_id = $test_category->addCategoryInBDD();
2103
                    $tab_test_category_id_old_new[$CourseCopyTestcategory->source_id] = $new_id;
2104
                }
2105
                $this->course->resources[RESOURCE_TEST_CATEGORY][$id]->destination_id = $tab_test_category_id_old_new[$CourseCopyTestcategory->source_id];
2106
            }
2107
        }
2108
        // lets check if quizzes-question are restored too, to redo the link between test_category and quizzes question for questions restored
2109
        // we can use the source_id field
2110
        // question source_id => category source_id
2111
        if ($this->course->has_resources(RESOURCE_QUIZQUESTION)) {
0 ignored issues
show
Bug introduced by
The method has_resources cannot be called on $this->course (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
2112
            // check the category number of each question restored
2113
            if (!empty($resources[RESOURCE_QUIZQUESTION])) {
2114
                foreach ($resources[RESOURCE_QUIZQUESTION] as $id => $CourseCopyQuestion) {
2115
                    $new_quiz_question_id = $resources[RESOURCE_QUIZQUESTION][$id]->destination_id;
2116
                    $question_category = $CourseCopyQuestion->question_category;
2117
                    if ($question_category > 0) {
2118
                        TestCategory::add_category_for_question_id(
2119
                            $tab_test_category_id_old_new[$question_category],
2120
                            $new_quiz_question_id,
2121
                            $course_id
2122
                        );
2123
                    }
2124
                }
2125
            }
2126
        }
2127
    }
2128
2129
    /**
2130
     * Restore surveys
2131
     * @param int $sessionId Optional. The session id
2132
     */
2133
    public function restore_surveys($sessionId = 0)
2134
    {
2135
        $sessionId = intval($sessionId);
2136
2137
        if ($this->course->has_resources(RESOURCE_SURVEY)) {
0 ignored issues
show
Bug introduced by
The method has_resources cannot be called on $this->course (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
2138
			$table_sur = Database :: get_course_table(TABLE_SURVEY);
2139
			$table_que = Database :: get_course_table(TABLE_SURVEY_QUESTION);
2140
			$table_ans = Database :: get_course_table(TABLE_SURVEY_QUESTION_OPTION);
2141
			$resources = $this->course->resources;
2142
			foreach ($resources[RESOURCE_SURVEY] as $id => $survey) {
2143
2144
				$sql = 'SELECT survey_id FROM '.$table_sur.'
2145
                        WHERE
2146
                            c_id = '.$this->destination_course_id.' AND
2147
                            code = "'.self::DBUTF8escapestring($survey->code).'" AND
2148
                            lang = "'.self::DBUTF8escapestring($survey->lang).'" ';
2149
2150
				$result_check = Database::query($sql);
2151
2152
				// check resources inside html from ckeditor tool and copy correct urls into recipient course
2153
                $survey->title = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2154
                    $survey->title,
2155
                    $this->course->code,
2156
                    $this->course->destination_path,
2157
                    $this->course->backup_path,
2158
                    $this->course->info['path']
2159
                );
2160
2161
                $survey->subtitle = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2162
                    $survey->subtitle,
2163
                    $this->course->code,
2164
                    $this->course->destination_path,
2165
                    $this->course->backup_path,
2166
                    $this->course->info['path']
2167
                );
2168
2169
                $survey->intro = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2170
                    $survey->intro,
2171
                    $this->course->code,
2172
                    $this->course->destination_path,
2173
                    $this->course->backup_path,
2174
                    $this->course->info['path']
2175
                );
2176
2177
                $survey->surveythanks = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2178
                    $survey->surveythanks,
2179
                    $this->course->code,
2180
                    $this->course->destination_path,
2181
                    $this->course->backup_path,
2182
                    $this->course->info['path']
2183
                );
2184
2185
                $params = [
2186
                    'c_id' => $this->destination_course_id,
2187
                    'code' => self::DBUTF8($survey->code),
2188
                    '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...
2189
                    '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...
2190
                    'author' => self::DBUTF8($survey->author),
2191
                    'lang' => self::DBUTF8($survey->lang),
2192
                    'avail_from' => self::DBUTF8($survey->avail_from),
2193
                    'avail_till' => self::DBUTF8($survey->avail_till),
2194
                    'is_shared' => self::DBUTF8($survey->is_shared),
2195
                    'template' => self::DBUTF8($survey->template),
2196
                    '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...
2197
                    '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...
2198
                    'creation_date' => self::DBUTF8($survey->creation_date),
2199
                    'invited' => '0',
2200
                    'answered' => '0',
2201
                    'invite_mail' => self::DBUTF8($survey->invite_mail),
2202
                    'reminder_mail' => self::DBUTF8($survey->reminder_mail),
2203
                    'session_id' => $sessionId,
2204
                ];
2205
2206
				//An existing survey exists with the same code and the same language
2207
				if (Database::num_rows($result_check) == 1) {
2208
					switch ($this->file_option) {
2209
						case FILE_SKIP:
2210
							//Do nothing
2211
							break;
2212
						case FILE_RENAME:
2213
							$survey_code = $survey->code.'_';
2214
							$i=1;
2215
							$temp_survey_code = $survey_code.$i;
2216
							while (!$this->is_survey_code_available($temp_survey_code)) {
2217
								$temp_survey_code = $survey_code.++$i;
2218
							}
2219
							$survey_code = $temp_survey_code;
2220
2221
                            $params['code'] = $survey_code;
2222
                            $new_id = Database::insert($table_sur, $params);
2223
                            if ($new_id) {
2224
                                $sql = "UPDATE $table_sur SET survey_id = iid WHERE iid = $new_id";
2225
                                Database::query($sql);
2226
2227
                                $this->course->resources[RESOURCE_SURVEY][$id]->destination_id = $new_id;
2228
                                foreach ($survey->question_ids as $index => $question_id) {
2229
                                    $qid = $this->restore_survey_question($question_id, $new_id);
2230
                                    $sql = "UPDATE ".$table_que." SET survey_id = ".$new_id."
2231
								            WHERE c_id = ".$this->destination_course_id." AND question_id = $qid";
2232
                                    Database::query($sql);
2233
                                    $sql = "UPDATE ".$table_ans." SET survey_id = ".$new_id."
2234
								            WHERE  c_id = ".$this->destination_course_id." AND  question_id = $qid";
2235
                                    Database::query($sql);
2236
                                }
2237
                            }
2238
							break;
2239
						case FILE_OVERWRITE:
2240
							// Delete the existing survey with the same code and language and import the one of the source course
2241
							// getting the information of the survey (used for when the survey is shared)
2242
2243
							$sql = "SELECT * FROM $table_sur
2244
							        WHERE
2245
							            c_id = ".$this->destination_course_id." AND
2246
							            survey_id='".self::DBUTF8escapestring(Database::result($result_check,0,0))."'";
2247
							$result = Database::query($sql);
2248
							$survey_data = Database::fetch_array($result,'ASSOC');
2249
2250
							// if the survey is shared => also delete the shared content
2251 View Code Duplication
							if (isset($survey_data['survey_share']) && is_numeric($survey_data['survey_share'])) {
2252
                                SurveyManager::delete_survey($survey_data['survey_share'], true,$this->destination_course_id);
2253
							}
2254
							SurveyManager :: delete_survey($survey_data['survey_id'],false,$this->destination_course_id);
2255
2256
							// Insert the new source survey
2257
                            $new_id = Database::insert($table_sur, $params);
2258
2259 View Code Duplication
                            if ($new_id) {
2260
                                $sql = "UPDATE $table_sur SET survey_id = iid WHERE iid = $new_id";
2261
                                Database::query($sql);
2262
2263
                                $this->course->resources[RESOURCE_SURVEY][$id]->destination_id = $new_id;
2264
                                foreach ($survey->question_ids as $index => $question_id) {
2265
                                    $qid = $this->restore_survey_question(
2266
                                        $question_id,
2267
                                        $new_id
2268
                                    );
2269
                                    $sql = "UPDATE $table_que SET survey_id = $new_id
2270
                                            WHERE c_id = ".$this->destination_course_id." AND question_id = $qid";
2271
                                    Database::query($sql);
2272
                                    $sql = "UPDATE $table_ans SET survey_id = $new_id
2273
                                            WHERE c_id = ".$this->destination_course_id." AND question_id = $qid";
2274
                                    Database::query($sql);
2275
                                }
2276
                            }
2277
							break;
2278
						default:
2279
							break;
2280
					}
2281
				} else {
2282
                    // No existing survey with the same language and the same code, we just copy the survey
2283
                    $new_id = Database::insert($table_sur, $params);
2284
2285 View Code Duplication
                    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(
2292
                                $question_id,
2293
                                $new_id
2294
                            );
2295
                            $sql = "UPDATE $table_que SET survey_id = $new_id
2296
                                    WHERE c_id = ".$this->destination_course_id." AND question_id = $qid";
2297
                            Database::query($sql);
2298
                            $sql = "UPDATE $table_ans SET survey_id = $new_id
2299
                                    WHERE c_id = ".$this->destination_course_id." AND question_id = $qid";
2300
                            Database::query($sql);
2301
                        }
2302
                    }
2303
				}
2304
			}
2305
		}
2306
	}
2307
2308
	/**
2309
	 * Check availability of a survey code
2310
	 */
2311 View Code Duplication
    public function is_survey_code_available($survey_code)
2312
    {
2313
		$table_sur = Database :: get_course_table(TABLE_SURVEY);
2314
		$sql = "SELECT * FROM $table_sur
2315
		        WHERE
2316
		            c_id = ".$this->destination_course_id." AND
2317
		            code='".self::DBUTF8escapestring($survey_code)."'";
2318
		$result = Database::query($sql);
2319
		if (Database::num_rows($result) > 0) return false; else return true;
2320
	}
2321
2322
	/**
2323
	 * Restore survey-questions
2324
	 */
2325
    public function restore_survey_question($id, $survey_id)
2326
    {
2327
		$resources = $this->course->resources;
2328
		$question = $resources[RESOURCE_SURVEYQUESTION][$id];
2329
2330
		$new_id=0;
2331
2332
		if (is_object($question)) {
2333
			if ($question->is_restored()) {
2334
				return $question->destination_id;
2335
			}
2336
			$table_que = Database :: get_course_table(TABLE_SURVEY_QUESTION);
2337
			$table_ans = Database :: get_course_table(TABLE_SURVEY_QUESTION_OPTION);
2338
2339
			// check resources inside html from ckeditor tool and copy correct urls into recipient course
2340
            $question->survey_question = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2341
                $question->survey_question,
2342
                $this->course->code,
2343
                $this->course->destination_path,
2344
                $this->course->backup_path,
2345
                $this->course->info['path']
2346
            );
2347
2348
            $params = [
2349
                'c_id' => $this->destination_course_id,
2350
                'survey_id' => self::DBUTF8($survey_id),
2351
                '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...
2352
                'survey_question_comment' => self::DBUTF8($question->survey_question_comment),
2353
                'type' => self::DBUTF8($question->survey_question_type),
2354
                'display' => self::DBUTF8($question->display),
2355
                'sort' => self::DBUTF8($question->sort),
2356
                'shared_question_id' => self::DBUTF8($question->shared_question_id),
2357
                'max_value' => self::DBUTF8($question->max_value),
2358
            ];
2359
2360
            $new_id = Database::insert($table_que, $params);
2361
            if ($new_id) {
2362
2363
                $sql = "UPDATE $table_que SET question_id = iid WHERE iid = $new_id";
2364
                Database::query($sql);
2365
2366
                foreach ($question->answers as $index => $answer) {
2367
2368
                    // check resources inside html from ckeditor tool and copy correct urls into recipient course
2369
                    $answer['option_text'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2370
                        $answer['option_text'],
2371
                        $this->course->code,
2372
                        $this->course->destination_path,
2373
                        $this->course->backup_path,
2374
                        $this->course->info['path']
2375
                    );
2376
2377
                    $params = [
2378
                        'c_id' => $this->destination_course_id,
2379
                        'question_id' => $new_id,
2380
                        '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...
2381
                        'sort' => $answer['sort'],
2382
                        'survey_id' => self::DBUTF8($survey_id),
2383
                    ];
2384
                    $answerId = Database::insert($table_ans, $params);
2385
                    if ($answerId) {
2386
                        $sql = "UPDATE $table_ans SET question_option_id = iid
2387
                                WHERE iid = $answerId";
2388
                        Database::query($sql);
2389
                    }
2390
                }
2391
                $this->course->resources[RESOURCE_SURVEYQUESTION][$id]->destination_id = $new_id;
2392
            }
2393
		}
2394
2395
		return $new_id;
2396
	}
2397
2398
    /**
2399
     * Restoring learning paths
2400
     * @param int $session_id
2401
     * @param bool|false $respect_base_content
2402
     */
2403
    public function restore_learnpaths($session_id = 0, $respect_base_content = false)
2404
    {
2405
        $session_id = intval($session_id);
2406
2407
		if ($this->course->has_resources(RESOURCE_LEARNPATH)) {
0 ignored issues
show
Bug introduced by
The method has_resources cannot be called on $this->course (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
2408
            $table_main = Database::get_course_table(TABLE_LP_MAIN);
2409
            $table_item = Database::get_course_table(TABLE_LP_ITEM);
2410
            $table_tool = Database::get_course_table(TABLE_TOOL_LIST);
2411
2412
			$resources = $this->course->resources;
2413
2414
			$origin_path = $this->course->backup_path.'/upload/learning_path/images/';
2415
			$destination_path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/upload/learning_path/images/';
2416
2417
			foreach ($resources[RESOURCE_LEARNPATH] as $id => $lp) {
2418
2419
				$condition_session = "";
2420 View Code Duplication
				if (!empty($session_id)) {
2421
                    if ($respect_base_content) {
2422
                        $my_session_id = $lp->session_id;
2423
                        if (!empty($lp->session_id)) {
2424
                            $my_session_id = $session_id;
2425
                        }
2426
                        $condition_session = $my_session_id;
2427
                    } else {
2428
                        $session_id = intval($session_id);
2429
                        $condition_session = $session_id;
2430
                    }
2431
				}
2432
2433
				// Adding the author's image
2434
				if (!empty($lp->preview_image)) {
2435
					$new_filename = uniqid('').substr($lp->preview_image,strlen($lp->preview_image)-7, strlen($lp->preview_image));
2436
					if (file_exists($origin_path.$lp->preview_image) && !is_dir($origin_path.$lp->preview_image)) {
2437
						$copy_result = copy($origin_path.$lp->preview_image, $destination_path.$new_filename);
2438
						//$copy_result = true;
2439
						if ($copy_result) {
2440
							$lp->preview_image = $new_filename;
2441
						} else {
2442
							$lp->preview_image ='';
2443
						}
2444
					}
2445
				}
2446
2447
                if ($this->add_text_in_items) {
2448
                    $lp->name = $lp->name.' '.get_lang('CopyLabelSuffix');
2449
                }
2450
2451
                if (isset($this->tool_copy_settings['learnpaths'])) {
2452
                    if (isset($this->tool_copy_settings['learnpaths']['reset_dates']) &&
2453
                        $this->tool_copy_settings['learnpaths']['reset_dates']
2454
                    ) {
2455
                        $lp->created_on     = api_get_utc_datetime();
2456
                        $lp->modified_on    = api_get_utc_datetime();
2457
                        $lp->publicated_on  = null;
2458
                    }
2459
                }
2460
2461
                $params = [
2462
                    'c_id' => $this->destination_course_id,
2463
                    'lp_type' => $lp->lp_type,
2464
                    'name' => self::DBUTF8($lp->name),
2465
                    'path' => self::DBUTF8($lp->path),
2466
                    'ref' => $lp->ref,
2467
                    'description' => self::DBUTF8($lp->description),
2468
                    'content_local' => self::DBUTF8($lp->content_local),
2469
                    'default_encoding' => self::DBUTF8($lp->default_encoding),
2470
                    'default_view_mod' => self::DBUTF8($lp->default_view_mod),
2471
                    'prevent_reinit' => self::DBUTF8($lp->prevent_reinit),
2472
                    'force_commit' => self::DBUTF8($lp->force_commit),
2473
                    'content_maker' => self::DBUTF8($lp->content_maker),
2474
                    'display_order' => self::DBUTF8($lp->display_order),
2475
                    'js_lib' => self::DBUTF8($lp->js_lib),
2476
                    'content_license' => self::DBUTF8($lp->content_license),
2477
                    'author' => self::DBUTF8($lp->author),
2478
                    'preview_image' => self::DBUTF8($lp->preview_image),
2479
                    'use_max_score' => self::DBUTF8($lp->use_max_score),
2480
                    'autolaunch' => self::DBUTF8(isset($lp->autolaunch) ? $lp->autolaunch : ''),
2481
                    'created_on' => self::DBUTF8($lp->created_on),
2482
                    'modified_on' => self::DBUTF8($lp->modified_on),
2483
                    'publicated_on' => empty($lp->publicated_on) ? api_get_utc_datetime() : self::DBUTF8($lp->publicated_on),
2484
                    'expired_on' => self::DBUTF8($lp->expired_on),
2485
                    'debug' => self::DBUTF8($lp->debug),
2486
                ];
2487
2488
                if (!empty($condition_session)) {
2489
                    $params['session_id'] = $condition_session;
2490
                }
2491
2492
				$new_lp_id = Database::insert($table_main, $params);
2493
2494
                if ($new_lp_id) {
2495
2496
                    $sql = "UPDATE $table_main SET id = iid WHERE iid = $new_lp_id";
2497
                    Database::query($sql);
2498
2499
                    if ($lp->visibility) {
2500
                        $params = [
2501
                            'c_id' => $this->destination_course_id,
2502
                            'name' => self::DBUTF8($lp->name),
2503
                            'link' => 'newscorm/lp_controller.php?action=view&lp_id=$new_lp_id&id_session='.$session_id,
2504
                            'image' => 'scormbuilder.gif',
2505
                            'visibility' => '0',
2506
                            'admin' => '0',
2507
                            'address' => 'squaregrey.gif',
2508
                            'session_id' => $session_id,
2509
                        ];
2510
                        $insertId = Database::insert($table_tool, $params);
2511
                        if ($insertId) {
2512
                            $sql = "UPDATE $table_tool SET id = iid WHERE iid = $insertId";
2513
                            Database::query($sql);
2514
                        }
2515
                    }
2516
2517
                    api_item_property_update(
2518
                        $this->destination_course_info,
2519
                        TOOL_LEARNPATH,
2520
                        $new_lp_id,
2521
                        'LearnpathAdded',
2522
                        api_get_user_id(),
2523
                        0,
2524
                        0,
2525
                        0,
2526
                        0,
2527
                        $session_id
2528
                    );
2529
2530
                    // Set the new LP to visible
2531
                    api_item_property_update(
2532
                        $this->destination_course_info,
2533
                        TOOL_LEARNPATH,
2534
                        $new_lp_id,
2535
                        'invisible',
2536
                        api_get_user_id(),
2537
                        0,
2538
                        0,
2539
                        0,
2540
                        0,
2541
                        $session_id
2542
                    );
2543
                }
2544
2545
                $new_item_ids = array();
2546
                $parent_item_ids = array();
2547
                $previous_item_ids = array();
2548
                $next_item_ids = array();
2549
                $old_prerequisite = array();
2550
                $old_refs = array();
2551
                $prerequisite_ids = array();
2552
2553
				foreach ($lp->get_items() as $index => $item) {
2554
					// we set the ref code here and then we update in a for loop
2555
					$ref = $item['ref'];
2556
2557
					// Dealing with path the same way as ref as some data has
2558
                    // been put into path when it's a local resource
2559
					// Only fix the path for no scos
2560
                    if ($item['item_type'] == 'sco') {
2561
                        $path = $item['path'];
2562
                    } else {
2563
                        $path = $item['path'];
2564
                        $path = $this->get_new_id($item['item_type'], $path);
2565
                    }
2566
2567
                    $params = [
2568
                        'c_id' => $this->destination_course_id,
2569
                        '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 2492 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...
2570
                        'item_type' => self::DBUTF8($item['item_type']),
2571
                        'ref' => self::DBUTF8($ref),
2572
                        'title' => self::DBUTF8($item['title']),
2573
                        'description' => self::DBUTF8($item['description']),
2574
                        'path' => self::DBUTF8($path),
2575
                        'min_score' => self::DBUTF8($item['min_score']),
2576
                        'max_score' => self::DBUTF8($item['max_score']),
2577
                        'mastery_score' => self::DBUTF8($item['mastery_score']),
2578
                        'parent_item_id' => self::DBUTF8($item['parent_item_id']),
2579
                        'previous_item_id' => self::DBUTF8($item['previous_item_id']),
2580
                        'next_item_id' => self::DBUTF8($item['next_item_id']),
2581
                        'display_order' => self::DBUTF8($item['display_order']),
2582
                        'prerequisite' => self::DBUTF8($item['prerequisite']),
2583
                        'parameters' => self::DBUTF8($item['parameters']),
2584
                        'audio' => self::DBUTF8($item['audio']),
2585
                        'launch_data' => self::DBUTF8($item['launch_data']),
2586
                    ];
2587
2588
					$new_item_id = Database::insert($table_item, $params);
2589
2590
                    $sql = "UPDATE $table_item SET id = iid WHERE iid = $new_item_id";
2591
                    Database::query($sql);
2592
2593
					//save a link between old and new item IDs
2594
					$new_item_ids[$item['id']] = $new_item_id;
2595
					//save a reference of items that need a parent_item_id refresh
2596
					$parent_item_ids[$new_item_id] = $item['parent_item_id'];
2597
					//save a reference of items that need a previous_item_id refresh
2598
					$previous_item_ids[$new_item_id] = $item['previous_item_id'];
2599
					//save a reference of items that need a next_item_id refresh
2600
					$next_item_ids[$new_item_id] = $item['next_item_id'];
2601
2602
					if (!empty($item['prerequisite'])) {
2603
						if ($lp->lp_type =='2') {
2604
							// if is an sco
2605
							$old_prerequisite[$new_item_id]= $item['prerequisite'];
2606
						} else {
2607
							$old_prerequisite[$new_item_id]= $new_item_ids[$item['prerequisite']];
2608
						}
2609
					}
2610
2611
					if (!empty($ref)) {
2612
						if ($lp->lp_type =='2') {
2613
							// if is an sco
2614
							$old_refs[$new_item_id]= $ref;
2615
						} else {
2616
                            $old_refs[$new_item_id]= $new_item_ids[$ref];
2617
						}
2618
					}
2619
2620
					$prerequisite_ids[$new_item_id] = $item['prerequisite'];
2621
				}
2622
2623
				// Updating prerequisites
2624 View Code Duplication
				foreach ($old_prerequisite  as $key=>$my_old_prerequisite) {
2625
					if($my_old_prerequisite != ''){
2626
						$sql = "UPDATE ".$table_item." SET prerequisite = '".$my_old_prerequisite."'
2627
						        WHERE c_id = ".$this->destination_course_id." AND id = '".$key."'  ";
2628
						Database::query($sql);
2629
					}
2630
				}
2631
2632
				// Updating refs
2633 View Code Duplication
				foreach ($old_refs  as $key=>$my_old_ref) {
2634
					if ($my_old_ref != '') {
2635
						$sql = "UPDATE ".$table_item." SET ref = '".$my_old_ref."'
2636
						        WHERE c_id = ".$this->destination_course_id." AND id = '".$key."'  ";
2637
						Database::query($sql);
2638
					}
2639
				}
2640
2641 View Code Duplication
				foreach ($parent_item_ids as $new_item_id => $parent_item_old_id) {
2642
					$parent_new_id = 0;
2643
					if($parent_item_old_id != 0){
2644
						$parent_new_id = $new_item_ids[$parent_item_old_id];
2645
					}
2646
					$sql = "UPDATE ".$table_item." SET parent_item_id = '".$parent_new_id."'
2647
					        WHERE c_id = ".$this->destination_course_id." AND id = '".$new_item_id."'";
2648
					Database::query($sql);
2649
				}
2650 View Code Duplication
				foreach ($previous_item_ids as $new_item_id => $previous_item_old_id) {
2651
					$previous_new_id = 0;
2652
					if($previous_item_old_id != 0){
2653
						$previous_new_id = $new_item_ids[$previous_item_old_id];
2654
					}
2655
					$sql = "UPDATE ".$table_item." SET previous_item_id = '".$previous_new_id."'
2656
					        WHERE  c_id = ".$this->destination_course_id." AND id = '".$new_item_id."'";
2657
					Database::query($sql);
2658
				}
2659
2660 View Code Duplication
				foreach ($next_item_ids as $new_item_id => $next_item_old_id) {
2661
					$next_new_id = 0;
2662
					if($next_item_old_id != 0){
2663
						$next_new_id = $new_item_ids[$next_item_old_id];
2664
					}
2665
					$sql = "UPDATE ".$table_item." SET next_item_id = '".$next_new_id."'
2666
					        WHERE c_id = ".$this->destination_course_id." AND id = '".$new_item_id."'";
2667
					Database::query($sql);
2668
				}
2669
2670 View Code Duplication
				foreach ($prerequisite_ids as $new_item_id => $prerequisite_old_id) {
2671
					$prerequisite_new_id = 0;
2672
					if($prerequisite_old_id != 0){
2673
						$prerequisite_new_id = $new_item_ids[$prerequisite_old_id];
2674
					}
2675
					$sql = "UPDATE ".$table_item." SET prerequisite = '".$prerequisite_new_id."'
2676
					        WHERE c_id = ".$this->destination_course_id." AND id = '".$new_item_id."'";
2677
					Database::query($sql);
2678
				}
2679
				$this->course->resources[RESOURCE_LEARNPATH][$id]->destination_id = $new_lp_id;
2680
			}
2681
		}
2682
	}
2683
2684
	/**
2685
	 * Restore works
2686
     * @deprecated use restore_works
2687
     *
2688
	 */
2689
	public function restore_student_publication($sessionId = 0)
2690
    {
2691
        $sessionId = intval($sessionId);
2692
		$work_assignment_table  = Database :: get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
2693
		$work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
2694
		$item_property_table  	= Database :: get_course_table(TABLE_ITEM_PROPERTY);
2695
2696
		// Query in student publication
2697
		$sql = 'SELECT * FROM '.$work_table.'
2698
		        WHERE c_id = '.$this->course_origin_id.' AND filetype = "folder" AND active IN (0, 1) ';
2699
2700
		$result = Database::query($sql);
2701
		$folders = Database::store_result($result, 'ASSOC');
2702
2703
		foreach ($folders  as $folder) {
2704
		    $old_id = $folder['id'];
2705
            unset($folder['id']);
2706
			$folder['c_id'] = $this->destination_course_id;
2707
            $folder['parent_id'] = 0;
2708
            $folder['session_id'] = $sessionId;
2709
			$new_id = Database::insert($work_table, $folder);
2710
2711
            if ($new_id) {
2712
                //query in item property
2713
                $sql = 'SELECT
2714
                        tool,
2715
                        insert_user_id,
2716
                        insert_date,
2717
                        lastedit_date,
2718
                        ref,
2719
                        lastedit_type,
2720
                        lastedit_user_id,
2721
                        to_group_id,
2722
                        to_user_id,
2723
                        visibility,
2724
                        start_visible,
2725
                        end_visible
2726
                        FROM '.$item_property_table.' ip
2727
                        INNER JOIN '.$work_table.' sp
2728
                        ON ip.ref=sp.id
2729
                        WHERE
2730
                            sp.c_id = '.$this->course_origin_id.' AND
2731
                            ip.c_id = '.$this->course_origin_id.' AND
2732
                            tool="work" AND sp.id = '.$old_id.'';
2733
2734
                $result = Database::query($sql);
2735
                $sub_folders = Database::store_result($result, 'ASSOC');
2736
                foreach ($sub_folders  as $sub_folder) {
2737
                    $sub_folder['c_id'] = $this->destination_course_id;
2738
                    $sub_folder['ref'] = $new_id;
2739
                    $sub_folder['session_id'] = $sessionId;
2740
                    $new_item_id = Database::insert($item_property_table, $sub_folder);
2741
                    if ($new_item_id) {
2742
                        $sql = "UPDATE $item_property_table SET id = iid WHERE iid = $new_item_id";
2743
                        Database::query($sql);
2744
                    }
2745
                }
2746
2747
                $sql = 'SELECT sa.id, sa.expires_on,sa.ends_on,sa.add_to_calendar, sa.enable_qualification, sa.publication_id
2748
                        FROM '.$work_assignment_table.' sa
2749
                        INNER JOIN '.$work_table.' sp ON sa.publication_id=sp.id
2750
                        WHERE
2751
                            sp.c_id = '.$this->course_origin_id.' AND
2752
                            sa.c_id = '.$this->course_origin_id.' AND
2753
                            filetype="folder" AND sp.id = '.$old_id.'';
2754
2755
                $result = Database::query($sql);
2756
                $assing_list = Database::store_result($result, 'ASSOC');
2757
                foreach ($assing_list  as $assign) {
2758
                    $assign['c_id'] = $this->destination_course_id;
2759
                    $assign['id'] = $new_id;
2760
                    $assignmentId = Database::insert($work_assignment_table, $assign);
2761
2762
                    if ($assignmentId) {
2763
                        $sql = "UPDATE $work_assignment_table SET id = iid WHERE iid = $assignmentId";
2764
                        Database::query($sql);
2765
                    }
2766
                }
2767
            }
2768
		}
2769
2770
		$destination = '../../courses/'.$this->course->destination_path.'/work/';
2771
		$origin = '../../courses/'.$this->course->info['path'].'/work/';
2772
		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...
2773
	}
2774
2775
    /**
2776
    * copy all directory and sub directory
2777
    * @param string The path origin
2778
    * @param string The path destination
2779
    * @param boolean Option Overwrite
2780
    * @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...
2781
    * @deprecated
2782
    */
2783
    public function allow_create_all_directory($source, $dest, $overwrite = false)
2784
    {
2785
        if (!is_dir($dest)) {
2786
            mkdir($dest, api_get_permissions_for_new_directories());
2787
        }
2788
        if ($handle = opendir($source)) {        // if the folder exploration is sucsessful, continue
2789
            while (false !== ($file = readdir($handle))) { // as long as storing the next file to $file is successful, continue
2790
                if ($file != '.' && $file != '..') {
2791
                    $path = $source . '/' . $file;
2792
                    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...
2793
                       /* if (!is_file($dest . '/' . $file) || $overwrite)
2794
                        if (!@copy($path, $dest . '/' . $file)) {
2795
                            echo '<font color="red">File ('.$path.') '.get_lang('NotHavePermission').'</font>';
2796
                        }*/
2797
                    } elseif(is_dir($path)) {
2798
                        if (!is_dir($dest . '/' . $file))
2799
                        mkdir($dest . '/' . $file);
2800
                       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...
2801
                    }
2802
                }
2803
            }
2804
            closedir($handle);
2805
        }
2806
    }
2807
2808
	/**
2809
	 * Gets the new ID of one specific tool item from the tool name and the old ID
2810
	 * @param	string	Tool name
2811
	 * @param	integer	Old ID
2812
	 * @return	integer	New ID
2813
	 */
2814
    public function get_new_id($tool, $ref)
2815
    {
2816
        // Check if the value exist in the current array.
2817
2818
        if ($tool == 'hotpotatoes') {
2819
            $tool = 'document';
2820
        }
2821
2822
        if (isset($this->course->resources[$tool][$ref]) &&
2823
            isset($this->course->resources[$tool][$ref]->destination_id) &&
2824
            !empty($this->course->resources[$tool][$ref]->destination_id)
2825
        ) {
2826
            return $this->course->resources[$tool][$ref]->destination_id;
2827
        }
2828
2829
        // Check if the course is the same (last hope).
2830
        if ($this->course_origin_id == $this->destination_course_id) {
2831
            return $ref;
2832
        }
2833
2834
        return '';
2835
	}
2836
2837
	/**
2838
	 * Restore glossary
2839
	 */
2840
    public function restore_glossary($session_id = 0)
2841
    {
2842
		if ($this->course->has_resources(RESOURCE_GLOSSARY)) {
0 ignored issues
show
Bug introduced by
The method has_resources cannot be called on $this->course (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
2843
			$table_glossary = Database :: get_course_table(TABLE_GLOSSARY);
2844
			$resources = $this->course->resources;
2845
			foreach ($resources[RESOURCE_GLOSSARY] as $id => $glossary) {
2846
2847
                $params = [];
2848
    			if (!empty($session_id)) {
2849
    				$session_id = intval($session_id);
2850
                    $params['session_id'] = $session_id;
2851
    			}
2852
2853
				// check resources inside html from ckeditor tool and copy correct urls into recipient course
2854
                $glossary->description = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2855
                    $glossary->description,
2856
                    $this->course->code,
2857
                    $this->course->destination_path,
2858
                    $this->course->backup_path,
2859
                    $this->course->info['path']
2860
                );
2861
2862
                $params['c_id'] = $this->destination_course_id;
2863
                $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...
2864
                $params['display_order'] = $glossary->display_order;
2865
                $params['name'] = self::DBUTF8($glossary->name);
2866
2867
                $my_id = Database::insert($table_glossary, $params);
2868 View Code Duplication
                if ($my_id) {
2869
2870
                    $sql = "UPDATE $table_glossary SET glossary_id = iid WHERE iid = $my_id";
2871
                    Database::query($sql);
2872
2873
                    api_item_property_update(
2874
                        $this->destination_course_info,
2875
                        TOOL_GLOSSARY,
2876
                        $my_id,
2877
                        "GlossaryAdded",
2878
                        api_get_user_id()
2879
                    );
2880
2881
                    if (!isset($this->course->resources[RESOURCE_GLOSSARY][$id])) {
2882
                        $this->course->resources[RESOURCE_GLOSSARY][$id] = new stdClass();
2883
                    }
2884
2885
                    $this->course->resources[RESOURCE_GLOSSARY][$id]->destination_id = $my_id;
2886
                }
2887
			}
2888
		}
2889
	}
2890
2891
    /**
2892
     * @param int $session_id
2893
     */
2894
    public function restore_wiki($session_id = 0)
2895
    {
2896
		if ($this->course->has_resources(RESOURCE_WIKI)) {
0 ignored issues
show
Bug introduced by
The method has_resources cannot be called on $this->course (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
2897
			// wiki table of the target course
2898
			$table_wiki = Database :: get_course_table(TABLE_WIKI);
2899
			$table_wiki_conf = Database :: get_course_table(TABLE_WIKI_CONF);
2900
2901
			// storing all the resources that have to be copied in an array
2902
			$resources = $this->course->resources;
2903
2904
			foreach ($resources[RESOURCE_WIKI] as $id => $wiki) {
2905
				// the sql statement to insert the groups from the old course to the new course
2906
2907
				// check resources inside html from ckeditor tool and copy correct urls into recipient course
2908
                $wiki->content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2909
                    $wiki->content,
2910
                    $this->course->code,
2911
                    $this->course->destination_path,
2912
                    $this->course->backup_path,
2913
                    $this->course->info['path']
2914
                );
2915
2916
                $params = [
2917
                    'c_id' => $this->destination_course_id,
2918
                    'page_id' => self::DBUTF8($wiki->page_id),
2919
                    'reflink' => self::DBUTF8($wiki->reflink),
2920
                    'title' => self::DBUTF8($wiki->title),
2921
                    '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...
2922
                    'user_id' => intval($wiki->user_id),
2923
                    'group_id' => intval($wiki->group_id),
2924
                    'dtime' => self::DBUTF8($wiki->dtime),
2925
                    'progress' => self::DBUTF8($wiki->progress),
2926
                    'version' => intval($wiki->version),
2927
                    'session_id' => !empty($session_id) ? intval($session_id) : 0,
2928
                ];
2929
2930
				$new_id = Database::insert($table_wiki, $params);
2931
2932
                if ($new_id) {
2933
2934
                    $sql = "UPDATE $table_wiki SET page_id = '$new_id', id = iid
2935
                            WHERE c_id = ".$this->destination_course_id." AND iid = '$new_id'";
2936
                    Database::query($sql);
2937
2938
                    $this->course->resources[RESOURCE_WIKI][$id]->destination_id = $new_id;
2939
2940
                    // we also add an entry in wiki_conf
2941
                    $params = [
2942
                        'c_id' => $this->destination_course_id,
2943
                        'page_id' => $new_id,
2944
                        'task' => '',
2945
                        'feedback1' => '',
2946
                        'feedback2' => '',
2947
                        'feedback3' => '',
2948
                        'fprogress1' => '',
2949
                        'fprogress2' => '',
2950
                        'fprogress3' => '',
2951
                        'max_size' => '',
2952
                        'max_text' => 0,
2953
                        'max_version' => 0,
2954
                        'startdate_assig' => '',
2955
                        'enddate_assig' => '',
2956
                        'delayedsubmit' => 0,
2957
                    ];
2958
2959
                    Database::insert($table_wiki_conf, $params);
2960
                }
2961
			}
2962
		}
2963
	}
2964
2965
    /**
2966
     * Restore Thematics
2967
     * @param int $session_id
2968
     */
2969
    public function restore_thematic($session_id = 0)
2970
    {
2971
		if ($this->course->has_resources(RESOURCE_THEMATIC)) {
0 ignored issues
show
Bug introduced by
The method has_resources cannot be called on $this->course (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
2972
            $table_thematic = Database:: get_course_table(TABLE_THEMATIC);
2973
            $table_thematic_advance = Database:: get_course_table(TABLE_THEMATIC_ADVANCE);
2974
            $table_thematic_plan = Database:: get_course_table(TABLE_THEMATIC_PLAN);
2975
2976
			$resources = $this->course->resources;
2977
			foreach ($resources[RESOURCE_THEMATIC] as $id => $thematic) {
2978
2979
				// check resources inside html from ckeditor tool and copy correct urls into recipient course
2980
                $thematic->params['content'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2981
                    $thematic->params['content'],
2982
                    $this->course->code,
2983
                    $this->course->destination_path,
2984
                    $this->course->backup_path,
2985
                    $this->course->info['path']
2986
                );
2987
				$thematic->params['c_id']  = $this->destination_course_id;
2988
				unset($thematic->params['id']);
2989
                unset($thematic->params['iid']);
2990
2991
				$last_id = Database::insert($table_thematic, $thematic->params, false);
2992
2993
				if ($last_id) {
2994
2995
                    $sql = "UPDATE $table_thematic SET id = iid WHERE iid = $last_id";
2996
                    Database::query($sql);
2997
2998
                    api_item_property_update(
2999
                        $this->destination_course_info,
3000
                        'thematic',
3001
                        $last_id,
3002
                        "ThematicAdded",
3003
                        api_get_user_id()
3004
                    );
3005
3006 View Code Duplication
					foreach ($thematic->thematic_advance_list as $thematic_advance) {
3007
						unset($thematic_advance['id']);
3008
                        unset($thematic_advance['iid']);
3009
						$thematic_advance['attendance_id'] = 0;
3010
						$thematic_advance['thematic_id'] = $last_id;
3011
						$thematic_advance['c_id']  = $this->destination_course_id;
3012
                        $my_id = Database::insert(
3013
                            $table_thematic_advance,
3014
                            $thematic_advance,
3015
                            false
3016
                        );
3017
3018
						if ($my_id) {
3019
3020
                            $sql = "UPDATE $table_thematic_advance SET id = iid WHERE iid = $my_id";
3021
                            Database::query($sql);
3022
3023
                            api_item_property_update(
3024
                                $this->destination_course_info,
3025
                                'thematic_advance',
3026
                                $my_id,
3027
                                "ThematicAdvanceAdded",
3028
                                api_get_user_id()
3029
                            );
3030
						}
3031
					}
3032
3033 View Code Duplication
					foreach($thematic->thematic_plan_list as $thematic_plan) {
3034
						unset($thematic_plan['id']);
3035
                        unset($thematic_plan['iid']);
3036
						$thematic_plan['thematic_id'] = $last_id;
3037
						$thematic_plan['c_id'] = $this->destination_course_id;
3038
						$my_id = Database::insert($table_thematic_plan, $thematic_plan, false);
3039
3040
						if ($my_id) {
3041
3042
                            $sql = "UPDATE $table_thematic_plan SET id = iid WHERE iid = $my_id";
3043
                            Database::query($sql);
3044
3045
                            api_item_property_update(
3046
                                $this->destination_course_info,
3047
                                'thematic_plan',
3048
                                $my_id,
3049
                                "ThematicPlanAdded",
3050
                                api_get_user_id()
3051
                            );
3052
						}
3053
					}
3054
				}
3055
			}
3056
		}
3057
	}
3058
3059
    /**
3060
     * Restore Attendance
3061
     * @param int $session_id
3062
     */
3063
    public function restore_attendance($session_id = 0)
3064
    {
3065
		if ($this->course->has_resources(RESOURCE_ATTENDANCE)) {
0 ignored issues
show
Bug introduced by
The method has_resources cannot be called on $this->course (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
3066
			$table_attendance = Database :: get_course_table(TABLE_ATTENDANCE);
3067
			$table_attendance_calendar = Database :: get_course_table(TABLE_ATTENDANCE_CALENDAR);
3068
3069
			$resources = $this->course->resources;
3070
			foreach ($resources[RESOURCE_ATTENDANCE] as $id => $obj) {
3071
3072
				// check resources inside html from ckeditor tool and copy correct urls into recipient course
3073
                $obj->params['description'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
3074
                    $obj->params['description'],
3075
                    $this->course->code,
3076
                    $this->course->destination_path,
3077
                    $this->course->backup_path,
3078
                    $this->course->info['path']
3079
                );
3080
3081
                unset($obj->params['id']);
3082
                unset($obj->params['iid']);
3083
3084
				$obj->params['c_id'] = $this->destination_course_id;
3085
3086
				$last_id = Database::insert($table_attendance, $obj->params);
3087
3088
				if (is_numeric($last_id)) {
3089
3090
                    $sql = "UPDATE $table_attendance SET id = iid WHERE iid = $last_id";
3091
                    Database::query($sql);
3092
3093
                    api_item_property_update(
3094
                        $this->destination_course_info,
3095
                        TOOL_ATTENDANCE,
3096
                        $last_id,
3097
                        "AttendanceAdded",
3098
                        api_get_user_id()
3099
                    );
3100
3101
                    foreach ($obj->attendance_calendar as $attendance_calendar) {
3102
						unset($attendance_calendar['id']);
3103
                        unset($attendance_calendar['iid']);
3104
3105
						$attendance_calendar['attendance_id'] = $last_id;
3106
						$attendance_calendar['c_id'] = $this->destination_course_id;
3107
                        $attendanceCalendarId = Database::insert(
3108
                            $table_attendance_calendar,
3109
                            $attendance_calendar
3110
                        );
3111
3112
                        $sql = "UPDATE $table_attendance_calendar SET id = iid WHERE iid = $attendanceCalendarId";
3113
                        Database::query($sql);
3114
					}
3115
				}
3116
			}
3117
		}
3118
	}
3119
3120
    /**
3121
     * Restore Works
3122
     * @param int $sessionId
3123
     */
3124
    public function restore_works($sessionId = 0)
3125
    {
3126
        require_once api_get_path(SYS_CODE_PATH).'work/work.lib.php';
3127
        if ($this->course->has_resources(RESOURCE_WORK)) {
0 ignored issues
show
Bug introduced by
The method has_resources cannot be called on $this->course (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
3128
            $table_work_assignment = Database :: get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
3129
3130
            $resources = $this->course->resources;
3131
            foreach ($resources[RESOURCE_WORK] as $obj) {
3132
3133
                // check resources inside html from ckeditor tool and copy correct urls into recipient course
3134
                $obj->params['description'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
3135
                    $obj->params['description'],
3136
                    $this->course->code,
3137
                    $this->course->destination_path,
3138
                    $this->course->backup_path,
3139
                    $this->course->info['path']
3140
                );
3141
3142
                $id_work = $obj->params['id'];
3143
                $obj->params['id'] = null;
3144
                $obj->params['c_id'] = $this->destination_course_info['real_id'];
3145
3146
                // re-create dir
3147
                // @todo check security against injection of dir in crafted course backup here!
3148
                $path = $obj->params['url'];
3149
                $path = '/'.str_replace('/','',substr($path,1));
3150
3151
                $workData = array();
3152
                switch ($this->file_option) {
3153
                    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...
3154
                        $workData = get_work_data_by_path(
3155
                            $path,
3156
                            $this->destination_course_info['real_id']
3157
                        );
3158
                        if (!empty($workData)) {
3159
                            continue;
3160
                        }
3161
                    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...
3162
                        // Creating folder.
3163
                        $workData = get_work_data_by_path(
3164
                            $path,
3165
                            $this->destination_course_info['real_id']
3166
                        );
3167
                    case FILE_RENAME:
3168
                        $obj->params['new_dir'] = $obj->params['title'];
3169
3170
                        if (!empty($this->course_origin_id)) {
3171
                            $sql = 'SELECT * FROM ' . $table_work_assignment . '
3172
                                    WHERE
3173
                                        c_id = ' . $this->course_origin_id . ' AND
3174
                                        publication_id = ' . $id_work;
3175
3176
                            $result = Database::query($sql);
3177
                            $cant = Database::num_rows($result);
3178
                            if ($cant > 0) {
3179
                                $row = Database::fetch_assoc($result);
3180
                            }
3181
3182
                            //$obj->params['qualification'] = empty($row['enable_qualification']) ? true : false;
3183
                            $obj->params['enableExpiryDate'] = $row['expires_on'] == '0000-00-00 00:00:00' ? false : true;
3184
                            $obj->params['enableEndDate'] = $row['ends_on'] == '0000-00-00 00:00:00' ? false : true;
3185
                            $obj->params['expires_on'] = $row['expires_on'];
3186
                            $obj->params['ends_on'] = $row['ends_on'];
3187
                            $obj->params['enable_qualification'] = $row['enable_qualification'];
3188
                            $obj->params['add_to_calendar'] = !empty($row['add_to_calendar']) ? 1 : 0;
3189
3190
                            if (empty($workData)) {
3191
                                addDir(
3192
                                    $obj->params,
3193
                                    api_get_user_id(),
3194
                                    $this->destination_course_info,
3195
                                    0,
3196
                                    $sessionId
3197
                                );
3198
                            } else {
3199
                                $workId = $workData['id'];
3200
                                updateWork(
3201
                                    $workId,
3202
                                    $obj->params,
3203
                                    $this->destination_course_info,
3204
                                    $sessionId
3205
                                );
3206
                                updatePublicationAssignment(
3207
                                    $workId,
3208
                                    $obj->params,
3209
                                    $this->destination_course_info,
3210
                                    0
3211
                                );
3212
                            }
3213
                        }
3214
                        break;
3215
                }
3216
            }
3217
        }
3218
    }
3219
3220
    /**
3221
     * Restore Works
3222
     * @param int $sessionId
3223
     */
3224
    public function restore_gradebook($sessionId = 0)
3225
    {
3226
        if ($this->course->has_resources(RESOURCE_GRADEBOOK)) {
0 ignored issues
show
Bug introduced by
The method has_resources cannot be called on $this->course (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
3227
            $resources = $this->course->resources;
3228
            /**
3229
             * @var GradeBookBackup $obj
3230
             */
3231
            foreach ($resources[RESOURCE_GRADEBOOK] as $id => $obj) {
3232
                if (!empty($obj->categories)) {
3233
                    $categoryIdList = [];
3234
                    /** @var Category $cat */
3235
                    foreach ($obj->categories as $cat) {
3236
                        $cat->set_course_code($this->destination_course_info['code']);
3237
                        $cat->set_session_id($sessionId);
3238
3239
                        $parentId = $cat->get_parent_id();
3240
                        if (!empty($parentId)) {
3241
                            if (isset($categoryIdList[$parentId])) {
3242
                                $cat->set_parent_id($categoryIdList[$parentId]);
3243
                            }
3244
                        }
3245
                        $oldId = $cat->get_id();
3246
                        $categoryId = $cat->add();
3247
                        $categoryIdList[$oldId] = $categoryId;
3248
                    }
3249
                }
3250
            }
3251
        }
3252
    }
3253
3254
    /**
3255
     * @param string $str
3256
     * @return string
3257
     */
3258
    public function DBUTF8($str)
3259
    {
3260
		if (UTF8_CONVERT) {
3261
            $str = utf8_encode($str);
3262
        }
3263
		return $str;
3264
	}
3265
3266
    /**
3267
     * @param string $str
3268
     * @return string
3269
     */
3270
    public function DBUTF8escapestring($str)
3271
    {
3272
        if (UTF8_CONVERT) {
3273
            $str = utf8_encode($str);
3274
        }
3275
		return Database::escape_string($str);
3276
	}
3277
3278
    /**
3279
     * @param array $array
3280
     * @return mixed
3281
     */
3282
    public function DBUTF8_array($array)
3283
    {
3284
        if (UTF8_CONVERT) {
3285
            foreach ($array as &$item)  {
3286
                $item = utf8_encode($item);
3287
            }
3288
            return $array;
3289
        } else {
3290
            return $array;
3291
        }
3292
    }
3293
3294
    /**
3295
     * Check if user exist otherwise use current user
3296
     * @param int $userId
3297
     * @param bool $returnNull
3298
     *
3299
     * @return int
3300
     */
3301
    private function checkUserId($userId, $returnNull = false) {
3302
3303
        if (!empty($userId)) {
3304
            $userInfo = api_get_user_info($userId);
3305
            if (empty($userInfo)) {
3306
                return api_get_user_id();
3307
            }
3308
        }
3309
3310
        if ($returnNull) {
3311
            return null;
3312
        }
3313
3314
        return $userId;
3315
    }
3316
}
3317