Passed
Push — 1.10.x ( 9111c6...a48a20 )
by
unknown
49:11
created

CourseRestorer::restore_course_descriptions()   C

Complexity

Conditions 8
Paths 26

Size

Total Lines 43
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 43
rs 5.3846
cc 8
eloc 29
nc 26
nop 1
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
1540
                $session_id = intval($session_id);
1541
                $params['session_id'] = $session_id;
1542
                $params['c_id'] = $this->destination_course_id;
1543
                $params['description_type'] = self::DBUTF8($descriptionType);
1544
                $params['title'] = self::DBUTF8($title);
1545
                $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...
1546
1547
                $id = Database::insert($table, $params);
1548
                if ($id) {
1549
                    $sql = "UPDATE $table SET id = iid WHERE iid = $id";
1550
                    Database::query($sql);
1551
1552
                    if (!isset($this->course->resources[RESOURCE_COURSEDESCRIPTION][$id])) {
1553
                        $this->course->resources[RESOURCE_COURSEDESCRIPTION][$id] = new stdClass();
1554
                    }
1555
                    $this->course->resources[RESOURCE_COURSEDESCRIPTION][$id]->destination_id = $id;
1556
                }
1557
			}
1558
		}
1559
	}
1560
1561
	/**
1562
	 * Restore announcements
1563
	 */
1564 View Code Duplication
    public function restore_announcements($sessionId = 0)
1565
    {
1566
		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...
1567
            $sessionId = intval($sessionId);
1568
			$table = Database :: get_course_table(TABLE_ANNOUNCEMENT);
1569
			$resources = $this->course->resources;
1570
			foreach ($resources[RESOURCE_ANNOUNCEMENT] as $id => $announcement) {
1571
1572
				// check resources inside html from ckeditor tool and copy correct urls into recipient course
1573
                $announcement->content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1574
                    $announcement->content,
1575
                    $this->course->code,
1576
                    $this->course->destination_path,
1577
                    $this->course->backup_path,
1578
                    $this->course->info['path']
1579
                );
1580
1581
                $params = [
1582
                    'c_id' => $this->destination_course_id,
1583
                    'title' =>  self::DBUTF8($announcement->title),
1584
                    '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...
1585
                    'end_date' => $announcement->date,
1586
                    'display_order' => $announcement->display_order,
1587
                    'email_sent' => $announcement->email_sent,
1588
                    'session_id' => $sessionId,
1589
                ];
1590
1591
				$new_announcement_id = Database::insert($table, $params);
1592
1593
                if ($new_announcement_id) {
1594
                    $sql = "UPDATE $table SET id = iid WHERE iid = $new_announcement_id";
1595
                    Database::query($sql);
1596
1597
                    if (!isset($this->course->resources[RESOURCE_ANNOUNCEMENT][$id])) {
1598
                        $this->course->resources[RESOURCE_ANNOUNCEMENT][$id] = new stdClass();
1599
                    }
1600
                    $this->course->resources[RESOURCE_ANNOUNCEMENT][$id]->destination_id = $new_announcement_id;
1601
                }
1602
1603
				$origin_path = $this->course->backup_path.'/upload/announcements/';
1604
				$destination_path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/upload/announcements/';
1605
1606
				// Copy announcement attachment file
1607
				if (!empty($this->course->orig)) {
1608
1609
					$table_attachment = Database::get_course_table(TABLE_ANNOUNCEMENT_ATTACHMENT);
1610
					$sql = 'SELECT path, comment, size, filename
1611
					        FROM '.$table_attachment.'
1612
					        WHERE
1613
					            c_id = '.$this->destination_course_id.' AND
1614
					            announcement_id = '.$id;
1615
					$attachment_event = Database::query($sql);
1616
					$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...
1617
1618
					if (file_exists($origin_path.$attachment_event->path) &&
1619
                        !is_dir($origin_path.$attachment_event->path)
1620
                    ) {
1621
						$new_filename = uniqid(''); //ass seen in the add_agenda_attachment_file() function in agenda.inc.php
1622
                        $copy_result = copy(
1623
                            $origin_path.$attachment_event->path,
1624
                            $destination_path.$new_filename
1625
                        );
1626
1627
						if ($copy_result) {
1628
							$table_attachment = Database :: get_course_table(TABLE_ANNOUNCEMENT_ATTACHMENT);
1629
1630
                            $params = [
1631
                                'c_id' => $this->destination_course_id,
1632
                                'path' => self::DBUTF8($new_filename),
1633
                                'comment' => self::DBUTF8($attachment_event->comment),
1634
                                'size' => $attachment_event->size,
1635
                                'filename' => $attachment_event->filename,
1636
                                'announcement_id' => $new_announcement_id,
1637
                            ];
1638
1639
                            $attachmentId = Database::insert($table_attachment, $params);
1640
1641
                            if ($attachmentId) {
1642
                                $sql = "UPDATE $table_attachment SET id = iid WHERE iid = $attachmentId";
1643
                                Database::query($sql);
1644
                            }
1645
						}
1646
					}
1647
				} else {
1648
					// get the info of the file
1649
					if (!empty($announcement->attachment_path) &&
1650
                        is_file($origin_path.$announcement->attachment_path) &&
1651
                        is_readable($origin_path.$announcement->attachment_path)
1652
                    ) {
1653
						$new_filename = uniqid(''); //ass seen in the add_agenda_attachment_file() function in agenda.inc.php
1654
						$copy_result = copy($origin_path.$announcement->attachment_path, $destination_path.$new_filename);
1655
1656
						if ($copy_result) {
1657
							$table_attachment = Database :: get_course_table(TABLE_ANNOUNCEMENT_ATTACHMENT);
1658
							/*$sql = "INSERT INTO ".$table_attachment." SET
1659
							        c_id = ".$this->destination_course_id." ,
1660
							        path = '".self::DBUTF8escapestring($new_filename)."',
1661
							        comment = '".self::DBUTF8escapestring($announcement->attachment_comment)."',
1662
							        size = '".$announcement->attachment_size."', filename = '".$announcement->attachment_filename."',
1663
							        announcement_id = '".$new_announcement_id."' ";
1664
							Database::query($sql);*/
1665
1666
                            $params = [
1667
                                'c_id' => $this->destination_course_id,
1668
                                'path' => self::DBUTF8($new_filename),
1669
                                'comment' => self::DBUTF8($announcement->attachment_comment),
1670
                                'size' => $announcement->attachment_size,
1671
                                'filename' => $announcement->attachment_filename,
1672
                                'announcement_id' => $new_announcement_id,
1673
                            ];
1674
1675
                            $attachmentId = Database::insert($table_attachment, $params);
1676
1677
                            if ($attachmentId) {
1678
                                $sql = "UPDATE $table_attachment SET id = iid WHERE iid = $attachmentId";
1679
                                Database::query($sql);
1680
                            }
1681
						}
1682
					}
1683
				}
1684
			}
1685
		}
1686
	}
1687
1688
    /**
1689
     * Restore Quiz
1690
     * @param int $session_id
1691
     * @param bool $respect_base_content
1692
     */
1693
    public function restore_quizzes(
1694
        $session_id = 0,
1695
        $respect_base_content = false
1696
    ) {
1697
		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...
1698
			$table_qui = Database :: get_course_table(TABLE_QUIZ_TEST);
1699
			$table_rel = Database :: get_course_table(TABLE_QUIZ_TEST_QUESTION);
1700
			$table_doc = Database :: get_course_table(TABLE_DOCUMENT);
1701
			$resources = $this->course->resources;
1702
1703
			foreach ($resources[RESOURCE_QUIZ] as $id => $quiz) {
1704
1705
                if (isset($quiz->obj)) {
1706
                    //For new imports
1707
                    $quiz = $quiz->obj;
1708
                } else {
1709
                    //For backward compatibility
1710
                    $quiz->obj = $quiz;
1711
                }
1712
1713
				$doc = '';
1714
                if (!empty($quiz->sound)) {
1715
                    if (isset($this->course->resources[RESOURCE_DOCUMENT][$quiz->sound]) &&
1716
                        $this->course->resources[RESOURCE_DOCUMENT][$quiz->sound]->is_restored()) {
1717
                        $sql = "SELECT path FROM " . $table_doc . "
1718
                                WHERE
1719
                                    c_id = " . $this->destination_course_id . "  AND
1720
                                    id = " . $resources[RESOURCE_DOCUMENT][$quiz->sound]->destination_id;
1721
						$doc = Database::query($sql);
1722
						$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...
1723
						$doc = str_replace('/audio/', '', $doc->path);
1724
					}
1725
				}
1726
1727
				if ($id != -1) {
1728
					// check resources inside html from ckeditor tool and copy correct urls into recipient course
1729
                    $quiz->description = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1730
                        $quiz->description,
1731
                        $this->course->code,
1732
                        $this->course->destination_path,
1733
                        $this->course->backup_path,
1734
                        $this->course->info['path']
1735
                    );
1736
1737
					global $_custom;
1738
					if (isset($_custom['exercises_clean_dates_when_restoring']) &&
1739
                        $_custom['exercises_clean_dates_when_restoring']
1740
                    ) {
1741
						$quiz->start_time = null;
1742
						$quiz->end_time   = null;
1743
					}
1744
1745
                    $params = array(
1746
                        'c_id' => $this->destination_course_id,
1747
                        'title' => self::DBUTF8($quiz->title),
1748
                        '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...
1749
                        'type' => isset($quiz->quiz_type) ? $quiz->quiz_type : $quiz->type,
1750
                        'random' => $quiz->random,
1751
                        'active' => $quiz->active,
1752
                        'sound' => self::DBUTF8($doc),
1753
                        'max_attempt' => (int)$quiz->max_attempt,
1754
                        'results_disabled' => (int)$quiz->results_disabled,
1755
                        'access_condition' => $quiz->access_condition,
1756
                        'start_time' => $quiz->start_time,
1757
                        'pass_percentage' => $quiz->pass_percentage,
1758
                        'end_time' => $quiz->end_time,
1759
                        'feedback_type' => (int)$quiz->feedback_type,
1760
                        'random_answers' => (int)$quiz->random_answers,
1761
                        'random_by_category' => $quiz->random_by_category,
1762
                        'review_answers' => $quiz->review_answers,
1763
                        'propagate_neg' => $quiz->propagate_neg,
1764
                        'text_when_finished' => $quiz->text_when_finished,
1765
                        'expired_time' => (int)$quiz->expired_time,
1766
                    );
1767
1768 View Code Duplication
                    if ($respect_base_content) {
1769
                        $my_session_id = $quiz->session_id;
1770
                        if (!empty($quiz->session_id)) {
1771
                            $my_session_id = $session_id;
1772
                        }
1773
                        $params['session_id'] = $my_session_id;
1774
                    } else {
1775
        				if (!empty($session_id)) {
1776
        					$session_id = intval($session_id);
1777
                            $params['session_id'] = $session_id;
1778
    				    }
1779
                    }
1780
                    $new_id = Database::insert($table_qui, $params);
1781
1782
                    if ($new_id) {
1783
                        $sql = "UPDATE $table_qui SET id = iid WHERE iid = $new_id";
1784
                        Database::query($sql);
1785
                    }
1786
1787
				} else {
1788
					// $id = -1 identifies the fictionary test for collecting
1789
					// orphan questions. We do not store it in the database.
1790
					$new_id = -1;
1791
				}
1792
1793
				$this->course->resources[RESOURCE_QUIZ][$id]->destination_id = $new_id;
1794
1795
				$order = 0;
1796
                if (!empty($quiz->question_ids)) {
1797
                    foreach ($quiz->question_ids as $index => $question_id) {
1798
                        $qid = $this->restore_quiz_question($question_id);
1799
                        $question_order = $quiz->question_orders[$index] ? $quiz->question_orders[$index] : ++$order;
1800
                        $sql = "INSERT IGNORE INTO $table_rel SET
1801
                                c_id = " . $this->destination_course_id . ",
1802
                                question_id = " . $qid . ",
1803
                                exercice_id = " . $new_id . ",
1804
                                question_order = " . $question_order;
1805
                        Database::query($sql);
1806
                    }
1807
                }
1808
			}
1809
		}
1810
	}
1811
1812
	/**
1813
	 * Restore quiz-questions
1814
     * @params int question id
1815
	 */
1816
    public function restore_quiz_question($id)
1817
    {
1818
		$resources = $this->course->resources;
1819
        $question = isset($resources[RESOURCE_QUIZQUESTION][$id]) ? $resources[RESOURCE_QUIZQUESTION][$id] : null;
1820
1821
		$new_id = 0;
1822
1823
		if (is_object($question)) {
1824
			if ($question->is_restored()) {
1825
				return $question->destination_id;
1826
			}
1827
			$table_que = Database::get_course_table(TABLE_QUIZ_QUESTION);
1828
			$table_ans = Database::get_course_table(TABLE_QUIZ_ANSWER);
1829
            $table_options = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION);
1830
1831
			// check resources inside html from ckeditor tool and copy correct urls into recipient course
1832
            $question->description = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1833
                $question->description,
1834
                $this->course->code,
1835
                $this->course->destination_path,
1836
                $this->course->backup_path,
1837
                $this->course->info['path']
1838
            );
1839
1840
            $params = [
1841
                'c_id' => $this->destination_course_id,
1842
                'question' => self::DBUTF8($question->question),
1843
                '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...
1844
                'ponderation' => self::DBUTF8($question->ponderation),
1845
                'position' => self::DBUTF8($question->position),
1846
                'type' => self::DBUTF8($question->quiz_type),
1847
                'picture' => self::DBUTF8($question->picture),
1848
                'level' => self::DBUTF8($question->level),
1849
                'extra' => self::DBUTF8($question->extra),
1850
            ];
1851
1852
			$new_id = Database::insert($table_que, $params);
1853
1854
            if ($new_id) {
1855
1856
                $sql = "UPDATE $table_que SET id = iid WHERE iid = $new_id";
1857
                Database::query($sql);
1858
1859
                if (!empty($question->picture)) {
1860
                    $question_temp = Question::read(
1861
                        $new_id,
1862
                        $this->destination_course_info['real_id']
1863
                    );
1864
1865
                    $documentPath = api_get_path(SYS_COURSE_PATH).$this->destination_course_info['path'].'/document';
1866
                    // picture path
1867
                    $picturePath = $documentPath.'/images';
1868
1869
                    $old_picture = api_get_path(SYS_COURSE_PATH).$this->course->info['path'].'/document/images/'.$question->picture;
1870
                    if (file_exists($old_picture)) {
1871
                        $picture_name = 'quiz-'.$new_id.'.jpg';
1872
1873
                        $result = $question_temp->uploadPicture($old_picture, $picture_name, $picturePath);
1874
                        if ($result) {
1875
                            $sql = "UPDATE $table_que SET
1876
                                        picture = '$picture_name'
1877
                                    WHERE
1878
                                        c_id = " . $this->destination_course_id . " AND
1879
                                        id = $new_id ";
1880
                            Database::query($sql);
1881
                        }
1882
                    }
1883
                }
1884
            }
1885
            if (in_array($question->quiz_type, [MATCHING, MATCHING_DRAGGABLE])) {
1886
                $temp = array();
1887
                foreach ($question->answers as $index => $answer) {
1888
                    $temp[$answer['position']] = $answer;
1889
                }
1890
1891
                foreach ($temp as $index => $answer) {
1892
                    //id = '".$index."',
1893
					$params = [
1894
                        'c_id' => $this->destination_course_id,
1895
                        'question_id' => $new_id,
1896
                        'answer' => self::DBUTF8($answer['answer']),
1897
                        'correct' => $answer['correct'],
1898
                        'comment' => self::DBUTF8($answer['comment']),
1899
                        'ponderation' => $answer['ponderation'],
1900
                        'position' => $answer['position'],
1901
                        'hotspot_coordinates' => $answer['hotspot_coordinates'],
1902
                        'hotspot_type' => $answer['hotspot_type'],
1903
                    ];
1904
                    $answerId = Database::insert($table_ans, $params);
1905
1906
                    if ($answerId) {
1907
                        $sql = "UPDATE $table_ans SET id = iid, id_auto = iid WHERE iid = $answerId";
1908
                        Database::query($sql);
1909
                    }
1910
				}
1911
			} else {
1912
                $correct_answers = array();
1913
				foreach ($question->answers as $index => $answer) {
1914
1915
					// check resources inside html from ckeditor tool and copy correct urls into recipient course
1916
                    $answer['answer'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1917
                        $answer['answer'],
1918
                        $this->course->code,
1919
                        $this->course->destination_path,
1920
                        $this->course->backup_path,
1921
                        $this->course->info['path']
1922
                    );
1923
1924
                    $answer['comment'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
1925
                        $answer['comment'],
1926
                        $this->course->code,
1927
                        $this->course->destination_path,
1928
                        $this->course->backup_path,
1929
                        $this->course->info['path']
1930
                    );
1931
1932
                    //                     id = '". ($index + 1)."',
1933
1934
                    $params = [
1935
                        'c_id' => $this->destination_course_id,
1936
                        'question_id' => $new_id,
1937
                        'answer' => self::DBUTF8($answer['answer']),
1938
                        'correct' => $answer['correct'],
1939
                        '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...
1940
                        'ponderation' => $answer['ponderation'],
1941
                        'position' => $answer['position'],
1942
                        'hotspot_coordinates' => $answer['hotspot_coordinates'],
1943
                        'hotspot_type' => $answer['hotspot_type'],
1944
                    ];
1945
1946
                    $answerId = Database::insert($table_ans, $params);
1947
1948
                    if ($answerId) {
1949
                        $sql = "UPDATE $table_ans SET id = iid, id_auto = iid WHERE iid = $answerId";
1950
                        Database::query($sql);
1951
                    }
1952
1953
                    $correct_answers[$answerId] = $answer['correct'];
1954
				}
1955
			}
1956
1957
            //Current course id
1958
            $course_id = api_get_course_int_id();
1959
1960
            //Moving quiz_question_options
1961
            if ($question->quiz_type == MULTIPLE_ANSWER_TRUE_FALSE) {
1962
                $question_option_list = Question::readQuestionOption($id, $course_id);
1963
1964
                //Question copied from the current platform
1965
                if ($question_option_list) {
1966
                    $old_option_ids = array();
1967
                    foreach ($question_option_list as $item) {
1968
                        $old_id = $item['id'];
1969
                        unset($item['id']);
1970
                        if (isset($item['iid'])) {
1971
                            unset($item['iid']);
1972
                        }
1973
                        $item['question_id'] = $new_id;
1974
                        $item['c_id'] = $this->destination_course_id;
1975
                        $question_option_id = Database::insert($table_options, $item);
1976
                        if ($question_option_id) {
1977
                            $old_option_ids[$old_id] = $question_option_id;
1978
                            $sql = "UPDATE $table_options SET id = iid WHERE iid = $question_option_id";
1979
                            Database::query($sql);
1980
                        }
1981
1982
                    }
1983
                    if ($old_option_ids) {
1984
                        $new_answers = Database::select(
1985
                            'iid, correct',
1986
                            $table_ans,
1987
                            array(
1988
                                'WHERE' => array(
1989
                                    'question_id = ? AND c_id = ? ' => array(
1990
                                        $new_id,
1991
                                        $this->destination_course_id,
1992
                                    ),
1993
                                ),
1994
                            )
1995
                        );
1996
1997 View Code Duplication
                        foreach ($new_answers as $answer_item) {
1998
                            $params = array();
1999
                            $params['correct'] = $old_option_ids[$answer_item['correct']];
2000
                            Database::update(
2001
                                $table_ans,
2002
                                $params,
2003
                                array(
2004
                                    'iid = ? AND c_id = ? AND question_id = ? ' => array(
2005
                                        $answer_item['iid'],
2006
                                        $this->destination_course_id,
2007
                                        $new_id,
2008
                                    ),
2009
                                ),
2010
                                false
2011
                            );
2012
                        }
2013
                    }
2014
                } else {
2015
                    $new_options = array();
2016
                    if (isset($question->question_options)) {
2017
                        foreach ($question->question_options as $obj) {
2018
                            $item = array();
2019
                            $item['question_id'] = $new_id;
2020
                            $item['c_id'] = $this->destination_course_id;
2021
                            $item['name'] = $obj->obj->name;
2022
                            $item['position'] = $obj->obj->position;
2023
2024
                            $question_option_id = Database::insert($table_options, $item);
2025
2026
                            if ($question_option_id) {
2027
                                $new_options[$obj->obj->id] = $question_option_id;
2028
                                $sql = "UPDATE $table_options SET id = iid WHERE iid = $question_option_id";
2029
                                Database::query($sql);
2030
                            }
2031
                        }
2032
2033 View Code Duplication
                        foreach($correct_answers as $answer_id => $correct_answer) {
2034
                            $params = array();
2035
                            $params['correct'] = $new_options[$correct_answer];
2036
                            Database::update(
2037
                                $table_ans,
2038
                                $params,
2039
                                array(
2040
                                    'id = ? AND c_id = ? AND question_id = ? ' => array(
2041
                                        $answer_id,
2042
                                        $this->destination_course_id,
2043
                                        $new_id,
2044
                                    ),
2045
                                ),
2046
                                false
2047
                            );
2048
                        }
2049
                    }
2050
                }
2051
            }
2052
			$this->course->resources[RESOURCE_QUIZQUESTION][$id]->destination_id = $new_id;
2053
		}
2054
		return $new_id;
2055
	}
2056
2057
	/**
2058
     * @todo : add session id when used for session
2059
     */
2060
    public function restore_test_category($session_id, $respect_base_content, $destination_course_code)
2061
    {
2062
        $course_id = api_get_course_int_id();
2063
        // Let's restore the categories
2064
        $tab_test_category_id_old_new = array(); // used to build the quiz_question_rel_category table
2065
        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...
2066
            $resources = $this->course->resources;
2067
            foreach ($resources[RESOURCE_TEST_CATEGORY] as $id => $CourseCopyTestcategory ) {
2068
                $tab_test_category_id_old_new[$CourseCopyTestcategory->source_id] = $id;
2069
                // check if this test_category already exist in the destination BDD
2070
                // do not Database::escape_string $title and $description, it will be done later
2071
                $title = $CourseCopyTestcategory->title;
2072
                $description = $CourseCopyTestcategory->description;
2073
2074
                if (TestCategory::category_exists_with_title($title)) {
2075
                    switch ($this->file_option) {
2076
                        case FILE_SKIP:
2077
                            //Do nothing
2078
                            break;
2079
                        case FILE_RENAME:
2080
                            $new_title = $title."_";
2081
                            while (TestCategory::category_exists_with_title(
2082
                                $new_title
2083
                            )) {
2084
                                $new_title .= "_";
2085
                            }
2086
                            $test_category = new TestCategory(0, $new_title, $description);
2087
                            $new_id = $test_category->addCategoryInBDD();
2088
                            $tab_test_category_id_old_new[$CourseCopyTestcategory->source_id] = $new_id;
2089
                            break;
2090
                        case FILE_OVERWRITE:
2091
                            $id = TestCategory::get_category_id_for_title($title);
2092
                            $my_cat = new TestCategory($id);
2093
                            $my_cat->name = $title;
2094
                            $my_cat->modifyCategory();
2095
                            $tab_test_category_id_old_new[$CourseCopyTestcategory->source_id] = $id;
2096
                            break;
2097
                    }
2098
                } else {
2099
                    // create a new test_category
2100
                    $test_category = new TestCategory(0, $title, $description);
2101
                    $new_id = $test_category->addCategoryInBDD();
2102
                    $tab_test_category_id_old_new[$CourseCopyTestcategory->source_id] = $new_id;
2103
                }
2104
                $this->course->resources[RESOURCE_TEST_CATEGORY][$id]->destination_id = $tab_test_category_id_old_new[$CourseCopyTestcategory->source_id];
2105
            }
2106
        }
2107
        // lets check if quizzes-question are restored too, to redo the link between test_category and quizzes question for questions restored
2108
        // we can use the source_id field
2109
        // question source_id => category source_id
2110
        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...
2111
            // check the category number of each question restored
2112
            if (!empty($resources[RESOURCE_QUIZQUESTION])) {
2113
                foreach ($resources[RESOURCE_QUIZQUESTION] as $id => $CourseCopyQuestion) {
2114
                    $new_quiz_question_id = $resources[RESOURCE_QUIZQUESTION][$id]->destination_id;
2115
                    $question_category = $CourseCopyQuestion->question_category;
2116
                    if ($question_category > 0) {
2117
                        TestCategory::add_category_for_question_id(
2118
                            $tab_test_category_id_old_new[$question_category],
2119
                            $new_quiz_question_id,
2120
                            $course_id
2121
                        );
2122
                    }
2123
                }
2124
            }
2125
        }
2126
    }
2127
2128
    /**
2129
     * Restore surveys
2130
     * @param int $sessionId Optional. The session id
2131
     */
2132
    public function restore_surveys($sessionId = 0)
2133
    {
2134
        $sessionId = intval($sessionId);
2135
2136
        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...
2137
			$table_sur = Database :: get_course_table(TABLE_SURVEY);
2138
			$table_que = Database :: get_course_table(TABLE_SURVEY_QUESTION);
2139
			$table_ans = Database :: get_course_table(TABLE_SURVEY_QUESTION_OPTION);
2140
			$resources = $this->course->resources;
2141
			foreach ($resources[RESOURCE_SURVEY] as $id => $survey) {
2142
2143
				$sql = 'SELECT survey_id FROM '.$table_sur.'
2144
                        WHERE
2145
                            c_id = '.$this->destination_course_id.' AND
2146
                            code = "'.self::DBUTF8escapestring($survey->code).'" AND
2147
                            lang = "'.self::DBUTF8escapestring($survey->lang).'" ';
2148
2149
				$result_check = Database::query($sql);
2150
2151
				// check resources inside html from ckeditor tool and copy correct urls into recipient course
2152
                $survey->title = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2153
                    $survey->title,
2154
                    $this->course->code,
2155
                    $this->course->destination_path,
2156
                    $this->course->backup_path,
2157
                    $this->course->info['path']
2158
                );
2159
2160
                $survey->subtitle = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2161
                    $survey->subtitle,
2162
                    $this->course->code,
2163
                    $this->course->destination_path,
2164
                    $this->course->backup_path,
2165
                    $this->course->info['path']
2166
                );
2167
2168
                $survey->intro = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2169
                    $survey->intro,
2170
                    $this->course->code,
2171
                    $this->course->destination_path,
2172
                    $this->course->backup_path,
2173
                    $this->course->info['path']
2174
                );
2175
2176
                $survey->surveythanks = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2177
                    $survey->surveythanks,
2178
                    $this->course->code,
2179
                    $this->course->destination_path,
2180
                    $this->course->backup_path,
2181
                    $this->course->info['path']
2182
                );
2183
2184
                $params = [
2185
                    'c_id' => $this->destination_course_id,
2186
                    'code' => self::DBUTF8($survey->code),
2187
                    '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...
2188
                    '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...
2189
                    'author' => self::DBUTF8($survey->author),
2190
                    'lang' => self::DBUTF8($survey->lang),
2191
                    'avail_from' => self::DBUTF8($survey->avail_from),
2192
                    'avail_till' => self::DBUTF8($survey->avail_till),
2193
                    'is_shared' => self::DBUTF8($survey->is_shared),
2194
                    'template' => self::DBUTF8($survey->template),
2195
                    '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...
2196
                    '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...
2197
                    'creation_date' => self::DBUTF8($survey->creation_date),
2198
                    'invited' => '0',
2199
                    'answered' => '0',
2200
                    'invite_mail' => self::DBUTF8($survey->invite_mail),
2201
                    'reminder_mail' => self::DBUTF8($survey->reminder_mail),
2202
                    'session_id' => $sessionId,
2203
                ];
2204
2205
				//An existing survey exists with the same code and the same language
2206
				if (Database::num_rows($result_check) == 1) {
2207
					switch ($this->file_option) {
2208
						case FILE_SKIP:
2209
							//Do nothing
2210
							break;
2211
						case FILE_RENAME:
2212
							$survey_code = $survey->code.'_';
2213
							$i=1;
2214
							$temp_survey_code = $survey_code.$i;
2215
							while (!$this->is_survey_code_available($temp_survey_code)) {
2216
								$temp_survey_code = $survey_code.++$i;
2217
							}
2218
							$survey_code = $temp_survey_code;
2219
2220
                            $params['code'] = $survey_code;
2221
                            $new_id = Database::insert($table_sur, $params);
2222
                            if ($new_id) {
2223
                                $sql = "UPDATE $table_sur SET survey_id = iid WHERE iid = $new_id";
2224
                                Database::query($sql);
2225
2226
                                $this->course->resources[RESOURCE_SURVEY][$id]->destination_id = $new_id;
2227
                                foreach ($survey->question_ids as $index => $question_id) {
2228
                                    $qid = $this->restore_survey_question($question_id, $new_id);
2229
                                    $sql = "UPDATE ".$table_que." SET survey_id = ".$new_id."
2230
								            WHERE c_id = ".$this->destination_course_id." AND question_id = $qid";
2231
                                    Database::query($sql);
2232
                                    $sql = "UPDATE ".$table_ans." SET survey_id = ".$new_id."
2233
								            WHERE  c_id = ".$this->destination_course_id." AND  question_id = $qid";
2234
                                    Database::query($sql);
2235
                                }
2236
                            }
2237
							break;
2238
						case FILE_OVERWRITE:
2239
							// Delete the existing survey with the same code and language and import the one of the source course
2240
							// getting the information of the survey (used for when the survey is shared)
2241
2242
							$sql = "SELECT * FROM $table_sur
2243
							        WHERE
2244
							            c_id = ".$this->destination_course_id." AND
2245
							            survey_id='".self::DBUTF8escapestring(Database::result($result_check,0,0))."'";
2246
							$result = Database::query($sql);
2247
							$survey_data = Database::fetch_array($result,'ASSOC');
2248
2249
							// if the survey is shared => also delete the shared content
2250 View Code Duplication
							if (isset($survey_data['survey_share']) && is_numeric($survey_data['survey_share'])) {
2251
                                SurveyManager::delete_survey($survey_data['survey_share'], true,$this->destination_course_id);
2252
							}
2253
							SurveyManager :: delete_survey($survey_data['survey_id'],false,$this->destination_course_id);
2254
2255
							// Insert the new source survey
2256
                            $new_id = Database::insert($table_sur, $params);
2257
2258 View Code Duplication
                            if ($new_id) {
2259
                                $sql = "UPDATE $table_sur SET survey_id = iid WHERE iid = $new_id";
2260
                                Database::query($sql);
2261
2262
                                $this->course->resources[RESOURCE_SURVEY][$id]->destination_id = $new_id;
2263
                                foreach ($survey->question_ids as $index => $question_id) {
2264
                                    $qid = $this->restore_survey_question(
2265
                                        $question_id,
2266
                                        $new_id
2267
                                    );
2268
                                    $sql = "UPDATE $table_que SET survey_id = $new_id
2269
                                            WHERE c_id = ".$this->destination_course_id." AND question_id = $qid";
2270
                                    Database::query($sql);
2271
                                    $sql = "UPDATE $table_ans SET survey_id = $new_id
2272
                                            WHERE c_id = ".$this->destination_course_id." AND question_id = $qid";
2273
                                    Database::query($sql);
2274
                                }
2275
                            }
2276
							break;
2277
						default:
2278
							break;
2279
					}
2280
				} else {
2281
                    // No existing survey with the same language and the same code, we just copy the survey
2282
                    $new_id = Database::insert($table_sur, $params);
2283
2284 View Code Duplication
                    if ($new_id) {
2285
                        $sql = "UPDATE $table_sur SET survey_id = iid WHERE iid = $new_id";
2286
                        Database::query($sql);
2287
2288
                        $this->course->resources[RESOURCE_SURVEY][$id]->destination_id = $new_id;
2289
                        foreach ($survey->question_ids as $index => $question_id) {
2290
                            $qid = $this->restore_survey_question(
2291
                                $question_id,
2292
                                $new_id
2293
                            );
2294
                            $sql = "UPDATE $table_que SET survey_id = $new_id
2295
                                    WHERE c_id = ".$this->destination_course_id." AND question_id = $qid";
2296
                            Database::query($sql);
2297
                            $sql = "UPDATE $table_ans SET survey_id = $new_id
2298
                                    WHERE c_id = ".$this->destination_course_id." AND question_id = $qid";
2299
                            Database::query($sql);
2300
                        }
2301
                    }
2302
				}
2303
			}
2304
		}
2305
	}
2306
2307
	/**
2308
	 * Check availability of a survey code
2309
	 */
2310 View Code Duplication
    public function is_survey_code_available($survey_code)
2311
    {
2312
		$table_sur = Database :: get_course_table(TABLE_SURVEY);
2313
		$sql = "SELECT * FROM $table_sur
2314
		        WHERE
2315
		            c_id = ".$this->destination_course_id." AND
2316
		            code='".self::DBUTF8escapestring($survey_code)."'";
2317
		$result = Database::query($sql);
2318
		if (Database::num_rows($result) > 0) return false; else return true;
2319
	}
2320
2321
	/**
2322
	 * Restore survey-questions
2323
	 */
2324
    public function restore_survey_question($id, $survey_id)
2325
    {
2326
		$resources = $this->course->resources;
2327
		$question = $resources[RESOURCE_SURVEYQUESTION][$id];
2328
2329
		$new_id=0;
2330
2331
		if (is_object($question)) {
2332
			if ($question->is_restored()) {
2333
				return $question->destination_id;
2334
			}
2335
			$table_que = Database :: get_course_table(TABLE_SURVEY_QUESTION);
2336
			$table_ans = Database :: get_course_table(TABLE_SURVEY_QUESTION_OPTION);
2337
2338
			// check resources inside html from ckeditor tool and copy correct urls into recipient course
2339
            $question->survey_question = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2340
                $question->survey_question,
2341
                $this->course->code,
2342
                $this->course->destination_path,
2343
                $this->course->backup_path,
2344
                $this->course->info['path']
2345
            );
2346
2347
            $params = [
2348
                'c_id' => $this->destination_course_id,
2349
                'survey_id' => self::DBUTF8($survey_id),
2350
                '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...
2351
                'survey_question_comment' => self::DBUTF8($question->survey_question_comment),
2352
                'type' => self::DBUTF8($question->survey_question_type),
2353
                'display' => self::DBUTF8($question->display),
2354
                'sort' => self::DBUTF8($question->sort),
2355
                'shared_question_id' => self::DBUTF8($question->shared_question_id),
2356
                'max_value' => self::DBUTF8($question->max_value),
2357
            ];
2358
2359
            $new_id = Database::insert($table_que, $params);
2360
            if ($new_id) {
2361
2362
                $sql = "UPDATE $table_que SET question_id = iid WHERE iid = $new_id";
2363
                Database::query($sql);
2364
2365
                foreach ($question->answers as $index => $answer) {
2366
2367
                    // check resources inside html from ckeditor tool and copy correct urls into recipient course
2368
                    $answer['option_text'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2369
                        $answer['option_text'],
2370
                        $this->course->code,
2371
                        $this->course->destination_path,
2372
                        $this->course->backup_path,
2373
                        $this->course->info['path']
2374
                    );
2375
2376
                    $params = [
2377
                        'c_id' => $this->destination_course_id,
2378
                        'question_id' => $new_id,
2379
                        '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...
2380
                        'sort' => $answer['sort'],
2381
                        'survey_id' => self::DBUTF8($survey_id),
2382
                    ];
2383
                    $answerId = Database::insert($table_ans, $params);
2384
                    if ($answerId) {
2385
                        $sql = "UPDATE $table_ans SET question_option_id = iid
2386
                                WHERE iid = $answerId";
2387
                        Database::query($sql);
2388
                    }
2389
                }
2390
                $this->course->resources[RESOURCE_SURVEYQUESTION][$id]->destination_id = $new_id;
2391
            }
2392
		}
2393
2394
		return $new_id;
2395
	}
2396
2397
    /**
2398
     * Restoring learning paths
2399
     * @param int $session_id
2400
     * @param bool|false $respect_base_content
2401
     */
2402
    public function restore_learnpaths($session_id = 0, $respect_base_content = false)
2403
    {
2404
        $session_id = intval($session_id);
2405
2406
		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...
2407
            $table_main = Database::get_course_table(TABLE_LP_MAIN);
2408
            $table_item = Database::get_course_table(TABLE_LP_ITEM);
2409
            $table_tool = Database::get_course_table(TABLE_TOOL_LIST);
2410
2411
			$resources = $this->course->resources;
2412
2413
			$origin_path = $this->course->backup_path.'/upload/learning_path/images/';
2414
			$destination_path = api_get_path(SYS_COURSE_PATH).$this->course->destination_path.'/upload/learning_path/images/';
2415
2416
			foreach ($resources[RESOURCE_LEARNPATH] as $id => $lp) {
2417
2418
				$condition_session = "";
2419 View Code Duplication
				if (!empty($session_id)) {
2420
                    if ($respect_base_content) {
2421
                        $my_session_id = $lp->session_id;
2422
                        if (!empty($lp->session_id)) {
2423
                            $my_session_id = $session_id;
2424
                        }
2425
                        $condition_session = $my_session_id;
2426
                    } else {
2427
                        $session_id = intval($session_id);
2428
                        $condition_session = $session_id;
2429
                    }
2430
				}
2431
2432
				// Adding the author's image
2433
				if (!empty($lp->preview_image)) {
2434
					$new_filename = uniqid('').substr($lp->preview_image,strlen($lp->preview_image)-7, strlen($lp->preview_image));
2435
					if (file_exists($origin_path.$lp->preview_image) && !is_dir($origin_path.$lp->preview_image)) {
2436
						$copy_result = copy($origin_path.$lp->preview_image, $destination_path.$new_filename);
2437
						//$copy_result = true;
2438
						if ($copy_result) {
2439
							$lp->preview_image = $new_filename;
2440
						} else {
2441
							$lp->preview_image ='';
2442
						}
2443
					}
2444
				}
2445
2446
                if ($this->add_text_in_items) {
2447
                    $lp->name = $lp->name.' '.get_lang('CopyLabelSuffix');
2448
                }
2449
2450
                if (isset($this->tool_copy_settings['learnpaths'])) {
2451
                    if (isset($this->tool_copy_settings['learnpaths']['reset_dates']) &&
2452
                        $this->tool_copy_settings['learnpaths']['reset_dates']
2453
                    ) {
2454
                        $lp->created_on     = api_get_utc_datetime();
2455
                        $lp->modified_on    = api_get_utc_datetime();
2456
                        $lp->publicated_on  = null;
2457
                    }
2458
                }
2459
2460
                $params = [
2461
                    'c_id' => $this->destination_course_id,
2462
                    'lp_type' => $lp->lp_type,
2463
                    'name' => self::DBUTF8($lp->name),
2464
                    'path' => self::DBUTF8($lp->path),
2465
                    'ref' => $lp->ref,
2466
                    'description' => self::DBUTF8($lp->description),
2467
                    'content_local' => self::DBUTF8($lp->content_local),
2468
                    'default_encoding' => self::DBUTF8($lp->default_encoding),
2469
                    'default_view_mod' => self::DBUTF8($lp->default_view_mod),
2470
                    'prevent_reinit' => self::DBUTF8($lp->prevent_reinit),
2471
                    'force_commit' => self::DBUTF8($lp->force_commit),
2472
                    'content_maker' => self::DBUTF8($lp->content_maker),
2473
                    'display_order' => self::DBUTF8($lp->display_order),
2474
                    'js_lib' => self::DBUTF8($lp->js_lib),
2475
                    'content_license' => self::DBUTF8($lp->content_license),
2476
                    'author' => self::DBUTF8($lp->author),
2477
                    'preview_image' => self::DBUTF8($lp->preview_image),
2478
                    'use_max_score' => self::DBUTF8($lp->use_max_score),
2479
                    'autolaunch' => self::DBUTF8(isset($lp->autolaunch) ? $lp->autolaunch : ''),
2480
                    'created_on' => self::DBUTF8($lp->created_on),
2481
                    'modified_on' => self::DBUTF8($lp->modified_on),
2482
                    'publicated_on' => empty($lp->publicated_on) ? api_get_utc_datetime() : self::DBUTF8($lp->publicated_on),
2483
                    'expired_on' => self::DBUTF8($lp->expired_on),
2484
                    'debug' => self::DBUTF8($lp->debug),
2485
                ];
2486
2487
                if (!empty($condition_session)) {
2488
                    $params['session_id'] = $condition_session;
2489
                }
2490
2491
				$new_lp_id = Database::insert($table_main, $params);
2492
2493
                if ($new_lp_id) {
2494
2495
                    $sql = "UPDATE $table_main SET id = iid WHERE iid = $new_lp_id";
2496
                    Database::query($sql);
2497
2498
                    if ($lp->visibility) {
2499
                        $params = [
2500
                            'c_id' => $this->destination_course_id,
2501
                            'name' => self::DBUTF8($lp->name),
2502
                            'link' => 'newscorm/lp_controller.php?action=view&lp_id=$new_lp_id&id_session='.$session_id,
2503
                            'image' => 'scormbuilder.gif',
2504
                            'visibility' => '0',
2505
                            'admin' => '0',
2506
                            'address' => 'squaregrey.gif',
2507
                            'session_id' => $session_id,
2508
                        ];
2509
                        $insertId = Database::insert($table_tool, $params);
2510
                        if ($insertId) {
2511
                            $sql = "UPDATE $table_tool SET id = iid WHERE iid = $insertId";
2512
                            Database::query($sql);
2513
                        }
2514
                    }
2515
2516
                    api_item_property_update(
2517
                        $this->destination_course_info,
2518
                        TOOL_LEARNPATH,
2519
                        $new_lp_id,
2520
                        'LearnpathAdded',
2521
                        api_get_user_id(),
2522
                        0,
2523
                        0,
2524
                        0,
2525
                        0,
2526
                        $session_id
2527
                    );
2528
2529
                    // Set the new LP to visible
2530
                    api_item_property_update(
2531
                        $this->destination_course_info,
2532
                        TOOL_LEARNPATH,
2533
                        $new_lp_id,
2534
                        'invisible',
2535
                        api_get_user_id(),
2536
                        0,
2537
                        0,
2538
                        0,
2539
                        0,
2540
                        $session_id
2541
                    );
2542
                }
2543
2544
                $new_item_ids = array();
2545
                $parent_item_ids = array();
2546
                $previous_item_ids = array();
2547
                $next_item_ids = array();
2548
                $old_prerequisite = array();
2549
                $old_refs = array();
2550
                $prerequisite_ids = array();
2551
2552
				foreach ($lp->get_items() as $index => $item) {
2553
					// we set the ref code here and then we update in a for loop
2554
					$ref = $item['ref'];
2555
2556
					// Dealing with path the same way as ref as some data has
2557
                    // been put into path when it's a local resource
2558
					// Only fix the path for no scos
2559
                    if ($item['item_type'] == 'sco') {
2560
                        $path = $item['path'];
2561
                    } else {
2562
                        $path = $item['path'];
2563
                        $path = $this->get_new_id($item['item_type'], $path);
2564
                    }
2565
2566
                    $params = [
2567
                        'c_id' => $this->destination_course_id,
2568
                        '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 2491 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...
2569
                        'item_type' => self::DBUTF8($item['item_type']),
2570
                        'ref' => self::DBUTF8($ref),
2571
                        'title' => self::DBUTF8($item['title']),
2572
                        'description' => self::DBUTF8($item['description']),
2573
                        'path' => self::DBUTF8($path),
2574
                        'min_score' => self::DBUTF8($item['min_score']),
2575
                        'max_score' => self::DBUTF8($item['max_score']),
2576
                        'mastery_score' => self::DBUTF8($item['mastery_score']),
2577
                        'parent_item_id' => self::DBUTF8($item['parent_item_id']),
2578
                        'previous_item_id' => self::DBUTF8($item['previous_item_id']),
2579
                        'next_item_id' => self::DBUTF8($item['next_item_id']),
2580
                        'display_order' => self::DBUTF8($item['display_order']),
2581
                        'prerequisite' => self::DBUTF8($item['prerequisite']),
2582
                        'parameters' => self::DBUTF8($item['parameters']),
2583
                        'audio' => self::DBUTF8($item['audio']),
2584
                        'launch_data' => self::DBUTF8($item['launch_data']),
2585
                    ];
2586
2587
					$new_item_id = Database::insert($table_item, $params);
2588
2589
                    $sql = "UPDATE $table_item SET id = iid WHERE iid = $new_item_id";
2590
                    Database::query($sql);
2591
2592
					//save a link between old and new item IDs
2593
					$new_item_ids[$item['id']] = $new_item_id;
2594
					//save a reference of items that need a parent_item_id refresh
2595
					$parent_item_ids[$new_item_id] = $item['parent_item_id'];
2596
					//save a reference of items that need a previous_item_id refresh
2597
					$previous_item_ids[$new_item_id] = $item['previous_item_id'];
2598
					//save a reference of items that need a next_item_id refresh
2599
					$next_item_ids[$new_item_id] = $item['next_item_id'];
2600
2601
					if (!empty($item['prerequisite'])) {
2602
						if ($lp->lp_type =='2') {
2603
							// if is an sco
2604
							$old_prerequisite[$new_item_id]= $item['prerequisite'];
2605
						} else {
2606
							$old_prerequisite[$new_item_id]= $new_item_ids[$item['prerequisite']];
2607
						}
2608
					}
2609
2610
					if (!empty($ref)) {
2611
						if ($lp->lp_type =='2') {
2612
							// if is an sco
2613
							$old_refs[$new_item_id]= $ref;
2614
						} else {
2615
                            $old_refs[$new_item_id]= $new_item_ids[$ref];
2616
						}
2617
					}
2618
2619
					$prerequisite_ids[$new_item_id] = $item['prerequisite'];
2620
				}
2621
2622
				// Updating prerequisites
2623 View Code Duplication
				foreach ($old_prerequisite  as $key=>$my_old_prerequisite) {
2624
					if($my_old_prerequisite != ''){
2625
						$sql = "UPDATE ".$table_item." SET prerequisite = '".$my_old_prerequisite."'
2626
						        WHERE c_id = ".$this->destination_course_id." AND id = '".$key."'  ";
2627
						Database::query($sql);
2628
					}
2629
				}
2630
2631
				// Updating refs
2632 View Code Duplication
				foreach ($old_refs  as $key=>$my_old_ref) {
2633
					if ($my_old_ref != '') {
2634
						$sql = "UPDATE ".$table_item." SET ref = '".$my_old_ref."'
2635
						        WHERE c_id = ".$this->destination_course_id." AND id = '".$key."'  ";
2636
						Database::query($sql);
2637
					}
2638
				}
2639
2640 View Code Duplication
				foreach ($parent_item_ids as $new_item_id => $parent_item_old_id) {
2641
					$parent_new_id = 0;
2642
					if($parent_item_old_id != 0){
2643
						$parent_new_id = $new_item_ids[$parent_item_old_id];
2644
					}
2645
					$sql = "UPDATE ".$table_item." SET parent_item_id = '".$parent_new_id."'
2646
					        WHERE c_id = ".$this->destination_course_id." AND id = '".$new_item_id."'";
2647
					Database::query($sql);
2648
				}
2649 View Code Duplication
				foreach ($previous_item_ids as $new_item_id => $previous_item_old_id) {
2650
					$previous_new_id = 0;
2651
					if($previous_item_old_id != 0){
2652
						$previous_new_id = $new_item_ids[$previous_item_old_id];
2653
					}
2654
					$sql = "UPDATE ".$table_item." SET previous_item_id = '".$previous_new_id."'
2655
					        WHERE  c_id = ".$this->destination_course_id." AND id = '".$new_item_id."'";
2656
					Database::query($sql);
2657
				}
2658
2659 View Code Duplication
				foreach ($next_item_ids as $new_item_id => $next_item_old_id) {
2660
					$next_new_id = 0;
2661
					if($next_item_old_id != 0){
2662
						$next_new_id = $new_item_ids[$next_item_old_id];
2663
					}
2664
					$sql = "UPDATE ".$table_item." SET next_item_id = '".$next_new_id."'
2665
					        WHERE c_id = ".$this->destination_course_id." AND id = '".$new_item_id."'";
2666
					Database::query($sql);
2667
				}
2668
2669 View Code Duplication
				foreach ($prerequisite_ids as $new_item_id => $prerequisite_old_id) {
2670
					$prerequisite_new_id = 0;
2671
					if($prerequisite_old_id != 0){
2672
						$prerequisite_new_id = $new_item_ids[$prerequisite_old_id];
2673
					}
2674
					$sql = "UPDATE ".$table_item." SET prerequisite = '".$prerequisite_new_id."'
2675
					        WHERE c_id = ".$this->destination_course_id." AND id = '".$new_item_id."'";
2676
					Database::query($sql);
2677
				}
2678
				$this->course->resources[RESOURCE_LEARNPATH][$id]->destination_id = $new_lp_id;
2679
			}
2680
		}
2681
	}
2682
2683
	/**
2684
	 * Restore works
2685
     * @deprecated use restore_works
2686
     *
2687
	 */
2688
	public function restore_student_publication($sessionId = 0)
2689
    {
2690
        $sessionId = intval($sessionId);
2691
		$work_assignment_table  = Database :: get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
2692
		$work_table = Database :: get_course_table(TABLE_STUDENT_PUBLICATION);
2693
		$item_property_table  	= Database :: get_course_table(TABLE_ITEM_PROPERTY);
2694
2695
		// Query in student publication
2696
		$sql = 'SELECT * FROM '.$work_table.'
2697
		        WHERE c_id = '.$this->course_origin_id.' AND filetype = "folder" AND active IN (0, 1) ';
2698
2699
		$result = Database::query($sql);
2700
		$folders = Database::store_result($result, 'ASSOC');
2701
2702
		foreach ($folders  as $folder) {
2703
		    $old_id = $folder['id'];
2704
            unset($folder['id']);
2705
			$folder['c_id'] = $this->destination_course_id;
2706
            $folder['parent_id'] = 0;
2707
            $folder['session_id'] = $sessionId;
2708
			$new_id = Database::insert($work_table, $folder);
2709
2710
            if ($new_id) {
2711
                //query in item property
2712
                $sql = 'SELECT
2713
                        tool,
2714
                        insert_user_id,
2715
                        insert_date,
2716
                        lastedit_date,
2717
                        ref,
2718
                        lastedit_type,
2719
                        lastedit_user_id,
2720
                        to_group_id,
2721
                        to_user_id,
2722
                        visibility,
2723
                        start_visible,
2724
                        end_visible
2725
                        FROM '.$item_property_table.' ip
2726
                        INNER JOIN '.$work_table.' sp
2727
                        ON ip.ref=sp.id
2728
                        WHERE
2729
                            sp.c_id = '.$this->course_origin_id.' AND
2730
                            ip.c_id = '.$this->course_origin_id.' AND
2731
                            tool="work" AND sp.id = '.$old_id.'';
2732
2733
                $result = Database::query($sql);
2734
                $sub_folders = Database::store_result($result, 'ASSOC');
2735
                foreach ($sub_folders  as $sub_folder) {
2736
                    $sub_folder['c_id'] = $this->destination_course_id;
2737
                    $sub_folder['ref'] = $new_id;
2738
                    $sub_folder['session_id'] = $sessionId;
2739
                    $new_item_id = Database::insert($item_property_table, $sub_folder);
2740
                    if ($new_item_id) {
2741
                        $sql = "UPDATE $item_property_table SET id = iid WHERE iid = $new_item_id";
2742
                        Database::query($sql);
2743
                    }
2744
                }
2745
2746
                $sql = 'SELECT sa.id, sa.expires_on,sa.ends_on,sa.add_to_calendar, sa.enable_qualification, sa.publication_id
2747
                        FROM '.$work_assignment_table.' sa
2748
                        INNER JOIN '.$work_table.' sp ON sa.publication_id=sp.id
2749
                        WHERE
2750
                            sp.c_id = '.$this->course_origin_id.' AND
2751
                            sa.c_id = '.$this->course_origin_id.' AND
2752
                            filetype="folder" AND sp.id = '.$old_id.'';
2753
2754
                $result = Database::query($sql);
2755
                $assing_list = Database::store_result($result, 'ASSOC');
2756
                foreach ($assing_list  as $assign) {
2757
                    $assign['c_id'] = $this->destination_course_id;
2758
                    $assign['id'] = $new_id;
2759
                    $assignmentId = Database::insert($work_assignment_table, $assign);
2760
2761
                    if ($assignmentId) {
2762
                        $sql = "UPDATE $work_assignment_table SET id = iid WHERE iid = $assignmentId";
2763
                        Database::query($sql);
2764
                    }
2765
                }
2766
            }
2767
		}
2768
2769
		$destination = '../../courses/'.$this->course->destination_path.'/work/';
2770
		$origin = '../../courses/'.$this->course->info['path'].'/work/';
2771
		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...
2772
	}
2773
2774
    /**
2775
    * copy all directory and sub directory
2776
    * @param string The path origin
2777
    * @param string The path destination
2778
    * @param boolean Option Overwrite
2779
    * @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...
2780
    * @deprecated
2781
    */
2782
    public function allow_create_all_directory($source, $dest, $overwrite = false)
2783
    {
2784
        if (!is_dir($dest)) {
2785
            mkdir($dest, api_get_permissions_for_new_directories());
2786
        }
2787
        if ($handle = opendir($source)) {        // if the folder exploration is sucsessful, continue
2788
            while (false !== ($file = readdir($handle))) { // as long as storing the next file to $file is successful, continue
2789
                if ($file != '.' && $file != '..') {
2790
                    $path = $source . '/' . $file;
2791
                    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...
2792
                       /* if (!is_file($dest . '/' . $file) || $overwrite)
2793
                        if (!@copy($path, $dest . '/' . $file)) {
2794
                            echo '<font color="red">File ('.$path.') '.get_lang('NotHavePermission').'</font>';
2795
                        }*/
2796
                    } elseif(is_dir($path)) {
2797
                        if (!is_dir($dest . '/' . $file))
2798
                        mkdir($dest . '/' . $file);
2799
                       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...
2800
                    }
2801
                }
2802
            }
2803
            closedir($handle);
2804
        }
2805
    }
2806
2807
	/**
2808
	 * Gets the new ID of one specific tool item from the tool name and the old ID
2809
	 * @param	string	Tool name
2810
	 * @param	integer	Old ID
2811
	 * @return	integer	New ID
2812
	 */
2813
    public function get_new_id($tool, $ref)
2814
    {
2815
        // Check if the value exist in the current array.
2816
2817
        if ($tool == 'hotpotatoes') {
2818
            $tool = 'document';
2819
        }
2820
2821
        if (isset($this->course->resources[$tool][$ref]) &&
2822
            isset($this->course->resources[$tool][$ref]->destination_id) &&
2823
            !empty($this->course->resources[$tool][$ref]->destination_id)
2824
        ) {
2825
            return $this->course->resources[$tool][$ref]->destination_id;
2826
        }
2827
2828
        // Check if the course is the same (last hope).
2829
        if ($this->course_origin_id == $this->destination_course_id) {
2830
            return $ref;
2831
        }
2832
2833
        return '';
2834
	}
2835
2836
	/**
2837
	 * Restore glossary
2838
	 */
2839
    public function restore_glossary($session_id = 0)
2840
    {
2841
		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...
2842
			$table_glossary = Database :: get_course_table(TABLE_GLOSSARY);
2843
			$resources = $this->course->resources;
2844
			foreach ($resources[RESOURCE_GLOSSARY] as $id => $glossary) {
2845
2846
                $params = [];
2847
    			if (!empty($session_id)) {
2848
    				$session_id = intval($session_id);
2849
                    $params['session_id'] = $session_id;
2850
    			}
2851
2852
				// check resources inside html from ckeditor tool and copy correct urls into recipient course
2853
                $glossary->description = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2854
                    $glossary->description,
2855
                    $this->course->code,
2856
                    $this->course->destination_path,
2857
                    $this->course->backup_path,
2858
                    $this->course->info['path']
2859
                );
2860
2861
                $params['c_id'] = $this->destination_course_id;
2862
                $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...
2863
                $params['display_order'] = $glossary->display_order;
2864
                $params['name'] = self::DBUTF8($glossary->name);
2865
2866
                $my_id = Database::insert($table_glossary, $params);
2867 View Code Duplication
                if ($my_id) {
2868
2869
                    $sql = "UPDATE $table_glossary SET glossary_id = iid WHERE iid = $my_id";
2870
                    Database::query($sql);
2871
2872
                    api_item_property_update(
2873
                        $this->destination_course_info,
2874
                        TOOL_GLOSSARY,
2875
                        $my_id,
2876
                        "GlossaryAdded",
2877
                        api_get_user_id()
2878
                    );
2879
2880
                    if (!isset($this->course->resources[RESOURCE_GLOSSARY][$id])) {
2881
                        $this->course->resources[RESOURCE_GLOSSARY][$id] = new stdClass();
2882
                    }
2883
2884
                    $this->course->resources[RESOURCE_GLOSSARY][$id]->destination_id = $my_id;
2885
                }
2886
			}
2887
		}
2888
	}
2889
2890
    /**
2891
     * @param int $session_id
2892
     */
2893
    public function restore_wiki($session_id = 0)
2894
    {
2895
		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...
2896
			// wiki table of the target course
2897
			$table_wiki = Database :: get_course_table(TABLE_WIKI);
2898
			$table_wiki_conf = Database :: get_course_table(TABLE_WIKI_CONF);
2899
2900
			// storing all the resources that have to be copied in an array
2901
			$resources = $this->course->resources;
2902
2903
			foreach ($resources[RESOURCE_WIKI] as $id => $wiki) {
2904
				// the sql statement to insert the groups from the old course to the new course
2905
2906
				// check resources inside html from ckeditor tool and copy correct urls into recipient course
2907
                $wiki->content = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2908
                    $wiki->content,
2909
                    $this->course->code,
2910
                    $this->course->destination_path,
2911
                    $this->course->backup_path,
2912
                    $this->course->info['path']
2913
                );
2914
2915
                $params = [
2916
                    'c_id' => $this->destination_course_id,
2917
                    'page_id' => self::DBUTF8($wiki->page_id),
2918
                    'reflink' => self::DBUTF8($wiki->reflink),
2919
                    'title' => self::DBUTF8($wiki->title),
2920
                    '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...
2921
                    'user_id' => intval($wiki->user_id),
2922
                    'group_id' => intval($wiki->group_id),
2923
                    'dtime' => self::DBUTF8($wiki->dtime),
2924
                    'progress' => self::DBUTF8($wiki->progress),
2925
                    'version' => intval($wiki->version),
2926
                    'session_id' => !empty($session_id) ? intval($session_id) : 0,
2927
                ];
2928
2929
				$new_id = Database::insert($table_wiki, $params);
2930
2931
                if ($new_id) {
2932
2933
                    $sql = "UPDATE $table_wiki SET page_id = '$new_id', id = iid
2934
                            WHERE c_id = ".$this->destination_course_id." AND iid = '$new_id'";
2935
                    Database::query($sql);
2936
2937
                    $this->course->resources[RESOURCE_WIKI][$id]->destination_id = $new_id;
2938
2939
                    // we also add an entry in wiki_conf
2940
                    $params = [
2941
                        'c_id' => $this->destination_course_id,
2942
                        'page_id' => $new_id,
2943
                        'task' => '',
2944
                        'feedback1' => '',
2945
                        'feedback2' => '',
2946
                        'feedback3' => '',
2947
                        'fprogress1' => '',
2948
                        'fprogress2' => '',
2949
                        'fprogress3' => '',
2950
                        'max_size' => '',
2951
                        'max_text' => 0,
2952
                        'max_version' => 0,
2953
                        'startdate_assig' => '',
2954
                        'enddate_assig' => '',
2955
                        'delayedsubmit' => 0,
2956
                    ];
2957
2958
                    Database::insert($table_wiki_conf, $params);
2959
                }
2960
			}
2961
		}
2962
	}
2963
2964
    /**
2965
     * Restore Thematics
2966
     * @param int $session_id
2967
     */
2968
    public function restore_thematic($session_id = 0)
2969
    {
2970
		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...
2971
            $table_thematic = Database:: get_course_table(TABLE_THEMATIC);
2972
            $table_thematic_advance = Database:: get_course_table(TABLE_THEMATIC_ADVANCE);
2973
            $table_thematic_plan = Database:: get_course_table(TABLE_THEMATIC_PLAN);
2974
2975
			$resources = $this->course->resources;
2976
			foreach ($resources[RESOURCE_THEMATIC] as $id => $thematic) {
2977
2978
				// check resources inside html from ckeditor tool and copy correct urls into recipient course
2979
                $thematic->params['content'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
2980
                    $thematic->params['content'],
2981
                    $this->course->code,
2982
                    $this->course->destination_path,
2983
                    $this->course->backup_path,
2984
                    $this->course->info['path']
2985
                );
2986
				$thematic->params['c_id']  = $this->destination_course_id;
2987
				unset($thematic->params['id']);
2988
                unset($thematic->params['iid']);
2989
2990
				$last_id = Database::insert($table_thematic, $thematic->params, false);
2991
2992
				if ($last_id) {
2993
2994
                    $sql = "UPDATE $table_thematic SET id = iid WHERE iid = $last_id";
2995
                    Database::query($sql);
2996
2997
                    api_item_property_update(
2998
                        $this->destination_course_info,
2999
                        'thematic',
3000
                        $last_id,
3001
                        "ThematicAdded",
3002
                        api_get_user_id()
3003
                    );
3004
3005 View Code Duplication
					foreach ($thematic->thematic_advance_list as $thematic_advance) {
3006
						unset($thematic_advance['id']);
3007
                        unset($thematic_advance['iid']);
3008
						$thematic_advance['attendance_id'] = 0;
3009
						$thematic_advance['thematic_id'] = $last_id;
3010
						$thematic_advance['c_id']  = $this->destination_course_id;
3011
                        $my_id = Database::insert(
3012
                            $table_thematic_advance,
3013
                            $thematic_advance,
3014
                            false
3015
                        );
3016
3017
						if ($my_id) {
3018
3019
                            $sql = "UPDATE $table_thematic_advance SET id = iid WHERE iid = $my_id";
3020
                            Database::query($sql);
3021
3022
                            api_item_property_update(
3023
                                $this->destination_course_info,
3024
                                'thematic_advance',
3025
                                $my_id,
3026
                                "ThematicAdvanceAdded",
3027
                                api_get_user_id()
3028
                            );
3029
						}
3030
					}
3031
3032 View Code Duplication
					foreach($thematic->thematic_plan_list as $thematic_plan) {
3033
						unset($thematic_plan['id']);
3034
                        unset($thematic_plan['iid']);
3035
						$thematic_plan['thematic_id'] = $last_id;
3036
						$thematic_plan['c_id'] = $this->destination_course_id;
3037
						$my_id = Database::insert($table_thematic_plan, $thematic_plan, false);
3038
3039
						if ($my_id) {
3040
3041
                            $sql = "UPDATE $table_thematic_plan SET id = iid WHERE iid = $my_id";
3042
                            Database::query($sql);
3043
3044
                            api_item_property_update(
3045
                                $this->destination_course_info,
3046
                                'thematic_plan',
3047
                                $my_id,
3048
                                "ThematicPlanAdded",
3049
                                api_get_user_id()
3050
                            );
3051
						}
3052
					}
3053
				}
3054
			}
3055
		}
3056
	}
3057
3058
    /**
3059
     * Restore Attendance
3060
     * @param int $session_id
3061
     */
3062
    public function restore_attendance($session_id = 0)
3063
    {
3064
		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...
3065
			$table_attendance = Database :: get_course_table(TABLE_ATTENDANCE);
3066
			$table_attendance_calendar = Database :: get_course_table(TABLE_ATTENDANCE_CALENDAR);
3067
3068
			$resources = $this->course->resources;
3069
			foreach ($resources[RESOURCE_ATTENDANCE] as $id => $obj) {
3070
3071
				// check resources inside html from ckeditor tool and copy correct urls into recipient course
3072
                $obj->params['description'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
3073
                    $obj->params['description'],
3074
                    $this->course->code,
3075
                    $this->course->destination_path,
3076
                    $this->course->backup_path,
3077
                    $this->course->info['path']
3078
                );
3079
3080
                unset($obj->params['id']);
3081
                unset($obj->params['iid']);
3082
3083
				$obj->params['c_id'] = $this->destination_course_id;
3084
3085
				$last_id = Database::insert($table_attendance, $obj->params);
3086
3087
				if (is_numeric($last_id)) {
3088
3089
                    $sql = "UPDATE $table_attendance SET id = iid WHERE iid = $last_id";
3090
                    Database::query($sql);
3091
3092
                    api_item_property_update(
3093
                        $this->destination_course_info,
3094
                        TOOL_ATTENDANCE,
3095
                        $last_id,
3096
                        "AttendanceAdded",
3097
                        api_get_user_id()
3098
                    );
3099
3100
                    foreach ($obj->attendance_calendar as $attendance_calendar) {
3101
						unset($attendance_calendar['id']);
3102
                        unset($attendance_calendar['iid']);
3103
3104
						$attendance_calendar['attendance_id'] = $last_id;
3105
						$attendance_calendar['c_id'] = $this->destination_course_id;
3106
                        $attendanceCalendarId = Database::insert(
3107
                            $table_attendance_calendar,
3108
                            $attendance_calendar
3109
                        );
3110
3111
                        $sql = "UPDATE $table_attendance_calendar SET id = iid WHERE iid = $attendanceCalendarId";
3112
                        Database::query($sql);
3113
					}
3114
				}
3115
			}
3116
		}
3117
	}
3118
3119
    /**
3120
     * Restore Works
3121
     * @param int $sessionId
3122
     */
3123
    public function restore_works($sessionId = 0)
3124
    {
3125
        require_once api_get_path(SYS_CODE_PATH).'work/work.lib.php';
3126
        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...
3127
            $table_work_assignment = Database :: get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
3128
3129
            $resources = $this->course->resources;
3130
            foreach ($resources[RESOURCE_WORK] as $obj) {
3131
3132
                // check resources inside html from ckeditor tool and copy correct urls into recipient course
3133
                $obj->params['description'] = DocumentManager::replace_urls_inside_content_html_from_copy_course(
3134
                    $obj->params['description'],
3135
                    $this->course->code,
3136
                    $this->course->destination_path,
3137
                    $this->course->backup_path,
3138
                    $this->course->info['path']
3139
                );
3140
3141
                $id_work = $obj->params['id'];
3142
                $obj->params['id'] = null;
3143
                $obj->params['c_id'] = $this->destination_course_info['real_id'];
3144
3145
                // re-create dir
3146
                // @todo check security against injection of dir in crafted course backup here!
3147
                $path = $obj->params['url'];
3148
                $path = '/'.str_replace('/','',substr($path,1));
3149
3150
                $workData = array();
3151
                switch ($this->file_option) {
3152
                    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...
3153
                        $workData = get_work_data_by_path(
3154
                            $path,
3155
                            $this->destination_course_info['real_id']
3156
                        );
3157
                        if (!empty($workData)) {
3158
                            continue;
3159
                        }
3160
                    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...
3161
                        // Creating folder.
3162
                        $workData = get_work_data_by_path(
3163
                            $path,
3164
                            $this->destination_course_info['real_id']
3165
                        );
3166
                    case FILE_RENAME:
3167
                        $obj->params['new_dir'] = $obj->params['title'];
3168
3169
                        if (!empty($this->course_origin_id)) {
3170
                            $sql = 'SELECT * FROM ' . $table_work_assignment . '
3171
                                    WHERE
3172
                                        c_id = ' . $this->course_origin_id . ' AND
3173
                                        publication_id = ' . $id_work;
3174
3175
                            $result = Database::query($sql);
3176
                            $cant = Database::num_rows($result);
3177
                            if ($cant > 0) {
3178
                                $row = Database::fetch_assoc($result);
3179
                            }
3180
3181
                            //$obj->params['qualification'] = empty($row['enable_qualification']) ? true : false;
3182
                            $obj->params['enableExpiryDate'] = $row['expires_on'] == '0000-00-00 00:00:00' ? false : true;
3183
                            $obj->params['enableEndDate'] = $row['ends_on'] == '0000-00-00 00:00:00' ? false : true;
3184
                            $obj->params['expires_on'] = $row['expires_on'];
3185
                            $obj->params['ends_on'] = $row['ends_on'];
3186
                            $obj->params['enable_qualification'] = $row['enable_qualification'];
3187
                            $obj->params['add_to_calendar'] = !empty($row['add_to_calendar']) ? 1 : 0;
3188
3189
                            if (empty($workData)) {
3190
                                addDir(
3191
                                    $obj->params,
3192
                                    api_get_user_id(),
3193
                                    $this->destination_course_info,
3194
                                    0,
3195
                                    $sessionId
3196
                                );
3197
                            } else {
3198
                                $workId = $workData['id'];
3199
                                updateWork(
3200
                                    $workId,
3201
                                    $obj->params,
3202
                                    $this->destination_course_info,
3203
                                    $sessionId
3204
                                );
3205
                                updatePublicationAssignment(
3206
                                    $workId,
3207
                                    $obj->params,
3208
                                    $this->destination_course_info,
3209
                                    0
3210
                                );
3211
                            }
3212
                        }
3213
                        break;
3214
                }
3215
            }
3216
        }
3217
    }
3218
3219
    /**
3220
     * Restore Works
3221
     * @param int $sessionId
3222
     */
3223
    public function restore_gradebook($sessionId = 0)
3224
    {
3225
        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...
3226
            $resources = $this->course->resources;
3227
            /**
3228
             * @var GradeBookBackup $obj
3229
             */
3230
            foreach ($resources[RESOURCE_GRADEBOOK] as $id => $obj) {
3231
                if (!empty($obj->categories)) {
3232
                    $categoryIdList = [];
3233
                    /** @var Category $cat */
3234
                    foreach ($obj->categories as $cat) {
3235
                        $cat->set_course_code($this->destination_course_info['code']);
3236
                        $cat->set_session_id($sessionId);
3237
3238
                        $parentId = $cat->get_parent_id();
3239
                        if (!empty($parentId)) {
3240
                            if (isset($categoryIdList[$parentId])) {
3241
                                $cat->set_parent_id($categoryIdList[$parentId]);
3242
                            }
3243
                        }
3244
                        $oldId = $cat->get_id();
3245
                        $categoryId = $cat->add();
3246
                        $categoryIdList[$oldId] = $categoryId;
3247
                    }
3248
                }
3249
            }
3250
        }
3251
    }
3252
3253
    /**
3254
     * @param string $str
3255
     * @return string
3256
     */
3257
    public function DBUTF8($str)
3258
    {
3259
		if (UTF8_CONVERT) {
3260
            $str = utf8_encode($str);
3261
        }
3262
		return $str;
3263
	}
3264
3265
    /**
3266
     * @param string $str
3267
     * @return string
3268
     */
3269
    public function DBUTF8escapestring($str)
3270
    {
3271
        if (UTF8_CONVERT) {
3272
            $str = utf8_encode($str);
3273
        }
3274
		return Database::escape_string($str);
3275
	}
3276
3277
    /**
3278
     * @param array $array
3279
     * @return mixed
3280
     */
3281
    public function DBUTF8_array($array)
3282
    {
3283
        if (UTF8_CONVERT) {
3284
            foreach ($array as &$item)  {
3285
                $item = utf8_encode($item);
3286
            }
3287
            return $array;
3288
        } else {
3289
            return $array;
3290
        }
3291
    }
3292
3293
    /**
3294
     * Check if user exist otherwise use current user
3295
     * @param int $userId
3296
     * @param bool $returnNull
3297
     *
3298
     * @return int
3299
     */
3300
    private function checkUserId($userId, $returnNull = false) {
3301
3302
        if (!empty($userId)) {
3303
            $userInfo = api_get_user_info($userId);
3304
            if (empty($userInfo)) {
3305
                return api_get_user_id();
3306
            }
3307
        }
3308
3309
        if ($returnNull) {
3310
            return null;
3311
        }
3312
3313
        return $userId;
3314
    }
3315
}
3316